Поддержание совместимости классов

Свойство переименования

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

classdef EmployeeList
   properties
      Name
      Email
      OfficeNumber % Rename as Location
   end
end

Использование скрытого зависимого свойства может достичь желаемых результатов.

  • В определении класса установите OfficeNumber атрибуты свойств к Dependent и Hidden.

  • Создайте метод набора свойств для OfficeNumber который устанавливает значение Location свойство.

  • Создайте метод получения свойств для OfficeNumber который возвращает значение Location свойство местоположения.

В то время как OfficeNumber свойство скрыто, существующий код может продолжить доступ к этому свойству. The Hidden атрибут не влияет на доступ.

Потому что OfficeNumber является зависимым, нет избыточности в хранилище, требуемой путем добавления нового свойства. MATLAB® не хранит и не сохраняет зависимые свойства.

Вот обновленное определение класса.

classdef EmployeeList
   properties
      Name
      Email
      Location
   end
   properties (Dependent, Hidden)
      OfficeNumber
   end
   methods
      function obj = set.OfficeNumber(obj,val)
         obj.Location = val;
      end
      function val = get.OfficeNumber(obj)
         val = obj.Location;    
      end
   end
end

Сохранение и загрузка EmployeeList Объекты

Можно загрузить старые образцы EmployeeList класс при наличии новой версии класса. Код, который относится к OfficeNumber свойство продолжает работать.

Прямая и обратная совместимость

Предположим, что вы хотите иметь возможность загружать новые EmployeeList объекты в системы, которые все еще имеют старую версию EmployeeList класс. Для достижения совместимости со старыми и новыми версиями:

  • Определите OfficeNumber свойство как Hidden, но не Dependent.

  • Определите Location свойство как Dependent.

В этой версии EmployeeList класс, OfficeNumber свойство сохраняет значение, используемое Location свойство. При загрузке объекта присваиваются значения трех исходных свойств (Name, Email, и OfficeNumber), но не присваивает значение новому Location свойство. Отсутствие Location свойство в определении старого класса не является проблемой.

classdef EmployeeList
   properties
      Name
      Email
   end
   properties (Dependent)
      Location
   end
   properties (Hidden)
      OfficeNumber
   end
   methods
      function obj = set.Location(obj,val)
         obj.OfficeNumber = val;
      end
      function val = get.Location(obj)
         val = obj.OfficeNumber;
      end
   end
end

Свойство Update при загрузке

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

Рассмотрим класс, который имеет AccountID свойство. Предположим, что все номера счетов должны мигрировать с восьмизначных числовых значений на 12-элементные символьные массивы.

Вы можете принять это изменение путем реализации loadobj способ.

loadobj метод:

  • Тесты, чтобы определить, является ли load функция прошла struct или объект. Все loadobj методы должны обрабатывать оба struct и объект, когда есть ошибка в load.

  • Тесты, чтобы определить, AccountID ли номер содержит восемь цифр. Если это так, измените его на 12-элементный символьный массив путем вызова paddAccID способ.

После обновления AccountID свойство, loadobj возвращает MyAccount объект, который MATLAB загружает в рабочую область.

classdef MyAccount
   properties
      AccountID
   end
   methods
      function obj = padAccID(obj)
         ac = obj.AccountID;
         acstr = num2str(ac);
         if length(acstr) < 12
            obj.AccountID = [acstr,repmat('0',1,12-length(acstr))];
         end
      end
   end
   methods (Static)
      function obj = loadobj(a)
         if isstruct(a)
            obj = MyAccount;
            obj.AccountID = a.AccountID;
            obj = padAccID(obj);
         elseif isa(a,'MyAccount')
            obj = padAccID(a);
         end
      end
   end
end

Вам не нужно реализовывать saveobj способ. Вы используете loadobj только для обеспечения актуальности старых сохраненных объектов во время загрузки.

Поддержание совместимых версий класса

The PhoneBookEntry класс использует комбинацию методов для поддержания совместимости с новыми версиями класса.

Предположим, что вы задаете класс, который будет представлять запись в телефонной книге. The PhoneBookEntry класс задает три свойства: Name, Address, и PhoneNumber.

classdef PhoneBookEntry
   properties
      Name
      Address
      PhoneNumber
   end
end

Однако в будущих релизах класс добавляет больше свойств. Для обеспечения гибкости, PhoneBookEntry сохраняет данные о свойствах в struct используя его saveobj способ.

methods
   function s = saveobj(obj)
      s.Name = obj.Name;
      s.Address = obj.Address;
      s.PhoneNumber = obj.PhoneNumber;
   end
end

loadobj метод создает PhoneBookEntry объект, который затем загружается в рабочую область.

methods (Static)
   function obj = loadobj(s)
      if isstruct(s)
         newObj = PhoneBookEntry;
         newObj.Name = s.Name;
         newObj.Address = s.Address;
         newObj.PhoneNumber = s.PhoneNumber;
         obj = newObj;
      else
         obj = s;
      end
   end
end

Версия 2 PhoneBookEntry Класс

В версии 2 PhoneBookEntry класс, вы разделяете Address свойство в StreetAddress, City, State, и ZipCode свойства.

С этими изменениями вы не смогли загрузить объект версии 2 в предыдущем релизе. Однако в версии 2 используется несколько методов для обеспечения совместимости:

  • Сохраните Address свойство (которое используется в версии 1) как Dependent свойство с частными SetAccess.

  • Задайте Address Метод получения свойств (get.Address) для создания char вектор, совместимый с версией 2 Address свойство.

  • The saveobj метод вызывает get.Address метод для назначения данных объекта struct совместим с предыдущими версиями. The struct продолжает иметь только Address поле, построенное из данных в новой StreetAddress, City, State, и ZipCode свойства.

  • Когда loadobj метод устанавливает Address свойство, оно вызывает метод набора свойств (set.Address), который извлекает подстроки, требуемые StreetAddress, City, State, и ZipCode свойства.

  • The Transient (не сохранено) свойство SaveInOldFormat позволяет вам задать, сохранять ли объект версии 2 как struct или объект.

classdef PhoneBookEntry
   properties
      Name
      StreetAddress
      City
      State
      ZipCode
      PhoneNumber
   end
   properties (Constant)
      Sep = ', '
   end
   properties (Dependent, SetAccess=private)
      Address
   end
   properties (Transient)
      SaveInOldFormat = false;
   end
   methods (Static)
      function obj = loadobj(s)
         if isstruct(s)
            obj = PhoneBookEntry;
            obj.Name = s.Name;
            obj.Address = s.Address;
            obj.PhoneNumber = s.PhoneNumber;
         else
            obj = s;
         end
      end
   end
   methods
      function address = get.Address(obj)
         address = [obj.StreetAddress,obj.Sep,obj.City,obj.Sep,...
            obj.State,obj.Sep,obj.ZipCode];
      end
      function obj = set.Address(obj,address)
         addressItems = regexp(address,obj.Sep,'split');
         if length(addressItems) == 4
            obj.StreetAddress = addressItems{1};
            obj.City = addressItems{2};
            obj.State = addressItems{3};
            obj.ZipCode = addressItems{4};
         else
            error('PhoneBookEntry:InvalidAddressFormat', ...
               'Invalid address format.');
         end
      end
      function s = saveobj(obj)
         if obj.SaveInOldFormat
            s.Name = obj.Name;
            s.Address = obj.Address;
            s.PhoneNumber = obj.PhoneNumber;
         end
      end
   end
end

Похожие темы

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