Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
May 18, 2002 Patterns Observable | ||||
---|---|---|---|---|
| ||||
I'm looking for a couple of things. Suggestions only mind but here goes. I've found the observer pattern very useful in JAVA, with one caveat, the fact they made it an object that you have to inherit from. Bang goes your single inheritence. But to define it as an interface would mean implementing the behaviour each time. Yuck. <Puts on fireproof suit :o) > So whats the option. Is there some way in the language we can have something like class Observeable { notifyObservers(); } class B encaptulates Observeable { } where what would actually happen is that the compiler would generate class B { notifyObservers(); } So the funtionality of Oberver is encapsulated in B. In this way Observer would work. Overloading of the method is not allowed. Although maybe you could sub-class Observable itself. Then again maybe not. Now I know this looks alot like multiple inheritence, but if the compiler barfed if the user added a function notifyObservers() to class B then it would overcome the issue. Multiple inheritence is difficult and prone to error, but single inheritence is very restrictive. Don |
May 18, 2002 Re: Patterns Observable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don Stewart | "Don Stewart" <donald.m.stewart@btinternet.com> wrote in news:ac5r2l$1s5a$1@digitaldaemon.com: > I've found the observer pattern very useful in JAVA, with one caveat, the fact they made it an object that you have to inherit from. Bang goes your single inheritence. But to define it as an interface would mean implementing the behaviour each time. Yuck. I think the solution to this type of problem is mixins. A mixin is a piece of data and functionality that can be aggregated into another class. I like to explain these types of with concrete examples. Lets take the observer pattern mentioned above. Lets also say for the moment that D has a preprocessor like C does. I'm not saying that D should have a preprocessor, I'm just using it as a device to explain the idea I'm getting to below. The observer interfaces... interface IObserver { void update(IObserver from, Object obj); } interface IObservable { void addObserver(IObserver obs); void deleteObserver(IObserver obs); void deleteObservers(); int countObservers(); boolean hasChanged(); void notifyObservers(); void notifyObservers(Object obj); } So you want class Foo to be observable. That means that you must specify IObservable as an interface Foo implements. But then you have to actually implement all the functionality that is in IObservable. As noted this is rather tedious to do for every class that you want to be Observable. But suppose you made a proprocessor macro. #define IMPLEMENTS_OBSERVABLE \ IObserver[] observers; \ bit changed; \ void addObserver(IObserver obs) \ { \ observers ~= obj; \ } \ void notifyObservers() \ { \ for(int i = 0; i < observers.length; ++i) \ observers[i].update(this,null); \ } I'm not going to create the whole macro but you get the idea. So now you can make Foo line this... class Foo : BaseClass, IObservable { IMPLEMENTS_OBSERVABLE } This works but it uses a macro preprocessor that D has doesn't have for various good reasons. So I might suggest something like this. struct Observable { IObserver[] observers; bit changed=false; void addObserver(IObserver obs) { observers ~= obj; } void notifyObservers() { for(int i = 0; i < observers.length; ++i) observers[i].update(this,null); } // Other functions } class Foo : BaseClass, IObservable { mixin Observable a; } This is better than the macro. The Observable struct can be syntax checked at the point it's defined. All the functions in Observable could automatically generated in Foo be generating functions like... void addObserver(IObserver obs) { a.addObserver(obs); } |
May 18, 2002 Re: Patterns Observable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Patrick Down | Yes exactly but I was thinking along the lines of the compiler inserting the binary code of the Observable class in the, implementing object (okay so it's not really implementing because it's not an interface it's a compiled mixin object) rather than using macros. So in effect there is a language keyword that supports the observable macro. Now I agree we cannot add keywords for too many things otherwise there is a keyword explosion. But some the Gamma patterns are used frequently these days and it would be nice for them to be language contsructs. I was glad when I switched to JAVA and dumped macro's, hopefully, for good. "Patrick Down" <pat@codemoon.com> wrote in message news:Xns92128C2162F8Epatcodemooncom@63.105.9.61... > "Don Stewart" <donald.m.stewart@btinternet.com> wrote in news:ac5r2l$1s5a$1@digitaldaemon.com: > > > I've found the observer pattern very useful in JAVA, with one caveat, the fact they made it an object that you have to inherit from. Bang goes your single inheritence. But to define it as an interface would mean implementing the behaviour each time. Yuck. > > > I think the solution to this type of problem is > mixins. A mixin is a piece of data and functionality > that can be aggregated into another class. I like > to explain these types of with concrete examples. > > Lets take the observer pattern mentioned above. Lets > also say for the moment that D has a preprocessor like > C does. I'm not saying that D should have a preprocessor, > I'm just using it as a device to explain the idea I'm > getting to below. > > The observer interfaces... > > interface IObserver > { > void update(IObserver from, Object obj); > } > > interface IObservable > { > void addObserver(IObserver obs); > void deleteObserver(IObserver obs); > void deleteObservers(); > int countObservers(); > boolean hasChanged(); > void notifyObservers(); > void notifyObservers(Object obj); > } > > So you want class Foo to be observable. That means > that you must specify IObservable as an interface > Foo implements. But then you have to actually implement > all the functionality that is in IObservable. As noted > this is rather tedious to do for every class that you > want to be Observable. But suppose you made a proprocessor > macro. > > #define IMPLEMENTS_OBSERVABLE \ > IObserver[] observers; \ > bit changed; \ > void addObserver(IObserver obs) \ > { \ > observers ~= obj; \ > } \ > void notifyObservers() \ > { \ > for(int i = 0; i < observers.length; ++i) \ > observers[i].update(this,null); \ > } > > I'm not going to create the whole macro but you get the idea. > > So now you can make Foo line this... > > > class Foo : BaseClass, IObservable > { > IMPLEMENTS_OBSERVABLE > } > > > This works but it uses a macro preprocessor that D has doesn't have for various good reasons. So I might suggest something like this. > > struct Observable > { > IObserver[] observers; > bit changed=false; > void addObserver(IObserver obs) > { > observers ~= obj; > } > void notifyObservers() > { > for(int i = 0; i < observers.length; ++i) > observers[i].update(this,null); > } > > // Other functions > } > > class Foo : BaseClass, IObservable > { > mixin Observable a; > } > > This is better than the macro. The Observable struct can be syntax checked at the point it's defined. All the functions in Observable could automatically generated in Foo be generating functions like... > > void addObserver(IObserver obs) { a.addObserver(obs); } |
May 24, 2002 Re: Patterns Observable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don Stewart | I managed to find the code inlusion in another language called Sather. Sather defines a keyword called partial. To quote "Partial classes define code that does not have corresponding objects or type, and may be included by other classes to obtain implementation. "Don Stewart" <donald.m.stewart@btinternet.com> wrote in message news:ac698h$280c$1@digitaldaemon.com... > Yes exactly but I was thinking along the lines of the compiler inserting the > binary code of the Observable class in the, implementing object (okay so it's not really implementing because it's not an interface it's a compiled mixin object) rather than using macros. So in effect there is a language keyword that supports the observable macro. Now I agree we cannot add keywords for too many things otherwise there is a keyword explosion. But some the Gamma patterns are used frequently these days and it would be nice > for them to be language contsructs. > > I was glad when I switched to JAVA and dumped macro's, hopefully, for good. > > "Patrick Down" <pat@codemoon.com> wrote in message news:Xns92128C2162F8Epatcodemooncom@63.105.9.61... > > "Don Stewart" <donald.m.stewart@btinternet.com> wrote in news:ac5r2l$1s5a$1@digitaldaemon.com: > > > > > I've found the observer pattern very useful in JAVA, with one caveat, the fact they made it an object that you have to inherit from. Bang goes your single inheritence. But to define it as an interface would mean implementing the behaviour each time. Yuck. > > > > > > I think the solution to this type of problem is > > mixins. A mixin is a piece of data and functionality > > that can be aggregated into another class. I like > > to explain these types of with concrete examples. > > > > Lets take the observer pattern mentioned above. Lets > > also say for the moment that D has a preprocessor like > > C does. I'm not saying that D should have a preprocessor, > > I'm just using it as a device to explain the idea I'm > > getting to below. > > > > The observer interfaces... > > > > interface IObserver > > { > > void update(IObserver from, Object obj); > > } > > > > interface IObservable > > { > > void addObserver(IObserver obs); > > void deleteObserver(IObserver obs); > > void deleteObservers(); > > int countObservers(); > > boolean hasChanged(); > > void notifyObservers(); > > void notifyObservers(Object obj); > > } > > > > So you want class Foo to be observable. That means > > that you must specify IObservable as an interface > > Foo implements. But then you have to actually implement > > all the functionality that is in IObservable. As noted > > this is rather tedious to do for every class that you > > want to be Observable. But suppose you made a proprocessor > > macro. > > > > #define IMPLEMENTS_OBSERVABLE \ > > IObserver[] observers; \ > > bit changed; \ > > void addObserver(IObserver obs) \ > > { \ > > observers ~= obj; \ > > } \ > > void notifyObservers() \ > > { \ > > for(int i = 0; i < observers.length; ++i) \ > > observers[i].update(this,null); \ > > } > > > > I'm not going to create the whole macro but you get the idea. > > > > So now you can make Foo line this... > > > > > > class Foo : BaseClass, IObservable > > { > > IMPLEMENTS_OBSERVABLE > > } > > > > > > This works but it uses a macro preprocessor that D has doesn't have for various good reasons. So I might suggest something like this. > > > > struct Observable > > { > > IObserver[] observers; > > bit changed=false; > > void addObserver(IObserver obs) > > { > > observers ~= obj; > > } > > void notifyObservers() > > { > > for(int i = 0; i < observers.length; ++i) > > observers[i].update(this,null); > > } > > > > // Other functions > > } > > > > class Foo : BaseClass, IObservable > > { > > mixin Observable a; > > } > > > > This is better than the macro. The Observable struct can be syntax checked at the point it's defined. All the functions in Observable could automatically generated in Foo be generating functions like... > > > > void addObserver(IObserver obs) { a.addObserver(obs); } > > |
May 24, 2002 Re: Patterns Observable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don Stewart | "Don Stewart" <donald@genient.com> wrote in message news:aclmtj$jq5$1@digitaldaemon.com... > I managed to find the code inlusion in another language called Sather. > > Sather defines a keyword called partial. To quote > "Partial classes define code that does not have corresponding objects or > type, and may be included by other classes to obtain implementation. I find myself wanting this type of functionality all the time. But I'm not sure that there isn't a better way. Sean |
May 25, 2002 Re: Patterns Observable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | Exactly. I'm not sugesting this is the way. But a way would be very very useful. Don "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:aclsmq$peh$1@digitaldaemon.com... > "Don Stewart" <donald@genient.com> wrote in message news:aclmtj$jq5$1@digitaldaemon.com... > > I managed to find the code inlusion in another language called Sather. > > > > Sather defines a keyword called partial. To quote > > "Partial classes define code that does not have corresponding objects or > > type, and may be included by other classes to obtain implementation. > > I find myself wanting this type of functionality all the time. But I'm not > sure that there isn't a better way. > > Sean > > |
Copyright © 1999-2021 by the D Language Foundation