2011-02-10 15 views
9

Mam klasy z kilkoma właściwościami, które są zależne, ale chciałbym policzyć tylko raz.MATLAB Lazy Ocena w zależności Property

Właśnie doszedłem do wniosku, że używanie leniwego oszacowania właściwości klasy zależnej w MATLAB jest albo niemożliwe, albo zły pomysł. Pierwotny plan miał mieć prywatną flagę logiczną dla każdej właściwości (publicznej), która wymaga aktualizacji i aby konstruktor ustawił ją na wartość true. Następnie, gdy wywoływany był właściwość accessor, sprawdzałby tę flagę i obliczał wartość i zapisywał ją (w innej własności prywatnej) tylko w razie potrzeby. Jeśli flaga była fałszywa, po prostu zwróciłaby kopię buforowanej wartości.

Sądzę, że trudność polega na ograniczeniu dostępu do nieruchomości, to znaczy, że pozostawiają one inne niepowiązane właściwości. Innymi słowy, metoda get.property (self) nie może zmienić stanu obiektu self. Co ciekawe, w mojej obecnej klasie nie działa to w sposób cichy. (Tzn. Ani flaga aktualizacji, ani buforowane wyniki obliczeń nie są ustawione w metodzie get., Więc kosztowne obliczenia są wykonywane za każdym razem).

Podejrzewam, że zmiana leniwej właściwości z publicznej usługi zależnej na metodę z publicznym GetAccess, ale działałaby prywatnie SetAccess. Nie lubię jednak spekulować konwencją własności w ten sposób. Chciałbym, żeby był tylko "leniwy" atrybut własności, który mógłby zrobić to wszystko dla mnie.

Czy brakuje mi czegoś oczywistego? Czy metody akcesorów dla zależnych właściwości klasy w programie MATLAB nie mają uprawnień do zmiany stanu instancji klasy? Jeśli tak, czy określenie, co jest akcesoriem z prywatnym efektem ubocznym, jest najmniejszym złym sposobem uzyskania pożądanego zachowania?

Edit: oto klasa Test ...

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 

uruchomić go z

close all; clear classes; clc 

t = LazyTest(3) 
t.factorial 

for num = 1:10 
    tic 
    t.factoriand = num 
    t.factorial 
    toc 
end 

Po dziedziczenie z handle czas spada znacząco.

Odpowiedz

11

Zakładam, że używasz klasy wartości. Dzięki handle class (classdef myClass < handle), który jest przekazywany przez odniesienie, można łatwo modyfikować klasę z metody get. Na przykład używam tego, co proponujesz, aby załadować dane z pliku (jeśli jeszcze nie zostały załadowane) lub z prywatnej, ukrytej właściwości.

Należy pamiętać, że przy użyciu właściwości lazy zależną sposób zaproponować nieco celowość wykorzystania właściwość zależną, tj gwarancji, że dane są zawsze na bieżąco ze stanem własności pochodzi od. Za każdym razem, gdy zmieniasz inne właściwości, twoja leniwy obiekt staje się przestarzały.

Można (należy) dodać metodę zestawu do wszystkich innych właściwości, które ustawiają własność prywatną na pustą (isempty(obj.myPrivateProperty) jest "flagą logiczną", którą musisz wiedzieć, czy musisz obliczyć). Ale jeśli to zrobisz, dlaczego nie po prostu zestaw metody wywołają metodę aktualizacji, która aktualizuje/ponownie oblicza wszystkie "zależne" właściwości od razu?

+0

To wydaje się załatwiać. –

+1

Podoba mi się również redukcja bałaganu używania isempty na tym, na którym mi zależy, w porównaniu do dodatkowych prywatnych właściwości. Dzięki. –

+1

1. Nie można zamienić jawnej flagi na domyślną na podstawie wartości bez przyjmowania pewnych założeń (tutaj puste wartości są tutaj niepoprawne). 2. Nie zawsze właściwe jest, aby ustawione metody aktualizowały właściwość "zależną", szczególnie. jeśli później jest kosztowna do obliczenia i zależy od dwóch lub więcej innych właściwości. Dlatego w ogólnym przypadku nadal bym korzystał z dodatkowych flag. – user1735003