1、簡單工廠模式實現計算器功能

松鼠阿濤發表於2020-10-02

簡單工廠模式實現計算機功能

作者:阿濤
CSDN部落格主頁:https://blog.csdn.net/qq_43313113

簡介

建立型模式

瞭解簡單工廠模式之前,首先要先了解下建立型模式,接下來的Java設計模式的學習,將會逐步學習建立型模式下的6種模式。

建立型模式描述如何將物件的建立和使用分離,讓使用者在使用物件時無須關心物件的建立細節,從而降低系統的耦合度,讓設計方案更易於修改和擴充套件。

在GoF設計模式中包含5種建立型模式,通常將一種非GoF設計模式——簡單工廠模式作為學習其他工廠模式的基礎。

模式名稱定義學習難度使用頻率
簡單工廠模式定義一個工廠類,它可以根據引數的不同返回不同類的例項,被建立的例項通常都具有共同的父類★★☆☆☆★★★☆☆
工廠方法模式定義一個用於建立物件的介面,但是讓子類決定將哪一個類例項化,工廠方法模式讓一個類的例項化延遲到其子類★★☆☆☆★★★★★
抽象工廠模式提供一個建立一系列相關或相互依賴物件的介面,而無須指定它們具體的類★★★★☆★★★★★
建造者模式將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以構建不同的表示★★★★☆★★☆☆☆
原型模式使用原型例項指定待建立物件的型別,並且通過複製這個原型來建立新的物件★★★☆☆★★★☆☆
單例模式確保一個類只有一個例項,並提供一個全域性訪問點來訪問這個唯一例項★☆☆☆☆★★★★☆

簡單工廠模式

概述

簡單工廠模式並不屬於GoF的23種經典設計模式,但通常將它作為學習其他工廠模式的基礎。

定義:定義一個工廠類,它可以根據引數的不同返回不同類的例項,被建立的例項通常都具有共同的父類。

由於在簡單工廠模式中用於建立例項的方法通常是靜態(static)方法,因此簡單工廠模式又被稱為靜態工廠方法模式,是一種類建立型模式。

流程

首先將需要建立的各種不同產品物件的相關程式碼封裝到不同的類中,,這些類稱為具體產品類,而將它們公共的程式碼進行抽象和提取後封裝在一個抽象產品類中,每一個具體產品類都是抽象產品類的子類;然後提供一個工廠類用於建立各種產品,在工廠類中提供一個建立產品的工廠方法,該方法可以根據所傳入的引數不同建立不同的具體產品物件;客戶端只需呼叫工廠類的工廠方法並傳入相應的引數即可得到一個產品物件。

結構

簡單工廠模式包含以下3個角色:

  1. Factory(工廠角色):工廠角色即工廠類,它是簡單工廠模式的核心,負責實現建立所有產品例項的內部邏輯;工廠類可以被外界直接呼叫,建立所需的產品物件;在工廠類中提供了靜態的工廠方法factoryMethod(),它的返回型別為抽象產品型別Product。
  2. Product(抽象產品角色):它是工廠類建立的所有物件的父類,封裝了各種產品物件的公有方法,它的引入將提高系統的靈活性,使得在工廠類中只需定義一個通用的工廠方法,因為所有建立的具體產品物件都是其子類物件。
  3. ConcreteProduct(具體產品角色):它是簡單工廠模式的建立目標,所有被建立的物件都充當這個角色的某個具體類的例項。每一個具體產品角色都繼承了抽象產品角色,需要實現在抽象產品中宣告的抽象方法。

理解

例如,現在有一家麵包店,這家麵包店就屬於簡單工廠模式下的工廠,麵包店的選單有許多產品,有面包、蛋糕、披薩,這些都是屬於抽象產品角色,只是選單上的名字,並不是實際產品。當有顧客點餐時,顧客看著選單點菜,報出的菜名就相當於是客戶端傳給工廠的引數,工廠根據引數建立出對應的具體產品物件,即麵包店根據顧客點的選單,製作出對應的食物。

類圖

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-reD1xMrx-1601638036820)(D:\臨時資料夾\img\image-20201001163254761.png)]

優點

  1. 工廠類包含必要的判斷邏輯,可以決定在什麼時候建立哪一個產品類的例項,客戶端可以免除直接建立產品物件的職責,而僅僅“消費”產品,簡單工廠模式實現了物件建立和使用的分離。
  2. 客戶端無須知道所建立的具體產品類的類名,只需要知道具體產品類所對應的引數即可,對於一些複雜的類名,通過簡單工廠模式可以在一定程度上減少使用者的記憶量。
  3. 通過引入配置檔案,可以在不修改任何客戶端程式碼的情況下更換和增加新的具體產品類,在一定程度上提高了系統的靈活性。

缺點

  1. 由於工廠類集中了所有產品的建立邏輯,職責過重,一旦不能正常工作,整個系統都要受到影響。
  2. 使用簡單工廠模式勢必會增加系統中類的個數(引入了新的工廠類),增加了系統的複雜度和理解難度。
  3. 系統擴充套件困難,一旦新增新產品就不得不修改工廠邏輯,在產品型別較多時有可能造成工廠邏輯過於複雜,不利於系統的擴充套件和維護。
  4. 簡單工廠模式由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結構。

適用環境

  1. 工廠類負責建立的物件比較少,由於建立的物件較少,不會造成工廠方法中的業務邏輯太過複雜。
  2. 客戶端只知道傳入工廠類的引數,對於如何建立物件並不關心。

練習題目

按如下類圖重新編寫四則運算的應用程式Calc2(不要在原有程式上修改)。類的內部實現可以不同,類結構必須完全相同。

在這裡插入圖片描述

原始碼

Clac2.java

import java.util.Scanner;

public class Calc2 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("請輸入運算子號:");
        String sign = scanner.next();
        System.out.print("請輸入數字1:");
        double num1 = scanner.nextDouble();
        System.out.print("請輸入數字2:");
        double num2 = scanner.nextDouble();

        Operator product = Factory.getOperator(sign);
        System.out.println(product.getResult(num1,num2));
    }
}

Factory.java

public class Factory {
    //靜態工廠方法
    public static Operator getOperator(String arg) {
        Operator product = null;
        if (arg.equalsIgnoreCase("+")) {
            product = new Add();
            //初始化設定product
        }
        else if (arg.equalsIgnoreCase("-")) {
            product = new Sub();
            //初始化設定product
        }
        else if (arg.equalsIgnoreCase("*")) {
            product = new Mul();
            //初始化設定product
        }
        else if (arg.equalsIgnoreCase("/")) {
            product = new Div();
            //初始化設定product
        }

        return product;
    }
}

Operator.java

public interface  Operator{
    public double getResult(double num1,double num2);
}

Add.java

public class Add implements Operator{
    public double getResult(double num1, double num2) {
        return num1+num2;
    }
}

Sub.java

public class Sub implements Operator{
    public double getResult(double num1, double num2) {
        return num1 - num2;
    }
}

Mul.java

public class Mul implements Operator{
    public double getResult(double num1, double num2) {
        return num1 * num2;
    }
}

Div.java

public class Div implements Operator{
    public double getResult(double num1, double num2) {
        return num1 / num2;
    }
}

作者:阿濤
CSDN部落格主頁:https://blog.csdn.net/qq_43313113
如有不對的地方,歡迎在評論區指正


相關文章