前言:
最近在研究android的時候,發現該系統大量使用了設計模式的知識。說來慚愧,在此之前,我從來沒見過C++代碼中有如此多重繼承的
使用方法,並曾一度認為是android故意搞這麼複雜,想讓我們看不明白。後來在用JAVA開發android的程式時候,發現JAVA的API大部分也是這麼弄的,不過用了Implements罷了....反思之,一定是我弄錯了。這時候想起了設計模式,買來一看,真的是非常經典啊,所以準備寫點東西,權當是筆記好了。
(該書已經看過一遍了,這是第二遍,準備每個模式都仔細體會下,難免有天馬行空的地方--畢竟這是我給自己做的總結)
abstract factory
學名抽象工廠。(設計模式是真正的物件導向,啥東西最終都會落實到對象上)。
簡單情境,以前經常在linux和windows平台上開發網路程式,後來搞了一個類,叫NetServer,要支援跨平台。一般會咋做呢?NetServer會定於成一個純虛類,裡邊全是一些虛函數(把它當做java的介面類好了,java確實更靠近OO)。比如說CreateListener,Connect等。然後在windows平台上寫了一個實作類別叫WinNetServer,在Linux平台上寫了一個LinuxNetServer。那麼在何種情況下使用呢?在NetServer.h中,提供了一個ConstructNetServer函數(不是類的成員),然後分別在WinNetServer.CPP和LinuxNetServer.CPP中實現這個函數(也可以在別的一個地方實現)。利用#ifdef WIN32等來new WinNetServer或者new LinuxNetServer。
這就是一個極其簡單的抽象工廠類。
但是,從書上感覺,該類對應的情況可以更廣泛。
1 在NetServer內部可以建立一系列的東西,比如CreateTCPSocket,CreateUDPSocket。這是該工廠生產的兩類產品。通過工廠類,我能保證在一個程式中,所有相關的東西全是一個工廠裡邊生產出來的(例如都是win平台,或者linux平台下的)
2 使用者根本不需要知道到底下面真實用的是哪個具體類(這似乎是所有設計模式要做到的事情)
優缺點:
這裡通過看書和仔細分析,解釋下幾個特點(書上有時候只有短短一句話,但卻意義深刻)
1 工廠類有個極大的問題。例如,如果以後增加了CreateHTTP的函數,那麼在所有類(基類和子類)都需要添加這個函數,即使這個函數生產出來的東西只是有個很小的變化----看來,如果基類開始不確定定義好的話,後續會有較大的改動。而且更深層次的意思是,如果要建立哪怕只有tcpsocket和其他不同的東西,都需要重新定義一個子類(意思是2個子類中,只有tcpsocket建立不一樣,其他都一樣,就這麼簡單的不同,都會需要重新定義一個子類)。--這個問題的解決辦法可以通過prototype模式
2 一個工廠,每個產品都需要定義一個建立函數
如 NetServerFactory(抽象工廠)--->建立NetServer(具體工廠)---->建立CreateTCPSocket(具體產品)。多個產品有多個這樣的create函數(又被稱為工廠函數),太麻煩了,不如Create(enum socketType)來解決....
3 按照上面的例子,NetServer是虛工廠,那實際工廠什麼時候建立?這個應該是要麼寫死,要麼條件編譯,要麼根據配置來產生。剛才那個ConstructNetServer實際是用來建立虛工廠的。
4 其實也可以這麼做,在別的函數參數中,傳遞這個虛工廠介面(已經被執行個體化了的),然後調用虛工廠的方法來Create這個,Create那個。(這句是廢話...呵呵)。
5 再想想還有什麼特點呢?在UI方面似乎更容易些。有一個適用情境很重要,即工廠的產品應該有共同的基類。
(越來越深奧了,是的,工廠的create函數返回的結果應該是一個介面,然後在不同的平台下,該介面有不同實現---和bridge模式由啥區別?以後再說。這個特點很關鍵。)--bridge模式解決的是沒有共同基類的情況。