設計模式 簡單工廠 工廠 抽象工廠
1 簡單工廠模式
1.1 定義
簡單工廠模式又叫靜態工廠模式,但不屬於23種設計模式之一。
簡單來說就是有一個類,提供一個建立方法createProduct,根據接收到的值決定例項化哪個類,但是這個簡單工廠類能例項化的類必須都是同一個抽象類下的子類
1.2 實際應用場景
在JDK的類庫中廣泛使用了這個模式,比如DateFormat,可以看到根據傳入的引數不同,返回不同DateFormat類的子類
1.3 手動實現
為了便於學習,程式碼都寫在一個檔案下
public class SimpleFactory { /** * 提供一個createProduct方法,根據傳入的引數決定要建立哪個類的物件 * @param type * @return */ public static Product createProduct(String type) { if ("A".equals(type)) { return new ProductA(); } else { return new ProductB(); } } public static void main(String[] args) { Product product = SimpleFactory.createProduct("A"); product.print(); } } /** * 建立一個抽象類 宣告一個抽象方法 */ abstract class Product{ public abstract void print(); } /** * 建立抽象類的子類A 實現抽象方法 */ class ProductA extends Product{ @Override public void print() { System.out.println("產品A建立了"); } } /** * 建立抽象類的子類B 實現抽象方法 */ class ProductB extends Product{ @Override public void print() { System.out.println("產品B建立了"); } }
1.4 優缺點
- 拓展:開閉原則
程式對於拓展是開放的,對於修改是封閉的,核心觀點:拓展優於修改
優點:實現了物件的建立和使用的分離,建立完全交給專門的工廠類負責,客戶端程式設計師無需關心物件如何建立,只需要關心怎麼使用
缺點:簡單工廠模式不夠靈活,每次新增產品類就要修改工廠類的判斷邏輯,如果產品類很多,這個邏輯就會很複雜,同時修改工廠類違反了開閉原則
2 工廠模式
2.1 定義
簡單來說就是隻定義一個工廠類介面,再實現介面得到不同的子工廠類,讓子工廠類分別負責不同的產品類的建立,而這些產品類依然屬於同一個介面下不同的實現類
2.2 對比簡單工廠模式
簡單工廠模式
建立一個工廠類,每當新增一個產品類時就要修改工廠類
工廠模式
定義一個工廠介面,只給出工廠類要實現的方法,而不再負責建立物件,轉而由工廠介面的各個實現類去建立物件,每當新增一個產品類時,只需要建立一個新的工廠類
2.3 實際應用場景
最常見的集合類Collection只是一個介面,對應著就是一個工廠介面,而具體的子類比如Arraylist,實現collection介面,就是一個實現了工廠介面的工廠類。
ArrayList能建立itr的例項,而itr是Iterator的實現類,因此整個過程就是一個工廠模式的運用。
類圖如下
collection就是抽象工廠,具體工廠就是LinkedList,ArrayList,Iteratior就是抽象產品,具體產品就是ListItr和Itr,他們分別由LinkedList和ArrayList建立
2.4 手動實現
為了便於學習,將程式碼都放在一個檔案下
public class FactoryPattern {
public static void main(String[] args) {
Factory factory = new ProductAFactory();
Product product = factory.create();
product.print();
}
}
/**
* 建立產品類介面
*/
interface Product{
void print();
}
/**
* 建立產品子類A並實現介面
*/
class ProductA implements Product{
@Override
public void print() {
System.out.println("產品A被建立了");
}
}
/**
* 建立產品子類B並實現介面
*/
class ProductB implements Product{
@Override
public void print() {
System.out.println("產品B被建立了");
}
}
/**
* 建立工廠介面
*/
interface Factory{
Product create();
}
/**
* 建立工廠子類A並生產產品子類A
*/
class ProductAFactory implements Factory{
@Override
public Product create() {
return new ProductA();
}
}
/**
* 建立工廠子類B並生產產品子類B
*/
class ProductBFactory implements Factory{
@Override
public Product create() {
return new ProductB();
}
}
2.5 優缺點
優點:解決了簡單工廠模式違反開閉原則的問題
缺點:工廠模式的每一個子工廠類只能建立固定的某個產品類,每當新增產品類時,就得新增一個子工廠類
3 抽象工廠模式
3.1 定義
簡單來說就是令工廠類和產品類原本一對一的關係變成了一對多,但是如果要擴充套件產品類,那麼還是要修改工廠介面和各個子工廠類的程式碼,違反開閉原則
3.2 對比工廠模式
-
抽象工廠模式解決了工廠模式的工廠類和產品類一一對應的缺點,每個工廠類可以建立其他產品類,但是抽象工廠模式的擴充套件性和簡單工廠模式一樣差,會違反開閉原則。
-
工廠方法模式對具體產品可擴充套件,抽象工廠模式對具體產品族可擴充套件
-
抽象工廠模式只是工廠模式的一個擴充套件,如果只有一個產品類,那麼抽象工廠模式就會退化成工廠模式
3.3 手動實現
為了便於學習,將程式碼都放在一個檔案下
/**
* 抽象工廠
*/
interface AbstractFactory{
Phone createPhone(String param);
Mask createMask(String param);
}
/**
* 具體工廠 可以建立產品A和B 即工廠類和產品類實現了一對多
*/
class SuperFactory implements AbstractFactory{
@Override
public Phone createPhone(String param) {
if ("A".equals(param)) {
return new iphone();
}else{
return new huawei();
}
}
@Override
public Mask createMask(String param) {
if ("C".equals(param)){
return new N95();
}else {
return new normal();
}
}
}
/**
* 抽象產品A
*/
interface Phone{}
/**
* 具體產品A和B
*/
class iphone implements Phone{}
class huawei implements Phone{}
/**
* 抽象產品B
*/
interface Mask{}
/**
* 具體產品C和D
*/
class N95 implements Mask{}
class normal implements Mask{}