設計模式 之 簡單工廠模式-計算器程序

一、需求

設計一個簡單的計算器程序, 要求給定兩個數字及運算符號後, 輸出對應的結果。

二、 普通實現

採用 Java 語言實現。
如果只是簡單的實現的話, 可以使用下面的程序:

package com.atguigu.JavaSchema.SimpleFactory;

import java.util.Scanner;

/**
 * @ author: cybeyond
 * @ create: 2020-04-06-15:48
 */
public class Operating {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);

        try {
            System.out.println("請輸入一個整數:");
            double NumberA = scan.nextDouble();
            System.out.println("請輸入另一個整數:");
            double NumberB = scan.nextDouble();
            System.out.println("請輸入要進行的操作(+-*/):");
            String operate = scan.next();

            double result = 0;
            switch (operate) {
                case "+":
                    result = NumberA + NumberB;
                    break;
                case "-":
                    result = NumberA - NumberB;
                    break;
                case "*":
                    result = NumberA * NumberB;
                    break;
                case "/":
                    result = NumberA / NumberB;
                    break;
            }

            System.out.println(NumberA + operate + NumberB + " = " + result);
        } catch (Exception e) {
            System.out.println("Error happend: " + e.getMessage());
        }
    }
}

但是這樣的程序不易維護、不易擴展, 也不易複用。 而且一旦我想加個開方的功能, 則需要全部都進行修改、編譯。
可以使用面向對象的方式, 將程序松耦合(計算和展示分開), 使用簡單工廠模式, 將程序變得易維護、易擴展、易複用。

三、 簡單工廠模式實現

3.1 給出一個 Operation 類

package com.atguigu.JavaSchema.SimpleFactory.SchemaImplete;

/**
 * @ author: cybeyond
 * @ create: 2020-04-06-16:09
 */
public class Operation {
    double NumberA = 0;
    double NumberB = 0;

    public double getNumberA() {
        return NumberA;
    }

    public void setNumberA(double numberA) {
        NumberA = numberA;
    }

    public double getNumberB() {
        return NumberB;
    }

    public void setNumberB(double numberB) {
        NumberB = numberB;
    }

    public double getResutl() throws Exception {
        double result = 0;
        return result;
    }
}

3.2 分別新建四個類對應加減乘除的四個方法

加:

package com.atguigu.JavaSchema.SimpleFactory.SchemaImplete;

/**
 * @ author: cybeyond
 * @ create: 2020-04-06-16:27
 */
public class OperAdd extends Operation {

    @Override
    public double getResutl() {
        double result;
        result = NumberA + NumberB;
        return result;
    }
}

減:

package com.atguigu.JavaSchema.SimpleFactory.SchemaImplete;

/**
 * @ author: cybeyond
 * @ create: 2020-04-06-16:31
 */
public class OperSub extends Operation {

    @Override
    public double getResutl() {
        double result;
        result = NumberA - NumberB;
        return result;
    }
}

乘:

package com.atguigu.JavaSchema.SimpleFactory.SchemaImplete;

/**
 * @ author: cybeyond
 * @ create: 2020-04-06-16:32
 */
public class OperMul extends Operation {

    @Override
    public double getResutl() {
        double result;
        result = NumberA * NumberB;
        return result;
    }
}

除:

package com.atguigu.JavaSchema.SimpleFactory.SchemaImplete;

/**
 * @ author: cybeyond
 * @ create: 2020-04-06-16:33
 */
public class OperDiv extends Operation {

    @Override
    public double getResutl() throws Exception {
        double result;
        if (NumberB == 0) {
            throw new Exception("除數不能爲 0.");
        }
        result = NumberA / NumberB;
        return result;
    }
}

3.3 新建一個簡單工廠類:

package com.atguigu.JavaSchema.SimpleFactory.SchemaImplete;

/**
 * @ author: cybeyond
 * @ create: 2020-04-06-16:38
 */
public class OperFactory {

    public static Operation createOperate(String operate) {
        Operation oper;
        switch (operate) {
            case "+":
                oper = new OperAdd();
                break;
            case "-":
                oper = new OperSub();
                break;
            case "*":
                oper = new OperMul();
                break;
            default:
                oper = new OperDiv();
                break;
        }
        return oper;
    }
}

3.4 新建一個展示信息的類:

package com.atguigu.JavaSchema.SimpleFactory.SchemaImplete;

import java.util.Scanner;

/**
 * @ author: cybeyond
 * @ create: 2020-04-06-16:41
 */
public class ShowOper {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);

        try {
            System.out.println("請輸入一個整數:");
            double NumberA = scan.nextDouble();
            System.out.println("請輸入另一個整數:");
            double NumberB = scan.nextDouble();
            System.out.println("請輸入要進行的操作(+-*/):");
            String operate = scan.next();

            Operation oper = OperFactory.createOperate(operate);
            oper.setNumberA(NumberA);
            oper.setNumberB(NumberB);
            double result = oper.getResutl();

            System.out.println(NumberA + operate + NumberB + " = " + result);
        } catch (Exception e) {
            System.out.println("Error happend: " + e.getMessage());
        }
    }
}

這樣就完成簡單工廠模式下的計算器程序(參數判斷未做全)。
如果有需求新增一個開方的運算, 只需要修改一下OperFactory類同時新增一個子類即可, 不必將原來的所有程序都拿過來去修改, 可以避免手抖造成其他不需要修改的程序被錯誤的修改。

3.5 使用Python語言實現的版本:

使用 Python 2.7 版本可以如此實現:

class Operation(object):

    def __init__(self):
        self.num_a = 0
        self.num_b = 0

    def set_num_a(self, value):
        self.num_a = value

    def set_num_b(self, value):
        self.num_b = value

    def get_result(self):
        pass


class OperAdd(Operation):

    def get_result(self):
        return self.num_a + self.num_b


class OperSub(Operation):

    def get_result(self):
        return self.num_a - self.num_b


class OperMul(Operation):

    def get_result(self):
        return self.num_a * self.num_b


class OperDiv(Operation):

    def get_result(self):
        if self.num_b == 0:
            raise Exception("B cannot be zero.")
        return self.num_a / self.num_b


class OperFactory(object):

    @classmethod
    def create_operation(cls, operate):
        if operate == '+':
            oper = OperAdd()
        elif operate == '-':
            oper = OperSub()
        elif operate == '*':
            oper = OperMul()
        else:
            oper = OperDiv()
        return oper


class ShowInfo(object):

    @classmethod
    def run(cls):
        try:
            num_a = int(raw_input('Please input number A: '))
            num_b = int(raw_input('Please input number B: '))
            operate = raw_input('Please input operator(+ - * /): ')
            
            oper = OperFactory.create_operation(operate)
            oper.set_num_a(num_a)
            oper.set_num_b(num_b)
            result = oper.get_result()

            print '%s %s %s = %s' % (num_a, operate, num_b, result)
        except Exception as e:
            print 'Error happened: %s' % e


if __name__ == '__main__':
    ShowInfo.run()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章