set class property only once
12 次查看(过去 30 天)
显示 更早的评论
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.
0 个评论
采纳的回答
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
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.
更多回答(2 个)
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
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.
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
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Construct and Work with Object Arrays 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!