=單例模式=

單例模式需要考慮的重要問題是其生存周期問題,一種是不死鳥,永遠不銷毀,最為簡單,但是占用了資源
另一種是有生存周期, 但是又要考慮其引用可能無效的問題
* Lifetime: Dead reference
* Double check locking
=工廠模式=
工廠模式是很常用的模式, 常見的有
*簡單工廠
*抽象工廠
*工廠方法
=生成器模式=
=原型模式=
這里只是簡單地用相應類圖來表示, 個中滋味, 在應用中自己慢慢體會吧
相似的一點是抽象的東西有具體的實現, 至于到底用哪個具體的實現, 交給工廠來創建吧
至于這個工廠, 視問題域的復雜性,可以是抽象的, 也可以是具體的,工廠模式大體如此
General Responsibility Assignment
Software Patterns 通用職責分配軟件模式
模式名稱
|
描述(問題/解決方案)
|
信息專家模式Information Expert
|
問題:對象設計和職責分配的一般原則是什么?
解決方案:將職責分配給擁有履行一個職責所必需信息的類--即信息專家。(也就是將職責分配給一個類,這個類必須擁有履行這個職責所需要的信息。)
|
創建者模式Creator
|
問題:誰應該負責產生類的實例(對應于GoF設計模式系列里的“工廠模式”)
解決方案:如果符合下面的一個或多個條件,則將創建類A實例的職責分配給類B.
.類B聚合類A的對象。
.類B包含類A的對象。
.類B記錄類A對象的實例。
.類B密切使用類A的對象。
.類B初始化數據并在創建類A的實例時傳遞給類A(類B是創建類A實例的一個專家)。
在以上情況下,類B是類A對象的創建者。
|
控制器模式
Controller
|
問題:誰處理一個系統事件?
解決方案:當類代表下列一種情況時,為它分配處理系統事件消息的職責。
.代表整個系統、設備或子系統(外觀控制器)。
.代表系統事件發生的用例場景(用例或回話控制器)。
|
低耦合Low Coupling
|
問題:如何支持低依賴性以及增加重用性?
解決方案:分配職責時使(不必要的)耦合保持為最低。
|
高內聚High Cohesion
|
問題:如何讓復雜性可管理?
解決方案:分配職責時使內聚保持為最高。
|
多態模式Polymorphism
|
問題:當行為隨類型變化而變化時誰來負責處理這些變化?
解決方案:當類型變化導致另一個行為或導致行為變化時,應用多態操作將行為的職責分配到引起行為變化的類型。
|
純虛構模式Pure Fabrication
|
問題:當不想破壞高內聚和低耦合的設計原則時,誰來負責處理這些變化?
解決方案:將一組高內聚的職責分配給一個虛構的或處理方便的“行為”類,它并不是問題域中的概念,而是虛構的事務,以達到支持高內聚、低耦合和重用的目的。
|
中介模式Indirection
|
問題:如何分配職責以避免直接耦合?
解決方案:分配職責給中間對象以協調組件或服務之間的操作,使得它們不直接耦合。
|
受保護變化模式Protected Variations
|
問題:如何分配職責給對象、子系統和系統,使得這些元素中的變化或不穩定的點不會對其他元素產生不利影響?
解決方案:找出預計有變化或不穩定的元素,為其創建穩定的“接口”而分配職責。
|
這些更象是一些OOD的原則, 模式會有很多, 但是萬變不離其宗, 大都遵循著一些基本的原則
-
OCP(Open-Closed Principle)
- DIP(Dependency Inversion
Principle)
-
LSP(Liskov Substitution
Principle)
- ISP(Interface Insolation
Principle)
- SRP(Single Resposibility
Principle)
- CARP(Composite/Aggregate Reuse
Principle)
- LoD(Law Of Demeter):don't talk
to stranger
之后我們來詳細討論這些原則
大名鼎鼎的GOF的設計模式是最著名的一本里程碑的作品
=模式分類=

=模式之間的關系=

