У меня есть класс с несколькими зависимыми свойствами, но я бы очень хотел вычислить только один раз.
Я почти пришел к выводу, что использование ленивой оценки свойства зависимого класса в MATLAB либо невозможно, либо плохая идея. Первоначальный план заключался в том, чтобы иметь частный логический флаг для каждого (общедоступного) свойства, которое требует обновления, и чтобы конструктор устанавливал его в значение true. Затем, когда вызывается метод доступа к свойству, он проверяет этот флаг, вычисляет значение и сохраняет его (в другом частном свойстве) только при необходимости. Если бы флаг был ложным, он просто вернул бы копию кэшированного значения.
Я считаю, что трудность заключается в ограничении средств доступа к свойствам, то есть в том, что они оставляют другие несвязанные свойства в покое. Другими словами, метод get.property (self) не может изменить состояние объекта self. Что интересно, в моем текущем классе это тихо не удается. (То есть ни флаг обновления, ни кешированные результаты вычислений не устанавливаются в методе get., Поэтому дорогостоящие вычисления выполняются каждый раз.)
Я подозреваю, что изменение ленивого свойства с общедоступного зависимого свойства на метод с общедоступным 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
После наследования от обработать
время существенно падает.