設計模式-三種工廠模式

工廠模式包括:

  • 簡單工廠
  • 工廠方法
  • 抽象工廠

將實例化對象的代碼提取出來,放到一個類中統一管理和維護,達到和主項目的依賴關係的解耦。從而提升項目的擴展和維護性。工廠模式都是實現建立者和調用者分離,下面開始逐一介紹:程序員

  • 簡單工廠模式

模式UML類圖

角色分析

  • Factory:工廠角色
  • Product:抽象產品角色
  • ConcreteProduct:具體產品角色
工廠角色(Creator) 是簡單工廠模式的核心,它負責實現建立全部具體產品類的實例。工廠類能夠被外界直接調用,建立所需的產品對象。
抽象產品角色(Product) 是全部具體產品角色的父類,它負責描述全部實例所共有的公共接 口 。
具體產品角色(Concrete Product) 繼承自抽象產品角色,通常爲多個,是簡單工廠模式的建立目標。工廠類返回的都是該角色的某一具體產品。

示例程序:經過汽車工廠生產汽車(奔馳和奧迪兩種車型),消費者(客戶端)只須要與汽車工廠聯繫(依賴)

示意圖

代碼實現

package Factory;
interface Car{
    void run();
}
class Aodi implements Car{
    @Override
    public void run() {
        System.out.println("我是奧迪汽車...");
    }
}
class Benchi implements Car{
    @Override
    public void run() {
        System.out.println("我是奔馳汽車...");
    }
}
class CarFactory{
    static public Car createCar(String name) {
        Car car = null;
        if(name.equals("奧迪")) {
            car = new Aodi();
        }else if(name.equals("奔馳")) {
            car = new Benchi();
        }
        return car;
    }
}
/**
 * @author Moti
 * @Time 2019年9月21日
 */
public class Main {
    public static void main(String[] args) {
        Car car = CarFactory.createCar("奔馳");
        car.run();
    }
}

分析簡單工廠模式的優缺點

  • 優勢

工廠類是整個模式的關鍵.包含了必要的邏輯判斷,根據外界給定的信息,決定究竟應該建立哪一個具體類的對象.經過使用工廠類,外界能夠從直接建立具體產品對象的尷尬局面擺脫出來,僅僅須要負責「消費」對象就能夠了。而沒必要管這些對象究竟如何建立及如何組織的.明確了各自的職責和權利,有利於整個軟件體系結構的優化。ide

  • 缺點

因爲工廠類集中了全部實例的建立邏輯,違反了高內聚責任分配原則,將所有建立邏輯集中到了一個工廠類中;它所能建立的類只能是事先考慮到的,若是須要添加新的類,則就須要改變工廠類了。違反開閉原則 。性能

當系統中的具體產品類不斷增多時候,可能會出現要求工廠類根據不一樣條件建立不一樣實例的需求.這種對條件的判斷和對具體產品類型的判斷交錯在一塊兒,很難避免模塊功能的蔓延,對系統的維護和擴展很是不利;優化

這些缺點在工廠方法模式中獲得了必定的克服。this

  • 工廠方法模式

模式UML類圖

每個產品都有本身獨立的工廠設計

角色分析

  • 抽象產品(Product)
  • 具體產品(Concrete Product)
  • 抽象工廠(Factory)
  • 具體工廠(Concrete Factory)
抽象產品(Product) 具體產品的父類
描述具體產品的公共接口
具體產品(Concrete Product) 抽象產品的子類;工廠類建立的目標類
描述生產的具體產品
抽象工廠(Factory) 具體工廠的父類
描述具體工廠的公共接口
具體工廠(Concrete Factory) 抽象工廠的子類;被外界調用描述具體工廠;實現FactoryMethod工廠方法建立產品的實例

示例程序:經過奧迪汽車工廠或者奔馳汽車工廠生產汽車,消費者(客戶端)只須要與汽車工廠聯繫(依賴)

示意圖

實例程序UML類圖

代碼實現

1. 汽車的抽象類3d

package AbstractFactory;
/**
 * 定義汽車的抽象類
 * @author Moti
 * @Time 2019年9月27日 下午3:04:23
 */
