1. 程式人生 > >走進設計模式的世界4:我不是你,但是大家都把我當成你-工廠模式和抽象工廠模式

走進設計模式的世界4:我不是你,但是大家都把我當成你-工廠模式和抽象工廠模式

工廠模式和抽象工廠模式:

工廠方法模式:定義了一個建立物件的介面,但由子類決定要例項化的類是哪一個。工廠方法讓類把例項化推遲到之類。

抽象工廠模式:提供一個介面,用於建立相關或以來物件的家族,而不需要明確指定具體類。

解釋:工廠方法使用繼承把物件的建立交給之類,子類實現工廠方法來建立物件。抽象工廠使用物件的組合:物件的建立被實現在工廠介面所暴露出來的方法中。所有工廠模式都通過減少應用程式和具體類間的依賴促進鬆耦合。工廠方法允許類將例項化延遲到子類進行。抽象工廠建立相關的物件家族,而不需要依賴他們的具體類。依賴倒置原則,指導我們避免依賴具體型別,儘量依賴抽象。 

設計原則:依賴抽象,不要依賴具體類。

以一個餃子店的業務為例。通過對不同業務的整合,分別完成工廠模式和抽象工廠模式。

以下是針對製作不同的餃子進行的工廠模式的設計。

/**

     這是一個餃子的工廠父類,用於餃子的建立
   
**/

public abstract JiaoZiFactory{

    /**
        生成餃子
    **/
    public orderJiaoZi(){
        // 做餡料
        doFillings();
        // 包餃子
        makeJiaoZi();   
        // 煮餃子
        boilingJiaoZi();
    }
    
    /**
    
        做餡料(抽象,交由子類實現)

    **/
    public JiaoZi doFillings();
    
    /**

        包餃子
    
    **/
    public JiaoZi makeJiaoZi(){
        System.out.println("餃子包好了");
    }

    /**

        煮餃子

    **/
    public JiaoZi boilingJiaoZi(){
        System.out.println("餃子煮好了,上菜。");
    }


}

/**

    餃子類的基類

**/
public class JiaoZi {
    private String[] fillings();
}


/**

    韭菜雞蛋餃子

**/
public class JiuCaiJiDanJiaoZi{
    
}

/**

    韭菜蝦仁餃子

**/
public class JiuCaiXiaRenJiaoZi{
    
}

/**
    牛肉餃子
**/
public class NiuRouJiaoZi{

}

/**

    韭菜雞蛋餃子工廠

**/
public JiuCaiJiDanJiaoZiFactory extends JiaoZiFactory{
     public JiaoZi doFillings(){
            fillings.add("韭菜");
            fillings.add("雞蛋");
     }
}

/**

    韭菜蝦仁餃子工廠

**/
public JiuCaiXiaRenFactory extends JiaoZiFactory{
      public JiaoZi doFillings(){
            fillings.add("韭菜");
            fillings.add("蝦仁");
      }
}


/**

    牛肉餃子工廠

**/
public NiuRouFactory extends JiaoZiFactory{
      public JiaoZi doFillings(){
            fillings.add("牛肉");
            fillings.add("洋蔥");
      }
}


public class Test{
       public static void main(String[]args){
            JiaoZiFactory factory = new  NiuRouFactory();
            factory.orderJiaoZi();
       }
}

以下是針對餃子原材料進行的抽象工廠的設計。

/**
    製作餃子需要2種原材料
    皮/餡料
    下面是餃子的工廠類設計
**/

public class JiaoZiFactory{

    // 把原料工廠當作一個屬性,提供介面 利用組合的方式
    private YuanLiaoFactory yuanLiaoFactory;
    // 工廠的建立指定不同的原料工廠
    public JiaoZiFactory (YuanLiaoFactory yuanliaoFactory){
        this.yuanLiaoFactory = yuanLiaoFactory;
    }
    // 獲取餃子
    public JiaoZi orderJiaozi(){
        Jiaozi jiaozi  = new Jiaozi();
        jiaozi = yuanLiaoFactory.createPi();
        jiaozi = yuanLiaoFactory.createXian();
        return jiaozi;
    }
}

/**

    製作餃子原料的工廠

**/
public interface yuanLiaoFactory(){
    // 製造皮的方法
    JiaoZi createPi(Jiaozi jiaozi);
    // 製造餡料的方法
    JiaoZi createXian(Jiaozi jiaozi);
}

/**

    南方餃子工廠

**/
public class NanJiaoZiFactory(){
       
    public JiaoZi createPi(Jiaozi jiaozi){
        jiaozi.setPi("南方餃子皮");
    }

    public JiaoZi createXian(Jiaozi jiaozi){
        jiaozi.setXian("南方餃子餡料");
    }
}

/**

    北方餃子工廠

**/
public class BeiJiaoZiFactory(){
      public JiaoZi createPi(Jiaozi jiaozi){
        jiaozi.setPi("北方餃子皮");
    }

    public JiaoZi createXian(Jiaozi jiaozi){
        jiaozi.setXian("北方餃子餡料");
    }
}

/**

    餃子實體類

**/
public class JiaoZi{
    // 皮
    private String Pi;
    // 餡料
    private String Xian;

    // 省略get,set
}

public class Test{
    public static void main(String[]agrs){
        // 餃子工廠(南餃子原料)
        JiaoZiFactory factory = new JiaoZiFactory(new NanJiaoZiFactory());
        // 南餃子
        JiaoZi jiaozi1 = factory.orderJiaozi();
        // 更換原料工廠(北餃子原料)
        factory  =  new JiaoZiFactory(new BeiJiaoZiFactory());
        // 北餃子
        JiaoZi jiaozi2 = factory.orderJiaozi();
    }
}

總結:雖然工廠模式和抽象工廠模式有很多類似之處。都是為了將物件解耦。工廠模式使用的是繼承的方式,實現物件的解耦,而抽象工廠模式是使用組合的方式進行物件的解耦。工廠模式適用於某個產品,而抽象工廠適用於某個產品家族,他們還是有很多區別的。