設計模式之工廠模式--慕課網筆記

第1章 工廠模式概述
1-1 工廠模式概述

什麼是設計模式?

設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、
代碼設計經驗總結。

應用設計模式有什麼好處?

設計模式是優秀的使用案例,使用設計模式可提高代碼的重用性、讓代碼更容易被他人理解、
保證代碼可靠性。

  • 工廠模式的概念
  • 工廠模式的意圖
  • 工廠模式的應用場景
  • 工廠模式的設計思想
  • 工廠模式的好處

工廠模式概率:
實例化對象,用工廠方法代替new操作。
工程模式包括工廠方法模式和抽象工廠模式。
抽象工廠模式是工廠方法模式的擴展。

工廠模式的意圖:
定義一個接口來創建對象,但是讓子類來決定哪些類需要被實例化。
工廠方法把實例化的工作推遲到子類中去實現。

什麼情況下適合工廠模式?

  • 有一組類似的對象需要創建。
  • 在編碼時不能預見需要創建哪些種類的實例。
  • 系統需要考慮擴展性,不應依賴於產品類實例如何被創建、組合和表達的細節。

項目中的狀況:
在軟件系統中經常面臨着“對象”的創建工作,由於需求的變化,這個對象可能隨之
發生改變,但它卻擁有比較穩定的接口。
爲此,我們需要提供一種封裝機制來隔離出這個易變對象的變化,從而保持系統中
其他依賴該對象的對象不隨這需求變化而變化。

基於項目狀態將代碼進行如下設計:

  • 儘量鬆耦合,一個對象的依賴對象的變化與本身無關
  • 具體產品與客戶端剝離,責任分割

客戶端–>creator–>Interface<–product1、2、3

多個產品族,就是抽象工廠模式

應用場景舉例
myotee臉萌,一款製作頭像的軟件
可以自由選擇髮型,髮色,臉型,膚色,眉毛,眼鏡,嘴巴,鼻子等。

以髮型爲例,髮型是這個大產品中的一個小部件,如果製作出了髮型,其它部分也都
相似。再有更高級的應用,不同的用戶級別需要不同的產品部件,這樣就產生了一個
產品系列。

第2章 工廠模式應用
2-1 工廠模式應用
/**
 * 髮型接口
 * @author Administrator
 *
 */
public interface HairInterface {

    /**
     * 畫圖
     */
    public void draw();
}
/**
 * 左偏分發型
 * @author Administrator
 *
 */
public class LeftHair implements HairInterface {

    @Override
    public void draw() {
        // TODO Auto-generated method stub
        System.out.println("-----------------左偏分發型-------------------");
    }

}
/**
 * 右偏分發型
 * @author Administrator
 *
 */
public class RightHair implements HairInterface {

    @Override
    public void draw() {
        // TODO Auto-generated method stub
        System.out.println("-----------------右偏分發型-------------------");
    }

}
/**
 * properties文件的讀取工具
 * @author Administrator
 *
 */
public class PropertiesReader {


