-
1. Data: 2012-03-16 09:39:17
Temat: Jaki wzorzec projektowy: pilnowanie cyklu życia innego obiektu ?
Od: zażółcony <r...@c...pl>
Najbardziej mi tu pasuje Proxy, ale Proxy jest zbyt ogólny.
Może macie inny pomysł.
Sytuacja jest taka: mamy język programowania,
w którym destruktory są wywoływane w ściśle określonych
momentach, tzn. mamy np. C++ bez garbage collectora
lub np. FoxPro.
Wykorzystujemy destruktory obiektów do tego, by
obiekty sprzątały po sobie. Np. mamy obiekt File, który
w destruktorze robi closa na deskryptorze otwartego pliku.
Albo mamy obiekt Transakcja, który w destruktorze stara
się zrobić commit'a. Albo mamy obiekt BlokadaZasobu czy
Mutex, który w destruktorze zwalnia zablokowany
zasób/podnosi opuszczony wcześniej semafor.
Wykorzystujemy tu destruktory po to, by zminimalizować
potrzebę pamiętania o sprzątaniu po obiektach, u których
czas życia nie budzi wątpliwości (bo są np. tworzone
lokalnie w procedurze, czy nawet zagłębionej sekcji jakiejś
procedury(funkcji,metody), a referencja nie jest nigdzie
przekazywana. Da się na tym budować bardzo ładny, elegancki kod,
który w przypadku języków z garbage collectorem trzeba najczęściej
dodatkowo obudowywać klauzulami try {}finally {...}, żeby sprzątać
jawnie. Tu tego nie mamy, a przynajmniej mamy znacznie mniej.
A teraz idźmy dalej: teraz chcę wszystkie w.w. obiekty plików czy
blokad zasobów gromadzić w jakiejś kolekcji utrzymywanej i zarządzanej
przez jakiś singleton (np. Manager Blokad, Manager Transakcji ...),
np. po to, żeby móc je sobie wszystkie wyświetlić.
Czyli łamię zasadę nie przekazywania/nie trzymania referencji
obiektów na zewnątrz. Złamanie tej zasady wprost prowadzi
do tego, że przestaje działać sprzątanie/zamykanie (ze względu
na wiszące referencje).
Nie mamy do dyspozycji czegoś takiego, jak weak reference, więc żeby
temu zaradzić działamy wg. wzorca takiego:
Lokalnie tworzymy obiekt proxy, który trzyma referencję
na obiekt właściwy i proxy w swoim destruktorze pilnuje,
by obiekt, którym się obiekuje "wypisać z systemu"/posprzątać
po nim/zlikwidować wszystkie referencje.
Pasowało mi określenie 'strażnik', ale Guard Pattern to raczej do
walidacji się nadaje, więc nie pasuje.
Teoretycznie każdy z obiektów typu Plik czy Semafor mógłby sam siebie
zapisywać i wypisywać z globalnych list - ale uważam, ze czystsze jest
rozwiązanie, kiedy tego typu obiekty nie maja za bardzo pojęcia
kto i dlaczego się nimi interesuje, zajmują się swoimi technicznymi
zadaniami i niczym więcej.
Cały obowiązek pilnowania powiązań składam więc bardziej na factory
tych obiektów, które to będą bardziej świadome, co jest w systemie
i gdzie obiekty są zapisywane. No właśnie - z kreacją nie ma
problemu - jest wzorzec factory. A brakuje mi tu jakiegoś wzorca
typu 'Garbage', 'Złomuj' :)))
Jakiegoś urzędnika, który uczestniczył w narodzinach, zapisał to
w swoich papierach i jest bardzo zainteresowany, by zarejestrować
również śmierć. Bez tego papiery mu się nie będą zgadzać :)
-
2. Data: 2012-03-16 10:04:17
Temat: Re: Jaki wzorzec projektowy: pilnowanie cyklu życia innego obiektu ?
Od: Bronek Kozicki <b...@s...net>
On 16/03/2012 09:39, zażółcony wrote:
> Nie mamy do dyspozycji czegoś takiego, jak weak reference, więc żeby
> temu zaradzić działamy wg. wzorca takiego:
jak to nie? Mamy, nazywa się std::weak_ptr (albo boost::weak_ptr ,
zależnie od kompilatora pod ręką).
B.
-
3. Data: 2012-03-16 10:06:02
Temat: Re: Jaki wzorzec projektowy: pilnowanie cyklu życia innego obiektu ?
Od: zażółcony <r...@c...pl>
W dniu 2012-03-16 11:04, Bronek Kozicki pisze:
> On 16/03/2012 09:39, zażółcony wrote:
>> Nie mamy do dyspozycji czegoś takiego, jak weak reference, więc żeby
>> temu zaradzić działamy wg. wzorca takiego:
>
> jak to nie? Mamy, nazywa się std::weak_ptr (albo boost::weak_ptr ,
> zależnie od kompilatora pod ręką).
Ok, ja nie mam :) (FoxPro)
-
4. Data: 2012-03-16 11:06:02
Temat: Re: Jaki wzorzec projektowy: pilnowanie cyklu życia innego obiektu ?
Od: Andrzej Jarzabek <a...@g...com>
On Mar 16, 10:06 am, zażółcony <r...@c...pl> wrote:
> W dniu 2012-03-16 11:04, Bronek Kozicki pisze:
>
> > On 16/03/2012 09:39, zażółcony wrote:
> >> Nie mamy do dyspozycji czegoś takiego, jak weak reference, więc żeby
> >> temu zaradzić działamy wg. wzorca takiego:
>
> > jak to nie? Mamy, nazywa się std::weak_ptr (albo boost::weak_ptr ,
> > zależnie od kompilatora pod ręką).
>
> Ok, ja nie mam :) (FoxPro)
Po pierwsze, może po prostu weak reference jest patternem, który
powinieneś zaimplementować?
Po drugie, może zamiast tego wariant 'observer pattern' na zasadzie
'obserwator prosi o wskaźnik/referencję na obiekt i chce być
powiadomiony kiedy obiekt będzie niszczony - plus enkapsulacja tego w
ten sposób, że masz implementację obserwatora z kolekcją i
zautomatyzowane operacje: obserwator dostaje wskaźnik - dodaje go do
kolekcji; obserwator dostaje powiadomienie o destrukcji obiektu -
usuwa wskaźnik z kolekcji. Nie wiem czy taka kombinacja ma swoją nazwę.
-
5. Data: 2012-03-16 12:28:54
Temat: Re: Jaki wzorzec projektowy: pilnowanie cyklu życia innego obiektu ?
Od: zażółcony <r...@c...pl>
W dniu 2012-03-16 12:06, Andrzej Jarzabek pisze:
> On Mar 16, 10:06 am, zażółcony<r...@c...pl> wrote:
>> W dniu 2012-03-16 11:04, Bronek Kozicki pisze:
>>
>>> On 16/03/2012 09:39, zażółcony wrote:
>>>> Nie mamy do dyspozycji czegoś takiego, jak weak reference, więc żeby
>>>> temu zaradzić działamy wg. wzorca takiego:
>>
>>> jak to nie? Mamy, nazywa się std::weak_ptr (albo boost::weak_ptr ,
>>> zależnie od kompilatora pod ręką).
>>
>> Ok, ja nie mam :) (FoxPro)
>
> Po pierwsze, może po prostu weak reference jest patternem, który
> powinieneś zaimplementować?
Ciężka sprawa w foxie ... Nie bardzo widzę sposób implementacji
bez mocnej ingerencji w same obiekty, które chcemy pilnować.
Bez wtykania w destruktory specjalnego kodu tego nie widzę.
Jak najmniej takich rzeczy w Foxie :)
> Po drugie, może zamiast tego wariant 'observer pattern' na zasadzie
> 'obserwator prosi o wskaźnik/referencję na obiekt i chce być
> powiadomiony kiedy obiekt będzie niszczony - plus enkapsulacja tego w
> ten sposób, że masz implementację obserwatora z kolekcją i
> zautomatyzowane operacje: obserwator dostaje wskaźnik - dodaje go do
> kolekcji; obserwator dostaje powiadomienie o destrukcji obiektu -
> usuwa wskaźnik z kolekcji. Nie wiem czy taka kombinacja ma swoją nazwę.
No to jest jakiś pomysł, czyli coś w rodzaju LifeCycleObserver.
Hmmm ... Może tak to właśnie u siebie nazwę :) Z tym tylko
niuansem, ze obserwer właściwie bardziej obserwuje siebie, niż
podpięty obiekt. Bo to obserwer byłby tym obiektem lokalnym,
który musi w destruktorze odpalić 'wypisanie' innego obiektu
z systemu. Taki SelfDestroyObserver :)
-
6. Data: 2012-03-17 12:17:57
Temat: Re: Jaki wzorzec projektowy: pilnowanie cyklu życia innego obiektu ?
Od: Andrzej Jarzabek <a...@g...com>
On 16/03/2012 12:28, zażółcony wrote:
> W dniu 2012-03-16 12:06, Andrzej Jarzabek pisze:
>>
>> Po pierwsze, może po prostu weak reference jest patternem, który
>> powinieneś zaimplementować?
> Ciężka sprawa w foxie ... Nie bardzo widzę sposób implementacji
> bez mocnej ingerencji w same obiekty, które chcemy pilnować.
> Bez wtykania w destruktory specjalnego kodu tego nie widzę.
> Jak najmniej takich rzeczy w Foxie :)
Nie znam się na foxpro, ale popatrz jak jest zrobiony shared_ptr i
weak_ptr w boost. Nie wymaga żadnej ingerencji w obiekty. To, czego
potrzebujesz, można zrobić podobnie z tą różnicą, że twój odpowiednik
shared_ptr nie będzie kopiowalny, więc nie musisz mieć licznika silnych
referencji.
> No to jest jakiś pomysł, czyli coś w rodzaju LifeCycleObserver.
> Hmmm ... Może tak to właśnie u siebie nazwę :) Z tym tylko
> niuansem, ze obserwer właściwie bardziej obserwuje siebie, niż
> podpięty obiekt. Bo to obserwer byłby tym obiektem lokalnym,
> który musi w destruktorze odpalić 'wypisanie' innego obiektu
> z systemu. Taki SelfDestroyObserver :)
Obserwator nie obserwuje siebie, tylko wrappera/smart pointera
zarządzającego czasem życia obiektu. Przy okazji desktukcji tego obiektu
wrapper powiadamia wszystkich obserwatorów, a oni obsługują
powiadomienie usuwając wskaźnik na niszczony obiekt z kolekcji.
-
7. Data: 2012-03-21 08:13:51
Temat: Re: Jaki wzorzec projektowy: pilnowanie cyklu życia innego obiektu ?
Od: zażółcony <r...@c...pl>
W dniu 2012-03-17 13:17, Andrzej Jarzabek pisze:
> On 16/03/2012 12:28, zażółcony wrote:
>> W dniu 2012-03-16 12:06, Andrzej Jarzabek pisze:
>>>
>>> Po pierwsze, może po prostu weak reference jest patternem, który
>>> powinieneś zaimplementować?
>> Ciężka sprawa w foxie ... Nie bardzo widzę sposób implementacji
>> bez mocnej ingerencji w same obiekty, które chcemy pilnować.
>> Bez wtykania w destruktory specjalnego kodu tego nie widzę.
>> Jak najmniej takich rzeczy w Foxie :)
>
> Nie znam się na foxpro, ale popatrz jak jest zrobiony shared_ptr i
> weak_ptr w boost. Nie wymaga żadnej ingerencji w obiekty. To, czego
> potrzebujesz, można zrobić podobnie z tą różnicą, że twój odpowiednik
> shared_ptr nie będzie kopiowalny, więc nie musisz mieć licznika silnych
> referencji.
>
>> No to jest jakiś pomysł, czyli coś w rodzaju LifeCycleObserver.
>> Hmmm ... Może tak to właśnie u siebie nazwę :) Z tym tylko
>> niuansem, ze obserwer właściwie bardziej obserwuje siebie, niż
>> podpięty obiekt. Bo to obserwer byłby tym obiektem lokalnym,
>> który musi w destruktorze odpalić 'wypisanie' innego obiektu
>> z systemu. Taki SelfDestroyObserver :)
>
> Obserwator nie obserwuje siebie, tylko wrappera/smart pointera
> zarządzającego czasem życia obiektu. Przy okazji desktukcji tego obiektu
> wrapper powiadamia wszystkich obserwatorów, a oni obsługują
> powiadomienie usuwając wskaźnik na niszczony obiekt z kolekcji.
Ok, dzieki, przyjrzałem sie temu. I to byłaby właśnie ta nazwa,
której szukałem: "Smart pointer"
http://en.wikipedia.org/wiki/Smart_pointer
Po połączeniu z wzorcem observer: smart pointer w destruktorze
robi 'update', czyli śle powiadomienia o zmianie do wszystkich obserwatorów.
Jest tu teraz trochę inny problem, specyficzny dla FoxPro, a mianowicie
za dużo obiektów (a z niewiadomych dla mnie powodów w FoxPro
tworzenie instancji obiektów jest wyjątkowo mało wydajne)
towarzyszących. Na obiekt rzeczywisty idzie dodatkowo konstrukcja
smart pointera i zaraz za nim konstrukcja observera. Dlatego ja
kombinowałem od razu z mniej czystym rozwiązaniem, gdzie
smart-pointer jest od razu obserwatorem i sam wie, skąd wypisać
wskazywany obiekt. Muszę nad tym pomyśleć. Jeszcze raz dzięki :)
-
8. Data: 2012-03-21 14:22:45
Temat: Re: Jaki wzorzec projektowy: pilnowanie cyklu życia innego obiektu ?
Od: Andrzej Jarzabek <a...@g...com>
On Mar 21, 8:13 am, zażółcony <r...@c...pl> wrote:
>
> Jest tu teraz trochę inny problem, specyficzny dla FoxPro, a mianowicie
> za dużo obiektów (a z niewiadomych dla mnie powodów w FoxPro
> tworzenie instancji obiektów jest wyjątkowo mało wydajne)
Ja potrafię sobie wyobrazić, dlaczego tak jest, ale jeśli chodzi o
porady w tym temacie, to jedyna jaką mam to "rzuć to g..no" :)
-
9. Data: 2012-03-21 14:42:41
Temat: Re: Jaki wzorzec projektowy: pilnowanie cyklu życia innego obiektu ?
Od: Andrzej Jarzabek <a...@g...com>
On Mar 21, 8:13 am, zażółcony <r...@c...pl> wrote:
[...]
> smart pointera i zaraz za nim konstrukcja observera. Dlatego ja
> kombinowałem od razu z mniej czystym rozwiązaniem, gdzie
> smart-pointer jest od razu obserwatorem i sam wie, skąd wypisać
> wskazywany obiekt. Muszę nad tym pomyśleć. Jeszcze raz dzięki :)
Przy okazji (jeszcze raz z poprawką, że nie znam się na FoxPro) to
raczej niweiele zmienia: w najbardziej topornym przypadku smart
pointer czy inny wrapper musi trzymać listę kolekcji i usuwać wskaźnik
do trzymanego obiektu z każdej z nich, w eleganckim rozwiązaniu trzyma
listę referencji (wskaźników czy co tam ma FoxPro) na interfejsy
(klasę bazową, czy co tam ma FoxPro) 'obserwator', które są
implementowane przez typ trzymający kolekcję i implementujący notify()
funkcją usuwającą przekazany wskaźnik z kolekcji. Z grubsza w obydwu
wariantach dzieje się dokładnie to samo, jedynie z ewentualnym
narzutem na wywołanie funkcji wirtualnej.
Jeśli chodzi o tworzenie dodatkowych obiektów, to zauważ:
1. Jeśli używasz w swoim smart pointerze obserwatora, zamiast weak
pointerów, to odchodzi ci tworzenie obiektu licznika.
2. Jeśli masz w FoxPro coś w rodzaju object composition z C++ i nie
wymagasz polimorfizmu, to możesz zamiast smart pointera zastosować
wrapper który powiadamia obserwatorów.
3. Jeśli nie masz kompozycji, możesz ewentualnie pomyśleć o
dziedziczeniu (w niektórych językach są do tego mixiny, ale FoxPro bym
o to nie podejrzewał), obserwatorów powiadamia destruktor klasy
bazowej. Oczywiście wtedy odpada automatyczna destrukcja pierwotnego
obiektu.
4. A najlepiej to rzuć to g..no :)
-
10. Data: 2012-03-21 14:46:13
Temat: Re: Jaki wzorzec projektowy: pilnowanie cyklu życia innego obiektu ?
Od: zażółcony <r...@c...pl>
W dniu 2012-03-21 14:22, Andrzej Jarzabek pisze:
> On Mar 21, 8:13 am, zażółcony<r...@c...pl> wrote:
>>
>> Jest tu teraz trochę inny problem, specyficzny dla FoxPro, a mianowicie
>> za dużo obiektów (a z niewiadomych dla mnie powodów w FoxPro
>> tworzenie instancji obiektów jest wyjątkowo mało wydajne)
>
> Ja potrafię sobie wyobrazić, dlaczego tak jest, ale jeśli chodzi o
> porady w tym temacie, to jedyna jaką mam to "rzuć to g..no" :)
Od kilku lat rzucamy. Na raty. To jest jak kredyt mieszkaniowy :)