設計模式之工廠模式

寫作緣由:對於一個有逼格的程序猿,23種設計模式應該不在話下,爲了擠身逼格程序猿之列,決定系統的學習設計模式

        關於設計模式(主要是思想方面)

               001.定義:

                               是一套反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結

               002.目的:

                               爲了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性

        設計模式之工廠模式:

               定義:

                       實例化對象,用工廠方法來代替new操作(創建我們需要的事物供我們使用)

               分類:

                       工廠方法模式、抽象工廠模式

               設計意圖:

                       定義一個用於創建對象的接口,讓子類決定實例化哪一些類。工廠方法使一個類的實例化延遲到其子類

               特點:

                       將創建實例的工作與使用實例的工作分離開,低耦合

               何時使用:

                       01.有一組類似的對象需要創建

                       02.編碼時不能預見那種類型的對象需要創建實例

                       03.系統需要考慮擴展性,不應依賴於產品類實例如何被創建、組合和表達的細節

               動機:

                       代碼之間實現鬆耦合,一個對象的依賴對象的變化與本身無關

                       具體產品與客戶端剝離,責任分割

               生活場景:

                      01.比如你想做一兩蘭博基尼,你只需要告訴你的工廠我需要蘭博基尼,工廠就會完成複雜的建造過程,最終把產品給你,也可以構建其他汽車,你只要告訴工長你需要什麼車即可;

       02.比如早晨起來刷牙洗臉,你用到的毛巾,你想要什麼樣的毛巾,你只需要去告訴工廠即可,它會返回你想要的毛巾,其他過程不用處理

               工廠方法模式類圖:

                      分析 ----> 客戶端下命令需要生產水果,creator就負責生產水果(利用factory生產Iproduct水果,水果下面就有很多水果:product1、product2),具體是由客戶端決定創建什麼水果



                 抽象工廠模式類圖:

                        分析 ----> 客戶端發命令,我需要什麼產品,工廠有兩個類系,他們都能創建客戶端的產品,可以理解爲家族與系列產品



               兩種的區別與聯繫:

                      分析 ----> 抽象工廠模式是工廠方法模式的擴展

                                      一個具體的工程可以生產一個對應的產品族,即工廠方法模式,多個工廠(產品族)就是抽象工廠模式



          代碼實現工廠方法模式:

                  Factory:

/**
 * 髮型工廠:生成髮型,不用客戶端顯式的調用
 */

public class HairFactory {
    /**
     * 根據類型來創建對象
     *
     * @param hair
     * @return
     */
    public HairInterface getHair(String hair) {
        if ("left".equals(hair)) {
            return new LeftHair();
        } else if ("right".equals(hair)) {
            return new RightHair();
        }
        return null;//兩種情況都不符合返回空
    }

    /**
     * 根據類名生產對象
     *
     * @param className
     * @return
     */
    public HairInterface getHairByClass(String className) {

        try {
            //利用反射生成類的名稱
            HairInterface hair = (HairInterface) Class.forName(className).newInstance();
            return hair;//獲取成功

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;//獲取失敗返回null
    }
}
 

                 產品(髮型)接口:

/**
 * 髮型接口:左偏分、右偏分等等
 */

public interface HairInterface {
    //實現了:繪製髮型
    void draw();
}

               具體的產品1(左偏分)       

/**
 * 左偏分發型
 */
public class LeftHair implements HairInterface {
    private static final String TAG = "LeftHair";

    //畫了一個左偏分發型
    @Override
    public void draw() {
        Log.i(TAG, "draw: " + "左偏分發型");
    }
}

                具體的產品2(右偏分)

/**
 * 有偏分發型
 */
public class RightHair implements HairInterface {

    private static final String TAG = "RightHair";

    //畫了一個右偏分發型
    @Override
    public void draw() {
        Log.i(TAG, "draw: " + "右偏分發型");
    }
}


                創建實例:

private void showHair() {
    // 1.0:普通方法:每次需要一個髮型都會創建一個新的hair,而且在客戶端顯式的調用,這樣的
    //      的代碼既不利於維護也不利於管理
    HairInterface left = new LeftHair();
    left.draw();

    //2.0:工廠模式創建:集中到HairFactory工廠中管理,產品的實現與客戶端分離(不用顯式的調用),
    //     現在只要告訴我需要左偏分或右偏分HairFactory就可以幫我創建
    // 缺點:每多一種髮型就要進行判斷生成對應的髮型,不能智能的根據髮型的類型幫我們創建

    HairFactory factory = new HairFactory();
    HairInterface left = factory.getHair("left");
    if (left != null) {
        left.draw();
    }

    //3.0利用類的對象創建對象:如果我們再增加發型,我們只需要增加發型的類並且告知客戶端我們有這個類,
    //我們就可以用這個類做事情
    HairFactory factory = new HairFactory();
    HairInterface left = factory.getHairByClass("com.test.okamiy.factorymode.myotee.LeftHair");//包名全路徑
    if (null != left) {
        left.draw();
    }
}