=如何應用模式=
DP中的引言說得很好,如何應該模式來解決設計問題
* 尋找合適的對象
對象包括數據和操作, 對象在收到請求(或消息)后, 執行相應的操作
客戶請求是使對象執行操作的唯一方法, 操作又是對象改變內部數據的唯一方法
(這就是封裝的意義,之所以強調對象的成員應該是私有的原因)
OOD最困難的部分就是將系統分解成對象集合,因為要考慮許多因素:
封裝,粒度,信賴關系,靈活性,性能,演化,復用等等,它們之間也互相有所影響或沖突.
設計模式可以幫助我們確定那些并不明顯的抽象和描述這些抽象的對象,如Strategy, State,etc.
==決定對象的粒度==
如何決定對象的大小,數目以及范圍呢, 設計模式亦有所幫助:
Facade 描述了怎樣用對象表示完整的子系統
Flyweight
Abstact Factory
Builder
Visitor
Command
==指定對象接口==
對象接口描述了該對象所能接受的全部請求的集合, 也就是它能夠提供哪些服務(方法)
當給對象發送請求時, 所引起的具體操作既與請求本身有關,又與接受對象有關
支持相同請求的不同對象可能對請求激發的操作有不同的實現(動態綁定和多態)
而設計模式通過確定接口的主要組成部分及經接口發送的數據類型, 來幫助你定義接口.
DP也許還會告訴你接口中不應包括哪些東西, 比如Memento模式所規定的接口
DP也指定了接口之間的關系,特別地,它常要求一些類具有相同或相似的接口,或對一些類的接口作出一些限制
如Decorator, Proxy模式要求修飾/代理對象和被修飾/受代理的對象接口保持一致
Visitor模式中Vistor接口必須反映能訪問的對象的所有類
==描述對象的實現==
* 類繼承還是接口繼承呢
* 針對接口編程,而不是針對實現編程
==運用復用機制==
1.優先使用對象組合,而不是類繼承
2.委托
3.繼承和泛型的比較
==關聯運行時刻和編譯時刻的結構==
==設計應支持變化==
* 設計中常出現的問題
** 通過顯式地指定一個類來創建對象
*** Factory , Prototype
** 對特殊操作的依賴
*** Chain of Reponsibility, Command
** 對硬件和軟件平臺的依賴
*** Abstract Factory, Bridge
** 對對象表示或實現的依賴
** 算法依賴
** 緊耦合
*** Abstract Factory, command, facade, mediator, observere,chain of responsibility
** 通過生成子類來擴充功能
*** Bridge, Chain of Reponsibility, composite, Decorator, Observer, Strategy
** 不能方便地對類進行修改
*** Adapter, Decorator, visitor
=如何選擇設計模式=
* 考慮設計模式是如何解決設計問題的
* 瀏覽模式的意圖部分
* 研究模式怎樣互相關聯
* 研究目的相似的模式
* 檢查重新設計的原因
* 考慮你的設計中哪些是可變的

=怎樣使用設計模式=
* 大致瀏覽一遍模式
* 回頭研究結構部分
* 看代碼示例部分
* 選擇模式參考者的名字, 使它們在應用上下文中有意義
* 定義類
* 定義模式中專用于應用的操作名稱
* 實現執行模式中責任和協作的操作
啥叫模式? Patterns in solutions come from patterns in problems.
針對某一類經常出現的問題所采取的行之有效的解決方案
"A pattern is a solution to a problem in a context."
"Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice."(Christopher Alexander -- A Pattern Language)
模式的四個基本要素:
1. 模式名稱pattern name
2. 問題problem
3. 解決方案solution
4. 效果consequences
如何描述設計模式(十大特點)
1. 意圖:描述,別名
2. 動機:場景
3. 適用性: 什么情況下
4. 結構: 類圖, 序列圖
5. 參考者
6. 協作
7. 效果
8. 實現
9. 應用
10. 相關模式
在實踐中學習是最佳的方式, 所以先要掌握每個模式的十大特點,更加重要的是在實際應用中學習, 在水中學會游泳
以迭代器模式為例, Java中有一個Iterator接口
1 public interface Iterator
2 {
3 /**
4 * Tests whether there are elements remaining in the collection. In other
5 * words, calling <code>next()</code> will not throw an exception.
6 *
7 * @return true if there is at least one more element in the collection
8 */
9 boolean hasNext();
10
11 /**
12 * Obtain the next element in the collection.
13 *
14 * @return the next element in the collection
15 * @throws NoSuchElementException if there are no more elements
16 */
17 Object next();
18
19 /**
20 * Remove from the underlying collection the last element returned by next
21 * (optional operation). This method can be called only once after each
22 * call to <code>next()</code>. It does not affect what will be returned
23 * by subsequent calls to next.
24 *
25 * @throws IllegalStateException if next has not yet been called or remove
26 * has already been called since the last call to next.
27 * @throws UnsupportedOperationException if this Iterator does not support
28 * the remove operation.
29 */
30 void remove();
31 }
32
假如你的類中有一些聚集關系, 那么考慮增加一個iterator方法,以實現下面這個接口
public interface Iterable
{
/**
* Returns an iterator for the collection.
*
* @return an iterator.
*/
Iterator iterator ();
}
返回你自己實現的ConcreteIterator類, 這個ConcreteIterator當然是實現了
Iterator接口的
你會發現在遍歷和迭代類中的這個成員的聚集元素時會有不同的感覺, 因為這個Iterator與實現是分離的.
你的類終歸是給自己或別人使用的,在調用者的眼里, 非常簡單, 管你里面是怎么實現的呢,
反正我知道你能給我一個迭代器就夠了, 這里面就體現了面向接口編程的好處. 也就是按契約編程