

Design Patterns in Python (Free Book) - okal
http://dpip.testingperspective.com/

======
anthonyb
Gotta love the MVC pattern ... with an SQL injection vulnerability -
<http://dpip.testingperspective.com/?p=18> (What happens when you search for a
component ID of "'; drop table defects")

Also, what is the controller _doing_? Why is there even a DefectModel with
database code in it? Why is it not using an ORM style like every other
database-fetching thing written this century?

I've looked at a couple of "chapters" of their "book" now, and it's all
hideous train wreck code like this, with stuff that reads like it's been
cut+pasted out of a wiki somewhere, and no sample output/data. I'm not sure
what you're supposed to learn from these examples, other than "Design Patterns
are hard".

------
beza1e1
These are Java design patterns. Python has different patterns. That's why
people say that Factory is natural in Python.

Two examples, what i consider (very simple) Python patterns (without fancy
names though):

    
    
        if __name__ == "__main__":
          ...
    
    
        def MyDecorator(func):
          def wrapper(...):
            def my_func(*args, **vargs):
               ...
            return my_func
          return wrapper

------
irahul
I looked at couple of them. Some of the patterns has a note mentioning it is a
port of C#/Java/C++ implementation in the Wikipedia article.

Python is drastically different from C#/Java/C++, and a direct port of
classical patterns won't make much sense. It will work, but it will the
equivalent of Fortran programmers writing Frotran in Python.

If anyone is interested, this talk by Alex Martelli is a good starting point:

    
    
        http://www.youtube.com/watch?v=0vJJlVBVTFg
    

I think Bruce Eckel was writing a book on "Design Patterns" in Python, but
that's not completed. However, there is a book using Ruby, which shows the
classical approach for implementing design patters, then shows how it is done
in Ruby:

<http://designpatternsinruby.com/>

------
est
Do we really need factory pattern in Python? I mean with all those dynamic
calling methods?

I'd like to see more patterns with decorators, list comprehension, map/filter
chain and yield.

~~~
irahul
> Do we really need factory pattern in Python?

Yes.

    
    
        from PIL import Image
        im = Image.open("bride.jpg")
    

Image.open here is a factory, and im will be an object of a different class,
depending on the filename you pass to it(jpeg, gif, png).

That is just one example, but you get the idea.

~~~
anthonyb
Well really, what's the point in calling it a factory? In Ruby or Python
everything is an object, every method or function call returns an object,
hence _everything_ is a factory, and the term loses its meaning.

