Python設計模式-享元模式

小屋子大俠發表於2017-06-21

Python設計模式-享元模式

基於Python3.5.2,程式碼如下

#coding:utf-8

class Coffee:
    name = ""
    price = 0
    def __init__(self,name):
        self.name = name
        self.price = len(name)
    def show(self):
        print("Coffee Name:%s Price:%s"%(self.name,self.price))
class Customer:
    name = ""
    coffee_factory = ""
    def __init__(self,name,coffee_factory):
        self.name = name
        self.coffee_factory = coffee_factory
    def order(self,coffee_name):
        print("%s order a cup of coffee:%s" % (self.name, coffee_name))
        return self.coffee_factory.getCoffee(coffee_name)

class CoffeeFactory():
    coffee_dict = {}
    def getCoffee(self,name):
        if self.coffee_dict.get(name,False) == False:
            self.coffee_dict[name] = Coffee(name)
        return self.coffee_dict[name]
    def getCoffeeCount(self):
        return len(self.coffee_dict)

if __name__ == "__main__":
    coffee_factory = CoffeeFactory()
    customer1 = Customer("Client 1",coffee_factory).order("coffee1")
    customer2 = Customer("Client 2", coffee_factory).order("coffee1")
    customer3 = Customer("Client 3", coffee_factory).order("coffee2")
    customer4 = Customer("Client 4", coffee_factory).order("coffee3")
    print("CoffeeFactory中coffee的例項物件數",coffee_factory.getCoffeeCount())

享元模式分析與解讀

享元模式

運用共享技術有效支援大量細粒度物件。在享元物件內部並且不會隨環境改變而改變的共享部分,可以稱為是享元物件的內部物件,而隨環境改變而改變的、不可以共享的狀態就是外部狀態了。享元模式可以避免大量非常相似類的開銷。在程式設計中,有時需要生成大量細粒度的類例項來表示資料。如果能發現這些例項除了幾個引數外基本相同的,有時就能夠大幅度減少需要例項化的類的數量,如果能把這些引數移到類例項的外面,在方法呼叫時將他們傳遞進來,就可以通過共享大幅度減少單個例項的數目。

享元模式的適用場景

1、系統中存在大量的相似物件時,可以選擇享元模式;
2、需要緩衝池的場景中,如程式池、執行緒池等技術。

解讀

程式碼中,模擬了不同使用者來下訂單購買咖啡的場景,咖啡店中可供選擇的咖啡型別有限,由於顧客每個都不同,在生成訂單買咖啡時,需要生成咖啡例項,如果同一個種類咖啡被不同顧客訂購時,會生成多個例項,此時就應用享元模式對該場景應用進行改造。
1、在Coffee類中,包含了Coffee的名稱和價格;
2、用CoffeeFactory類來管理Coffee類,類通過getCoffee()來確保同一個種類的Coffee只生成一次。
3、在Customer類中,初始化時將CoffeeFactory物件傳入,當Customer呼叫order()方法時,通過CoffeeFactory物件的getCoffee()方法來獲得Coffee物件,從而達到物件共享的目的。

程式執行結果如下:

Client 1 order a cup of coffee:coffee1
Client 2 order a cup of coffee:coffee1
Client 3 order a cup of coffee:coffee2
Client 4 order a cup of coffee:coffee3
CoffeeFactory中coffee的例項物件數 3

通過執行結果,顯示工廠類中只生成了三個coffee物件,不同的顧客實現了對coffee物件的共享。

享元模式的優缺點

優點:

1、減少重複物件,節約系統資源。

缺點:

1、雖然節約了系統資源,但同時也提高了系統的複雜性,尤其當遇到外部狀態與內部狀態混在一起時,需要先將其分離,再使用享元模式。
2、享元模式需要注意執行緒安全問題。

備註

class Flyweight():
    def operation(self):
        raise NotImplementedError

class ConcreteFlyweight(Flyweight):
    def operation(self):
        print("實現operation")

class FlyweightFactory():
    flyweights = {}
    def __init__(self):
        self.flyweights["A"] = ConcreteFlyweight()
        self.flyweights["B"] = ConcreteFlyweight()
        self.flyweights["C"] = ConcreteFlyweight()
    def getFlyweight(self,key):
        return self.flyweights[key]

if __name__ == "__main__":
    f = FlyweightFactory()
    fa = f.getFlyweight("A")
    fa.operation()

    fb = f.getFlyweight("B")
    fb.operation()

該實現方式,對不同的語言具有通用性。

相關文章