GOF23-工廠模式

引申覆習面向對象的設計的六大原則,一些設計模式中就體現了這類原則

  1. 單一職責:一個合理的類功能應該只有一個,消除耦合減少需求變化對代碼的修改

  2. 開閉原則:一個類應該對擴展開啓,對修改關閉。降低程序模塊之間的耦合度,增加擴展性

  3. 里氏替換原則:子類應該能替換基類。 能夠很好的實現功能的調整和升級,並且不影響客戶端調用

  4. 依賴倒換原則:設計依賴於抽象而不是依賴於具體化。

  5. 接口隔離原則:劃分接口應該單一細緻,讓系統容易實現重構,對接口修改時影響較少。

  6. 迪米特法則:一個類儘可能少的去了解其他對象 

這些原則其實最後的目的是爲了程序中模塊分工明確,便於升級和調整。

工廠模式:實例化對象,用工廠方法代替new操作,將實現類和對象的創建統一管理和控制,從而將調用者和實現類解耦。

工廠模式也分爲三種,簡單工廠模式(靜態工廠模式)、工廠方法模式,抽象工廠模式

一、簡單抽象模式(靜態抽象模式)

1、UML類圖

動物產品可以有Cat、Pig、Dog 客戶端來生成產品時需要與每一個具體的產品產生聯繫,比如 Animal cat = new Cat();這樣 對象的生成和控制全在客戶端client。 不便於管理,那麼我們可以將對象的生成交給第三方來管理。 客戶端需要產品 只要通知一個組件 我需要什麼對象,組件返回相應對象滿足客戶端;那麼對象的生成相對於客戶端透明, 便於統一管理。這就是簡單抽象模式。

2、產品類: Cat 、Pig、Dog實現Animal接口

package factory.simple;

public interface Animal {
    public void say();
}
package factory.simple;

public class Cat implements Animal {
    public void say() {
        System.out.println("喵喵喵");
    }
}
package factory.simple;

public class Dog implements Animal {
    public void say() {
        System.out.println("汪汪汪");
    }
}
package factory.simple;

public class Pig implements Animal {
    public void say() {
        System.out.println("哼哼哼");
    }
}

3、工廠類:SimpleFactory

package factory.simple;
public class SimpleFactory01 {
    //第一種簡單工廠模式
    public static Animal creatAnimal(String type){
        if("cat".equals(type)){
            return new Cat();
        }else if("pig".equals(type)){
            return new Pig();
        }else{
            return null;
        }
    }

    //第二種簡單工廠模式
    public static Animal creatCat(){
        return new Cat();
    }
    public static Animal creatPig(){
        return new Pig();
    }
}

4、客戶端

package factory.simple;

public class Client1 {
    public static void main(String[] args) {
        Animal cat = SimpleFactory01.creatAnimal("cat");
        cat.say();
        Animal pig = SimpleFactory01.creatAnimal("pig");
        pig.say();
        
        Animal cat2 = SimpleFactory01.creatCat();
        cat2.say();
        Animal pig2 = SimpleFactory01.creatPig();
        pig2.say();
        
    }
}

5、總結:客戶端在需要動物產品時 只需要向SimpleFactory通知需要什麼對象就能得到滿足。實現了對象的生成與統一管理交給了工廠SimpleFactory。實現了分工。

優點:簡單工廠模式實現簡單。

缺點:對於新產品的添加需要對已存在的工廠代碼修改,違反了開閉原則。

二、工廠方法模式

通過上面的建檔工廠模式,當我們需要增加一個新的產品(alpaca羊駝)時,我們需要在原工廠內增加邏輯生成新產品,這違背了開閉原則,對擴展開放,對修改關閉。這顯然不合理,那麼我們可以通過工廠方法模式來解決這個問題。 我們可以將工廠類進行拆分。將產品和工廠類一一對應,那麼我們需要增加新的產品時,只需要增加相應的產品類和工廠類就可以解決了。

1、UML類圖

2、產品類(與簡單工程類一致)

3、工廠類

package factory.method;

import factory.method.Animal;

/**
 * 工廠方法模式
 */
public interface MethodFactory {
    Animal create();
}
package factory.method;

public class CatFactory implements MethodFactory {
    public Animal create() {
        return new Cat();
    }
}
package factory.method;

public class PigFactory implements MethodFactory {
    public Animal create() {
        return new Pig();
    }
}

4、客戶端

package factory.method;

public class Client {
    public static void main(String[] args) {
        Animal cat = new CatFactory().create();
        cat.say();
        Animal pig = new PigFactory().create();
        pig.say();
    }
}

5.總結:當需要新增加其他產品時,只需要增加產品類、和產品對應的工廠類。不需要對已存在的工廠類做修改,符合的開閉原則。

優點:符合開閉原則,對擴展支持良好

缺點:增加了類,增加了類的管理

三、抽象工廠模式

工廠方法模式很好的解決了簡單工廠模式遺留下的擴展問題。但並不是工廠方法就是完美的存在這種情況:當我們需要同種產品存在差異時,比如我需要一個很肥的貓,需要一個瘦的貓。 如果使用抽象工廠方法模式,那麼需要再增加肥的 和瘦的對應的商品類 並且增加對應的工廠類。

1、UML類圖

2.產品類

package factory.abstractfactory;

public interface Animal {
    public void say();
}
package factory.abstractfactory;

public interface BigAnimal extends Animal {
}
package factory.abstractfactory;

public interface SmallAnimal extends Animal {
}
package factory.abstractfactory;

public class BigCat implements BigAnimal {
    public void say() {
        System.out.println("肥貓喵喵喵");
    }
}
package factory.abstractfactory;

public class SmallCat implements BigAnimal {
    public void say() {
        System.out.println("瘦貓嗷嗷嗷");
    }
}

3、工廠類

package factory.abstractfactory;

public interface AbstractFactory {
    public Animal createBig();
    public Animal createSmall();
}
package factory.abstractfactory;

public class CatFactory implements AbstractFactory{

    public Animal createBig() {
        return new BigCat();
    }

    public Animal createSmall() {
        return new SmallCat();
    }
}

4、客戶端

package factory.abstractfactory;

public class Client {
    public static void main(String[] args) {
        Animal bigCat = new CatFactory().createBig();
        Animal smallCat = new CatFactory().createSmall();
        bigCat.say();
        smallCat.say();
    }
}

5.總結:抽象工廠類在 工廠方法的基礎上對產品和產品的工廠進行再次的抽象分類。 抽象分爲建爲約束,那麼就只能建立類似的產品進行擴展,增加了約束條件。

總結:三種工廠類  沒有必須使用哪一種。 根據具體情況選擇使用

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章