exponenta event banner

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

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

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

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

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

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

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

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

Восстановить не зависящие свойства

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

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

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

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

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

  • Функция загрузки восстанавливает 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, загружая, он вызывает свой метод аппарата и вызывает TotalDistance для повторной установки свойства.

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

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

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

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

Связанные темы