Maintain Backward and Forward Compatibility Between Class Definitions - MATLAB & Simulink (original) (raw)
Main Content
Revising a class definition can lead to errors when trying to deserialize instances of a different version of that class using the default load process. When changing a class definition, you can inherit from matlab.mixin.CustomElementSerialization and use it to control how the new class definition serializes and deserializes instances to preserve compatibility. The general process is:
- When you revise your class definition in a way that breaks compatibility with the older version, add
matlab.mixin.CustomElementSerialization
as a superclass. - If you need to change how objects of the revised class are serialized, implement the
modifyOutgoingSerializationContent
method ofmatlab.mixin.CustomElementSerialization
. The method takes an instance of matlab.serialization.ElementSerializationContent as input. That object represents what will be serialized, and the methods ofmatlab.serialization.ElementSerializationContent
enable you to change how properties are serialized. - If you need to change how objects of the revised class are deserialized, implement the
modifyIncomingSerializationContent
method ofmatlab.mixin.CustomElementSerialization
. The method takes an instance of thematlab.serialization.ElementSerializationContent
class as input. That object represents what will be deserialized, and the methods ofmatlab.serialization.ElementSerializationContent
enable you to change how properties are deserialized. - If you need to perform any final operations on the deserialized object, such as adding an event listener, implement the
finalizeIncomingObject
method ofmatlab.mixin.CustomElementSerialization
. The method takes the deserialized object as input.
Backward Compatibility
Define a class Employee
that stores basic information. TheEmployeeID
property is stored as a string with "ID-
" at the beginning, as shown by the default value.
classdef Employee properties Name Department EmployeeID = "ID-0000" Email end end
Create an instance of Employee
, assign values to all the properties, and save it. Replace yourfilepath
with your local path.
eOld = Employee; eOld.Name = "Alex Cruz"; eOld.Department = "Sales"; eOld.EmployeeID = "ID-1301" eOld.Email = "acruz@notacompany.com" save("yourfilepath/oldEmployee.mat","eOld");
Update the class definition with new and redefined properties:
- Split
Name
intoFirstName
andLastName
. - Change
Department
toDivision
. - Remove the "
ID-
" prefix from theEmployeeID
property.
Trying to deserialize an object that was serialized under the old definition would leave some properties without proper values. To keep the old objects as accessible as possible, add matlab.mixin.CustomElementSerialization
as a superclass and implement the static method modifyIncomingSerialization
to convert the old property data into the new format as needed.
classdef Employee < matlab.mixin.CustomElementSerialization properties LastName FirstName EmployeeID Division Email end methods (Static) function modifyIncomingSerializationContent(sObj) if sObj.hasNameValue("Name") nameArray = split(sObj.Name); sObj.addNameValue("FirstName",nameArray(1)); sObj.addNameValue("LastName",nameArray(2)); sObj.remove("Name"); sObj.rename("Department","Division"); id = split(sObj.EmployeeID,"-"); sObj.updateValue("EmployeeID",id(2)); end end end end
MATLABĀ® calls modifyIncomingSerializationContent
when you load an object of Employee
. The method takes as input an instance of matlab.serialization.ElementSerializationContent. ThehasNameValue
method ofmatlab.serialization.ElementSerializationContent
checks to see if the saved object has a property called Name
. If there is aName
property, the object being deserialized was serialized under the old class definition. In that case, the methods ofmatlab.serialization.ElementSerializationContent
convert and assign the old property data into the revised properties:
- The value of the
Name
property is split into an array of two strings, and theaddNameValue
method adds theFirstName
andLastName
properties.remove
discards the old propertyName
. - The
rename
method changesDepartment
toDivision
. - The
updateValue
method changes the value of theEmployeeID
property to include only the numeric portion.
Clear eOld
from memory.
Remove the old definition of Employee
from your path. Add the revised definition ofEmployee
to the path, and load the eOld
object. Display the object to confirm that the variable has been deserialized as an object of the revised definition of Employee
.
load("yourfilepath/oldEmployee.mat","eOld") eOld
eOld =
Employee with properties:
LastName: "Cruz"
FirstName: "Alex"
EmployeeID: "1301"
Division: "Sales"
Email: "acruz@notacompany.com"
matlab.mixin.CustomElementSerialization
also provides a staticfinalizeIncomingObject
method. If the method is implemented, MATLAB calls it after modifyIncomingSerializationContent
. Use the method to perform any necessary cleanup on the deserialized object, like restoring property listeners, for example. In the case of Employee
,finalizeIncomingObject
could be used to fill in the unknown value for EmployeeID
if the method has access to that data from other sources.
The modifyOutgoingSerializationContent
method also has an optional input argument, an instance of matlab.serialization.SerializationContext. An instance of this class can be used to determine the context in which the object is being serialized. For example, MATLAB sets the CustomizeForReadability
property of the instance to true
if the serialized object is readable by external users.
For an additional example on preserving backward compatibility, see Load Serialized Objects After Changing Class Definition.
Forward Compatibility
The latest version of Employee
can now successfully deserialize objects saved under the older version of the class, but the class does not have forward compatibility. In other words, someone who only has access to the older version of the class cannot successfully deserialize an object serialized under the latest version of the class.
To support forward compatibility, implement themodifyOutgoingSerializationContent
method ofmatlab.mixin.CustomElementSerialization
in the new class definition. This method controls what information is serialized, so the goal is to save the information in a way that both the old and new versions of the class can access.
MATLAB calls modifyOutgoingSerializationContent
when you save an object of Employee
. The method takes as inputs an object of matlab.serialization.ElementSerializationContent as well as the object itself. The process from there is the inverse of howmodifyIncomingSerializationContent
works. The properties are reverted to the format of the older version so that the data can be deserialized by either version of the class.
classdef Employee < matlab.mixin.CustomElementSerialization properties LastName FirstName EmployeeID = "0000" Division Email end methods (Static) function modifyIncomingSerializationContent(sObj) if sObj.hasNameValue("Name") nameArray = split(sObj.Name); sObj.addNameValue("FirstName",nameArray(1)); sObj.addNameValue("LastName",nameArray(2)); sObj.remove("Name"); sObj.rename("Department","Division"); id = split(sObj.EmployeeID,"-"); sObj.updateValue("EmployeeID",id(2)); end end function modifyOutgoingSerializationContent(sObj,obj) nameStr = append(obj.FirstName," ",obj.LastName); sObj.addNameValue("Name",nameStr); sObj.remove("FirstName"); sObj.remove("LastName"); sObj.rename("Division","Department"); fullID = append("ID-",obj.EmployeeID); sObj.updateValue("EmployeeID",fullID); end end end
Resave eOld
under the newer definition ofEmployee
and then load it under the older class definition. The deserialized version under the older definition is in the correct format.
eOld =
Employee with properties:
Name: "Alex Cruz"
Department: "Sales"
EmployeeID: "ID-1301"
Email: "acruz@notacompany.com"
For another example of a revised class definition that supports both forward and backward compatibility, see Maintain Backward and Forward Compatibility During Serialization.
See Also
matlab.mixin.CustomElementSerialization | matlab.serialization.ElementSerializationContent | matlab.serialization.SerializationContext