Избегайте зависимости порядка инициализации свойств

Загрузка свойств управления

Проблемы могут возникнуть, если значения свойств зависят от порядка, в котором load устанавливает значения свойств.

Предположим, что ваш проект класса такова, что оба из следующих являются true:

  • Метод набора свойств изменяет другое значение свойства.

  • Значение свойства вычисляется из других значений свойств.

Тогда окончательное состояние объекта после изменения ряда значений свойств может зависеть от порядка, в котором вы задаете свойства. Эта зависимость порядка может повлиять на результат загрузки объекта.

load функция устанавливает значения свойств в конкретном порядке. Этот порядок может отличаться от порядка, в котором вы устанавливаете свойства в сохраненном объекте. В результате загруженный объект может иметь другие значения свойств, чем объект, когда он был сохранен.

Восстановление недозависимых свойств

Если функция набора свойств изменяет значения других свойств, задайте Dependent атрибут этого свойства как true. MATLAB® не сохраняет и не восстанавливает значения зависимых свойств.

Используйте независимые свойства для хранения значений, заданных зависимым свойством. Затем load функция восстанавливает невязочные свойства с теми же значениями, которые были сохранены. load функция не вызывает метод набора зависимых свойств, потому что в сохраненном файле нет значения для этого свойства.

Зависимое свойство с частным хранилищем

The Odometer класс избегает зависимостей порядка при загрузке объектов путем управления, какие свойства восстанавливаются при загрузке:

  • The Units свойство является зависимым. Его метод набора свойств устанавливает TotalDistance свойство. Поэтому load не вызывает Units метод набора свойств.

  • Функция load восстанавливает TotalDistance с любым значением, которое оно имело при сохранении объекта.

classdef Odometer
   properties(Constant)
      ConversionFactor = 1.6
   end
   properties
      TotalDistance = 0
   end
   properties(Dependent)
      Units
   end
   properties(Access=private)
      PrivateUnits = 'mi'
   end
   methods
      function unit = get.Units(obj)
         unit = obj.PrivateUnits;
      end
      function obj = set.Units(obj,newUnits)
         % validate newUnits to be a char vector
         switch(newUnits)
            case 'mi'
               if strcmp(obj.PrivateUnits,'km')
                  obj.TotalDistance = obj.TotalDistance / ...
                     obj.ConversionFactor;
                  obj.PrivateUnits = newUnits;
               end
            case 'km'
               if strcmp(obj.PrivateUnits,'mi')
                  obj.TotalDistance = obj.TotalDistance * ...
                     obj.ConversionFactor;
                  obj.PrivateUnits = newUnits;
               end
            otherwise
               error('Odometer:InvalidUnits', ...
                  'Units ''%s'' is not supported.', newUnits);
         end
      end
   end
end

Предположим, что вы создаете образец Odometer и установите следующие значения свойств:

odObj = Odometer;
odObj.Units = 'km';
odObj.TotalDistance = 16;

Когда вы сохраняете объект:

  • ConversionFactor не сохранен, потому что это Constant свойство.

  • TotalDistance сохранен.

  • Units не сохранен, потому что это Dependent свойство.

  • PrivateUnits сохранен и предоставляет хранилище для текущего значения Units.

Когда вы загружаете объект:

  • ConversionFactor получен из определения класса.

  • TotalDistance загружается.

  • Units не загружен, поэтому его метод set не вызывается.

  • PrivateUnits загружается из сохраненного объекта.

Если на Units свойство не Dependent, загрузка вызывает свой метод set и вызывает TotalDistance свойство, которое будет установлено снова.

Значение свойства, вычисленное из других свойств

The Odometer2 классы TripDistance свойство зависит только от значений двух других свойств, TotalDistance и TripMarker.

Класс избегает зависимости порядка при инициализации значений свойств в процессе загрузки путем создания TripDistance зависимый от свойств. MATLAB не сохраняет и не загружает значение для TripDistance свойство, но сохраняет и загружает значения для двух свойств, используемых для вычисления TripDistance в своем методе получения свойств.

classdef Odometer2
   properties
      TotalDistance = 0
      TripMarker = 0
   end
   properties(Dependent)
      TripDistance
   end
   methods
      function distance = get.TripDistance(obj)
         distance = obj.TotalDistance - obj.TripMarker;
      end
   end
end

Похожие темы