通過(guò)“對(duì)象創(chuàng)建”模式繞開(kāi)new,來(lái)避免對(duì)象創(chuàng)建(new)過(guò)程中所導(dǎo)致的緊耦合(依賴(lài)工具類(lèi)),從而支持對(duì)象創(chuàng)建的穩(wěn)定敲董。它是接口抽象之后的第一步工作紫皇。
典型模式
- Factory Method
- Abstract Factory
- Prototype
- Builder
Factory Method 工廠(chǎng)方法
動(dòng)機(jī)
- 在軟件系統(tǒng)中,經(jīng)常面臨著創(chuàng)建對(duì)象的工作;由于需求的變化腋寨,需要?jiǎng)?chuàng)建的對(duì)象的具體類(lèi)型經(jīng)常變化.
- 如何應(yīng)對(duì)這種變化?如何繞過(guò)常規(guī)的對(duì)象創(chuàng)建方法(new)聪铺,提供一種“封裝機(jī)制”來(lái)避免客戶(hù)程序和這種“具體對(duì)象創(chuàng)建工作”的緊耦合?
- 關(guān)鍵方法返回一個(gè)對(duì)象
非靜態(tài)方法 工廠(chǎng)基類(lèi)
模式定義
- 定義一個(gè)創(chuàng)建對(duì)象的接口,讓子類(lèi)決定實(shí)例化哪一個(gè)類(lèi).Factory Method 使得一個(gè)類(lèi)的實(shí)例化延遲(目的:解耦,手段:虛函數(shù))到子類(lèi).
要點(diǎn)總結(jié)
- Factory Method模式用于隔離類(lèi)對(duì)象的使用者和具體類(lèi)型之間的耦合關(guān)系萄窜。面對(duì)一個(gè)經(jīng)常變化的具體類(lèi)型铃剔,緊耦合關(guān)系(new)會(huì)導(dǎo)致軟件的脆弱。
- Factory Method模式通過(guò)面向?qū)ο蟮氖址?將所要?jiǎng)?chuàng)建的具體對(duì)象工作延遲到子類(lèi)查刻,從而實(shí)現(xiàn)一種擴(kuò)展(而非更改)的策略键兜,較好地解決了這種緊耦合關(guān)系
- Factory Method模式解決“單個(gè)對(duì)象”的需求變化。缺點(diǎn)在于要求創(chuàng)建方法/參數(shù)相同
Abstract Factory抽象工廠(chǎng)
定義
產(chǎn)品族:位于不同產(chǎn)品等級(jí)結(jié)構(gòu)穗泵,功能相關(guān)聯(lián)的產(chǎn)品組成的家族蝶押。
如圖:
產(chǎn)品族
圖中一共有四個(gè)產(chǎn)品族,分布于三個(gè)不同的產(chǎn)品等級(jí)結(jié)構(gòu)中火欧。只要指明一個(gè)產(chǎn)品所處的產(chǎn)品族以及它所屬的等級(jí)結(jié)構(gòu),就可以唯一的確定這個(gè)產(chǎn)品茎截。
所謂的抽象工廠(chǎng)是指一個(gè)工廠(chǎng)等級(jí)結(jié)構(gòu)可以創(chuàng)建出分屬于不同產(chǎn)品等級(jí)結(jié)構(gòu)的一個(gè)產(chǎn)品族中的所有對(duì)象苇侵。如果用圖來(lái)描述的話(huà),如下圖:
結(jié)構(gòu)
圖中描述的東西用產(chǎn)品族描述如下
舉例
//數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)有關(guān)的基類(lèi)
class IDBConnection{
}
class IDBCommand{
}
class IDataReader{
}
abstract class IDBFactory{
public abstract IDBConnection createDBConnection();
public abstract IDBCommand createDBCommand();
public abstract IDataReader createDataReader();
}
//支持My SQL
class MySqlConnection extends IDBConnection{
}
class MySqlCommand extends IDBCommand{
}
class MySqlDataReader extends IDataReader{
}
class MySqlDBFactory extends IDBFactory{
@Override
public IDBConnection createDBConnection() {
return new MySqlConnection();
}
@Override
public IDBCommand createDBCommand() {
return new MySqlCommand();
}
@Override
public IDataReader createDataReader() {
return new MySqlDataReader();
}
}
//支持Oracle
class OracleConnection extends IDBConnection{
}
class OracleCommand extends IDBCommand{
}
class OracleDataReader extends IDataReader{
}
class OracleDBFactory extends IDBFactory{
@Override
public IDBConnection createDBConnection() {
return new OracleConnection();
}
@Override
public IDBCommand createDBCommand() {
return new OracleCommand();
}
@Override
public IDataReader createDataReader() {
return new OracleDataReader();
}
}
class EmployeeDAO{
IDBFactory dbFactory;
public Vector<EmployeeDO> getEmployees(){
IDBConnection connection =dbConnectionFactory.createDBConnection();
connection.setConnectionString("...");
IDBCommand command = dbCommandFactory.createDBCommand();
command.setCommandText("...");
command.setConnection(connection);//關(guān)聯(lián)性
IDBDataReader reader = command.executeReader();//關(guān)聯(lián)性
while (reader.read()) {
}
return employeeDOs;
}
}
在什么情形下使用抽象工廠(chǎng)模式:
- 一個(gè)系統(tǒng)不應(yīng)當(dāng)依賴(lài)于產(chǎn)品類(lèi)實(shí)例如何被創(chuàng)建企锌、組合和表達(dá)的細(xì)節(jié)榆浓,這對(duì)于所有形態(tài)的工廠(chǎng)模式都是重要的。
- 這個(gè)系統(tǒng)有多于一個(gè)的產(chǎn)品族撕攒,而系統(tǒng)只消費(fèi)其中某一產(chǎn)品族陡鹃。
- 同屬于同一個(gè)產(chǎn)品族的產(chǎn)品是在一起使用的,這一約束必須在系統(tǒng)的設(shè)計(jì)中體現(xiàn)出來(lái)抖坪。
- 系統(tǒng)提供一個(gè)產(chǎn)品類(lèi)的庫(kù)萍鲸,所有的產(chǎn)品以同樣的接口出現(xiàn),從而使客戶(hù)端不依賴(lài)于實(shí)現(xiàn)擦俐。