A Design Pattern Question for Functional Programers
Functional programing is getting the presses in mainstream. I ran across this dialogue where a imperative coder was trying to get into functional programing: A: What are the design patterns that help structure functional systems? B: Design patterns? Hey everyone, look at the muggle try to get the wand to work! from: 〈Code Watch: Functional programming's smugness problem〉 (2012-04-16) By By Larry O'brien. @ http://www.sdtimes.com/content/article.aspx?ArticleID=36534 hi, my dearly beloved C++ java perl python hackers, design pattern your mom! further readings: 〈Why Software Suck〉 http://xahlee.org/UnixResource_dir/writ/why_software_suck.html 〈What is a Tech Geeker?〉 http://xahlee.org/UnixResource_dir/writ/tech_geeker.html 〈Book Review: Patterns of Software〉 http://xahlee.org/PageTwo_dir/Personal_dir/bookReviewRichardGabriel.html 〈Are You Intelligent Enough to Understand HTML5?〉 http://xahlee.org/UnixResource_dir/writ/html5_vs_intelligence.html Xah -- http://mail.python.org/mailman/listinfo/python-list
observer pattern question #1 (reference to subject)
I have two questions about the observer pattern in Python. This is question #1. (I'll put the other is a separate post.) Here is a standard example of the observer pattern in Python: http://en.wikipedia.org/wiki/Observer_pattern Contrast with this rather standard discussion: http://www.dofactory.com/Patterns/PatternObserver.aspx#_self1 The difference I am focusing on is that in the latter, the observer (investor) maintains a reference to the subject (stock). (Many questions can be raised of course: see the discussion at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/131499). Is anything lost by not maintaining this reference (other than error checking ...)? If I feel the observer needs access to the subject, what is wrong with just having the subject pass itself as part of the notification? Thank you, Alan Isaac -- http://mail.python.org/mailman/listinfo/python-list
observer pattern question #2 (notification chain)
I have two questions about the observer pattern in Python. This is question #2. (I'll put the other is a separate post.) Consider this standard example of the observer pattern in Python: URL:http://en.wikipedia.org/wiki/Observer_pattern Now suppose I have a variant. (I am not a programmer, so this may be a separate related pattern.) To make it a little concrete and relate it to the discussion at URL:http://www.dofactory.com/Patterns/PatternObserver.aspx#_self1, suppose there are stocks, mutual funds, and investors. Let us say that funds are observers for stocks, and investors are observers for funds. Once a month I want all stocks to notify their observing funds of their end-of-month price, and *then* all fund to notify their observing investors of their end-of-month investment value. I see a couple differences from the standard pattern referenced above, and one problem. Differences: - observer/subject linked hierarchy (funds are both observers and subjects) - many-many relation (a fund is an observer of many stocks) I think (?) these differences are inessential, but the second does create the following problem: if I do not want a fund to notify an its investors until all stocks have reported, what is the best way to determine the last report in event? Here is one way: create a ``reportreceived`` dict that maps stocks to True or False, and after each stock notification change False to True and check ``all(reportreceived.values())`` to determine whether it is ok to notify investors. When it is ok, then notify investors and reset all the ``reportreceived`` values. This is meant to be a general description so please do not focus on the real world aspects, which are only for illustration. Thank you, Alan Isaac -- http://mail.python.org/mailman/listinfo/python-list
Re: observer pattern question #1 (reference to subject)
Alan Isaac [EMAIL PROTECTED] writes: Is anything lost by not maintaining this reference (other than error checking ...)? If I feel the observer needs access to the subject, what is wrong with just having the subject pass itself as part of the notification? It reduces the number of places the observer can be called from, because now the event source is part of the function signature. If you omit the event source in the signature, you gain looser coupling - it's the observer business to create the dependency. Also, consider the situation where you want all investors to refresh their idea about stock prices (because of, short network failure). It's easy to run through a list of them and call update() for everybody, while it's not so easy to find out what stock the investor is observing (that's the investors business!) and pass that object to the investor in the call. Are these school questions btw? ;-) -- http://mail.python.org/mailman/listinfo/python-list
Re: observer pattern question #1 (reference to subject)
Alan Isaac [EMAIL PROTECTED] writes: Is anything lost by not maintaining this reference (other than error checking ...)? If I feel the observer needs access to the subject, what is wrong with just having the subject pass itself as part of the notification? Ville M. Vainio wrote: It reduces the number of places the observer can be called from, because now the event source is part of the function signature. If you omit the event source in the signature, you gain looser coupling - it's the observer business to create the dependency. As I said, I'm not a programmer, and perhaps as a result, I have questions about both of your points. I'll stick with the stock example, since it is concrete. Note that the observor/listener in the example at URL:http://en.wikipedia.org/wiki/Observer_pattern does not create a reference to the subject. So in this context I take you to be saying something like the following: OK, here's the pattern, now your listener wants to know the event source, do not ask something new the subject to respond to that need. That is unnecessary coupling. Instead, just rewrite your listener to maintain a reference to the subject. Do I have that right? It seems to me that this response begs the question. That is, an appropriate reply seems to be: here is a related pattern, call it observer2. In the observer2 pattern, the subject has a getState method and always passes itself when it notifies the observer. Now: in what sense does this require closer coupling? Also, consider the situation where you want all investors to refresh their idea about stock prices (because of, short network failure). It's easy to run through a list of them and call update() for everybody, while it's not so easy to find out what stock the investor is observing (that's the investors business!) and pass that object to the investor in the call. I seem to be missing your point here. Let's keep using the stock/investor example. When the network comes up, each stock should notifies everyone in its list of listeners. It either passes itself or does not. In either case, the investor took care of hir side of the business by registering as a listener. If the stock does not notify all its registered investors, it is breaking its contract. So, what is the problem? Or to put it a different way, your suggestion that the investors should have to *pull* this information from the stocks seems out of step with the observer pattern, where the stocks should be pushing this information to the investor. Again, talk of stocks and investors is just a convenient short hand for discussing the observer pattern. I do not care about stocks/investors more than other applications. Are these school questions btw? No, sorry. But I still appreciate the feedback. Cheers, Alan Isaac -- http://mail.python.org/mailman/listinfo/python-list
Re: observer pattern question #1 (reference to subject)
Alan Isaac [EMAIL PROTECTED] writes: the following: OK, here's the pattern, now your listener wants to know the event source, do not ask something new the subject to respond to that need. That is unnecessary coupling. Instead, just rewrite your listener to maintain a reference to the subject. Do I have that right? Not really. It has to be determined case-by-case. Note that I'm not arguing *for* not passing subject on notification, just trying to elaborate on situations that might want to choose that route. It seems to me that this response begs the question. That is, an appropriate reply seems to be: here is a related pattern, call it observer2. In the observer2 pattern, the subject has a getState method and always passes itself when it notifies the observer. Now: in what sense does this require closer coupling? It creates stronger connection between the subject and observer, thereby reducing the amount different of places that can call the observer (I don't mean different stock, but altogether different places - say, a central stock controller that can broadcast the change in several stocks at the time by stock id, once per second). This is not really a feature of the observer pattern, both approaches are somewhat valid observer patterns, depending on problem domain. If you think it makes sense in the first place to have ONE reference to the subject in observer, it's probably a workable approach - but in case of stocks, you are probably monitoring several stock objects, so the stock should probably pass itself to the observer (so that you don't need to check all stocks every time something changes!). Of course this stock thing is a bad example for this case, because you have several stocks per investor. It's analogous to a typical UI scenario where you have several widgets forwarding events to one big observer - and they *do* provide the event source and event type. Or to put it a different way, your suggestion that the investors should have to *pull* this information from the stocks seems out of step with the observer pattern, where the stocks should be pushing this information to the investor. It's not necessarily the observer that has the interesting information. It's quite typical to have general catch-all notifications than report observers that something has chanced somewhere, so you should refresh your data. All in all, though, the right solution should be obvious from the problem at hand. -- http://mail.python.org/mailman/listinfo/python-list
Re: observer pattern question #1 (reference to subject)
Ville M. Vainio wrote: in case of stocks, you are probably monitoring several stock objects, so the stock should probably pass itself to the observer OK. This is related to my question #2 (in a separate thread), where I'd also appreciate your comments. analogous to a typical UI scenario where you have several widgets forwarding events to one big observer - and they *do* provide the event source and event type. That is a helpful comparison. All in all, though, the right solution should be obvious from the problem at hand. For CS types, maybe. The rest of us are just trying to get things done without as much background and context. Thanks, Alan -- http://mail.python.org/mailman/listinfo/python-list
Re: observer pattern question #1 (reference to subject)
On May 8, 4:57 pm, Alan Isaac [EMAIL PROTECTED] wrote: Ville M. Vainio wrote: in case of stocks, you are probably monitoring several stock objects, so the stock should probably pass itself to the observer OK. This is related to my question #2 (in a separate thread), where I'd also appreciate your comments. analogous to a typical UI scenario where you have several widgets forwarding events to one big observer - and they *do* provide the event source and event type. That is a helpful comparison. All in all, though, the right solution should be obvious from the problem at hand. For CS types, maybe. The rest of us are just trying to get things done without as much background and context. Thanks, Alan My local vernacular calls them carfulls of people, which analogy to the body of collective man, extends pretty far. It's not the gas pedal we hate! I'm schedule more coasting on shore. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pattern question
Scott David Daniels a écrit : cantabile wrote: bruno modulix a écrit : You may want to have a look at the Factory pattern... ... demo of class Factory ... Taking advantage of Python's dynamic nature, you could simply: # similarly outrageously oversimplified dummy example class Gui(object): def __init__(self, installer): self.installer = installer class PosixGui(Gui): pass class Win32Gui(Gui): pass if os.name == 'posix': makeGui = PosixGui elif os.name == 'win32': makeGui = Win32Gui else: raise os %s not supported % os.name class Installer(object): def __init__(self, guiFactory): self.gui = guiFactory(self) def main(): inst = Installer(makeGui) return inst.gui.main() --Scott David Daniels [EMAIL PROTECTED] Thank you too for this tip. :) Coming from C++ (mainly), I'm not used to this dynamic way of doing things. That's usefull. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pattern question
cantabile wrote: Hi, I'm trying to write a small installer for a server. But this program should be able to run in the future under heterogenous environments and os (at least linux/windows). I mean, the install will be done either in text mode or curses or gtk or tk, either in debian or windows 2000 and so on... The idea, at the moment, is as follows : class Server: def __init__(self, params = None): self.params = params def __getattr__(self, attr): return self.params.get(attr, None) class Installer: def __init__(self, gui = None): self.gui = gui self.srv = None def update(self, dict): self.srv = Server(dict) class Gui: def __init__(self, installer = None): self.installer = installer def main(): ## Some stuff here calling doIt() when the ## user is done with filling various fields def doIt(self): dict = {param1:qwerty, param2:uiop} self.installer.update(dict) def main(): inst = Installer() gui = Gui(inst) inst.gui = gui inst.gui.main() ## Here will be the actual install method ## ... ## An example of accessing srv values: print inst.srv.param1, inst.srv.param2 But, considering this code, I find the 3 first lines of my main() a bit heavy. I have to inform inst that it has a 'gui', and Gui that it has an 'installer'. I was trying to implement something looking like (very roughly) to the Observer pattern (so that the Gui would be totally independant from the actual install process). I guess there is something wrong in my approach. Is there a better pattern than this one for that kind of stuff ? Tanks for your help. You may want to have a look at the Factory pattern... # outrageously oversimplified dummy exemple class Gui(object): def __init__(self, installer): self.installer = installer class PosixGui(Gui): pass class Win32Gui(Gui): pass class GuiFactory(object): def getGui(self, installer): if os.name == 'posix': return PosixGui(installer) elif os.name == 'win32': return Win32Gui(installer) else: raise os %s not supported % os.name class Installer(object): def __init__(self, guiFactory): self.gui = guiFactory.getGui(self) def main(): inst = Installer(GuiFactory()) return inst.gui.main() NB 1: You may want to hide away the gui stuff: class Installer(object): def __init__(self): self.gui = GuiFactory().getGui(self) def main(self): return self.gui.main() def main(): return Installer().main() NB 2 : if it has to run in text mode, you should consider renaming gui to ui, since a CLI is not really a 'graphical' ui !-) NB 3 : I made the GuiFactory a class, but it could also be a simple function. NB 4 : there are of course other solutions to the problem, which may or not be more appropriate... HTH -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: Pattern question
bruno modulix a écrit : You may want to have a look at the Factory pattern... # outrageously oversimplified dummy exemple class Gui(object): def __init__(self, installer): self.installer = installer class PosixGui(Gui): pass class Win32Gui(Gui): pass class GuiFactory(object): def getGui(self, installer): if os.name == 'posix': return PosixGui(installer) elif os.name == 'win32': return Win32Gui(installer) else: raise os %s not supported % os.name class Installer(object): def __init__(self, guiFactory): self.gui = guiFactory.getGui(self) def main(): inst = Installer(GuiFactory()) return inst.gui.main() NB 1: You may want to hide away the gui stuff: class Installer(object): def __init__(self): self.gui = GuiFactory().getGui(self) def main(self): return self.gui.main() def main(): return Installer().main() Thanks for this, Bruno. It is much more elegant and adaptable than my first attempt. NB 2 : if it has to run in text mode, you should consider renaming gui to ui, since a CLI is not really a 'graphical' ui !-) You're right :)) NB 3 : I made the GuiFactory a class, but it could also be a simple function. NB 4 : there are of course other solutions to the problem, which may or not be more appropriate... Thanks a lot for these detailed explanations. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pattern question
cantabile wrote: bruno modulix a écrit : You may want to have a look at the Factory pattern... ... demo of class Factory ... Taking advantage of Python's dynamic nature, you could simply: # similarly outrageously oversimplified dummy example class Gui(object): def __init__(self, installer): self.installer = installer class PosixGui(Gui): pass class Win32Gui(Gui): pass if os.name == 'posix': makeGui = PosixGui elif os.name == 'win32': makeGui = Win32Gui else: raise os %s not supported % os.name class Installer(object): def __init__(self, guiFactory): self.gui = guiFactory(self) def main(): inst = Installer(makeGui) return inst.gui.main() --Scott David Daniels [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Pattern question
Hi, I'm trying to write a small installer for a server. But this program should be able to run in the future under heterogenous environments and os (at least linux/windows). I mean, the install will be done either in text mode or curses or gtk or tk, either in debian or windows 2000 and so on... The idea, at the moment, is as follows : class Server: def __init__(self, params = None): self.params = params def __getattr__(self, attr): return self.params.get(attr, None) class Installer: def __init__(self, gui = None): self.gui = gui self.srv = None def update(self, dict): self.srv = Server(dict) class Gui: def __init__(self, installer = None): self.installer = installer def main(): ## Some stuff here calling doIt() when the ## user is done with filling various fields def doIt(self): dict = {param1:qwerty, param2:uiop} self.installer.update(dict) def main(): inst = Installer() gui = Gui(inst) inst.gui = gui inst.gui.main() ## Here will be the actual install method ## ... ## An example of accessing srv values: print inst.srv.param1, inst.srv.param2 But, considering this code, I find the 3 first lines of my main() a bit heavy. I have to inform inst that it has a 'gui', and Gui that it has an 'installer'. I was trying to implement something looking like (very roughly) to the Observer pattern (so that the Gui would be totally independant from the actual install process). I guess there is something wrong in my approach. Is there a better pattern than this one for that kind of stuff ? Tanks for your help. -- http://mail.python.org/mailman/listinfo/python-list