Java設計模式之工廠方法模式

giants發表於2019-01-12

定義

定義一個用於建立物件的介面,讓子類決定例項化哪個類。工廠方法使一個類的例項化延遲到其子類。

工廠方法與簡單工廠

對於簡單工廠模式,我們知道其在工廠類中包含了必要的邏輯判斷,根據不同的條件來動態例項化相關類。對於客戶端來說,這去除了與具體產品的依賴;但於此同時也帶來了一個問題:如果我們要增加產品,比如我們要生產蘋果計算機,就需要在工廠類中新增一個 Case 分支條件,這違背了開放封閉原則,對修改也開放了。而工廠方法模式就沒有違背這個開放封閉原則。如果我們需要生產蘋果電腦,則無需修改工廠類,直接建立產品即可。

角色

  • Product:抽象產品類。
  • ConcreteProduct:具體產品類,實現 Product 介面。
  • Factory:抽象工廠類,該方法返回一個 Product 型別的物件。
  • ConcreteFactory:具體工廠類,返回 ConcreteProduct 例項。

工廠方法模式的簡單實現

  1. 首先建立一個計算機的抽象產品類,其中有一個抽象方法使用者啟動計算機生產:
public abstract class Computer {
    /**
     * 產品的抽象方法,由具體的產品類實現
     */
    public abstract void start();
}
複製程式碼
  1. 接著我們建立各個品牌的計算機,其都繼承了自己的父類 Computer ,並實現了父類的 start 方法。
public class LenovoComputer extends Computer {

    @Override
    public void start() {
        System.out.println("聯想計算機啟動");
    }
}

public class HpComputer extends Computer {
    @Override
    public void start() {
        System.out.println("惠普計算機啟動");
    }
}

public class AsusComputer extends Computer {
    @Override
    public void start() {
        System.out.println("華碩計算機啟動");
    }
}
複製程式碼
  1. 建立抽象工廠類,裡面有一個 createComputer 方法,用於生產各種品牌的計算機。
public abstract class ComputerFactory {
    public abstract <T extends Computer> T createComputer(Class<T> clz);
}

複製程式碼
  1. 建立具體工廠,廣大代工廠是一個具體的工廠,其繼承抽象工廠,通過反射來生產不同廠家的計算機。
public class GDComputerFactory extends ComputerFactory {
    @Override
    public <T extends Computer> T createComputer(Class<T> clz) {
            Computer computer = null;
            String className = clz.getName();
        try {
            //通過反射來生產不同廠家的計算機
            computer = (Computer)Class.forName(className).newInstance();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) computer;
    }
}
複製程式碼
  1. 客戶端呼叫,客戶端建立 GDComputerFactory 生產各種計算機。
public class Client {
    public static void main(String[] args) {
        ComputerFactory computerFactory = new GDComputerFactory();

        LenovoComputer mLenovoComputer = computerFactory.createComputer(LenovoComputer.class);
        mLenovoComputer.start();

        HpComputer mHpComputer = computerFactory.createComputer(HpComputer.class);
        mHpComputer.start();

        AsusComputer mAsusComputer = computerFactory.createComputer(AsusComputer.class);
        mAsusComputer.start();
    }
}
複製程式碼

相關文章