    public Map<String, String> getProperties() {

        Properties props = new Properties();
        Map<String, String> map = new HashMap<String, String>();
        try {

            InputStream in = getClass().getResourceAsStream("type.properties");
            props.load(in);
            Enumeration en = props.propertyNames();
            while (en.hasMoreElements()) {
                String key = (String) en.nextElement();
                String property = props.getProperty(key);
                map.put(key, property);
//              System.out.println(key + "  " + property);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
}
left=com.sunny.project.LeftHair
right=com.sunny.project.RightHair
in=com.sunny.project.InHair
/**
 * 中分發型
 * @author Administrator
 *
 */
public class InHair implements HairInterface {

    @Override
    public void draw() {
        // TODO Auto-generated method stub
        System.out.println("-----------------中分發型-------------------");

    }

}
/**
 * 髮型工廠
 * @author Administrator
 *
 */
public class HairFactory {

    /**
     * 根據類型來創建對象
     * @param key
     * @return
     */
    public HairInterface getHair(String key){
        if("left".equals(key)){
            return new LeftHair();          
        }else if("right".equals(key)){
            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) {
            // 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 null;
    }


    /**
     * 根據類的名稱來生產對象
     * @param className
     * @return
     */
    public HairInterface getHairByClassKey(String key){

        try {
            Map<String, String> map = new PropertiesReader().getProperties();

            HairInterface hair = (HairInterface) Class.forName(map.get(key)).newInstance();
            return hair;
        } 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 null;
    }
}
第3章 抽象工廠模式應用
3-1 抽象工廠模式應用
/**
 * 男孩
 * @author Administrator
 *
 */
public interface Boy {


    public void drawMan();
}
/**
 * 女孩子
 * @author Administrator
 *
 */
public interface Girl {

    public void drawWomen();
}
/**
 * 聖誕系列的女孩
 * @author Administrator
 *
 */
public class MCGirl implements Girl {

    @Override
    public void drawWomen() {
        // TODO Auto-generated method stub
        System.out.println("-----------------聖誕系列的女孩子--------------------");
    }

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

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

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

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

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

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

}
/**
 * 人物的實現接口
 * @author Administrator
 *
 */
public interface PersonFactory {

    //男孩接口
    public Boy getBoy();
    //女孩接口
    public Girl getGirl();

}
/**
 * 聖誕系列加工廠
 * @author Administrator
 *
 */
public class MCFctory implements PersonFactory {

    @Override
    public Boy getBoy() {
        // TODO Auto-generated method stub
        return new MCBoy();
    }

    @Override
    public Girl getGirl() {
        // TODO Auto-generated method stub
        return new MCGirl();
    }

}
/**
 * 新年系列加工廠
 * @author Administrator
 *
 */
public class HNFactory implements PersonFactory {

    @Override
    public Boy getBoy() {
        // TODO Auto-generated method stub
        return new HNBoy();
    }

    @Override
    public Girl getGirl() {
        // TODO Auto-generated method stub
        return new HNGirl();
    }

}
public class SunnyTest {

    public static void main(String[] args){

//      HairInterface left = new LeftHair();
//      left.draw();

        HairFactory factory = new HairFactory();
//      HairInterface right =  factory.getHair("right");
//      right.draw();

//      HairInterface left = factory.getHairByClass("com.sunny.project.LeftHair");
//      left.draw();

//      HairInterface hair = factory.getHairByClassKey("in");
//      hair.draw();

//      PersonFactory facoty = new MCFctory();
//      Girl girl = facoty.getGirl();
//      girl.drawWomen();

        PersonFactory facoty = new HNFactory();
        Boy boy =  facoty.getBoy();
        boy.drawMan();
    }
}
第4章 總結
4-1 總結

常見應用

  • JDBC
    是一種用於執行SQL語句的Java API,可以爲多種關係數據庫提供統一訪問,它由一組用
    Java語言編寫的類和接口組成。
    客戶端–>數據操作工程–>jdbc接口<–db2/mysql/oracle/sqlserver
  • Spring BeanFactroy
    BeanFactroy,作爲Spring基礎的IoC容器,是Spring的一個Bean工廠。
    如果單從工廠模式的角度來考慮,它就是用來“生產 Bean”,然後提供給
    客戶端。

Bean的實例化過程如下:

  • 調用Bean的默認構造方法,或指定的構造方法,生成bean實例(暫稱爲instance1)
  • 如果Bean的配置文件中注入了Bean的屬性值,則在instance基礎上進行屬性注入形成
    instance2,這種注入是覆蓋性的
  • 如果Bean實現了InitializingBean接口,則調用afterPropertiesSet()方法,來改變或
    操作instance2,得到instance3
  • 如果Bean的配置文件中指定了init-method=”init”屬性,則會調用指定的初始化方法
    則在instance3的基礎上調用初始化方法init(),將對象最終初始化爲instance4;當然
    這個初始化的名字是任意的

工廠方法模式和抽象工廠模式對比

  • 工廠模式是一種極端情況的抽象工廠模式,而抽象模式可以看成是工廠模式的推廣
  • 工廠模式用來創建一個產品等級結構,而抽象工廠模式是用來創建多個產品的等級結構
  • 工廠模式只有一個抽象產品類,而抽象工廠模式有多個抽象產品類

工廠模式的實現幫助我們

  • 系統可以在不修改具體工廠角色的情況下引進新的產品
  • 客戶端不必關心對象如何創建,明確了職責
  • 更好的理解面向對象的原則 面向接口編程,而不要面向實現編程

工廠模式適用於哪些場景

  • 一個系統應當不依賴於產品類實例被創立,組成,和表示的細節。這對於所有
    形態的工廠模式都是重要的
  • 這個系統的產品有至少一個的產品族
  • 同屬於同一個產品族的產品是設計成在一起使用的。這一約束必須得在系統的設計
    中體現出來
  • 不同的產品以一系列的接口的面貌出現,從而使系統不依賴於接口實現的細節

《模式的祕密——工廠模式》視頻地址

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