У меня есть класс с несколькими зависимыми свойствами, но я бы хотел вычислить только один раз.
Я только что пришел к выводу, что использование отложенных вычислений для свойства зависимого класса в MATLAB либо невозможно, либо является плохой идеей.Первоначальный план состоял в том, чтобы иметь частный логический флаг для каждого (открытого) свойства, которое необходимо обновить, и чтобы конструктор установил его в значение true.Затем, когда вызывался метод доступа к свойству, он проверял этот флаг, вычислял значение и сохранял его (в другом частном свойстве) только при необходимости.Если бы флаг был ложным, он просто возвратил бы копию кэшированного значения.
Я считаю, что трудность заключается в ограничении средств доступа к свойствам, то есть в том, что они оставляют другие несвязанные свойства в покое.Другими словами, метод get.property (self) не может изменить состояние объекта self.Интересно, что это молча терпит неудачу в моем текущем классе.(Т.е. ни флаг обновления, ни кэшированные результаты вычислений не устанавливаются в методе get. Поэтому дорогостоящие вычисления выполняются каждый раз).
Я подозреваю, что изменение свойства lazy из общедоступного зависимого свойствак методу с общедоступным GetAccess, но частный SetAccess будет работать.Тем не менее, мне не нравится подделывать соглашение о собственности таким образом.Хотелось бы, чтобы был только «ленивый» атрибут свойства, который мог бы сделать все это для меня.
Я что-то упускаю из виду?Запрещено ли методам доступа для зависимых свойств класса в MATLAB изменять состояние экземпляра класса?Если да, то определяет ли средство доступа с частным побочным эффектом наименее злой способ получить желаемое поведение?
Редактировать: вот тестовый класс ...
classdef LazyTest
properties(Access = public)
% num to take factorial of
factoriand
end
properties(Access = public, Dependent)
factorial
end
properties(Access = private)
% logical flag
do_update_factorial
% old result
cached_factorial
end
methods
function self = LazyTest(factoriand)
self.factoriand = factoriand;
self.do_update_factorial = true;
end
end
methods
function result = get.factorial(self)
if self.do_update_factorial
self.cached_factorial = factorial(self.factoriand);
% pretend this is expensive
pause(0.5)
self.do_update_factorial = false
end
result = self.cached_factorial;
end
end
end
Запустите его с
close all; clear classes; clc
t = LazyTest(3)
t.factorial
for num = 1:10
tic
t.factoriand = num
t.factorial
toc
end
После наследования от handle
время существенно уменьшается.