On Wed, 29 Jun 2005 00:18:24 -0400, Paul McGuire wrote (in article <[EMAIL PROTECTED]>):
> Lee - > > Bruce Eckel's observation: > > "the above scaffolding of Obstacle, Player and GameElementFactory > (which was translated from the Java version of this example) is > unnecessary - it's only required for languages that have static > type checking. As long as the concrete Python classes follow the form > of the required classes, we don't need any base classes..." > > is consistent with my "duck-typing" comment that all that is needed of > A,B,etc. is that they provide the necessary testit and doit methods in > the proper form. He also goes on to say that, even if the base classes > were empty, they still provide a useful handle for all of the derived > classes, to indicate they are all common subtypes of "Shape" or > whatever. > > I think you were referring to the "Poking Python with a Stick" entry in > the second link. The inheritance of all taunts from Taunt allowed the > author to put some overriding common-to-all-taunts behavior into the > superclass, even if it was just a "sorry, not implemented" exception > into the base Taunt class's tauntTheKnights() method. The idea was to > provide a runtime exception if the needed method had not been > overridden in the subclass. But it also provides a place to put any > other common-to-all-taunts behavior, perhaps a common constructor, or > other common helper methods. I think this is a good use of > inheritance, when the base class actually adds some value to the > architecture, even if it is just Bruce Eckel's empty placeholder base > class. Note also that this author was doing patterns experimentation > in both Python and Java. I envision him writing the factory's > getInstance() method in Java, and having to declare its return value > type. In this case Java really drives you to having all possible > return values derive from a common base class, so that you can define > the method as: > > Taunt getInstance(string tauntTypeTag) { ... > > which is a bit easier to deal with than just declaring that getInstance > returns an object, and then having to cast it - in fact, if there were > no common base type, it would be problematic to know just what to cast > it to. > > But Python does not require this sort of type rigidity. In your code, > the only requirement is that each class A,B,etc. have testit and doit > methods - they have to walk and talk like ducks, they don't need to > *be* ducks. My point in an earlier post was, I think many current > design patterns were born out of the C++ and Java worlds, and may be > overly restrictive for a comparable implementation in Python. > > One step you might take in the MultiEvaluator constructor is to > validate the provided classes on input, so that you don't have to > exhaustively test all A thru Z classes before finding out that you > misspelled Z's doit method as "dooit". This goes one better than the > abstract subclass's "you forgot to override me" method implementation. > > In sum, both of the links you sent used examples that had inheritance > hierarchies where the base class provided some contribution and > commonality among the derived classes. TauntArthur "is-a" Taunt, > TauntGalahad "is-a" Taunt. It really does look like the Factory > pattern should return objects that share a common base class. But in > Python, that common base class can also be just "something that walks > like a duck." > > -- Paul > > Thank you for the clarification Paul. I missed the influence of C++ and Java origins because my past experience was more in the assembler realm with a little C and Pascal, and now I'm trying to get up to speed with Python, ObjC and the OO world. You've helped me look at what I'm reading in a better light. Thanks again, Lee C -- http://mail.python.org/mailman/listinfo/python-list