設(shè)計模式之工廠模式總結(jié)

1. 工廠方法模式

使用場景

  1. 工廠方法模式是new一個對象的替代品,所以在所有需要生成對象的地方都可以使用,到那時需要慎重考慮是否要增加一個工廠類進行管理,增加代碼的復(fù)雜度。
  2. 需要靈活的、可擴展的框架時,可以考慮采用工廠方法模式。
  3. 工廠方法模式可以用在異構(gòu)項目中。
  4. 可以使用在測試驅(qū)動開發(fā)的框架下。

定義

定義一個用于創(chuàng)建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。
下面是工廠方法模式的通用類圖

通用類圖

優(yōu)點

  • 良好的封裝性,代碼結(jié)構(gòu)清晰
    一個對象創(chuàng)建是有條件約束的,如一個調(diào)用者需要一個具體的產(chǎn)品對象,只要知道這個產(chǎn)品的類名(或約束字符串)就可以了,不用知道創(chuàng)建對象的艱辛過程,降低模塊間的耦合。
  • 工廠方法模式的擴展性非常優(yōu)秀
    在增加產(chǎn)品類的情況下,只要適當?shù)匦薷木唧w的工廠類或擴展一個工廠類,就可以完成“擁抱變化”。
  • 屏蔽產(chǎn)品類
    這一點非常重要,產(chǎn)品類的實現(xiàn)如何變化,調(diào)用者都不需要關(guān)系,它只需要關(guān)心產(chǎn)品的接口,只要接口保持不變,系統(tǒng)中的上層模塊就不要發(fā)生變化。因為產(chǎn)品類的實例化工作是由工廠類負責的,一個產(chǎn)品對象具體由哪一個產(chǎn)品生成是由工廠類決定的。
  • 工廠方法模式是典型的解耦框架
    高層模塊只需要知道產(chǎn)品的抽象類,其他的實現(xiàn)類都不用關(guān)心,符合迪米特法則,我不需要的就不要去交流;也符合依賴倒置原則,只依賴產(chǎn)品類的抽象;當然也符合里氏替換原則,使用產(chǎn)品子類替換父類也沒問題。

具體實現(xiàn)

  • 抽象產(chǎn)品類
/**
 * 抽象產(chǎn)品類
 *
 */
public abstract class Product {
 
    // 產(chǎn)品類的公共方法
    public void method1() {
        // 業(yè)務(wù)處理邏輯
        System.out.println("這是所有產(chǎn)品共有的方法!");
    }
     
    // 抽象方法
    public abstract void method2();
     
}
  • 具體產(chǎn)品類

具體產(chǎn)品1

/**
 * 具體產(chǎn)品類1
 * 
 */
public class ConcreteProduct1 extends Product {

    @Override
    public void method2() {
        System.out.println("產(chǎn)生了具體產(chǎn)品一!");

    }

}

具體產(chǎn)品2

/**
 * 具體產(chǎn)品類2
 * 
 */
public class ConcreteProduct2 extends Product {

    @Override
    public void method2() {
        System.out.println("產(chǎn)生了具體產(chǎn)品二!");

    }

}
  • 抽象工廠類
/**
 * 抽象工廠類
 *
 */
public abstract class Creator {
 
    /**
     * 創(chuàng)建一個產(chǎn)品對象,其輸入?yún)?shù)類型可以自行設(shè)置
     * 通常為String、Enum、Class等,當然也可以為空
     * @param <T>
     * @param c
     * @return
     */
    public abstract <T extends Product> T createProduct(Class<T> c);
     
}
  • 具體工廠類
/**
 * 具體工廠類
 * 
 */
public class ConcreteCreator extends Creator {

    @Override
    public <T extends Product> T createProduct(Class<T> c) {
        Product product = null;
        try {
            product = (Product) Class.forName(c.getName()).newInstance();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return (T) product;
    }

}
  • 測試類
/**
 * 客戶類
 * 
 */
public class testCreator {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        Creator creator = new ConcreteCreator();
        Product product1 = creator.createProduct(ConcreteProduct1.class);
        Product product2 = creator.createProduct(ConcreteProduct2.class);
        /*
         * 繼續(xù)業(yè)務(wù)處理
         */
        product1.method1();
        product1.method2();
        product2.method1();
        product2.method2();
    }
 
}

2. 抽象工廠模式

使用場景

一個對象族(或是一組沒有任何關(guān)系的對象)都有相同的約束,則可以使用抽象工廠模式。

定義

