1. 程式人生 > >23種設計模式介紹(一)---- 創建型模式

23種設計模式介紹(一)---- 創建型模式

接口 ret static 深復制 return 對象 相互 object c png

由於設計模式篇幅比較大,如果在一篇文章講完所有的設計模式的話不利於閱讀。於是我把它分為三篇文章

  • 23種設計模式介紹(一)---- 創建型模式
  • 23種設計模式介紹(二)---- 結構型模式
  • 23種設計模式介紹(三)---- 行為型模式

由於設計模式都是比較抽象的概念,所以大家一定要確保看懂類圖,而後再自己寫代碼加強記憶。

簡介

  設計模式分為三大類:

  創建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。   結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。   行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、叠代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。

  設計模式的六大原則:

原則 解釋
單一原則 (SRP) 一個類只做一件事
開放-封閉原則(OCP) 軟件實體(類、模塊、函數)可以拓展,但是不可修改
依賴倒轉原則(DIP)
A.高層模塊不應該依賴底層,兩個都應該依賴抽。B.抽象不應該依賴細節,細節依賴抽象
裏氏代換原則(LSP) 子類型必須能夠替換掉它們的父類型
迪米特法則(LoD) 如果兩個類不必直接通信,那麽這兩個類不應當發生直接的相互作用。如果其中一個類需要調用另一個類的某一個方法的話,可通過第三者發起這個調用
合成/聚合復用原則(CARP) 盡量使用合成/聚合,盡量不要使用類繼承

-----------------------------------------------------------------------------------------------------------------------------------------

  這一篇為第一篇介紹創建型模式,創建型模式一共有5種:
  • 工廠模式 
  • 抽象工廠模式
  • 單例模式
  • 構造者模式
  • 原型模式   

一、工廠模式

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

  適用:當一個類不知道它所必須創建的對象的類的時候

  類圖:

技術分享

  例子代碼:

interface IProduct{}
class ProductA implements IProduct{}
class ProductB implements IProduct{}
interface IFactory{
    public IProduct getProduct();
}
class FactoryA implements IFactory{
    public IProduct getProduct(){
        return new ProductA();
    }
}
class FactoryB implements IFactory{
    public IProduct getProduct(){
        return new ProductB();
    }
}
// 工廠方法
class Factory {
    public IProduct getProductA(){
        return new ProductA();
    }
    public IProduct getProductB(){
        return new ProductB();
    }
    public IProduct getProduct(int type){
        if (type==1){
            return new ProductA();
        }else{
            return new ProductB();
        }
    }
}
public class TestFactory {
    public static void test(){
        IFactory factory = new FactoryA();
        IProduct product =factory.getProduct();
        // 
        factory = new FactoryB();
        product =factory.getProduct();
    }
}

二、抽象工廠模式

  定義:提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類

  適用:一個系統要獨立於它的產品的創建、組合和表示時

  與工廠模式的區別:工廠模式的一個工廠接口的子類只能實例化一個產品;抽象工廠能實例多個產品

  類圖:

技術分享

  例子代碼:

// 產品1
interface
IProduct1{} class Product1A implements IProduct1{} // 擴展產品1 B系列 class Product1B implements IProduct1{} // 產品2 interface IProduct2{} class Product2A implements IProduct2{} // 擴展產品2 B系列 class Product2B implements IProduct2{} // 工廠 interface IFactory{ public IProduct1 getProduct1(); public IProduct2 getProduct2(); }; // 工廠 A ,生產A系列產品 class FactoryA implements IFactory{ public IProduct1 getProduct1(){ return new Product1A(); }; public IProduct2 getProduct2(){ return new Product2A(); }; } // 工廠 B ,生產B系列產品 class FactoryB implements IFactory{ public IProduct1 getProduct1(){ return new Product1B(); }; public IProduct2 getProduct2(){ return new Product2B(); }; } public class testAbstractFactory { public void test(){ IFactory factory = new FactoryA(); IProduct1 product1A = (IProduct1)factory.getProduct1(); IProduct2 product2A = (IProduct2)factory.getProduct2(); // 如果擴展產品系列B時,添加 FactoryB、ProductB即可,不需要修改原來代碼 factory = new FactoryB(); IProduct1 product1B = (IProduct1)factory.getProduct1(); IProduct2 product2B = (IProduct2)factory.getProduct2(); } }

