設(shè)計模式學(xué)習(xí)04----之簡單工廠模式以及工廠方法模式以及抽象工廠模式
Spring Boot 的學(xué)習(xí)先告一段落,我們先溫習(xí)下相關(guān)設(shè)計模式。我們先學(xué)習(xí)下簡單工廠模式和工廠方法模式。
簡單工廠模式
定義和結(jié)構(gòu)
簡單工廠模式是屬于創(chuàng)建型模式,又叫做靜態(tài)工廠方法(Static Factory
Method)模式,但不屬于23種GOF設(shè)計模式之一。簡單工廠模式是由一個工廠對象決定創(chuàng)建出哪一種產(chǎn)品類的實例。簡單工廠模式是工廠模式家族中最簡單實用的模式,可以理解為是不同工廠模式的一個特殊實現(xiàn)。
優(yōu)缺點
優(yōu)點: 實現(xiàn)了封裝
缺點:違反了高內(nèi)聚的原則
工廠方法模式
定義和結(jié)構(gòu)
GOF中給出的定義是:工廠方法模式定義一個創(chuàng)建對象的接口,但由子類決定要實例化的類是哪一個。
有以下四種角色:
抽象工廠角色:定義創(chuàng)建產(chǎn)品的方法
具體工廠角色: 具體實現(xiàn)創(chuàng)建產(chǎn)品的方法
抽象產(chǎn)品角色: 抽象產(chǎn)品的共有方法
具體產(chǎn)品角色:實現(xiàn)產(chǎn)品的共有方法。
以下是一個demo
抽象產(chǎn)品類(Product):
package com.factory.factoryMethod;
/**
-
抽象產(chǎn)品
-
@author xiang.wei
-
@create 2018/4/8 10:42
/
abstract class Product {
/*- 商品展示
*/
public abstract void show();
}
具體產(chǎn)品類 (ProductA 與ProductB)
- 商品展示
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:55
*/
public class ProductA extends Product {@Override
public void show() {
System.out.println(“產(chǎn)品A被生產(chǎn)出來”);
}
}
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:02
*/
public class ProductB extends Product {@Override
public void show() {
System.out.println(“產(chǎn)品B被生產(chǎn)”);
}
}抽象工廠類(Factory)
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:35
/
abstract class Factory {
/*- 抽象工廠
- @return
*/
public abstract Product manufacture();
}
具體工廠類(FactoryA與FactoryB),不同的工廠生產(chǎn)不同的產(chǎn)品
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:54
*/
public class FactoryA extends Factory {@Override
public Product manufacture() {
return new ProductA();
}
}
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:03
*/
public class FactoryB extends Factory {@Override
public Product manufacture() {
return new ProductB();
}
}客戶端調(diào)用
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:05
*/
public class FactoryPattern {
public static void main(String[] args) {
//客戶需要產(chǎn)品A
Factory factoryA = new FactoryA();
factoryA.manufacture().show();
//客戶需要產(chǎn)品B
FactoryB factoryB = new FactoryB();
factoryB.manufacture().show();
}
}
優(yōu)缺點
優(yōu)點:
擴展性好,符合開閉原則,對擴展開放,對修改關(guān)閉,在增加產(chǎn)品類的情況下,只需要適當(dāng)修改具體的工廠類或擴展一個工廠類。
多態(tài)性:客戶代碼可以做到與特定應(yīng)用無關(guān),使用于任何實體類。
良好的封裝性,代碼結(jié)構(gòu)清晰。
屏蔽產(chǎn)品類
典型的解耦框架:高層模塊只需要知道產(chǎn)品的抽象類,其他的實現(xiàn)類都不需要關(guān)心,符合迪米特法則,符合里氏替換原則。
缺點:
一個具體工廠只能創(chuàng)建一類產(chǎn)品。
抽象工廠模式
定義和結(jié)構(gòu)
GOF 中給出的定義是:抽象工廠模式提供一個接口,用于創(chuàng)建相關(guān)或依賴對象的家族,而不需要明確指定具體的類。
抽象工廠模式
從類圖中我們可以看出,抽象工廠中每個工廠可以創(chuàng)建多種產(chǎn)品,比如:Factory1可以創(chuàng)建ProductA和ProductB兩種產(chǎn)品。
組成 關(guān)系 作用
抽象工廠類(Factory) 具體工廠的父類 定義具體工廠的公共接口方法
具體工廠類(Factory1) 抽象工廠的子類,被外界調(diào)用 描述具體工廠,實現(xiàn)FactoryMethod工廠方法創(chuàng)建產(chǎn)品的實例
抽象產(chǎn)品類(ProductA) 具體產(chǎn)品的父類 定義具體產(chǎn)品的公共接口
具體產(chǎn)品類(ProductA1) 抽象產(chǎn)品的子類,工廠類創(chuàng)建的目標(biāo)類 定義生產(chǎn)的具體產(chǎn)品
抽象工廠類
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:35
/
public interface Factory {
/*- 創(chuàng)建抽象產(chǎn)品A
- @return
*/
ProductA createProductA();
/**
- 創(chuàng)建抽象產(chǎn)品B
- @return
*/
ProductB createProductB();
}
具體工廠類A和具體工廠類B
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:54
*/
public class FactoryA implements Factory {public ProductA createProductA() {
return new ProductA1();
}public ProductB createProductB() {
return new ProductB1();
}
}
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:03
*/
public class FactoryB implements Factory {public ProductA createProductA() {
return new ProductA2();
}public ProductB createProductB() {
return new ProductB2();
}
}
抽象產(chǎn)品A
package com.factory.abstractFactory;
/**
-
抽象產(chǎn)品
-
@author xiang.wei
-
@create 2018/4/8 10:42
/
public interface ProductA {
/*- 商品展示
*/
void show();
}
- 商品展示
具體產(chǎn)品A1和具體產(chǎn)品A2
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:55
*/
public class ProductA1 implements ProductA {public void show() {
System.out.println(“產(chǎn)品A1被生產(chǎn)出來”);
}
}
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:55
*/
public class ProductA2 implements ProductA {public void show() {
System.out.println(“產(chǎn)品A2被生產(chǎn)出來”);
}
}
抽象產(chǎn)品B
package com.factory.abstractFactory;
/**
-
抽象產(chǎn)品
-
@author xiang.wei
-
@create 2018/4/8 10:42
/
public interface ProductB {
/*- 商品展示
*/
void show();
}
- 商品展示
具體產(chǎn)品B1和具體產(chǎn)品B2
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:02
*/
public class ProductB1 implements ProductB {public void show() {
System.out.println(“產(chǎn)品B1被生產(chǎn)”);
}
}
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:02
*/
public class ProductB2 implements ProductB {public void show() {
System.out.println(“產(chǎn)品B2被生產(chǎn)”);
}
}
總結(jié):抽象工廠模式的角色與工廠方法模式的角色相同,可以將抽象工廠模式看成是工廠方法模式的擴展。
優(yōu)缺點
優(yōu)點
降低耦合
抽象工廠模式將具體產(chǎn)品的創(chuàng)建延遲到具體工廠的子類中,這樣將對象的創(chuàng)建封裝起來,可以減少客戶端與具體產(chǎn)品類之間的依賴,從而使系統(tǒng)耦合度低,這樣更有利于后期的維護和擴展。
更符合開-閉原則
新增一種產(chǎn)品類時,只需要增加相應(yīng)的具體產(chǎn)品類和相應(yīng)的工廠子類即可。而簡單工廠模式需要修改工廠類的判斷邏輯。
符合單一職責(zé)原則
每個具體工廠類只負責(zé)創(chuàng)建對應(yīng)的產(chǎn)品,而簡單工廠中的工廠類存在復(fù)雜的switch邏輯判斷。
不使用靜態(tài)工廠方法, 可以形成基于繼承的等級結(jié)構(gòu)
不使用靜態(tài)工廠方法, 可以形成基于繼承的等級結(jié)構(gòu),簡單工廠模式的工廠類使用靜態(tài)工廠方法。
缺點
抽象工廠模式很難支持新種類產(chǎn)品的變化。
這是因為抽象工廠接口中已經(jīng)確定了可以被創(chuàng)建的產(chǎn)品集合,如果需要添加新產(chǎn)品,此時就必須去修改抽象工廠的接口,這樣就涉及到抽象工廠類的以及所有子類的改變,這樣也就違背了“開發(fā)——封閉”原則。
對于新的產(chǎn)品族符合開-閉原則;對于新的產(chǎn)品種類不符合開-閉原則,這一特性稱為開-閉原則的傾斜性。
不管簡單工廠模式,工廠方法模式還是抽象工廠模式,他們具有相似的特性,所以他們的適用場景也是類似的。
首先,作為一種創(chuàng)建型模式,在任何需要生成復(fù)雜對象的地方。都可以使用工廠方法模式,有一點需要注意的是復(fù)雜對象適合適用工廠模式,而簡單對象,特別是只需要通過new
就可以完成創(chuàng)建的對象,無需適用工廠模式。如果使用工廠模式,就需要引入一個工廠類,會增加系統(tǒng)的復(fù)雜度。
其次,工廠模式是一種典型的解耦模式,迪米特法則在工廠模式中的表現(xiàn)的尤其明顯。例如調(diào)用者自己組裝增加依賴關(guān)系時,可以考慮試用工廠模式。將會大大降低對象之間的耦合度。
最后,由于工廠模式是依賴抽象架構(gòu)的。它把實例化產(chǎn)品的任務(wù)交由實現(xiàn)類完成,擴展性比較好,也就是,當(dāng)系統(tǒng)需要有比較好的擴展性時,可以考慮工廠模式,不同的產(chǎn)品用不同的實現(xiàn)工廠來組裝。
引用
https://www.cnblogs.com/yumo1627129/p/7197524.html
https://blog.csdn.net/qq_25551295/article/details/49837513
作者:碼農(nóng)飛哥
微信公眾號:碼農(nóng)飛哥
![](https://img-blog.csdnimg.cn/20210425103418854.jpg?)