public abstract class Car {
    public abstract void run();
}

2. 奧迪汽車類code

package AbstractFactory;
/**
 * 定義奧迪車,繼承抽象類Car實現run方法
 * @author Moti
 * @Time 2019年9月27日 下午3:06:10
 */
public class Aodi extends Car {
    @Override
    public void run() {
        System.out.println("我是奧迪車..滴滴滴..");
    }
}

3. 奔馳汽車類對象

package AbstractFactory;
/**
 * 定義奔馳車,繼承抽象類Car實現run方法
 * @author Moti
 * @Time 2019年9月27日 下午3:07:29
 */
public class Benchi extends Car {
    @Override
    public void run() {
        System.out.println("我是奔馳車..滴滴滴..");
    }
}

4. 抽象汽車工廠的接口blog

package AbstractFactory;
/**
 * 汽車工廠的接口,將具體實例的生成交給子類
 * @author Moti
 * @Time 2019年9月27日 下午3:08:35
 */
public interface CarFactory {
    Car createCar();
}

5. 奧迪汽車工廠的類,實現了抽象汽車工廠接口

package AbstractFactory;
/**
 * 定義奧迪車的工廠
 * @author Moti
 * @Time 2019年9月27日 下午3:09:53
 */
public class AodiCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Aodi();
    }
}

6. 奔馳汽車工廠的類,實現了抽象汽車工廠接口

package AbstractFactory;
/**
 * 定義奔馳車的工廠
 * @author Moti
 * @Time 2019年9月27日 下午3:10:57
 */
public class BenchiCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Benchi();
    }
}

7. 客戶端調用

package AbstractFactory;
/**
 * @author Moti
 * @Time 2019年9月27日 下午3:12:45
 */
public class Client {
    public static void main(String[] args) {
        CarFactory carFactory1 = new AodiCarFactory();
        CarFactory carFactory2 = new BenchiCarFactory();
        Car car1 = carFactory1.createCar();
        Car car2 = carFactory2.createCar();
        car1.run();
        car2.run();
    }
}

分析工廠方法模式的優缺點

  • 優勢

用戶只須要關心所需產品對應的工廠,無需關心建立細節,甚至無需知道具體產品類名;全部的具體工廠類都具備同一抽象父類;符合開閉原則,新增產品只須要添加工廠類和具體產品,無需修改代碼,擴展性好;

  • 缺點

添加一個新的產品,系統中類的個數增長,致使增長了系統的複雜性,有更多的類須要編譯和運行,會增長系統性能的開銷;因爲考慮到系統的可擴展性,須要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增長了系統的抽象性和理解難度;

  • 抽象工廠模式

前言

  1. 抽象工廠模式:定義了一個interface用於建立相關或有依賴關係的對象簇,而無需指明具體的類
  2. 抽象工廠模式能夠將簡單工廠模式和工廠方法模式進行整合。
  3. 從設計層面看,抽象工廠模式就是對簡單工廠模式的改進(或者稱爲進一步的抽象)。
  4. 將工廠抽象成兩層,AbsFactory(抽象工廠) 和 具體實現的工廠子類。程序員能夠根據建立對象類型使用對應的工廠子類。這樣將單個的簡單工廠類變成了工廠簇,更利於代碼的維護和擴展。

產品等級:產品等級結構即產品的繼承結構,如一個抽象類是電視機,其子類有海爾電視機、海信電視機、TCL電視機,則抽象電視機與具體品牌的電視機之間構成了一個產品等級結構,抽象電視機是父類,而具體品牌的電視機是其子類。

產品族:在抽象工廠模式中,產品族是指由同一個工廠生產的,位於不一樣產品等級結構中的一組產品,如海爾電器工廠生產的海爾電視機、海爾電冰箱,海爾電視機位於電視機產品等級結構中,海爾電冰箱位於電冰箱產品等級結構中,海爾電視機、海爾電冰箱構成了一個產品族。

模式UML類圖

這裏,1號工廠(ConcreteFactory1)能夠生產A,B,C三種產品(ConcreteProductA,B,C)
一樣,2號工廠也能夠生產A,B,C三種產品