為創(chuàng)建一組相關(guān)或相互依賴的對象提供一個接口,而且無需指定它們的具體類。
抽象工廠模式是工廠方法模式的升級版本,在有多個業(yè)務(wù)品種、業(yè)務(wù)分類時,通過抽象工廠模式產(chǎn)生需要的對象是一種非常好的解決方式。

通用類圖如下:


抽象工廠類圖

優(yōu)缺點

優(yōu)點:

  • 封裝性。
    每個產(chǎn)品的實現(xiàn)類不是高層模塊要關(guān)心的,高層模塊只關(guān)心抽象和接口,不關(guān)心對象是如何創(chuàng)建出來的。
  • 產(chǎn)品族內(nèi)的約束為非公開狀態(tài)。
    具體的產(chǎn)品族內(nèi)的約束是在工廠內(nèi)實現(xiàn)的。

缺點:

  • 抽象工廠模式的最大缺點就是產(chǎn)品族擴展非常困難。
    例如增加產(chǎn)品C,也就是說產(chǎn)品家族由原來2個增加到3個,抽象類AbstractFactory要增加一個方法createProductC(),然后兩個實現(xiàn)類都要修改。

具體實現(xiàn)

  • 抽象產(chǎn)品類

抽象產(chǎn)品類A

/**
 * 抽象產(chǎn)品類A
 *
 */
public abstract class AbstractProductA {
    public void shareMethod(){
        System.out.println("這是共享的產(chǎn)品A方法!");
    }
    
    public abstract void doSomething();
}

抽象產(chǎn)品類B

/**
 * 抽象產(chǎn)品類B
 *
 */
public abstract class AbstractProductB {
    public void shareMethod(){
        System.out.println("這是共享的產(chǎn)品B方法!");
    }
    
    public abstract void doSomething();
}
  • 具體產(chǎn)品類

具體產(chǎn)品A1

/**
 * 具體產(chǎn)品類A1
 * 
 */
public class ProductA1 extends AbstractProductA {

    @Override
    public void doSomething() {
        System.out.println("這是產(chǎn)品A1");

    }

}

具體產(chǎn)品A2

/**
 * 具體產(chǎn)品類A2
 * 
 */
public class ProductA2 extends AbstractProductA {

    @Override
    public void doSomething() {
        System.out.println("這是產(chǎn)品A2");

    }

}

具體產(chǎn)品B1

/**
 * 具體產(chǎn)品類B1
 * 
 */
public class ProductB1 extends AbstractProductB {

    @Override
    public void doSomething() {
        System.out.println("這是產(chǎn)品B1");

    }

}

具體產(chǎn)品B2

/**
 * 具體產(chǎn)品類B2
 * 
 */
public class ProductB2 extends AbstractProductB {

    @Override
    public void doSomething() {
        System.out.println("這是產(chǎn)品B2");

    }

}
  • 抽象工廠類
/**
 * 抽象工廠類
 *
 */
public abstract class AbstractFactory {
    
    public abstract AbstractProductA createProductA();
    
    public abstract AbstractProductB createProductB();

}
  • 具體工廠類

具體工廠類1(產(chǎn)生X1系列產(chǎn)品)

/**
 * 具體工廠類1
 * 
 */
public class Factory1 extends AbstractFactory {

    @Override
    public AbstractProductA createProductA() {
        // TODO Auto-generated method stub
        return new ProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        // TODO Auto-generated method stub
        return new ProductB1();
    }

}

具體工廠類2(產(chǎn)生X2系列產(chǎn)品)

/**
 * 具體工廠類2
 * 
 */
public class Factory2 extends AbstractFactory {

    @Override
    public AbstractProductA createProductA() {
        // TODO Auto-generated method stub
        return new ProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        // TODO Auto-generated method stub
        return new ProductB2();
    }

}
  • 測試類
/**
 * 客戶類
 * 
 */
public class testAbstractFactory {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        // 定義出兩個工廠
        AbstractFactory factory1 = new Factory1();
        AbstractFactory factory2 = new Factory2();
 
        // 產(chǎn)生A1對象
        AbstractProductA a1 = factory1.createProductA();
 
        // 產(chǎn)生A2對象
        AbstractProductA a2 = factory2.createProductA();
 
        // 產(chǎn)生B1對象
        AbstractProductB b1 = factory1.createProductB();
 
        // 產(chǎn)生B2對象
        AbstractProductB b2 = factory2.createProductB();
 
        // 業(yè)務(wù)處理
        a1.shareMethod();
        a1.doSomething();
        a2.shareMethod();
        a2.doSomething();
        b1.shareMethod();
        b1.doSomething();
        b2.shareMethod();
        b2.doSomething();
    }
 
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容