                代碼實現抽象工廠模式:

                       抽象工廠:PersonFactory

/**
 * 人物的實現接口
 */
public interface PersonFactory {

    //男孩接口
    public Boy getBoy();

    //女孩接口
    public Girl getGirl();
}


                     新年系類工廠:

/**
 * 新年系列加工廠
 */
public class HNFactory implements PersonFactory {

   @Override
   public Boy getBoy() {
      return new HNBoy();
   }

   @Override
   public Girl getGirl() {
      return new HNGirl();
   }
}

                     新年系列的具體對象(新年系列的女子

/**
 * 新年系列的女孩子
 */
public class HNGirl implements Girl {

   @Override
   public void drawWomen() {
      System.out.println("-----------------新年系列的女孩子--------------------");
   }

}
           

                    新年系列的具體對象(新年系列的男子

/**
 * 新年系列的男孩子
 */
public class HNBoy implements Boy {

   @Override
   public void drawMan() {
      System.out.println("-----------------新年系列的男孩子--------------------");
   }
}

                   聖誕系類工廠

/**
 * 聖誕系列加工廠
 */
public class MCFctory implements PersonFactory {

   @Override
   public Boy getBoy() {
      return new MCBoy();
   }

   @Override
   public Girl getGirl() {
      return new MCGirl();
   }
}

                   聖誕系列的具體對象(聖誕系列的女子

/**
 * 聖誕系列的女孩
 */
public class MCGirl implements Girl {

   @Override
   public void drawWomen() {
      System.out.println("-----------------聖誕系列的女孩--------------------");
   }
}

                    聖誕系列的具體對象(聖誕系列的男子

/**
 * 聖誕系列的男孩子
 */
public class MCBoy implements Boy {

   @Override
   public void drawMan() {
      System.out.println("-----------------聖誕系列的男孩子--------------------");
   }
}

                         女孩接口

/**
 * 女孩
 */
public interface Girl {
   public void drawWomen();
}

                          男孩接口

/**
 * 男孩
 */
public interface Boy {
   public void drawMan();
}

                         最終的測試:

private void test() {
    PersonFactory facoty = new HNFactory();
    Boy boy =  facoty.getBoy();
    boy.drawMan();
}
            打印“-----------------新年系列的男孩子--------------------”


            總結:通過以上兩組代碼做出分析

                     分析一:從兩種工廠模式對比

                            a. 工廠方法模式是一種極端的抽象工廠模式,而抽象工廠模式可以看成是工廠模式的推廣

                            b. 工廠方法模式用來創建一個產品的等級結構,而抽象工廠模式是用來創建多個產品的等級結構

                            c. 工廠方法模式只有一個抽象類,而抽象工廠模式有多個抽象產品類

                            d. 工廠模式方法是有一個抽象的父類定義的公共接口,子類負責生成具體的對象,這樣做的目的是將類的實例化操作延遲到子類當中完成

                            e. 抽象工廠模式提供一個創建一系列相關或相互依賴對象的接口,而無需指定他們具體的類,它針對的是有多個產品的等級結構,而工廠方法模式針對的是一個產品的等級結構

                     分析二:從工廠模式優點

                            a. 系統可以在不修改具體工廠角色的情況下引進新的產品

                            b. 客戶端不必關心對象的創建,明確職責

                            c. 更好的理解面向對象的原則、面向接口編程,而不是面向實現編程


                     分析三:從工廠模式使用場景

                            a. 一個系統應當不依賴於產品實例的創建、組成和表示細節,這對於所有形態的工廠模式都是很重要的

                            b. 這個系統的產品有至少一個產品族

                            c. 同屬於一個產品族的產品是設計在一起使用的,這一約束必須得在系統的設計中提現出來

                            d. 不同的產品以一系列的接口的面貌出現,從而使得系統不依賴與接口的實現細節

 

               Last:本篇參照慕課網視頻學習,有不懂的可以去慕課網看視頻學習!

           

                       歡迎探討學習,真心希望大家推薦好文共同成長!                     

發佈了39 篇原創文章 · 獲贊 30 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章