Thread View: pl.comp.objects
13 messages
13 total messages
Started by Adam Przybylek
Wed, 11 Jul 2007 18:54
Composition Filters
Author: Adam Przybylek
Date: Wed, 11 Jul 2007 18:54
Date: Wed, 11 Jul 2007 18:54
10 lines
1189 bytes
1189 bytes
Czy ktos z Was moze wyjasnic dlaczego CFs nie zyskaly popularnosci chocby takiej jak AOP (chocby na poziomie akademickim). Przeczytalem kilka papierow i wydaje mi sie, ze koncepcyjnie CFs w elegancki sposob rozszerza model obiektowy i rozwiazuje czesc problemow zwiazanych z klasycznym OO. Jesli w CFs jest jakis haczyk ktorego nie widze to bede wdzieczny za nakierowanie. Gdyby ktos chcial sie zainteresowac podaje linka: http://trese.cs.utwente.nl/oldhtml/composition_filters/ Pozdrawiam, Adam
Re: Composition Filters
Author: A.L.
Date: Sun, 15 Jul 2007 04:22
Date: Sun, 15 Jul 2007 04:22
16 lines
1365 bytes
1365 bytes
On Wed, 11 Jul 2007 20:54:29 +0200, Adam Przybylek <adampap1@vp.pl> wrote: >Czy ktos z Was moze wyjasnic dlaczego CFs nie zyskaly popularnosci >chocby takiej jak AOP (chocby na poziomie akademickim). Przeczytalem >kilka papierow i wydaje mi sie, ze koncepcyjnie CFs w elegancki sposob >rozszerza model obiektowy i rozwiazuje czesc problemow zwiazanych z >klasycznym OO. Jesli w CFs jest jakis haczyk ktorego nie widze to bede >wdzieczny za nakierowanie. Gdyby ktos chcial sie zainteresowac podaje linka: >http://trese.cs.utwente.nl/oldhtml/composition_filters/ > Dlatego, jak sadze, ze podobnie jak w przypadku Aspect Programming, odpowiada na pytanie ktorego nikt nie zadal. A.L.
Re: Composition Filters
Author: Kamil Janiszewski
Date: Thu, 02 Aug 2007 22:45
Date: Thu, 02 Aug 2007 22:45
36 lines
2988 bytes
2988 bytes
On 15 Lip, 06:22, A.L. <f...@2005.com> wrote: > On Wed, 11 Jul 2007 20:54:29 +0200, Adam Przybylek <adamp...@vp.pl> > wrote: > > >Czy ktos z Was moze wyjasnic dlaczego CFs nie zyskaly popularnosci > >chocby takiej jak AOP (chocby na poziomie akademickim). Przeczytalem > >kilka papierow i wydaje mi sie, ze koncepcyjnie CFs w elegancki sposob > >rozszerza model obiektowy i rozwiazuje czesc problemow zwiazanych z > >klasycznym OO. Jesli w CFs jest jakis haczyk ktorego nie widze to bede > >wdzieczny za nakierowanie. Gdyby ktos chcial sie zainteresowac podaje linka: > >http://trese.cs.utwente.nl/oldhtml/composition_filters/ > > Dlatego, jak sadze, ze podobnie jak w przypadku Aspect Programming, > odpowiada na pytanie ktorego nikt nie zadal. > > A.L. Moim zdaniem problem separacji zagadnie jest istotny w codziennym yciu programistów i architektów. AOP jest kolejnym krokiem na nieko cz cej si drodze ku rozwi zaniu tego problemu. Uwa am, e programowanie aspektowe zdecydowanie zdoby o/zdobywa sobie popularno , zacz o od wiata Javy, w którym wietnymi przyk adami s zastosowania tej metodyki w Springu, JBossie i GlassBoxie. Po stronie .Netu równie co si ruszy o: w sk ad Enterprise Library (od wersji 3.0) wchodzi Policy Injection Block, który jest czym na kszta t AOP. Z tego co wiem, to AOP czerpie z CF, programowania adaptacyjnego, i meta-poziomowego. Mam nadziej , e czerpie z nich to co najlepsze :) Ponadto AOP z jakiego powodu jest bardzo dobrze umocowane politycznie, Gregor Kiczales, by y pracownik Xerox PARC (tam pracowa w a nie nad AOP), jest do wp ywowy, od 1999 roku zarz dza dzia em wytwarzania oprogramowania w Xerox Canada/Sierra Systems/Natural Sciences and Engineering Research Council of Canada/ University of British Columbia.
Re: Composition Filters
Author: A.L.
Date: Thu, 02 Aug 2007 23:31
Date: Thu, 02 Aug 2007 23:31
15 lines
1389 bytes
1389 bytes
On Thu, 02 Aug 2007 22:45:04 -0000, Kamil Janiszewski <zedzik@googlemail.com> wrote: >Ponadto AOP z jakiego powodu jest bardzo dobrze umocowane >politycznie, Gregor Kiczales, by y pracownik Xerox PARC (tam pracowa >w a nie nad AOP), jest do wp ywowy, od 1999 roku zarz dza dzia em >wytwarzania oprogramowania w Xerox Canada/Sierra Systems/Natural >Sciences and Engineering Research Council of Canada/ University of >British Columbia. To ma byc argument na co?... Taki argument ze "Teoria Lysenki musi byc prawdziwa bo Lusenko to Uczony Radziecki"?... A.L.
Re: Composition Filters
Author: Adam Przybylek
Date: Fri, 03 Aug 2007 10:45
Date: Fri, 03 Aug 2007 10:45
19 lines
1623 bytes
1623 bytes
Kamil Janiszewski napisał(a): > [...] > Z tego co wiem, to AOP czerpie z CF, programowania adaptacyjnego, i > meta-poziomowego. Mam nadziej , e czerpie z nich to co najlepsze :) > W papierach pisza, ze CFs byly prekursorem AOP, ale podobienstwa miedzy nimi to za bardzo nie widze. Jedyne co je laczy to cel - lepsza separacja zagadnien niz w klasycznym modelu OO. Mnie jednak ciekawilo co innego: dlaczego AOP pomimo, ze narusza pewne praktyki wypracowane przez OO rozwija sie dynamicznie, natomiast CFs praktycznie nie istnieja, choc w elegancki i naturalny sposob rozszerzaja OO. Ale juz chyba czesciowo znalazlem odpowiedz. Za kilka dni jak bede mial wiecej czasu pokaze przyklad. Pozdrawiam, Adam
Re: Composition Filters
Author: Kamil Janiszewski
Date: Fri, 03 Aug 2007 13:26
Date: Fri, 03 Aug 2007 13:26
24 lines
2331 bytes
2331 bytes
On 3 Sie, 01:31, A.L. <f...@2005.com> wrote: > On Thu, 02 Aug 2007 22:45:04 -0000, Kamil Janiszewski > > <zed...@googlemail.com> wrote: > >Ponadto AOP z jakiego powodu jest bardzo dobrze umocowane > >politycznie, Gregor Kiczales, by y pracownik Xerox PARC (tam pracowa > >w a nie nad AOP), jest do wp ywowy, od 1999 roku zarz dza dzia em > >wytwarzania oprogramowania w Xerox Canada/Sierra Systems/Natural > >Sciences and Engineering Research Council of Canada/ University of > >British Columbia. > > To ma byc argument na co?... Taki argument ze "Teoria Lysenki musi byc > prawdziwa bo Lusenko to Uczony Radziecki"?... > > A.L. Moim zdaniem o popularno ci AOP przes dzi a wp ywowo pana Kiczalesa, ten kawa ek tekstu mia j potwierdza . Prosz zerkn na: http://media.xerox.ca/news/default.asp?articleID=153 , mo e to b dzie mocniejsza poszlaka. Zobaczymy jakie nowo ci przyniesie przysz a wypowied Pana Adama Przybyleka.
Re: Composition Filters
Author: A.L.
Date: Fri, 03 Aug 2007 13:32
Date: Fri, 03 Aug 2007 13:32
26 lines
1985 bytes
1985 bytes
On Fri, 03 Aug 2007 06:26:09 -0700, Kamil Janiszewski <zedzik@googlemail.com> wrote: >On 3 Sie, 01:31, A.L. <f...@2005.com> wrote: >> On Thu, 02 Aug 2007 22:45:04 -0000, Kamil Janiszewski >> >> <zed...@googlemail.com> wrote: >> >Ponadto AOP z jakiego powodu jest bardzo dobrze umocowane >> >politycznie, Gregor Kiczales, by y pracownik Xerox PARC (tam pracowa >> >w a nie nad AOP), jest do wp ywowy, od 1999 roku zarz dza dzia em >> >wytwarzania oprogramowania w Xerox Canada/Sierra Systems/Natural >> >Sciences and Engineering Research Council of Canada/ University of >> >British Columbia. >> >> To ma byc argument na co?... Taki argument ze "Teoria Lysenki musi byc >> prawdziwa bo Lusenko to Uczony Radziecki"?... >> >> A.L. > >Moim zdaniem o popularno ci AOP przes dzi a wp ywowo pana Kiczalesa, >ten kawa ek tekstu mia j potwierdza . "Popularmosc" AOP jest dokladnie zerowa, neizaleznei od tego co Pan Kiczales twierdzi. A.L.
Re: Composition Filters
Author: A.L.
Date: Fri, 03 Aug 2007 13:33
Date: Fri, 03 Aug 2007 13:33
19 lines
1571 bytes
1571 bytes
On Fri, 03 Aug 2007 12:45:09 +0200, Adam Przybylek <adampap1@vp.pl> wrote: >Kamil Janiszewski napisał(a): >> [...] >> Z tego co wiem, to AOP czerpie z CF, programowania adaptacyjnego, i >> meta-poziomowego. Mam nadziej , e czerpie z nich to co najlepsze :) >> > >W papierach pisza, ze CFs byly prekursorem AOP, ale podobienstwa miedzy >nimi to za bardzo nie widze. Jedyne co je laczy to cel - lepsza >separacja zagadnien niz w klasycznym modelu OO. >Mnie jednak ciekawilo co innego: dlaczego AOP pomimo, ze narusza pewne >praktyki wypracowane przez OO rozwija sie dynamicznie, Ze jak sie rozwija?... Moze i dymamicznie sie rozwija, ino nikt go nie uzywa. A.L.
Re: Composition Filters
Author: Adam Przybylek
Date: Fri, 03 Aug 2007 16:04
Date: Fri, 03 Aug 2007 16:04
11 lines
1189 bytes
1189 bytes
A.L. napisał(a): > > Ze jak sie rozwija?... Moze i dymamicznie sie rozwija, ino nikt go nie > uzywa. > Tzn. ja oceniam AOP z perspektywy zainteresowania na konferencjach naukowych, a nie w przemysle. Pozdrawiam, Adam
Re: Composition Filters [uwaga dlugie]
Author: Adam Przybylek
Date: Thu, 16 Aug 2007 16:28
Date: Thu, 16 Aug 2007 16:28
418 lines
12432 bytes
12432 bytes
Kamil Janiszewski napisa?(a):
> Zobaczymy jakie nowosci przyniesie przyszla wypowiedz Pana Adama
> Przybylka.
No wie;c skoro obieca?em to pisze;. W poprzednim pos'cie mówi?em, z.e
znalaz?em cze;s'ciowo odpowiedz' na pytanie dlaczego CFs sie; nie
upowszechni?y. Otóz. celem CFs by?o dostarczenie mechanizmu
umoz.liwiaja;cego lepsza; separacje; zagadnien' (SoC - Separation of
Concerns) niz. w paradygmacie obiektowym. Moje zdanie jest takie, z.e
wykorzystuja;c CFs dla niektórych przypadków moz.na osia;gna;c' lepsza; SoC,
ale nie ma ona wie;kszego wp?ywu na poprawe; evolvability i reusability.
Poniz.ej przyk?ad na problemy jakie powstaja; przy implementacji w Javie
oraz próba (bezowocna) rozwia;zania ich przy pomocy dodania do Javy
filtrów input (hipotetyczna sk?adnia).
Za?óz.my, z.e tworza;c nowy modu? chcemy w jak najwie;kszym stopniu
wykorzystac' istnieja;ce modu?y. Ponadto na kaz.dym etapie chcemy zrobic'
dobra; implementacje; pod aktualne wymagania, a nie pod ewentualne
przysz?e, o których nic nie wiemy. Zapominamy o istnieniu gotowych
pakietów Javy. Za?óz.my takz.e, z.e posiadamy w repozytorium naste;puja;ca;
implementacje; kolejki:
public class Queue {
protected Object[] buf;
protected int numItems;
protected int nextToRemove;
public Queue(int capacity) {
buf = new Object[capacity];
}
public boolean isFull() {
return (numItems==buf.length);
}
public boolean isEmpty() {
return (numItems==0);
}
public int size() {
return numItems;
}
public boolean put(Object x) {
if ( isFull() ) return false;
buf[(nextToRemove+numItems) % buf.length] = x;
numItems++;
return true;
}
public Object get() {
Object tmp=null;
if ( !isEmpty() ) {
tmp = buf[nextToRemove];
numItems--;
nextToRemove = (nextToRemove+1) % buf.length;
}
return tmp;
}
}
Etap 1. Nalez.y zaimplementowac' klase; Buffer pod klasyczny problem
producenta-konsumenta.
a) rozwia;zanie Java
public class Buffer extends Queue {
public Buffer(int capacity) {
super(capacity);
}
public synchronized boolean put(Object x) {
while ( isFull() ) try {
wait();
} catch (InterruptedException e) {}
super.put(x);
notifyAll();
return true;
}
public synchronized Object get() {
while ( isEmpty() ) try {
wait();
} catch (InterruptedException e) {}
Object tmp = super.get();
notifyAll();
return tmp;
}
}
Nalez.y zauwaz.yc', z.e zagadnienie synchronizacji (zagadnienie
przecinaja;ce) jest splecione z zagadnieniem odk?adania i pobierania
danych (zagadnienie podstawowe).
b) rozwia;zanie CFs
public class BufferCF {
private Queue delegate;
filter Wait {
delegate.isFull() => put(Object),
delegate.isEmpty() => get()
};
filter Dispatch { true => delegate.* };
}
Dzia?a to w ten sposób, z.e kaz.dy komunikat przychodza;cy z zewna;trz do
obiektu przechodzi najpierw przez filtr Wait, a naste;pnie przez filtr
Dispatch. Pierwszy wpis w filtrze Wait mówi, aby us'pic' wa;tek wykonuja;cy
put(Object) na pe?nym buforze, a drugi, aby us'pic' wa;tek wykonuja;cy get()
na pustym buforze.
Na?oz.enie na metode; filtru Wait sprawia, z.e staje sie; ona synchroniczna.
Ponadto sprawdzenie warunku (równiez. synchroniczne) i ewentualne
rozpocze;cie metody jest atomowe.
Z kolei zastosowany filtr Dispatch mówi, aby kaz.dy komunikat (*)
bezwarunkowo (true) przekazac' do obs?uz.enia obiektowi delegate. Gdyby
filtr Dispatch zawiera? wie;cej wpisów rozpatrywane by by?y od lewej do
prawej tak d?ugo az. skojarzony z któryms' warunek be;dzie spe?niony. Jes'li
z.aden warunek nie zostanie spe?niony to rzucany jest run-time error.
Etap 2. Przychodzi nowe wymaganie - dla kaz.dego elementu wk?adanego do
bufora nalez.y pamie;tac' date; kiedy zosta? on w?oz.ony. Ponadto umoz.liwic'
pobranie elementu razem z ta; data;.
a) rozwia;zanie Java
public class HistoryBuffer extends Buffer {
protected Queue delegateDates;
public HistoryBuffer(int capacity) {
super(capacity);
delegateDates = new Queue(capacity);
}
public synchronized boolean put(Object x) {
while ( isFull() ) try {
wait();
} catch (InterruptedException e) {}
super.put(x);
delegateDates.put( new Date() );
notifyAll();
return true;
}
public synchronized Object get() {
while ( isEmpty() ) try {
wait();
} catch (InterruptedException e) {}
Object tmp = super.get();
delegateDates.get();
notifyAll();
return tmp;
}
public synchronized Pair getWithDate() {
while ( isEmpty() ) try {
wait();
} catch (InterruptedException e) {}
Pair tmp = new Pair( super.get(), delegateDates.get() );
notifyAll();
return tmp;
}
}
b) rozwiazanie CFs
public class HistoryBufferCF {
private Queue delegateObjects;
private Queue delegateDates;
public HistoryBufferCF(int capacity) {
delegateObjects = new Queue(capacity);
delegateDates = new Queue(capacity);
}
public void put(Object x) {
delegateObjects.put(x);
delegateDates.put(new Date());
}
public Object get() {
delegateDates.get();
return delegateObjects.get();
}
public Pair getWithDate() {
return new Pair(delegateObjects.get(),delegateDates.get());
}
filter Wait {
delegateObjects.isFull() => put(Object),
delegateObjects.isEmpty() => { get(), getWithDate() }
};
filter Dispatch { true => this.*, true => delegateObjects.* };
}
Etap 3. Na potrzeby monitoringu nalez.y logowac' informacje o stanie
bufora po kaz.dej transakcji.
a) rozwia;zanie Java
public class LogHistoryBuffer extends HistoryBuffer {
public LogHistoryBuffer(int capacity) {
super(capacity);
}
protected void log() {
System.out.println("stan bufora: "+size());
}
public synchronized boolean put(Object x) {
super.put(x);
log();
return true;
}
public synchronized Object get() {
Object tmp = super.get();
log();
return tmp;
}
public synchronized Pair getWithDate() {
Pair tmp = super.getWithDate();
log();
return tmp;
}
}
b) rozwia;zanie CFs
public class LogHistoryBufferCF {
private HistoryBufferCF delegate;
private void log() {
System.out.println("stan bufora: "+delegate.size());
}
public void put(Object x) {
delegate.put(x);
log();
}
public Object get() {
Object tmp = delegate.get();
log();
return tmp;
}
public Pair getWithDate() {
Pair tmp = delegate.getWithDate();
log();
return tmp;
}
filter Wait {
delegate.isFull() => put(Object),
delegate.isEmpty() => { get(), getWithDate() }
};
filter Dispatch { true => this.*, true => delegate.* };
}
W obu implementacjach zagadnienie logowania (zagadnienie przecinaja;ce)
przeplatane jest z zagadnieniem podstawowym.
Etap 4. Stworzyc' moz.liwos'c' pobrania n kolejnych elementów w postaci
tablicy. Pobieranie rozpocza;c' jes'li istnieje w buforze przynajmniej
jeden element. Logowanie ma byc' pojedyncze dla kaz.dej transakcji
(pobranie tablicy n elementów be;dzie logowane tylko raz).
a) rozwia;zanie Java
public class EnhancedLogHistoryBuffer extends HistoryBuffer {
protected boolean lock;
public EnhancedLogHistoryBuffer(int capacity) {
super(capacity);
}
protected void lock(boolean b) {
lock = b;
}
protected boolean isLock() {
return lock;
}
protected void log() {
System.out.println("stan bufora: "+size());
}
public synchronized boolean put(Object x) {
super.put(x);
log();
return true;
}
public synchronized Object get() {
while ( isEmpty()||isLock() ) try {
wait();
} catch (InterruptedException e) {}
Object tmp = super.get();
log();
return tmp;
}
public synchronized Pair getWithDate() {
while ( isEmpty()||isLock() ) try {
wait();
} catch (InterruptedException e) {}
Pair tmp = super.getWithDate();
log();
return tmp;
}
public synchronized Object[] get(int n) {
while ( isEmpty()||isLock() ) try {
wait();
} catch (InterruptedException e) {}
lock(true);
Object[] tmp = new Object[n];
for(int i=0; i<n; i++) {
tmp[i] = super.get();
dates.get();
}
lock(false);
log();
return tmp;
}
public synchronized Pair[] getWithDate(int n) {
while ( isEmpty()||isLock() ) try {
wait();
} catch (InterruptedException e) {}
lock(true);
Pair[] tmp = new Pair[n];
for(int i=0; i<n; i++) tmp[i] = super.getWithDate();
lock(false);
log();
return tmp;
}
}
Implementuja;c operacje get(int) i getWithDate(int) nie moz.na wykorzystac'
implementacji get() i getWithDate() z klasy LogHistoryBuffer poniewaz. sa;
one splecione z zagadnieniem logowania. Poniewaz. w Javie nie ma
moz.liwos'ci, aby niepolimorficznie wywo?ac' metode; zdefiniowana; w
okres'lonej nadklasie, nalez.y ponownie za punkt wyjs'cia przyja;c' klase;
HistoryBuffer. Takie rozwia;zanie wymaga ponownego zaimplementowania
metody log.
b) rozwia;zanie CFs
public class EnhancedLogHistoryBufferCF {
private HistoryBufferCF delegate;
private boolean lock;
public EnhancedLogHistoryBufferCF(int capacity) {
delegate = new HistoryBufferCF(capacity);
}
public void lock(boolean b) {
lock = b;
}
public boolean isLock() {
return lock;
}
private void log() {
System.out.println("stan bufora: "+delegate.size());
}
public void put(Object x) {
delegate.put(x);
log();
}
public Object get() {
Object tmp = delegate.get();
log();
return tmp;
}
public Pair getWithDate() {
Pair tmp = delegate.getWithDate();
log();
return tmp;
}
public Object[] get(int n) {
lock(true);
Object[] tmp = new Object[n];
for(int i=0; i<n; i++) tmp[i] = delegate.get();
lock(false);
log();
return tmp;
}
public Pair[] getWithDate(int n) {
lock(true);
Pair[] tmp = new Pair[n];
for(int i=0; i<n; i++) tmp[i] = delegate.getWithDate();
lock(false);
log();
return tmp;
}
filter Wait {
delegate.isFull() => put(Object),
delegate.isEmpty() || isLock() => { get(), getWithDate(), get(int),
getWithDate(int) }
};
filter Dispatch { true => this.*, true => delegate.* };
}
Podobnie jak w przypadku rozwia;zania w Javie, trzeba ponownie
zaimplementowac' zagadnienie logowania. Ponadto zagadnienie
synchronizacji poprzez metode; lock zosta?o splecione z zagadnieniem
podstawowym.
***
Wszystkie przedstawione problemy zwia;zane z przeplataniem zagadnien'
moz.na rozwia;zac' za pomoca; AspectJ, a cze;s'c' z nich w klasycznym je;zyku OO
umoz.liwiaja;cym niepolimorficzne wo?anie metody.
Pozdrawiam,
Adam
Re: Composition Filters [uwaga dlugie]
Author: Adam Przybylek
Date: Thu, 16 Aug 2007 16:35
Date: Thu, 16 Aug 2007 16:35
417 lines
12506 bytes
12506 bytes
Jeszcze raz to samo tylko poprawiłem kodowanie na polskie.
W poprzednim poście napisałem, że znalazłem częściowo odpowiedź na
pytanie dlaczego CFs się nie upowszechniły. Otóż celem CFs było
dostarczenie mechanizmu umożliwiającego lepszą separację zagadnień (SoC
- Separation of Concerns) niż w paradygmacie obiektowym. Moje zdanie
jest takie, że wykorzystując CFs dla niektórych przypadków można
osiągnąć lepszą SoC, ale nie ma ona większego wpływu na poprawę
evolvability i reusability.
Poniżej przykład na problemy jakie powstają przy implementacji w Javie
oraz próba (bezowocna) rozwiązania ich przy pomocy dodania do Javy
filtrów input (hipotetyczna składnia).
Załóżmy, że tworząc nowy moduł chcemy w jak największym stopniu
wykorzystać istniejące moduły. Ponadto na każdym etapie chcemy zrobić
dobrą implementację pod aktualne wymagania, a nie pod ewentualne
przyszłe, o których nic nie wiemy. Zapominamy o istnieniu gotowych
pakietów Javy. Załóżmy także, że posiadamy w repozytorium następującą
implementację kolejki:
public class Queue {
protected Object[] buf;
protected int numItems;
protected int nextToRemove;
public Queue(int capacity) {
buf = new Object[capacity];
}
public boolean isFull() {
return (numItems==buf.length);
}
public boolean isEmpty() {
return (numItems==0);
}
public int size() {
return numItems;
}
public boolean put(Object x) {
if ( isFull() ) return false;
buf[(nextToRemove+numItems) % buf.length] = x;
numItems++;
return true;
}
public Object get() {
Object tmp=null;
if ( !isEmpty() ) {
tmp = buf[nextToRemove];
numItems--;
nextToRemove = (nextToRemove+1) % buf.length;
}
return tmp;
}
}
Etap 1. Należy zaimplementować klasę Buffer pod klasyczny problem
producenta-konsumenta.
a) rozwiązanie Java
public class Buffer extends Queue {
public Buffer(int capacity) {
super(capacity);
}
public synchronized boolean put(Object x) {
while ( isFull() ) try {
wait();
} catch (InterruptedException e) {}
super.put(x);
notifyAll();
return true;
}
public synchronized Object get() {
while ( isEmpty() ) try {
wait();
} catch (InterruptedException e) {}
Object tmp = super.get();
notifyAll();
return tmp;
}
}
Należy zauważyć, że zagadnienie synchronizacji (zagadnienie
przecinające) jest splecione z zagadnieniem odkładania i pobierania
danych (zagadnienie podstawowe).
b) rozwiązanie CFs
public class BufferCF {
private Queue delegate;
filter Wait {
delegate.isFull() => put(Object),
delegate.isEmpty() => get()
};
filter Dispatch { true => delegate.* };
}
Działa to w ten sposób, że każdy komunikat przychodzący z zewnątrz do
obiektu przechodzi najpierw przez filtr Wait, a następnie przez filtr
Dispatch. Pierwszy wpis w filtrze Wait mówi, aby uśpić wątek wykonujący
put(Object) na pełnym buforze, a drugi, aby uśpić wątek wykonujący get()
na pustym buforze.
Nałożenie na metodę filtru Wait sprawia, że staje się ona synchroniczna.
Ponadto sprawdzenie warunku (również synchroniczne) i ewentualne
rozpoczęcie metody jest atomowe.
Z kolei zastosowany filtr Dispatch mówi, aby każdy komunikat (*)
bezwarunkowo (true) przekazać do obsłużenia obiektowi delegate. Gdyby
filtr Dispatch zawierał więcej wpisów rozpatrywane by były od lewej do
prawej tak długo aż skojarzony z którymś warunek będzie spełniony. Jeśli
żaden warunek nie zostanie spełniony to rzucany jest run-time error.
Etap 2. Przychodzi nowe wymaganie - dla każdego elementu wkładanego do
bufora należy pamiętać datę kiedy został on włożony. Ponadto umożliwić
pobranie elementu razem z tą datą.
a) rozwiązanie Java
public class HistoryBuffer extends Buffer {
protected Queue delegateDates;
public HistoryBuffer(int capacity) {
super(capacity);
delegateDates = new Queue(capacity);
}
public synchronized boolean put(Object x) {
while ( isFull() ) try {
wait();
} catch (InterruptedException e) {}
super.put(x);
delegateDates.put( new Date() );
notifyAll();
return true;
}
public synchronized Object get() {
while ( isEmpty() ) try {
wait();
} catch (InterruptedException e) {}
Object tmp = super.get();
delegateDates.get();
notifyAll();
return tmp;
}
public synchronized Pair getWithDate() {
while ( isEmpty() ) try {
wait();
} catch (InterruptedException e) {}
Pair tmp = new Pair( super.get(), delegateDates.get() );
notifyAll();
return tmp;
}
}
b) rozwiazanie CFs
public class HistoryBufferCF {
private Queue delegateObjects;
private Queue delegateDates;
public HistoryBufferCF(int capacity) {
delegateObjects = new Queue(capacity);
delegateDates = new Queue(capacity);
}
public void put(Object x) {
delegateObjects.put(x);
delegateDates.put(new Date());
}
public Object get() {
delegateDates.get();
return delegateObjects.get();
}
public Pair getWithDate() {
return new Pair(delegateObjects.get(),delegateDates.get());
}
filter Wait {
delegateObjects.isFull() => put(Object),
delegateObjects.isEmpty() => { get(), getWithDate() }
};
filter Dispatch { true => this.*, true => delegateObjects.* };
}
Etap 3. Na potrzeby monitoringu należy logować informacje o stanie
bufora po każdej transakcji.
a) rozwiązanie Java
public class LogHistoryBuffer extends HistoryBuffer {
public LogHistoryBuffer(int capacity) {
super(capacity);
}
protected void log() {
System.out.println("stan bufora: "+size());
}
public synchronized boolean put(Object x) {
super.put(x);
log();
return true;
}
public synchronized Object get() {
Object tmp = super.get();
log();
return tmp;
}
public synchronized Pair getWithDate() {
Pair tmp = super.getWithDate();
log();
return tmp;
}
}
b) rozwiązanie CFs
public class LogHistoryBufferCF {
private HistoryBufferCF delegate;
private void log() {
System.out.println("stan bufora: "+delegate.size());
}
public void put(Object x) {
delegate.put(x);
log();
}
public Object get() {
Object tmp = delegate.get();
log();
return tmp;
}
public Pair getWithDate() {
Pair tmp = delegate.getWithDate();
log();
return tmp;
}
filter Wait {
delegate.isFull() => put(Object),
delegate.isEmpty() => { get(), getWithDate() }
};
filter Dispatch { true => this.*, true => delegate.* };
}
W obu implementacjach zagadnienie logowania (zagadnienie przecinające)
przeplatane jest z zagadnieniem podstawowym.
Etap 4. Stworzyć możliwość pobrania n kolejnych elementów w postaci
tablicy. Pobieranie rozpocząć jeśli istnieje w buforze przynajmniej
jeden element. Logowanie ma być pojedyncze dla każdej transakcji
(pobranie tablicy n elementów będzie logowane tylko raz).
a) rozwiązanie Java
public class EnhancedLogHistoryBuffer extends HistoryBuffer {
protected boolean lock;
public EnhancedLogHistoryBuffer(int capacity) {
super(capacity);
}
protected void lock(boolean b) {
lock = b;
}
protected boolean isLock() {
return lock;
}
protected void log() {
System.out.println("stan bufora: "+size());
}
public synchronized boolean put(Object x) {
super.put(x);
log();
return true;
}
public synchronized Object get() {
while ( isEmpty()||isLock() ) try {
wait();
} catch (InterruptedException e) {}
Object tmp = super.get();
log();
return tmp;
}
public synchronized Pair getWithDate() {
while ( isEmpty()||isLock() ) try {
wait();
} catch (InterruptedException e) {}
Pair tmp = super.getWithDate();
log();
return tmp;
}
public synchronized Object[] get(int n) {
while ( isEmpty()||isLock() ) try {
wait();
} catch (InterruptedException e) {}
lock(true);
Object[] tmp = new Object[n];
for(int i=0; i<n; i++) {
tmp[i] = super.get();
dates.get();
}
lock(false);
log();
return tmp;
}
public synchronized Pair[] getWithDate(int n) {
while ( isEmpty()||isLock() ) try {
wait();
} catch (InterruptedException e) {}
lock(true);
Pair[] tmp = new Pair[n];
for(int i=0; i<n; i++) tmp[i] = super.getWithDate();
lock(false);
log();
return tmp;
}
}
Implementując operacje get(int) i getWithDate(int) nie można wykorzystać
implementacji get() i getWithDate() z klasy LogHistoryBuffer ponieważ są
one splecione z zagadnieniem logowania. Ponieważ w Javie nie ma
możliwości, aby niepolimorficznie wywołać metodę zdefiniowaną w
określonej nadklasie, należy ponownie za punkt wyjścia przyjąć klasę
HistoryBuffer. Takie rozwiązanie wymaga ponownego zaimplementowania
metody log.
Alternatywne rozwiązanie polega na rozszerzeniu klasy LogHistoryBuffer i
"od zera" napisanie implementacji get(int) i getWithDate(int).
b) rozwiązanie CFs
public class EnhancedLogHistoryBufferCF {
private HistoryBufferCF delegate;
private boolean lock;
public EnhancedLogHistoryBufferCF(int capacity) {
delegate = new HistoryBufferCF(capacity);
}
public void lock(boolean b) {
lock = b;
}
public boolean isLock() {
return lock;
}
private void log() {
System.out.println("stan bufora: "+delegate.size());
}
public void put(Object x) {
delegate.put(x);
log();
}
public Object get() {
Object tmp = delegate.get();
log();
return tmp;
}
public Pair getWithDate() {
Pair tmp = delegate.getWithDate();
log();
return tmp;
}
public Object[] get(int n) {
lock(true);
Object[] tmp = new Object[n];
for(int i=0; i<n; i++) tmp[i] = delegate.get();
lock(false);
log();
return tmp;
}
public Pair[] getWithDate(int n) {
lock(true);
Pair[] tmp = new Pair[n];
for(int i=0; i<n; i++) tmp[i] = delegate.getWithDate();
lock(false);
log();
return tmp;
}
filter Wait {
delegate.isFull() => put(Object),
delegate.isEmpty() || isLock() => {
get(), getWithDate(), get(int), getWithDate(int)
}
};
filter Dispatch { true => this.*, true => delegate.* };
}
Podobnie jak w przypadku rozwiązania w Javie, trzeba ponownie
zaimplementować zagadnienie logowania. Ponadto zagadnienie
synchronizacji poprzez metodę lock zostało splecione z zagadnieniem
podstawowym.
***
Wszystkie przedstawione problemy związane z przeplataniem zagadnień
można rozwiązać za pomocą AspectJ, a część z nich w klasycznym języku OO
umożliwiającym niepolimorficzne wołanie metody.
Re: Composition Filters
Author: Jarek
Date: Thu, 30 Aug 2007 09:57
Date: Thu, 30 Aug 2007 09:57
12 lines
1522 bytes
1522 bytes
> > Ze jak sie rozwija?... Moze i dymamicznie sie rozwija, ino nikt go nie > uzywa. > A już wymieniony przez kogoś Spring to nikt? Przecież to jeden z najpopularniejszych frameworków. JBoss też wewnętrznie używa AOP do implementacji paru rzeczy. Kolega twierdzi, że w firmie (dość dużej), w której pracuje też używają AOP, o ile się nie mylę, do zarządzania transakcjami. Pozdrawiam Jarek
Re: Composition Filters
Author: Kamil Janiszewski
Date: Wed, 05 Sep 2007 17:20
Date: Wed, 05 Sep 2007 17:20
76 lines
5024 bytes
5024 bytes
On 30 Sie, 11:57, "Jarek" <nie...@takiego.numeru> wrote:
> > Ze jak sie rozwija?... Moze i dymamicznie sie rozwija, ino nikt go nie
> > uzywa.
>
> A ju wymieniony przez kogo Spring to nikt? Przecie to jeden z
> najpopularniejszych frameworków.
> JBoss te wewn trznie u ywa AOP do implementacji paru rzeczy.
> Kolega twierdzi, e w firmie (do du ej), w której pracuje te u ywaj AOP,
> o ile si nie myl , do zarz dzania transakcjami.
>
> Pozdrawiam
> Jarek
On 30 Sie, 11:57, "Jarek" <nie...@takiego.numeru> wrote:
> > Ze jak sie rozwija?... Moze i dymamicznie sie rozwija, ino nikt go nie
> > uzywa.
>
> A ju wymieniony przez kogo Spring to nikt? Przecie to jeden z
> najpopularniejszych frameworków.
> JBoss te wewn trznie u ywa AOP do implementacji paru rzeczy.
> Kolega twierdzi, e w firmie (do du ej), w której pracuje te u ywaj AOP,
> o ile si nie myl , do zarz dzania transakcjami.
>
> Pozdrawiam
> Jarek
Wycinek z mojej, mam nadziej , przysz ej pracy magisterskiej:
AOP a wiat, kto korzysta z AOP
Wydawa oby si , e niewielu informatyków s ysza o o programowaniu
aspektowym. Dlatego nikt nie spodziewa si , e AOP jest wykorzystywane
w powa nych projektach. Tymczasem rzeczywisto mo e zaskoczy wielu z
nas.
Programowanie aspektowe jest u ywane w kilku wielkich projektach:
ˇ Deutsche Post World Net - aplikacja stanowi ca rozwi zanie problemów
zarz dzania, transportu, przesy ania informacji i p atno ci dla grupy
firm: Deutsche Post, DHL i Postbank (.NET),
ˇ Philips - wiele projektów informatycznych firmy stworzonych na bazie
autorskiego rozwi zania Koala. (inne),
ˇ Spring Framework - bardzo popularny szkielet wytwarzania aplikacji
(Java),
ˇ JBoss - równie popularny serwer aplikacji (Java),
ˇ Glassbox - agent pomagaj cy rozwi zywa cz sto wyst puj ce problemy
programistyczne (Java).
Inne zastosowania AOP to np.:
ˇ Tapestry - szkielet dla dynamicznych, atwo skalowalnych aplikacji
rozproszonych (Java),
ˇ Contract4J - narz dzie wspieraj ce programowanie kontraktowe (Design
by Contract - DBC),
ˇ Jakarta Cactus - szkielet testowy do przeprowadzania testów
jednostkowych kodu po stronie serwera (Java),
ˇ Objectweb Cooperative Open Workflow - silnik przep ywów pracy
(Java),
ˇ Objectweb Java Open Transaction Manager - zarz dca transakcji (na
przyk ad bazodanowych) (Java),
ˇ GridSphere portal framework - szkielet portalu internetowego (Java),
ˇ MySQL Connector/J - natywny sterownik bazy danych dla JDBC (Java).
Po przeczytaniu tej listy projektów nazuwa si spostrze enie, e
korzystanie z AOP jest znacznie bardziej popularne w wiecie Javy, ni
na platformie .NET, czy w C++. Powodem jest znaczna przewaga w rozwoju
narz dzi i j zyków programowania aspektowego w Javie oraz cz sto
otwarty charakter projektów pisanych w Javie. Realnie programowanie
aspektowe do niedawna mia o tylko jednego prawdziwego (dopracowanego i
popularnego) przedstawiciela i by to AspectJ. Jest to rozszerzenie do
Javy stworzone w s ynnym laboratorium Xerox PARC pod kierownictwem
Gregora Kiczalesa. Pierwsza publiczna wersja AspectJ ujrza a wiat o
dzienne w roku 2001.
Nie ma popularnych implementacji AOP poza AspectJ, aczkolwiek mo na
spodziewa si znacznego zainteresowania bibliotek Policy Injection
Block wchodz c w sk ad Enterprise Library od wersji 3.0 (kwiecie
2007) dla platformy .NET. Pury ci AOP mog zwraca uwag , na to, e
Policy Injection Block nie jest do ko ca zgodny z wszystkim
za o eniami AOP (nie planowano tego), mimo to ja uwa am, e jest
w a nie tym, co spopularyzuje podej cie do programowania znanego z AOP
w pot nym rodowisku programistów .NET.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads