設計模式(四)——簡單工廠模式

Elsie64N 8年前發布 | 11K 次閱讀 工廠模式

設計模式(一)——設計模式概述 中簡單介紹了設計模式以及各種設計模式的基本概念,本文主要介紹簡單工廠模式,包括其概念、用途、實現方式及存在的問題等。

概念

簡單工廠模式是屬于創建型模式,又叫做靜態工廠方法(Static Factory Method)模式。簡單工廠模式是由一個工廠對象決定創建出哪一種產品類的實例。簡單工廠模式是工廠模式家族中最簡單實用的模式,可以理解為是不同工廠模式的一個特殊實現。

值得注意的是,簡單工廠模式并不屬于23種GOF設計模式之一。但是他是抽象工廠模式,工廠方法模式的基礎,并且也有廣泛的應用。

用途

在介紹簡單工廠模式之前,我們嘗試解決以下問題:

現在我們要使用面向對象的形式定義計算器,為了實現各算法之間的解耦。主要的用到的類如下:

// 計算類的基類
public abstract class Operation {

    private double value1 = 0;
    private double value2 = 0;

    public double getValue1() {
        return value1;
    }

    public void setValue1(double value1) {
        this.value1 = value1;
    }

    public double getValue2() {
        return value2;
    }

    public void setValue2(double value2) {
        this.value2 = value2;
    }

    protected abstract double getResule();
}

//加法
public class OperationAdd extends Operation {

    @Override
    protected double getResule() {
        return getValue1() + getValue2();
    }
}

//減法
public class OperationSub extends Operation {

    @Override
    protected double getResule() {
        return getValue1() - getValue2();
    }
}

//乘法
public class OperationMul extends Operation {

    @Override
    protected double getResule() {
        return getValue1() * getValue2();
    }
}

//除法
public class OperationDiv extends Operation {

    @Override
    protected double getResule() {
        if (getValue2() != 0) {
            return getValue1() / getValue2();
        }
        throw new IllegalArgumentException("除數不能為零");
    }
}

當我想要執行加法運算時,可以使用如下代碼:

public class Main {

    public static void main(String[] args) {
        OperationAdd operationAdd = new OperationAdd();
        operationAdd.setValue1(10);
        operationAdd.setValue2(5);
        System.out.println(operationAdd.getResule());
    }
}

當我需要執行減法運算時,我就要創建一個OperationSub類。也就是說,我想要使用不同的運算的時候就要創建不同的類,并且要明確知道該類的名字。那么這種重復的創建類的工作其實可以放到一個統一的工廠類中。

簡單工廠模式有以下優點:

1、一個調用者想創建一個對象,只要知道其名稱就可以了。

2、屏蔽產品的具體實現,調用者只關心產品的接口。

實現方式

簡單工廠模式其實和他的名字一樣,很簡單。先來看看它的組成:

1) 工廠類角色:這是本模式的核心,含有一定的商業邏輯和判斷邏輯。在java中它往往由 一個具體類實現。(OperationFactory)

2) 抽象產品角色:它一般是具體產品繼承的父類或者實現的接口。在java中由接口或者抽象類來實現。(Operation)

3) 具體產品角色:工廠類所創建的對象就是此角色的實例。在java中由一個具體類實現。 來用類圖來清晰的表示下的它們之間的關系(OperationAdd\OperationSub等)

在原有類的基礎上,定義工廠類:

//工廠類
public class OperationFactory {

    public static Operation createOperation(String operation) {
        Operation oper = null;
        switch (operation) {

            case "+":
                oper = new OperationAdd();
                break;

            case "-":
                oper = new OperationSub();
                break;

            case "*":
                oper = new OperationMul();
                break;

            case "/":
                oper = new OperationDiv();
                break;
            default:
                throw new UnsupportedOperationException("不支持該操作");
                break;

        }
        return oper;
    }
}

有了工廠類之后,可以使用工廠創建對象:

Operation operationAdd = OperationFactory.createOperation("+");
operationAdd.setValue1(10);
operationAdd.setValue2(5);
System.out.println(operationAdd.getResule());

通過簡單工廠模式,該計算器的使用者不需要關系實現加法邏輯的那個類的具體名字,他只要知道該類對應的參數”+”就可以了。

簡單工廠模式存在的問題

在設計模式(一)——設計模式概述 中介紹了設計模式一般應該遵循的幾個原則。

下面我們從開閉原則(對擴展開放;對修改封閉)上來分析下簡單工廠模式。當我們需要增加一種計算時,例如開平方。這個時候我們需要先定義一個類繼承 Operation 類,其中實現平方的代碼。除此之外我們還要修改 OperationFactory 類的代碼,增加一個case。這顯然是違背開閉原則的。可想而知對于新產品的加入,工廠類是很被動的。

我們舉的例子是最簡單的情況。而在實際應用中,很可能產品是一個多層次的樹狀結構。 簡單工廠可能就不太適用了。

總結

工廠類是整個簡單工廠模式的關鍵。包含了必要的邏輯判斷,根據外界給定的信息,決定究竟應該創建哪個具體類的對象。通過使用工廠類,外界可以從直接創建具體產品對象的尷尬局面擺脫出來,僅僅需要負責“消費”對象就可以了。而不必管這些對象究竟如何創建及如何組織的。明確了各自的職責和權利,有利于整個軟件體系結構的優化。

但是

由于工廠類集中了所有實例的創建邏輯,違反了高內聚責任分配原則,將全部創建邏輯集中到了一個工廠類中;它所能創建的類只能是事先考慮到的,如果需要添加新的類,則就需要改變工廠類了。

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

這些缺點在工廠方法模式中得到了一定的解決。

文中所有代碼見 GitHub

參考資料

大話設計模式

來自: http://www.hollischuang.com/archives/1391

 本文由用戶 Elsie64N 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!