"Laura Creighton" <lac at cd.chalmers.se> wrote in message news:mailman.987763024.10421.python-list at python.org... > Why? > > I thought the only reason to get out flyweight was because your program > was a turtle "Turtle"? You mean as in "sea turtle" or as in "turtle dove"? In either case, I must be missing some idiom here, I guess. > and you have too many objects, callbacks, or both. Those > objects are likely to be singletons. Getting out Flyweight is an > indication that the real world has stomped on your clean, elegant, but > woefully inefficient design -- a hack we wouldn't need if we had infinite > memory, cpu speed, or some other resource. > > What am I misunderstanding? I don't know, because I can barely make out what you're saying. Anyway, there are several general cases where I like "flyweight proxies" as opposed to using the singleton design pattern, and not one of them seems best framed to me as "a hack I wouldn't need" except for performance. Say I have a class that models some thing of which, at this stage of my design, I'm considering there can be only one "live instance" -- maybe "the display screen", maybe "the database I'm connected to", or "the printer". Call it "the application-level class". (In each of these cases, it's quite possible that the program will need to evolve to have several screens, several databases, etc -- the evolutionary push towards once-singleton items to become non-singletons need not distort my design _today_, but it's better to keep it at the back of one's mind because it keeps coming up). Some part of my system is already up and "the singleton" (if it were one) is already instantiated. Now, another part comes up, say a GUI, or a web-interface that does administrative things. I'm likely to have a nice mixin class which makes my life easy for GUI/web/whatever purposes if I inherit from it, so I want to dress up the application-level class, for purposes of this one subsystem, and the easiest approach is to inherit from it an from my mixin: class SpiffyObject(AppLevelObject,SpiffyMixin): def __init__(self, whatever): # blah, blah, and so on There's only one problem with that -- it doesn't work if AppLevelObject implements the Singleton Pattern! As "the one and only object that can possibly exist in that class" has already been instantiated by the other subsystem, it can't be instantiated again. So rather than using handy inheritance for code sharing I have to explicitly hold that darned One&OnlyObject and delegate to it appropriately. Not as much of a chore in Python as it would be in other languages, sure, but still some deadweight boilerplate -- and what is the advantage I'm buying with this cost? None that I can see (I _do_ keep looking -- it's been years, and I still haven't found anything). Not being able to inherit also puts me in trouble if any other code tests with isinstance, etc, of course. So I just have AppLevelObject be freely, innocuously instantiable as many times as it needs to be (all instances sharing state with each other), and live happily ever after. I.e., "flyweight proxy". Similarly: I have an object which holds a (oops, THE) "one&only" -- can I persist it or otherwise stream it freely and depersist/unstream it again? Not with the Singleton DP I can't, without (once again) going to the trouble to implement special code for saving and restoring, just because one of my attributes is the cranky one&only. Again, boilerplate in each subsystem that needs to access the one&only as its client. A flyweight proxy can handle its own save and restore needs (incredibly modest ones, to be sure, as it gets its state from elsewhere:-) and make life simpler for all the rest of the code, that uses it. The exact problems change in each language and object system, of course -- the loss of handiness in losing multiple inheritance and thus mixins applies to C++ or Python, which DO have MI in the first place, but not to languages that lack them; on the other hand, C++ has its share of problems whenever one tries to use smart-pointers & similar constructs around an object that's not canonical (i.e. has a default ctor, copy ctor, copy assignment, accessible dtor) -- COM has _its own_ problems with Singletons, which are well known -- and so on. In general, an OO language's or object-system's ordinary machinery seems to be rather geared to ordinary objects -- ones that (depending on language's/system's viewpoints) CAN be ordinarily inherited/aggregated/extended/instantiated/persisted/ depersisted/copied/assigned/whatever. Singleton DP generally finds some way or other to trip you up with some of these mechanisms in each language or system. And when and if the time comes to migrate to "oops, it's not just ONE printer any more, could be two or three", again Singleton trips you up as its key design assumption breaks down ruinously; flyweights are more resilient -- they start sharing state in groups or clusters, rather than all of them having the _same_ state, but client code is remarkably unaffected besides passing the appropriate arguments to the relevant factory functions or __init__ calls. Not sure what this has to do with "hacks for speed" or resource limitations... Alex
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4