星期日, 7月 25, 2010

[Python] Patterns in Python


Design Pattern那本四人幫的經典是1995年出版的 居然已經歷經15年了 實在是太可怕了..... 雖然Design Pattern並非銀彈 也極容易被濫用 但是還是一個很重要的思維的參考與轉變.....

在不同的語言下 會有不同的Pattern的實作 甚至根本不需要 因為語言本身就直接解決..... 像是Observer Pattern....在C#直接可以用delegate/event解決....

雖然都了解Pattern大概的concept 但是每當換一個語言 要implement的時候還是傻眼...... 不知從何開始... 最近在寫Python.. 在網路上找到這一篇倒是挺有趣的...... Patterns in Python

大概讀完了文章 就來作個紀錄 還有英翻中 + 複習Patterns吧...

# Factory Pattern
主要的精神 把Create objects獨立出來單一窗口 回傳一個符合基本interface的object.... 單一窗口內要怎麼create不同的objects 可以一直改變....

這在任何語言實作都很簡單... 但是在Python中 文章提及很有趣的觀點是 「Python」可以把Factory Pattern的精神 做在Module level.... 以下面為example

import random  def listOfRandom(n):         return [random.random() for i in range(n)]
random這個module可以隨時被抽換....
呵~ 我倒還沒真的想過這樣使用


# Singleton
這是最易懂卻難實作的Pattern了
在Python的話 直接貼上文上的範例 就不多作解釋了

class Singleton(object):         _instance = None         def __new__(cls, *args, **kwargs):             if not cls._instance:                 cls._instance = super(Singleton, cls).__new__(                                    cls, *args, **kwargs)             return cls._instance

# Flyweight
Flyweight主要的精神在於reused很多數量 或是 heavy的物件 所以用一個很多小的proxy 指向共用的物件,而這些物件存在pool裡......

實作如下 值得一提的是它用的是Weak Reference....
其實不用也沒關係 就是always Pool那份不會被清掉 用Weak Reference的用意我想在於long term來說 比較節省記憶體 因為Pool Dictionary那份 如果沒有被用到 可以確保long term應該會被garbage collection掉..... 因為是用weak reference的關係

class Instrument(object):     _InstrumentPool = weakref.
WeakValueDictionary() def __new__(cls, name): '''Instrument(name) Create a new instrument object, or return an existing one''' obj = Instrument._InstrumentPool.get(name, None) if not obj: print "new",name obj = object.__new__(cls) Instrument._InstrumentPool[name] = obj return obj def __init__(self, name): '''Complete object construction''' self.name = name print "New instrument @%04x, %s" % (id(self), name) # ... connect instrument to datasource ...

# Observer

這個實作有點長 我就不貼了 直接refer 文章
主要是實作Delegate跟Event....
我之前也有找了很多Delegate/Event的實作體
剛剛稍稍研究了一下 好像這篇考慮的比較全面一點....


# Iterator & Generators

Iterator的概念很好懂..... 實作也很單純 因為Python已經有內建這個概念 直接實作就好了.....

Generator其實我是第一次看到 也沒有特別看的太懂....不過可以refer另一篇文章(中文)..... 看完就看似比較懂一點....

英文文章是說....如果使用iterator 實作上被迫得放棄recursive way的直覺方法..... 像example他就是用stack/pop/push的方法實作 但是用generators 有一個"yield"的特別方法 可以在實作上變的直覺又容易....


# Command Dispatch Pattern

四人幫的Patterns沒有這個Patterns....不過文中說很多python libraries都用了這個十分elegant的方法..... 唔...... 是還蠻方便的,只是我沒有特別感受到妙用 (通常會這麼講 以我的經驗就是沒有全懂 或是 這部分經驗還不夠.....:p)
class Dispatcher:      def do_get(self): ...      def do_put(self): ...      def error(self): ...      def dispatch(self, command):         mname = 'do_' + command         if hasattr(self, mname):             method = getattr(self, mname)             method()         else:             self.error()

好啦~~ 複習結束..........
本來只是要作個筆記 結果說了一堆.......歲月真是不饒人,很多東西真的很容易忘掉,像是簡單的Weak Reference...我剛剛還特別想了一下,這倒底是什麼東西,明明一年前大量使用,卻還是忘掉....... Orz

說好聽是見山不是山.......說難聽是歲月不饒人....