原創文章,轉載請標註出處: "《Java設計模式系列 工廠方法模式》" 一、概述 工廠,就是生產產品的地方。 在Java設計模式中使用工廠的概念,那就是生成對象的地方了。 本來直接就能創建的對象為何要增加一個工廠類呢? 這就需要瞭解工廠方法要解決的是什麼問題了,如果只有一個類,我們直接new一個對象 ...
原創文章,轉載請標註出處:《Java設計模式系列-工廠方法模式》
一、概述
工廠,就是生產產品的地方。
在Java設計模式中使用工廠的概念,那就是生成對象的地方了。
本來直接就能創建的對象為何要增加一個工廠類呢?
這就需要瞭解工廠方法要解決的是什麼問題了,如果只有一個類,我們直接new一個對象完事,這是最簡單的;但是如果有多個類呢,而且這些類還需要針對不同的情況來創建不同的對象,這時候就需要工廠了,我們可以在工廠中根據條件來創建具體的對象。
這樣一來就將調用方和具體的目標類進行瞭解耦,調用方根本就不知道需要創建那個對象,它只是提出了條件,然後工廠就可以根據給定的條件來決定創建哪一個對象。
二、簡單工廠方法模式
要說工廠方法模式,不得不先瞭解下簡單工程方法模式,這個模式並不是23種設計模式中的內容。
所謂簡單工廠方法模式,就是為目標類創建一個工廠,當有多個目標實現的時候,在這個工廠內部進行邏輯判斷來根據條件創建不同的目標實例。
下麵看個例子,我就以桌子為例來寫:
桌子介面:Desk
/**
* 桌子介面
*/
public interface Desk {
String getType();
}
木質桌子:WoodenDesk
/**
* 木質桌子
*/
public class WoodenDesk implements Desk{
private String type = "木質桌";
@Override
public String getType() {
return type;
}
}
塑料桌子:PlasticDesk
/**
* 塑料桌
*/
public class PlasticDesk implements Desk {
private String type = "塑料桌";
@Override
public String getType() {
return type;
}
}
類型枚舉:Type
/**
* 類型
*/
public enum Type {
PLASTIC,WOODEN;
}
桌子工廠:DeskFactory
/**
* 桌子工廠
*/
public class DeskFactory {
public static Desk createDesk(Type type) {
switch (type) {
case WOODEN:
return new WoodenDesk();
case PLASTIC:
return new PlasticDesk();
default:
return null;
}
}
}
測試類:Clienter
/**
* 測試類
*/
public class Clineter {
public static void main(String[] args) {
Desk desk = DeskFactory.createDesk(Type.PLASTIC);
System.out.println(desk.getType());
}
}
執行結果
塑料桌
這就是簡單工廠方法,只有一個工廠類來面向多個目標實現。當目標實現增多時,我們不得不去修改工廠類的方法,使其相容新的實現類型,這明顯違背了開閉原則,所以出現了工廠方法模式。
三、工廠方法模式
工廠方法模式是對簡單工廠模式的抽象升級,將工廠這個概念抽象出來成為介面,然後針對每種目標實現類創建一個工廠實現,一對一來實現,當新增了目標實現,只要同時新增一個工廠實現即可。
下麵看看實例:
桌子介面:Desk
/**
* 桌子介面
*/
public interface Desk {
String getType();
}
木質桌子:WoodenDesk
/**
* 木質桌子
*/
public class WoodenDesk implements Desk{
private String type = "木質桌";
@Override
public String getType() {
return type;
}
}
塑料桌子:PlasticDesk
/**
* 塑料桌
*/
public class PlasticDesk implements Desk {
private String type = "塑料桌";
@Override
public String getType() {
return type;
}
}
桌子工廠介面:DeskFactory
/**
* 桌子工廠介面
*/
public interface DeskFactory {
Desk createDesk();
}
木質桌子工廠:WoodenDeskFactory
/**
* 木質桌子工廠
*/
public class WoodenDeskFactory implements DeskFactory{
@Override
public Desk createDesk(){
return new WoodenDesk();
}
}
塑料桌子工廠:
/**
* 塑料桌子工廠
*/
public class PlasticDeskFactory implements DeskFactory {
@Override
public Desk createDesk() {
return new PlasticDesk();
}
}
測試類:Clienter
/**
* 測試類
*/
public class Clienter {
public static void main(String[] args) {
DeskFactory factory = new WoodenDeskFactory();
Desk desk = factory.createDesk();
System.out.println(desk.getType());
}
}
執行結果:
木質桌
四、解析
從上面的實例中可以很容易看出來,工廠方法模式的重點就在這個工廠介面了。
目標可以無限擴展,工廠類也要隨之擴展,一對一存在,滿足了開閉原則,但如果目標實現較多,工廠實現類也會增多,不簡潔。
MyBatis中使用的比較多,事務模塊和數據源模塊都使用了工廠方法模式。