文章同步發(fā)放到CSDN博客
工廠模式
工廠模式主要是為創(chuàng)建對(duì)象提供接口,將創(chuàng)建對(duì)象的過(guò)程隔離起來(lái),實(shí)現(xiàn)了創(chuàng)建者與調(diào)用者的分離直晨,提高了程序的靈活性趁啸。
核心本質(zhì):
- 實(shí)例化對(duì)象,用工廠方法代替new操作垃帅。
- 將選擇實(shí)現(xiàn)類、創(chuàng)建對(duì)象統(tǒng)一管理和控制,從而將調(diào)用者跟我們實(shí)現(xiàn)類解耦恨胚。
工廠模式分類:
- 簡(jiǎn)單工廠模式(Simple Factory)
- 工廠方法模式(Factory Method)
- 抽象工廠模式(Abstract Factory)
一、簡(jiǎn)單工廠模式
又稱為靜態(tài)工廠方法模式用來(lái)生產(chǎn)同一等級(jí)結(jié)構(gòu)中的任意產(chǎn)品炎咖,通過(guò) 建立一個(gè)工廠(一個(gè)函數(shù)或一個(gè)類方法)來(lái)制造新的對(duì)象赃泡。
模式組成結(jié)構(gòu):
抽象產(chǎn)品: 它一般是具體產(chǎn)品繼承的父類或者實(shí)現(xiàn)的接口。在java中由接口或者抽象類來(lái)實(shí)現(xiàn)乘盼。
具體產(chǎn)品: 工廠類所創(chuàng)建的對(duì)象就是此角色的實(shí)例升熊。在java中由一個(gè)具體類實(shí)現(xiàn)。
工廠類: 這是本模式的核心绸栅,含有一定的商業(yè)邏輯和判斷邏輯级野。在java中它往往由一個(gè)具體類實(shí)現(xiàn)。
示例代碼
抽象產(chǎn)品:
public interface Car {
void run();
}
具體產(chǎn)品:
public class Audi implements Car {
@Override
public void run() {
System.out.println("奧迪車!");
}
}
public class Byd implements Car {
@Override
public void run() {
System.out.println("比亞迪車粹胯!");
}
}
工廠類:
public class SimpleFactory {
public Car createCar(String type ){
if("奧迪".equals(type)){
return new Audi();
}else if("比亞迪".equals(type)){
return new Byd();
}else{
return null ;
}
}
}
客戶類:
public class Customer {
public static void main(String[] args ) {
SimpleFactory factory = new SimpleFactory();
Car car1 =factory.createCar("奧迪");
Car car2 =factory.createCar("比亞迪");
}
}
以上便是簡(jiǎn)單工廠模式蓖柔, 但是工廠部分好像不太理想,因?yàn)槊吭黾右环N新型車风纠,都要在工廠類中增加相應(yīng)的創(chuàng)建業(yè)務(wù)邏輯(createCar(String type)方法需要新增case)况鸣,這顯然是違背開(kāi)閉原則的 。可想而知對(duì)于新產(chǎn)品的加入竹观,工廠類是很被動(dòng)的镐捧。對(duì)于這樣的工廠類潜索,我們稱它為全能類或者上帝類。
于是工廠方法模式出現(xiàn)了懂酱。 工廠類定義成了接口,而每新增的車種類型,就增加該車種類型對(duì)應(yīng)工廠類的實(shí)現(xiàn),這樣工廠的設(shè)計(jì)就可以擴(kuò)展了,而不必去修改原來(lái)的代碼竹习。
二、工廠方法模式
工廠方法模式是簡(jiǎn)單工廠模式的進(jìn)一步抽象化和推廣玩焰,工廠方法模式里不再只由一個(gè)工廠類決定那一個(gè)產(chǎn)品類應(yīng)當(dāng)被實(shí)例化,這個(gè)決定被交給抽象工廠的子類去做由驹。
模式組成結(jié)構(gòu):
- 抽象產(chǎn)品: 它一般是具體產(chǎn)品繼承的父類或者實(shí)現(xiàn)的接口。在java中由接口或者抽象類來(lái)實(shí)現(xiàn)昔园。
- 具體產(chǎn)品: 工廠類所創(chuàng)建的對(duì)象就是此角色的實(shí)例蔓榄。在java中由一個(gè)具體類實(shí)現(xiàn)。
- 抽象工廠: 這是工廠方法模式的核心默刚,它與應(yīng)用程序無(wú)關(guān)甥郑。是具體工廠角色必須實(shí)現(xiàn)的接口或者必須繼承的父類。在java中它由抽象類或者接口來(lái)實(shí)現(xiàn)荤西。
- 具體工廠: 它含有和具體業(yè)務(wù)邏輯有關(guān)的代碼澜搅。由應(yīng)用程序調(diào)用以創(chuàng)建對(duì)應(yīng)的具體產(chǎn)品的對(duì)象。
示例代碼
抽象產(chǎn)品與具體產(chǎn)品類代碼與上面相同邪锌。
抽象工廠:
public interface CarFactory {
Car createCar();
}
具體工廠:
public class AudiFactory implements CarFactory {
@Override
public Car createCar() {
return new Audi();
}
}
public class BydFactory implements CarFactory {
@Override
public Car createCar() {
return new Byd();
}
}
客戶類:
public class Customer {
public static void main(String[] args) {
Car c1 = new AudiFactory().createCar();
Car c2 = new BydFactory().createCar();
}
}
工廠方法模式使用繼承自抽象工廠角色的多個(gè)子類來(lái)代替簡(jiǎn)單工廠模式中的“上帝類”勉躺。正如上面所說(shuō),這樣便分擔(dān)了對(duì)象承受的壓力觅丰;而且這樣使得結(jié)構(gòu)變得靈活 起來(lái)——當(dāng)有新的產(chǎn)品產(chǎn)生時(shí)饵溅,只要按照抽象產(chǎn)品角色、抽象工廠角色提供的合同來(lái)生成妇萄,那么就可以被客戶使用蜕企,而不必去修改任何已有的代 碼」诰洌可以看出工廠角色的結(jié)構(gòu)也是符合開(kāi)閉原則的轻掩!
三、簡(jiǎn)單工廠模式VS工廠方法模式
1 ) 結(jié)構(gòu)復(fù)雜度:簡(jiǎn)單工廠模式優(yōu)勝懦底。
2)代碼復(fù)雜度:簡(jiǎn)單工廠模式占優(yōu)唇牧。
3)管理難度: 工廠方法模式的核心是一個(gè)抽象工廠類,而不像簡(jiǎn)單工廠模式, 把核心放在一個(gè)實(shí)類上【厶疲可拓展性更好丐重,易于管理。
總結(jié):根據(jù)設(shè)計(jì)理論建議用工廠方法模式拱层,但是實(shí)際上弥臼,我們一般都是使用簡(jiǎn)單工廠模式宴咧!
四根灯、抽象工廠模式
在抽象工廠模式中,抽象產(chǎn)品 (AbstractProduct) 可能是一個(gè)或多個(gè),從而構(gòu)成一個(gè)或多個(gè)產(chǎn)品族(Product Family)烙肺。如構(gòu)成一輛車需要有發(fā)動(dòng)機(jī)纳猪,座椅,輪胎等配件桃笙,而每個(gè)配件又有多種(如發(fā)動(dòng)機(jī)有A氏堤,B不同型號(hào)),那么該抽象產(chǎn)品構(gòu)成一個(gè)產(chǎn)品族搏明。
當(dāng)每個(gè)抽象產(chǎn)品都有多于一個(gè)的具體子類的時(shí)候(發(fā)動(dòng)機(jī)有型號(hào)A和B兩種鼠锈,座椅也有型號(hào)A和B兩種),工廠角色怎么知道實(shí)例化哪一個(gè)子類呢星著?比如每個(gè)抽象產(chǎn)品角色都有兩個(gè)具體產(chǎn)品(產(chǎn)品輪胎有兩個(gè)具體產(chǎn)品輪胎A和輪胎B)购笆。抽象工廠模式提供兩個(gè)具體工廠角色(A型汽車系列工廠和B型系列工廠),分別對(duì)應(yīng)于這兩個(gè)具體產(chǎn)品角色虚循,每一個(gè)具體工廠角色只負(fù)責(zé)某一個(gè)產(chǎn)品角色的實(shí)例化同欠。每一個(gè)具體工廠類只負(fù)責(zé)創(chuàng)建抽象產(chǎn)品的某一個(gè)具體子類的實(shí)例。
示例代碼
不同的抽象產(chǎn)品族:
/**
* 發(fā)動(dòng)機(jī)接口及具體子類
*/
public interface Engine {
void run();
}
class EngineA implements Engine{
@Override
public void run() {
System.out.println("轉(zhuǎn)的快横缔!");
}
}
class EngineB implements Engine{
@Override
public void run() {
System.out.println("轉(zhuǎn)的慢铺遂!");
}
}
/**
* 座椅接口及具體子類
*/
public interface Seat {
void massage();
}
class LuxurySeat implements Seat {
@Override
public void massage() {
System.out.println("可以自動(dòng)按摩!");
}
}
class LowSeat implements Seat {
@Override
public void massage() {
System.out.println("不能按摩茎刚!");
}
}
不同的工廠:
//汽車工廠接口
public interface CarFactory {
Engine createEngine();
Seat createSeat();
}
//A類汽車工廠
public class CarFactoryA implements CarFactory {
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Seat createSeat() {
return new SeatA();
}
}
//B類汽車工廠
public class CarFactoryB implements CarFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Seat createSeat() {
return new SeatB();
}
}
客戶:
public class Customer {
public static void main(String[] args) {
//得到不同配件構(gòu)成的汽車
CarFactory factory1 = new CarFactoryA();
Engine e = factory1.createEngine();
Seat s=factory1.createSeat();
CarFactory factory2 = new CarFactoryB();
Engine e1= factory2.createEngine();
Seat s1=factory2.createSeat();
}
}
抽象工廠模式提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口襟锐,而無(wú)須指定他們具體的類。它針對(duì)的是有多個(gè)產(chǎn)品的等級(jí)結(jié)構(gòu)斗蒋。