Gabriel Genellina wrote: > En Wed, 29 Aug 2007 07:32:21 -0300, BJörn Lindqvist <[EMAIL PROTECTED]> > escribi�: > >> On 8/24/07, Gabriel Genellina <[EMAIL PROTECTED]> wrote: >>> En Thu, 23 Aug 2007 09:20:21 -0300, BJörn Lindqvist <[EMAIL PROTECTED]> >>> escribi�: >>> >>>> def check_user_logged_in(func): >>>> def f(*args, **kwargs): >>>> if global_state.the_user.is_logged_in: >>>> return func(*args, **kwargs) >>>> return show_login_page() >>>> return f >>> I think there is a semantic problem, perhaps we are not talking >>> about the same thing. I'm considering the software complexity AS >>> PERCEIVED BY THE PROGRAMMER, looking at the interactions between a >>> program and a programmer who is working on some task; some people >>> would say "cognitive complexity" to make it clear. >> There is no semantic problem. You are just mistaken in your belief >> that the complexity that the user of the decorator has to deal with is >> different from the complexity in implementing the decorator. > > But they ARE different. That's the whole point of abstractions, code > reuse, layered design... Designing a simple interfase on top of a complex > system is very common. Nobody writes X-Window code, as nobody writes a raw > event loop for Windows anymore: there are very good GUI toolkits, even > portable frameworks, that put an abstract layer on top of that so the > programmer has a much simple and coherent view. The complexity is behind > the scenes. > >>> Which API is more complex: one in which you can play a movie with >>> just a single call like PlayMovie(Title), or one on which you must >>> call a zillion functions to firtly initialize the stream format, >>> configure the display, disable undesired user interfase elements, >>> locate the movie file, load it in chunks, etc.? The first one is >>> certainly much simpler to use (simpler = less complex), and maybe >>> internally it calls the same functions as the second one, but nobody >>> cares. >> "nobody cares" is your guess. I'd bet that the caller of the PlayMovie >> function cares a lot: Is the movie played full screened? Which >> encodings are supported? Can you set the title of the movie window? Is >> streaming supported? Does it even work on windows? Which URI schemes >> does it support? And so on and so on. >> >> That is why no video decoding API:s have a PlayMovie(Title) function >> and why I haven't seen a single 3d engine with a >> MakeReallyCoolDoomCloneFPSGame() function. > > (yet!). What about urlopen? Using a single call one can be authenticated > and retrieve any file in the other side of the planet. I consider it a > simple interfase, altough it does complex things. Would you say it is > better to use plain sockets everywhere? Or, since sockets are abstractions > themselves, would you say it is better to use lower level primitives > instead? Each time you descend a level, you have to use many simpler > functions - but their combination is more complex. > >> "hiding details" only works if the client programmer really doesn't >> care about the details. > > Why should he care? Isn't "hiding implementation details" a good design > principle? > When I use urlopen, I don't even care of the underlying socket > implementation. I don't care which interfase the request is sent thru. I > don't care if the answer got fragmented and some packets had to be > reassembled. urlopen gives me something that looks like a file, and I just > read() from it. > >>> Back to your example, the fact that a decorator builds a higher order >>> function, does NOT make it more complex - because the programmer does >>> not >>> see that. In fact, hiding the details makes it simpler. >> Yes, the programmer does see that. The example decorator I posted >> requires about a zillion preconditions to work correctly and will fail >> in weird ways when those preconditions are not satisfied. The >> programmer is interested in the crazy failures he or she will >> experience. I dare you to try and implementing the code both as a >> decorator and as a function, then write the unit tests and >> documentation. The complexity of those three items together >> (implementation + tests + documentation) will be much higher for the >> decorator choice because the complexity of the decorator >> implementation is a bit higher than using a plain old function. > > Testing the decorator is as hard as testing any other function. Testing > the decorated functions might involve *only* checking if the decorator is > actually used for those functions. > Going to your posted example, I don't see the difference - I should say, I > don't see the advantage. Using a decorator hides some implementation > details and reduces coupling between modules, both good things on "my" > book; your function with no decorator does quite the opposite, and doesn't > look like good coding style (on "my" book, of course). > >> Note also that it is extremely rare to see well-documented or >> well-tested code, which means that the programmer WILL have to analyze >> the implementation which means that implementation complexity matters >> a lot. > > In any case, that would require testing and analyzing ONE function (the > decorator) instead of inspecting a zillion repetitions of the same code > that, when being wrong, have to be located and fixed on all those places. > > Really, I still can't understand how you can defend such silly things - > unless we are talking about different things. >
FACADE Intent : Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. GoF Design Patterns. pp.185 -- http://mail.python.org/mailman/listinfo/python-list