三、單例模式

  定義:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

  適用:當類只能有一個實例而且客戶可以從一個眾所周知的訪問點訪問它時

  類圖:

技術分享

  例子代碼:

class Singleton {
    private static Singleton instance = null;
    // 防止被外部實例化
    private Singleton() {
    }
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
public class TestSingleton {
    public test(){
        // 獲取單例
        Singleton singleton = Singleton.getInstance();
    }
}

四、構造者模式

  定義:將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示

  適用:當創建復雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時

  類圖:

技術分享

技術分享

  例子代碼:

class Person{
    private String name;
    private String address;
    private int age;
    private int sex;
    private int height;
    private int weight;
    public void setName(String name) {this.name = name;}
    public String getName() {return name;}
    public void setAddress(String address) {this.address = address;}
    public String getAddress() {return address;}
    public void setAge(int age) {this.age = age;}
    public int getAge() {return age;}
    public void setSex(int sex) {this.sex = sex;}
    public int getSex() {return sex;}
    public void setHeight(int height) {this.height = height;}
    public int getHeight() {return height;}
    public void setWeight(int weight) {this.weight = weight;}
    public int getWeight() {return weight;}
}
class PersonBuilder{
    private Person person;
    public PersonBuilder(){
        this.person = new Person();
    }
    public PersonBuilder name(String name){
        this.person.setName(name);
        return this;
    }
    public PersonBuilder address(String address){
        this.person.setAddress(address);
        return this;
    }
    public PersonBuilder age(int age){
        this.person.setAge(age);
        return this;
    }
    public PersonBuilder sex(int sex){
        this.person.setSex(sex);
        return this;
    }
    public PersonBuilder height(int height){
        this.person.setHeight(height);
        return this;
    }
    public PersonBuilder weight(int weight){
        this.person.setWeight(weight);
        return this;
    }
}
public class TestBuilder {
    public test(){
        PersonBuilder builder = new PersonBuilder();
        Person person = builder.name("lion")
                .address("america")
                .age(18)
                .sex(2)
                .height(180)
                .weight(150);
    }
}

五、原型模式

  定義:用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象

  適用:當要實例化的類是在運行時刻指定時;或者需要創建多個對象並且這些對象內部狀態相差不大

  例子代碼:

class Car implements Cloneable{
    private int id;
    public int getId() {return id;}
    public void setId(int id) {this.id = id;}

    public Car clone(){
        try {
            return (Car)super.clone();
        }catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}
class Prototype implements Cloneable{
    private int id;
    private Car car;
    public Car getCar() {return car;}
    public void setCar(Car car) {this.car = car;}
    public int getId() {return id;}
    public void setId(int id) {this.id = id;}
    public Object clone(){
        try {
            boolean deep = true;
            if (deep){
                /**
                 * 深復制,復制出了兩輛車
                 * */
                Prototype prototype = (Prototype)super.clone();
                prototype.setCar((Car)this.car.clone());
                // 繼續復制其他引用對象
                return prototype;

            }else{
                /**
                 * 淺復制 ,是同一輛車
                 * */
                return super.clone();
            }
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}
public class TestPrototype {
    public void test(){
        Prototype p1 = new Prototype();
        p1.setCar(new Car());
        p1.setId(1);
        // 復制
        Prototype p2 = (Prototype)p1.clone();
        p2.setId(2);
    }
} 

23種設計模式介紹(一)---- 創建型模式