1. 程式人生 > >Java學習——工廠模式

Java學習——工廠模式

工廠設計模式

目的:將客戶端的new操作解耦到第三方(工廠類)

假設我有一天想買一個電腦,有surface pro和macbook pro我很喜歡,根據這個場景,可以設計出如下程式碼:

interface Computer{
    void printComputerType();
}
class Surface implements Computer{
    @Override
    public void printComputerType() {
        System.out.println("This is surface Pro");
    }
}
class Mac implements Computer{
    public void printComputerType(){
        System.out.println("This is macbook Pro");
    }
}
class Test{
    public static void main(String[] args) {
        Computer computer = new Surface();
        computer.printComputerType();
    }
}

假設我突然不想買這兩個了,想買一個Alienware,應該怎麼辦呢?我們需要去客戶端修改程式碼,讓客戶端支援Alienware筆記本。那麼,如何將例項化具體類的程式碼從客戶端中抽離,或者封裝起來,使它們不會干擾應用的其他部分呢?這就引入了工廠模式。

一、簡單工廠模式——用於產品個數少且且沒有家族

簡單工廠模式:專門定義一個類用來建立其它類的例項,被建立的例項通常都具有共同的父類。

在上述問題中,這裡我們相當於是建立生產電腦的工廠,客戶需要購買什麼樣的電腦,只要輸入型別編號就可以獲取該電腦。將類的例項化交給工廠,易於解耦。

import java.util.Scanner;
interface Computer{
    void printComputerType();
}
class Mac implements Computer{
    public void printComputerType(){
        System.out.println("this is Mac");
    }
}
class Surface implements Computer{
    public void printComputerType(){
        System.out.println("this is Surface");
    }
}
class Factory{
    public static Computer fun(String str)
    {
        Computer c = null;
        if(str.equals("mac")){
            c = new Mac();
        }else if(str.equals("surface")){
            c = new Surface();
        }
        return c;
    }
}
class Test{
    public static void main(String[] args) {
        System.out.println("What do you want?");
        java.util.Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        Computer c = Factory.fun(str);
        c.printComputerType();
    }
}

特點:

1.要有一個抽象產品類(介面)

2.要有多個具體產品類

3.一個工廠(new操作在此工廠中進行)——客戶端通過工廠類獲取具體例項

優點:易於實現、把類的例項化交給工廠,易於解耦

缺點:新增具體產品需要修改工廠 違反OCP開放封閉原則

二、工廠方法模式(橫向擴充套件方便)——每個產品有自己家族,家族下有很多兄弟

定義一個用來建立物件的介面,讓子類決定例項化哪一個類。

針對每個產品(產品族)提供一個工廠類,客戶端需要判斷使用哪個工廠

interface Computer{
    void printComputerType();
}
interface ComputerFactory{
    Computer createComputer();
}
class macbookComputer implements Computer{
    public void printComputerType(){
        System.out.println("This is macbook");
    }
}
class surfaceComputer implements Computer{
    public void printComputerType(){
        System.out.println("This is surface");
    }
}
class surfaceFactory implements ComputerFactory{
    public Computer createComputer(){
        return new surfaceComputer();
    }
}
class macbookFactory implements ComputerFactory{
    public Computer createComputer(){
        return new macbookComputer();
    }
}
class Test{
    public static void main(String[] args){
        ComputerFactory factory = new macbookFactory();
        Computer computer = factory.createComputer();
        computer.printComputerType();
    }
}

對於簡單工廠模式而言,建立物件的邏輯判斷放在了工廠類中,客戶不感知具體的類,但是其違背了開閉原則,如
果要增加新的具體類,就必須修改工廠類。
對於工廠方法模式而言,是通過擴充套件來新增具體類的,符合開閉原則,但是在客戶端就必須要感知到具體的工廠
類,也就是將判斷邏輯由簡單工廠的工廠類挪到客戶端。

工廠方法模式概要

  • 一個抽象產品類
  • 多個具體產品類
  • 一個抽象工廠(針對抽象產品類)
  • 多個具體工廠(每個產品家族用於自己的工廠)

優點:
1. 降低了程式碼耦合度,物件的生成交給子類去完成
2. 實現了開放封閉原則 - 每次新增子產品 不需要修改原有程式碼
缺點:
1. 增加了程式碼量,每個具體產品都需要一個具體工廠
2. 當增加抽象產品 也就是新增一個其他產品族 需要修改工廠 違背OCP

簡單工廠模式和工廠方法模式總結:

簡單工廠模式最大的優點就是工廠內有具體的邏輯去判斷生成什麼產品,將類的例項化交給了工廠,這樣當我
們需要什麼產品只需要修改工廠的呼叫而不需要去修改客戶端,對於客戶端來說降低了與具體產品的依賴
工廠方法模式是簡單工廠的擴充套件,工廠方法模式把原先簡單工廠中的實現那個類的邏輯判斷交給了客戶端,如
果像新增功能只需要修改客戶和新增具體的功能,不用去修改之前的類。

三、抽象工廠模式——多個產品線混合——提供一個建立一系列相關或相互依賴物件的介面,而無需指定它們具體的類。