Update a value class property only if required

16 views (last 30 days)
Hello everyone,
I am new to object oriented programming and have some issues getting the behavior of my class in the way I want it. I have several input properties and a "dependent" output property. Because the algorithm to compute the output is numerically intensive, I do not want to handle it as an actual dependent property. It should only be updated if necessary. Also I want to be able to save my results to my hard drive, which would not work with a dependent property.
I got this basically working if my class is a handle class as shown in the example down below. But I do not like how handle classes function. In particular it can be very unintuitive to the user if they try something like this:
A = myclass(1,2);
B = A;
A.input1 = 5;
So here is my example with the handle class. Can anyone tell me if that can also be achieved with a value class? General improvement suggests are welcome as well :-)
Thanks a lot in advance!
classdef myclass < handle
properties
input1
input2
output
update_required
end
methods
function obj = myclass(value1, value2)
obj.input1 = value1;
obj.input2 = value2;
obj.output = [];
end
function set.input1(obj, value)
if obj.input1 == value
return
end
obj.input1 = value;
obj.update_required = true;
end
function set.input2(obj, value)
if obj.input2 == value
return
end
obj.input2 = value;
obj.update_required = true;
end
function value = get.output(obj)
if obj.update_required
disp('Update required.')
obj.output = obj.input1 + obj.input2;
obj.update_required = false;
else
disp('No update required.')
end
value = obj.output;
end
end
end
  3 Comments
Peng Li
Peng Li on 13 Apr 2020
within some modifications, you might be able to make it work with these all twisted set. methods, although it's not recommended.

Sign in to comment.

Accepted Answer

Peng Li
Peng Li on 14 Apr 2020
Edited: Peng Li on 14 Apr 2020
I think my solution works if you reset your update_required within your if...end block.
classdef myclass
properties
input1
input2
end
properties (Dependent = true)
output
update_required
end
properties (Hidden = true)
output_
update_required_
end
methods
function obj = myclass(value1, value2)
obj.input1 = value1;
obj.input2 = value2;
obj.output = value1 + value2;
end
function obj = set.input1(obj, value)
if obj.input1 == value
obj.update_required = false;
return
end
obj.input1 = value;
obj.update_required = true;
end
function obj = set.input2(obj, value)
if obj.input2 == value
obj.update_required = false;
return
end
obj.input2 = value;
obj.update_required = true;
end
function value = get.output(obj)
if obj.update_required
disp('Update required.')
obj.output = obj.input1 + obj.input2;
obj.update_required = false;
else
disp('No update required.')
end
value = obj.output_;
end
function obj = set.output(obj, val)
obj.output_ = val;
end
function val = get.update_required(obj)
val = obj.update_required_;
end
function obj = set.update_required(obj, val)
obj.update_required_ = val;
end
end
end
>> A = myclass(1, 2);
>> A
A =
Update required.
myclass with properties:
input1: 1
input2: 2
output: 3
update_required: 1
>> A.input1 = 1
A =
No update required.
myclass with properties:
input1: 1
input2: 2
output: 3
update_required: 0
>> A.input2 = 2
A =
No update required.
myclass with properties:
input1: 1
input2: 2
output: 3
update_required: 0
>> A.input1 = 5
A =
Update required.
myclass with properties:
input1: 5
input2: 2
output: 7
update_required: 1
>> A.input2 = 10
A =
Update required.
myclass with properties:
input1: 5
input2: 10
output: 15
update_required: 1
  4 Comments
Peng Li
Peng Li on 15 Apr 2020
yeah this is annoying and that's why i don't like this twisted way, although it seems to work. And i don't want to make input1 and input2 dependent, as conceptually I think they shouldn't be.

Sign in to comment.

More Answers (2)

Matt J
Matt J on 13 Apr 2020
Edited: Matt J on 13 Apr 2020
You have two separate issues that need to be addressed. The issue of handle class versus value class is the easier of the two. The only difference is that in a value class implementation, your set.prop() methods must return an output.
The second issue is whether input1 and input2 should be Dependent classes. They should, since it is dangerous for a non-Dependent property set or get method to reference other properties. This is true regardless of whether myclass is a value or handle class. Below is the value class implementation I would recommend.
classdef myclass
properties (Hidden)
Input1 %holds the data for "input1"
Input2 %holds the data for "input2"
output
end
properties
update_required;
end
properties (Dependent)
input1
input2
end
methods
function obj = myclass(value1, value2)
obj.Input1 = value1;
obj.Input2 = value2;
obj.output = [];
obj.update_required=1;
end
function input1=get.input1(obj)
input1=obj.Input1;
end
function input2=get.input2(obj)
input2=obj.Input2;
end
function obj=set.input1(obj, input1)
if obj.Input1 == input1
return
end
obj.Input1 = input1;
obj.update_required = true;
end
function obj=set.input2(obj, input2)
if obj.Input2 == input2
return
end
obj.Input2 = input2;
obj.update_required = true;
end
function value = get.output(obj)
if obj.update_required
disp('Update required.')
obj.output = obj.input1 + obj.input2;
obj.update_required = false;
else
disp('No update required.')
end
value = obj.output;
end
end
end
  4 Comments
Christian Vetter
Christian Vetter on 14 Apr 2020
@Peng Li,
No, this is wouldn't work. At least not in the way I indend. In the set-methods for the input variables, updated_required should be set to true. In the get-method for the output variable, the update should be executed if necessary and the updated_required should be set back to false. But this isn't going to work in a value class it seems. Because the get-method for the output variable cannot access/write the property obj.updated_required.

Sign in to comment.


Matt J
Matt J on 14 Apr 2020
Edited: Matt J on 14 Apr 2020
Is there a reason you don't update when changes to input1 or input2 occur, like in the following?
classdef myclass
properties
input1;
input2;
output;
end
methods
function obj = myclass(value1, value2)
obj.input1 = value1;
obj.input2 = value2;
end
function obj=set.input1(obj, input1)
if obj.input1 == input1
return
end
obj.input1 = input1;
obj = update_output(obj);
end
function obj=set.input2(obj, input2)
if obj.input2 == input2
return
end
obj.input2 = input2;
obj = update_output(obj);
end
function obj=update_output(obj)
obj.output=obj.input1+obj.input2;
end
end
end
  2 Comments
Matt J
Matt J on 14 Apr 2020
Edited: Matt J on 14 Apr 2020
So I guess I have to live with the fact that my class needs to be a handle class.
No, that's not the only solution. Instead of a get.output() method, you could instead use an ordinary method like below. This does not enable the syntax you were looking for, but it does allow you to use value classes and still get the computational efficiency you're after. I would also argue that it is probably better to undertake a large computation in an explicit function call like this, rather than have it hidden from view in a property access operation.
function obj=update_Object(obj)
if obj.update_required
disp('Update required.')
obj.output = obj.input1 + obj.input2;
obj.update_required = false;
else
disp('No update required.')
end
end

Sign in to comment.

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by