那麼1號工廠生產的這三種產品構成一個產品族,2號工廠生產的這三種產品也構成一個產品族.

1號工廠生產的A產品和2號工廠生產的A產品構成一個產品等級
1號工廠生產的B產品和2號工廠生產的B產品 構成一個產品等級
1號工廠生產的C產品和2號工廠生產的C產品 構成一個產品等級

角色分析

  • 抽象產品(Product)
  • 具體產品(Concrete Product)
  • 抽象工廠(Factory)
  • 具體工廠(Concrete Factory)
抽象產品(Product) 具體產品的父類
描述具體產品的公共接口
具體產品(Concrete Product) 抽象產品的子類;工廠類建立的目標類
描述生產的具體產品
抽象工廠(Factory) 具體工廠的父類
描述具體工廠的公共接口
具體工廠(Concrete Factory) 抽象工廠的子類;被外界調用描述具體工廠;實現抽象工廠中建立產品的實例

示例程序:得到三種電子元件(RAM,CPU,Mouse),有日本工廠和中國工廠,這兩個工廠均可以生產這三種電子元件

注意:這裏日本工廠生產的全部產品構成一個產品族,中國工廠生產的全部產品也構成一個產品族,共兩個產品族.示例程序中出現了兩種RAM,兩種CPU,兩種Mouse(分別來自中國工廠和日本工廠),這些同種商品分類構成一個產品等級,也就是說有三個產品等級.

示例程序UML類圖

代碼實現

1.抽象產品和具體產品

//設備接口(產品的抽象)
public interface Device {
    String getDeviceName();
}
//RAM(具體的產品)
public class RAM implements Device {
    private String factoryName;
    public RAM(String factoryName) {
        this.factoryName = factoryName;
    }
    @Override
    public String getDeviceName() {
        return "得到"+factoryName+"生產的RAM";
    }
}
//CPU(具體的產品)
public class CPU implements Device {
    private String factoryName;
    public CPU(String factoryName) {
        this.factoryName = factoryName;
    }
    @Override
    public String getDeviceName() {
        return "得到"+factoryName+"生產的CPU";
    }
}
//Mouse(具體的產品)
public class Mouse implements Device {
    private String factoryName;
    public Mouse(String factoryName) {
        this.factoryName = factoryName;
    }
    @Override
    public String getDeviceName() {
        return "得到"+factoryName+"生產的Mouse";
    }
}

2.抽象工廠和具體工廠

//抽象工廠
public interface DeviceFactory {
    Device createCPU();
    Device createARM();
    Device createMouse();
}
//具體工廠
public class ChinaFactoy implements DeviceFactory {
    @Override
    public Device createCPU() {
        return new CPU("中國");
    }
    @Override
    public Device createARM() {
        return new RAM("中國");
    }
    @Override
    public Device createMouse() {
        return new Mouse("中國");
    }
}
//具體工廠
public class JapanFactory implements DeviceFactory{
    @Override
    public Device createCPU() {
        return new CPU("日本");
    }
    @Override
    public Device createARM() {
        return new RAM("日本");
    }
    @Override
    public Device createMouse() {
        return new Mouse("日本");
    }
}

3.客戶端Client

public class Client {
    public static void main(String[] args) {
        DeviceFactory factory = new JapanFactory();
        Device device = factory.createMouse();
        String string = device.getDeviceName();
        System.out.println(string);
    }
}

分析抽象工廠模式的優缺點

  • 優勢

分離了具體的類。客戶經過抽象接口操縱實例,產品的類名也在具體工廠的實現中被分離,它們不出如今客戶代碼中。

易於交換產品系列。一個具體工廠類只在初始化時出現一次,這使得改變一個應用的具體工廠變得很容易,只需改變具體的工廠便可使用不一樣的產品配置。

有利於產品的一致性。當一個系列的產品對象被設計成一塊兒工做時,一個應用一次只能使用同一個系列中的對象,這一點很重要,而抽象工廠很容易實現這一點。 

  • 缺點

難以支持新種類的產品。由於抽象工廠接口肯定了能夠被建立的產品集合(產品族),因此難以擴展抽象工廠以生產新種類的產品。

相關文章
相關標籤/搜索