Poor programming practice?
I have been trying to make use of the builtin medusa ftp_server classes and after struggling a while came across the strange practice some internal zope developer has of dynamically changing classes at runtime. ie in ZServer.FTPServer I came across from medusa.ftp_server import ftp_channel, ftp_server, recv_channel ....... ....... # Override ftp server receive channel reponse mechanism # XXX hack alert, this should probably be redone in a more OO way. def handle_close (self): .......... self.readable=lambda :0 # don't call close again recv_channel.handle_close=handle_close which makes it virtually impossible to re-use medusa's ftp_server in a reasonable way. The comment says it all. The real problem is that ftp_channel uses a method make_recv_channel which uses a global class recv_channel and the recv_channel class has a particular method which zope wants to override. How ought this kind of situation to be handled more cleanly? -- Robin Becker
Robin Becker wrote:
The real problem is that ftp_channel uses a method make_recv_channel which uses a global class recv_channel and the recv_channel class has a particular method which zope wants to override. How ought this kind of situation to be handled more cleanly?
I haven't looked at the code, so the following is based only on your paragraph above, and probably doesn't apply to the real classes we're talking about :-) This sounds like a classic application of the Factory Method pattern. In brief, you have the ftp_channel class. Its instances have a make_recv_channel method. This is the Factory Method. It returns whatever is appropriate for a recv_channel. You create a subclass derived fom ftp_channel called perhaps zope_ftp_channel, which defines a new make_recv_channel method. This new method does whatever Zope needs for making the recv_channel. The other option is to use the Abstract Factory pattern. In this case, you'd pass the constructor of the ftp_channel class a bound method (or a function) that returns the appropriate kind of recv_channel. You could let an ftp_channel instance know about this bound method (or function) by other means instead, rather than passing it in the constructor. Both patterns are discussed in the infamous "Gang Of Four book" Design Patterns: Elements of reusable object-oriented software, Gamma, Helm, Johnson and Vlissides. There will be explanations on the web somewhere too, no doubt. -- Steve Alexander Software Engineer Cat-Box limited http://www.cat-box.net
In article <3A77D3A9.6070603@cat-box.net>, Steve Alexander <steve@cat- box.net> writes
Robin Becker wrote:
The real problem is that ftp_channel uses a method make_recv_channel which uses a global class recv_channel and the recv_channel class has a particular method which zope wants to override. How ought this kind of situation to be handled more cleanly?
.....
This sounds like a classic application of the Factory Method pattern.
....
The other option is to use the Abstract Factory pattern. In this case, you'd pass the constructor of the ftp_channel class a bound method (or a function) that returns the appropriate kind of recv_channel.
yes I have the go4 book and I fully agree that one or other of the above patterns would be feasible. The problem is that the base medusa comes from Sam Rushing and Zope makes use of it. I guess since I already patch the Zope code I could just extend the patch, but the best solution would come from having two main players agree on such stuff. -- Robin Becker
In article <W6YEZWAjD+d6Ew59@jessikat.demon.co.uk>, Robin Becker <robin@jessikat.fsnet.co.uk> writes ...
yes I have the go4 book and I fully agree that one or other of the above patterns would be feasible. The problem is that the base medusa comes from Sam Rushing and Zope makes use of it. I guess since I already patch the Zope code I could just extend the patch, but the best solution would come from having two main players agree on such stuff. well I implemented Steve's first method by giving ftp_channel an attribute called recv_channel_class (defaulted to recv_channel from ftp_server). Then in FTPServer I modified zope_ftp_channel so that recv_channel_class was set to an appropriate class Zrecv_channel derived from recv_channel. Zrecv_channel only needed to override the handle_close method. Now I can have a proper file_sys ftp as well as the Zope one. -- Robin Becker
participants (2)
-
Robin Becker -
Steve Alexander