Simulate a C ++ pattern in MATLAB

I am trying to find a better way to create an alternative to a C ++ template or shared Java objects. I wanted to do this several times in the past for several reasons, but right now what I want to do is to create saveobj and loadobj functions for several related classes. The idea is that I want to have a common set of routines to create the default structure, and then manipulate it a bit further to get the structures as I need them.

I canโ€™t just use an external function because I need access to all public (non-problem) and protected (problem) non-transient properties of an object in order to create loadobj and saveobj.

Then I looked at using an abstract interface. However, using an abstract interface leaves me with the same problem; identical, copy the pasted code floating in all my object files. So, I thought about using some sort of full-blown object in combination with multiple inheritance (most of my objects already inherit from the base nodule of interfaces). I thought using a superclass would allow me to expose the protected properties of a subclass, but it seems like it is not. Any suggestions?

Here is an example of a multiple inheritance approach (the closest I have so far) for the save obj approach.

Serializer.m

% Serializer.m classdef Serializer methods function [saveObj] = saveobj( obj ) % Get metadata about the Object meta = metaclass( obj ); meta = meta.PropertyList; for p = meta' if p.Transient | p.Dependent continue; % Only serialize the correct fields end saveobj.(p.Name) = { obj.(p.Name) }; % Serialize end % for ( property ) end % function ( saveobj ) end % methods end % classdef ( Serializer ) 

TestSerializerA.m

 % TestSerializerA.m classdef TestSerializerA < Serializer properties PropA = 'a'; end % properties ( public ) properties( Access = protected ) HiddenA = 'ha' end % properties ( protected ) end % classdef ( TestSerializerA ) 

TestSerializerB.m

 % TestSerializerB.m classdef TestSerializerB < TestSerializerA & Serializer properties PropB = 'b' end properties( Access = protected ) HiddenB = 'hb'; end % properties ( protected ) end % classdef ( TestSerializerB ) 
+4
source share
1 answer

Decision

You can accomplish what you want to do using Access Lists . You can allow access of the Serializer class to any protected / private class that you would like to serialize. This allows each class to independently determine which of its members is serialized. Since you allow access to the Serializer , you do not want to inherit it. If you do this, all classes in the hierarchy will have access to these members. Here is the rewritten Serializer class:

 classdef Serializer methods function SerializedObj = serialize(~, Obj) % Get metadata about the Object meta = metaclass(Obj); meta = meta.PropertyList; for p = meta' %' if p.Transient || p.Dependent continue; % Only serialize the correct fields end try SerializedObj.(p.Name) = { Obj.(p.Name) }; % Serialize catch Me % the class has chosen not to allow this property to be % serialized. decide how to handle it. if ~strcmp(Me.identifier, 'MATLAB:class:GetProhibited') Me.rethrow() end end end end end end 

Note that you can decide how you want to handle access restrictions. In the above example, I am not doing anything. But you can issue a warning, throw an error, etc.

Now, instead of inheriting from Serializer create an abstract Serializable class that allows serialization.

 classdef (Abstract) Serializable properties (Access = private) Serializer_ = Serializer() end methods function savedObj = saveobj(This) savedObj = This.Serializer_.serialize(This); end end end 

Now, any class that you want to enable serialization additionally inherits from Serializable . You can specify which protected / private members have access to the Serializer .

Examples

The following class has two serializable properties and one hidden (non-serializable) property.

 classdef TestSerializerA < Serializable properties PropA = 'a'; end properties( Access = {?TestSerializerA, ?Serializer} ) % This property is protected and serializable SerializableA = 'sa' end properties (Access = private) % This property is private and not serializable HiddenA = 'ha'; end end 

This is the result of MATLAB:

 >> Test = TestSerializerA Test = TestSerializerA with properties: PropA: 'a' >> b = saveobj(Test) b = PropA: {'a'} SerializableA: {'sa'} 

The following example inherits from TestSerializerA and has two additional serializable properties and one hidden property.

 classdef TestSerializerB < TestSerializerA & Serializable properties PropB = 'b'; end properties (Access = {?TestSerializerB, ?Serializer}) % This property is protected and serializable. SerializableB = 'sb'; end properties (Access = protected) % This property is protected and not serializable. HiddenPropB = 'hb'; end end 

Note that re-inheritance with Serializable not necessary, but makes code reading easier.

Finally, the result of MATLAB:

 >> Test = TestSerializerB Test = TestSerializerB with properties: PropB: 'b' PropA: 'a' >> b = saveobj(Test) b = PropB: {'b'} SerializableB: {'sb'} PropA: {'a'} SerializableA: {'sa'} 

Hope this helps!

0
source

Source: https://habr.com/ru/post/1487542/


All Articles