設計模式1-創建型模式

1. UML

1.1 UML中的關係

主要4種:

  • 關聯關係(association)
  • 依賴關係(dependency)
  • 實現關係(realization)
  • 泛化關係(generalization)

1.2 用例圖

從客戶角度描述功能,包括:

  • 參與者(actor),畫個小人
  • 用例(use case),橢圓,代表功能
  • 關係,小人指向功能

1.2.1 泛化關係(generalization)

即虛函數,如支付方式分爲微信、支付寶。 會員用戶繼承自普通用戶。用空心箭頭指向父類。

1.2.2 包含關係(include)

如添加、修改、刪除數據均需包含更新數據庫功能。

1.2.3 擴展關係(extend)

偶爾執行其它可選功能,如保存成績後想打印出來。

1.3 類圖

主要元素:類、接口、關係。 關係 即4大關係。 類圖中也有包含和約束。

由類名、屬性和方法組成。加號public,減號private,井號protected。

1.3.1 關聯關係

比如,人擁有(實線指向)車,用小箭頭(->)。

1.3.2 聚合關係

更強的關聯關係,如汽車和引擎,引擎指向車,空心菱形在車一端。

1.3.3 關聯-組合

如公司和部門,空心菱形改實心。

2. 設計模式

目前分類:GoF的23種+簡單工廠模式 == 24種

2.1 OOP設計原則

可維護,可複用,目的是高內聚低耦合。

  • 單一職責原則,single responsibility principle,對外只提供一個功能,引起類變化的原因只有一個;
  • 開閉原則,open-closed principle,類的改動通過增加代碼進行,而不是修改源碼,且不影響舊代碼;
  • 里氏代換原則,Liskov substitution principle,任何抽象類出現的地方都能由實現類替換;
  • 依賴倒轉原則,dependence inversion principle,面向接口編程,不要依賴實現類,也就是中間層是抽象的,如doBusiness(AbstractBankWorker *p);
  • 接口隔離原則,interface segragation principle,一個接口只提供一種功能,不要封裝太多功能;
  • 合成複用原則,composite reuse principle,父類變化會影響子類,所以對於繼承和組合,後者優先,比如人不應繼承車,而是擁有抽象車類指針成員;
  • 迪米特法則,law of Demeter(LoD),一個對象不應瞭解另一個對象,即提供接口,低耦合,黑盒原理。又叫最少知識原則,比如買房需要中介。

3. 創建型模式

3.1 簡單工廠模式、工廠方法模式、抽象工廠模式

情景:不想new(繁瑣),而是直接用,且類很少。所以給工廠CreateObject傳參,返回需要的對象。

缺點:

  • 不符合開閉原則
  • 功能過多

爲了符合產品族開閉原則,可以引入抽象工廠,每個具體工廠生產一個類,如蘋果廠,香蕉廠。這叫做工廠方法模式,適用於客戶不需要知道所需對象的情況。

缺點:類會越來越多,不好維護。


工廠方法模式可以增加產品等級,抽象工廠模式則是針對產品族。

  • 產品族:同一工廠的產品,比如增加一箇中國水果工廠,且並不需要改變抽象工廠;
  • 產品等級:不同工廠的產品,如增加香蕉則要在抽象工廠中增加CreateBanana,不符合開閉原則。

3.2 單例模式

一般用於管理者對象。

步驟:

  1. 構造函數私有
  2. 靜態私有類指針
  3. 靜態GetInstance()

單例模式不用考慮釋放問題

// 懶漢式
class Singleton_lazy
{
private:
	Singleton_lazy() {}
	static Singleton_lazy* GetInstance()
	{
		if (pSingleton == NULL)
		{
			pSingleton = new Singleton_lazy;
		}
		return pSingleton;
	}
private:
	static Singleton_lazy* pSingleton;
};
Singleton_lazy* Singleton_lazy::pSingleton = NULL;

// 餓漢式
class Singleton_hungry
{
private:
	Singleton_hungry() {}
	static Singleton_hungry* GetInstance()
	{
		return pSingleton;
	}
private:
	static Singleton_hungry* pSingleton;
};
Singleton_hungry* Singleton_hungry::pSingleton = new Singleton_hungry;

多線程問題

懶漢式遇到多線程是不安全的,可能多次new。所以要用餓漢式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章