設(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)飛哥