In this particularly case Image isn't a class, and Image.open isn't a method:
[https://bitbucket.org/effbot/pil-117/src/162542cc8aca/PIL/Im...](https://bitbucket.org/effbot/pil-117/src/162542cc8aca/PIL/Image.py#cl-1943)

I don't know that there's any equivalent for this in Java, so I think the
grandparent's question still stands.

~~~
irahul
> In Ruby or Python everything is an object, every method or function call
> returns an object, hence everything is a factory, and the term loses its
> meaning.

I don't think _factory_ is defined as _anything that returns an object._

I am not a design pattern buff, but here is what the wiki entry says:

* it deals with the problem of creating objects (products) without specifying the exact class of object that will be created. *

I don't see why it has anything to do with everything being an object.

The Image.open example is _factory pattern_. It isn't implemented the same way
it's implemented for Java/C++, and I wasn't commenting on the implementation;
but that doesn't make it _not factory_.

Similarly, the command pattern, in a language with first-class functions and
closures, will be implicit and look nothing like the one implemented in GoF
book.

If you are taking the implementation in GoF as the definition, callbacks as we
do in Ruby, JS, Python et al. look nothing like _command pattern_. But the
implementation isn't definition, and GoF explicitly mentions it that these
patterns aren't the same in all languages.

~~~
anthonyb
> I don't see why it has anything to do with everything being an object.

Well it certainly blurs the lines, doesn't it? If you're returning an object
anyway, it's not that much of a stretch to return a slightly different object
depending on circumstances. Why does it warrant a pattern all to itself and an
entire chapter of a book? And more to the point, why should I care about it,
other than to try and decipher legacy ex-Java code like this?

To return slightly to the original point - where are the patterns for list
comprehensions, decorators or generators? There aren't any, because in the
Java/C++ world it's so hard to throw functions around like this. You need to
look to fields like FP and Haskell to find good uses for list comprehensions
beyond the very basic stuff.

~~~
irahul
> Why does it warrant a pattern all to itself and an entire chapter of a book?
> And more to the point, why should I care about it, other than to try and
> decipher legacy ex-Java code like this?

I think we started discussing different things. I wasn't saying the way GoF
implements factory for C++, or the article in question does that, is useful; I
mentioned elsewhere that copying patterns literally from Java/C++ isn't really
fruitful when programming in Python
<http://news.ycombinator.com/item?id=3399581>

Many of the classical design patterns will either be invisible or simpler in
dynamic languages. In Peter Norwig's presentation, he claims 17 of the 23 are
either invisible or much simpler for Dylan - we can make the same claim for
Python, Perl, Ruby et al.

But even in Python, some patterns are non-obvious, and it's better that the
developer knows them beforehand, rather than re-inventing them. Apart from the
non-obvious ones, you sometimes need the others as they condense a paragraph
of explanation to single term.

Factory isn't one of those non-obvious patterns - a competent developer, given
the problem for the factory pattern(the above Image.open) will invent factory
in under 5 minutes.

~~~
anthonyb
So, I'm curious - which patterns do you consider non-obvious in Python?

------
buster
Somehow, i'm not sure if i like the word "pattern". Patterns are something
which can be used generally and repeatedly. I think that's sort of scary. For
example: I've learned factory usage while doing twisted and it came naturally
how and why this was used. But somehow i feel that with all those books and
courses about "design patterns" new programers are missing out how to find a
solution. It's like "here are your tools, MVC, factories and observers, try to
solve your problems with those". This can be dangerous when a programer first
looks how he can mold his problem to be solved with some pattern, whereas he
should first analyse the problem and use patterns carefully where they fit
naturally. I'm scared of a programming world where every bit is solved by
factories of factories of metafactories ;)

~~~
SammyRulez
Design patterns are useful because they improve.. design. I mean application
and code design. They model a recognizable structure. You are right: they have
been sold as the ace of all trades in CS books and courses and they are not.
That lead to the ' factories of factories of metafactories ' situation.
Experience and intelligence are the real 'ace of all trades'. On the other
side chaos is not good for anyone. Instead having a common lingo to identify
code structure and common solutions to local architectural challenges is a
good thing.

~~~
buster
So, wouldn't it be better to write books on how someone got from a problem to
a solution and why the outcome was something that can be described as a
factory pattern, rather then the other way around?

I didn't read books on design patterns, but the book from the link structures
around what design patterns there are and how they got applied to a problem.
It'd be nicer to first have a problem and show why and how a particular
pattern is better than, say, a bunch of monolithic lines of code.. So that you
can say "oh and by the way, the way we solved that problem falls into the
category of factory patterns".

------
krosaen
related: Norvig's presentation design patterns in dynamic languages (and how
many of the GOF patterns are built in idioms, e.g 'strategy' is just passing
in a function as a parameter).

<http://norvig.com/design-patterns>

------
shabda
For everyone saying if you really need these patterns. From the site header

> This book is about learning design patterns through the medium of Python
> language.

Its a book about learning the patterns, not idiomatic (or even good) Python.
As a example of idiomatic and good python, this book is useless, but if you
just want to understand how patterns are used in other languages, this book is
not bad.

~~~
anthonyb
Except that a lot of patterns tend to be language specific. So while it does
teach you patterns, sort of - the patterns here are unlikely to be of any use,
since they won't be usable if you're writing Python, and if you're writing
Java or C++ you'll need to translate them anyway.

For instance, go and have a look at the example code for his command pattern:
<http://dpip.testingperspective.com/?p=22> That's not idiomatic _anything_ \-
in normal Python you'd probably expose a couple of methods on the Light
(on/off) and construct a switch to call those. Two classes, duck typed and no
need for Command abstract classes and all the extra boilerplate.

