set class property only once

조회 수: 12 (최근 30일)
Marc Youcef
Marc Youcef 2020년 3월 12일
답변: per isakson 2020년 3월 21일
I am having multiples classes which needs to read a shared common variable called 'MasterData'.
This MasterData variable is getting its data from an api call. In order to avoid to make this api call in each of my different classes that need it, I wanted to define MasterData as a propery in a handle class (MasterDataConfiguration class) and then make other classes inherit from that superclass.
classdef MasterDataConfiguration < handle
properties
MasterData
end
methods
function obj = MasterDataConfiguration2(~)
% Get MasterData from CyPET4
% Read data form config
ini = IniConfig();
ini.ReadFile('MPS_AutoJSON_ConfigFile.ini');
% API info
APIbaseurl = ini.GetValues('Web App API', 'PreformFilesrequestURI_Prod');
APIparameter = 'admin/masterdata';
% API call
options = weboptions('Timeout',120);
obj.MasterData = webread([APIbaseurl,APIparameter],options);
disp('MasterData API was queried');
end
For the sub clases which would inherit from the above class:
classdef SubClassExample < MasterDataConfiguration
properties
ColdHalfDataStruct
end
methods
function obj = SubClassExample(OtherObj)
%ColdHalfData Construct an instance of ColdHalfData from a PreformDataObj of
%class PreformData
% work done on MasterData
obj.MasterData
end
end
end
My difficulty here is that I get the API requested each time I create a subclass object SubClassExample.
What I would like is that the attribute MasterData from class MasterDataConfiguration gets set once and for all and the other subclasses simply refers to it without re generating it.
I tried using Properties (constant) but I can't make an API call in such way.
I read some documentation here :
But could not understand whet is meant by the following :
"MATLAB® evaluates property default values only once when loading the class. MATLAB does not reevaluate the assignment each time you create an object of that class. If you assign an object as a default property value in the class definition, MATLAB calls the constructor for that object only once when loading the class."
In my case I see the API is always called.
Thanks in advance for any hint on how to proceed.

채택된 답변

Guillaume
Guillaume 2020년 3월 12일
편집: Guillaume 2020년 3월 12일
It sounds like you want a singleton property. This is how I'd designed it. As commented in Steven's answer, this doesn't and should not involve inheritence:
classdef MasterConfiguration < handle %handle require so it can modify its own properties
properties (SetAccess = private)
MasterData
end
methods
function this = MasterConfiguration() %constructor
this.Initialise(); %Initialise
end
function Initialise(this) %Actual initialisation code. Decoupled from the constructor, so it can be reinitialised as needed
%... initialisation code
end
end
end
classdef MasterDataUser %can be handle or value class depending on needs
properties (Constant)
MasterDataConfiguration = MasterConfiguration; %singleton object shared by all instances
end
methods
%...
function ReinitialiseMasterData(this) %in case MasterData need to be reread
this.MasterDataConfiguration.Initialise(); %all instances of MasterDataUser will see the newly initialised MasterConfiguration
end
end
end
If several classes need access to the same shared MasterData, then they must derive from MasterDataUser not from MasterConfiguration.
  댓글 수: 3
Guillaume
Guillaume 2020년 3월 12일
No, they will all have to inherit from this class holding the singleton. Call it MasterDataInterface if you wish.
The only other option is to do the sharing with a global variable with all the pitfalls that entails.
Marc Youcef
Marc Youcef 2020년 3월 13일
That is perfectly doing the job. Thanks to you both for detailed guidance.

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Steven Lord
Steven Lord 2020년 3월 12일
It sounds like you want an immutable property as described here or perhaps to have your classes that want to use the data to store a MasterDataConfiguration handle object in their properties. In that latter case, you may want to assign the MasterDataConfiguration handle object in the property definition for the objects that need it rather than in their constructors. See the "Expression Evaluation in Handle and Value Classes" section on this documentation page for more information about why that may be more appropriate for your class hierarchy.
  댓글 수: 3
Guillaume
Guillaume 2020년 3월 12일
I'm very confused about your design. If MasterData in subClassExample is a property of type MasterDataConfiguration, why does subClassExample derive from MasterDataConfiguration? It sounds like there should be no inheritance from MasterDataConfiguration.
I'm a bit unclear on the desired lifetime for MasterData. What the bit about constant properties say, is that if the property is constant, the initialisation function is called only once, when the class is loaded which is typically the firsts time an object is created (documentation is purposefully unclear, this may depends on the jit optimisation). It is then never called again, regardless of the number of instances of the class. The only way to get it to be called again would be to restart matlab, use clear classes or possibly edit the class code.
Marc Youcef
Marc Youcef 2020년 3월 12일
Indeed I should have removed that inheritance. I can't try it out now. Will do that tomorrow.
Your description is exactly what I would be looking for. Meaning that I would like subClassExample first instance to create only once the MasterData property. In return, to build MasterData property, it will construct MasterDataConfiguration.
Then when another instance of subClassExample is generated, I am hoping that it would not construct again MasterDataConfiguration. Removing the inheritance should solve that.
I try out and let you know.
Thanks.

댓글을 달려면 로그인하십시오.


per isakson
per isakson 2020년 3월 21일
Here is an minimal working example of the design, which I think OP tried to implement. That is, use the fact that "MATLAB® evaluates property default values only once when loading the class.".
"I tried using Properties (constant) but I can't make an API call in such way." The trick is to put the code, which creates the value of MaterData, in a static method (or an ordinary function) and call that in the property block.
First, I create three instancies of SubClassExample(). The method, configureMasterData(), is called only for the first instance. (Instead of calling the API, I call randi() to create a vector of three random whole numbers.) Next, I show that the values of the property, MasterData, is identical for the three instances.
>> sce_1 = SubClassExample();
MasterData API was queried
>> sce_2 = SubClassExample();
>> sce_3 = SubClassExample();
>> sce_1.MasterData
ans =
8 9 2
>> sce_2.MasterData
ans =
8 9 2
>> sce_3.MasterData
ans =
8 9 2
where
classdef MasterDataConfiguration < handle
properties ( SetAccess = private )
MasterData = MasterDataConfiguration.configureMasterData;
end
methods ( Static, Access = private )
function master_data = configureMasterData();
master_data = randi( [1,9], 1,3 );
disp('MasterData API was queried');
end
end
end
and
classdef SubClassExample < MasterDataConfiguration
properties
ColdHalfDataStruct
end
end

카테고리

Help CenterFile Exchange에서 Construct and Work with Object Arrays에 대해 자세히 알아보기

제품


릴리스

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by