设计模式-简单工厂

本文介绍了一种使用面向对象编程和简单工厂模式设计计算器的方法,通过将运算符封装成独立的类,提高了程序的扩展性和灵活性。文章详细展示了如何创建抽象基类Operation以及具体运算符子类,并利用简单工厂模式根据用户输入的运算符动态创建对应的运算对象。

假设有这么一道题,要用一门面向对象的语言实现一个计算器,用户输入两个数和运算符,返回相应的结果。大部分同学应该都会觉得很简单,十分钟不到就能写出来不错的代码。比如:

import java.util.Scanner;
public class main {
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
       String oper;
       double number1,number2;
        System.out.println("请输入运算符");
        oper = sc.nextLine();
        System.out.println("请输入第一个数");
        number1 = sc.nextDouble();
        System.out.println("请输入第二个数");
        number2 = sc.nextDouble();
        double result = 0;
        switch (oper){
            case "+":
                result=number1+number2;break;
            case "-":
                result=number1-number2;break;
            case "*":
                result=number1*number2;break;
            case "/":
                if(Math.abs(number2-0.0D)<1e-10){
                    System.out.println("除数不能为0!");
                    return;
                }
                result=number1/number2;
                break;
        }
        System.out.println(result);
    }
}

但是,如果还需要处理开根号,是不是就要再加一个case,而且如果在加的时候不小心把别的case给改动了,就会引起程序的错乱,无法得到正常的结果。这就说明这个程序扩展性、灵活性差。另外结果的显示和运算的处理都在同一个类下,耦合性低,不易修改。

因此,需要引入简单工厂模式。

简单工厂模式:定义一个Factory类,可以根据参数的不同返回不同类的实例,被创建的实例通常有共同的父类。

我们需要将每个运算符独自封装成一个类,继承自Operation父类,每次修改只需修改运算符类中的内容,添加运算符的话也只需新建一个子类即可。

子类通过重写getResult方法进行计算。

同时将运算与结果展示分开,在用户输入的类调用运算程序,再将得到的结果进行显示。

首先编写Operation类及每个运算符子类

/**
 * @Author: Bhy
 * @Date: 2018/11/16
 */
public abstract class Operation {
    double numberA;
    double numberB;
    abstract double getResult() throws Exception;
}

class OperationAdd extends Operation{
    @Override
    double getResult() {
        return numberA + numberB;
    }
}

class OperationSub extends Operation{
    @Override
    double getResult() {
        return numberA - numberB;
    }
}

class OperationMul extends Operation{
    @Override
    double getResult() {
        return numberA * numberB;
    }
}

class OperationDiv extends Operation {
    @Override
    double getResult() throws Exception{
        if(Math.abs(numberA-0.0D)<1e-10){
            throw new Exception("被除数不能为0");
        }
        else{
            return numberA / numberB;
        }
    }
}

创建简单工厂类,能够通过用户输入的运算符返回对应的运算符子类。

/**
 * @Author: Bhy
 * @Date: 2018/11/16
 */
public class OperationFactory {
    //根据输入的运算符返回对应的运算函数
    public static Operation createOperate(String operate){
        Operation operation = null;
        switch (operate){
            case "+":
                operation =  new OperationAdd();break;
            case "-":
                operation = new OperationSub();break;
            case "*":
                operation = new OperationMul();break;
            case "/":
                operation = new OperationDiv();break;
        }
        return operation;
    }
}

在主函数用调用简单工厂类,得到运算结果并输出。

import java.util.Scanner;

/**
 * @Author: Bhy
 * @Date: 2018/11/16
 */
public class main {
    public static void main(String args[]){
         Scanner sc = new Scanner(System.in);
         String operate;
         System.out.println("请输入运算符");
         operate = sc.nextLine();
         Operation operation = OperationFactory.createOperate(operate);
         System.out.println("请输入第一个数");
         operation.numberA = sc.nextDouble();
         System.out.println("请输入第二个数");
         operation.numberB = sc.nextDouble();
         try{
            System.out.println(operation.getResult());
         }catch (Exception ex) {
             System.out.println("输入有误,请检查");
         }
    }
}

至此,这个计算器就有了良好的维护性、扩展性和灵活性。当需要加入新的运算符时,只需要编写新的运算符子类并在简单工厂类中添加一个case即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值