美文网首页
设计模式——简单工厂模式

设计模式——简单工厂模式

作者: PnR | 来源:发表于2018-04-08 09:49 被阅读0次

计算器的例子

以面向过程的方式做一个简单实现

在本例子中,将通过一个简单的实现方式,做一个简单的加减乘除的计算器。

CalcSimpleImpl类

public class CalcSimpleImpl {

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

        System.out.print("请输入第一个数:");
        int firstInput = Integer.valueOf(scanner.nextLine());

        System.out.print("请输入操作符:");
        String operator = scanner.nextLine();

        System.out.print("请输入第二个数:");
        int secondInput = Integer.valueOf(scanner.nextLine());

        String result = "";
        switch (operator) {
            case "+":
                result = firstInput + secondInput + "";
                break;
            case "-":
                result = firstInput - secondInput + "";
                break;
            case "*":
                result = firstInput * secondInput + "";
                break;
            case "/":
                result = firstInput / secondInput + "";
                break;
            default:
                break;
        }

        System.out.println("计算结果:" + result);
    }
}

在上述代码中,很容易看出一些问题。

  1. 所有的输入没有做相关校验,这里我们不多说,本文的重点不在这里。

  2. 做除法的时候没有做被除数为0 的判断

  3. 代码完全面向过程操作,可维护性极低,如果说以后加需求,需要加上一个算平方跟的计算方式,那么就需要添加switch里面的case,需要定位到具体算法的位置才可以实现。


以面向对象的方式修改实现

下面开始针对上述问题进行修改(第1条暂不修改,本文针对第2、3条进行修改)

首先,我们需要一个面向对象的思维进行修改,将具体的计算方法进行封装,对调用方(main方法)进行隐藏,仅仅暴露出一个getResult方法。

Operation类

public class Operation {
    
    private String type;

    public Operation(String type) {
        this.type = type;
    }

    public String getResult(int firstInput, int secondInput) {
        String result = "";
        switch (this.type) {
            case "+":
                result = firstInput + secondInput + "";
                break;
            case "-":
                result = firstInput - secondInput + "";
                break;
            case "*":
                result = firstInput * secondInput + "";
                break;
            case "/":
                result = firstInput / secondInput + "";
                break;
            default:
                break;
        }
        return result;
    }
}

CalculatorOop类

public class CalculatorOop {

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

        System.out.print("请输入第一个数:");
        int firstInput = Integer.valueOf(scanner.nextLine());

        System.out.print("请输入操作符:");
        String operator = scanner.nextLine();

        System.out.print("请输入第二个数:");
        int secondInput = Integer.valueOf(scanner.nextLine());

        Operation operation = new Operation(operator);
        System.out.println("计算结果:" + operation.getResult(firstInput, secondInput));
    }
}

经过上面的修改之后,我们的代码具备了面向对象的部分特性。
但是仍然不能算是一个优秀的代码,当我们需要新增某种操作符的运算时,我们需要对Operation类中的switch进行修改,存在更改到其他运算符的实现的风险。


使用简单工厂模式进行修改

针对简单实现中的第3条问题,在本例中,各个操作符算法之间是相互独立的。
而具体的运算算法的使用,由使用方的传入值所决定,我们可以进行如下的修改。

定义一个Operator操作接口,接口中有一个getResult方法,每一种运算操作都各自实现它。
而用户在使用时,只需要通过该接口进行操作,无需关心内部如何实现。
再定义一个OperatorFactory类,根据不同的输入值,获取不同的Operator操作实例。

OperatorFactory类

public class OperatorFactory {

    public static Operator getOperator(String type) {
        Operator operator = null;
        switch (type) {
            case "+":
                operator = new OperatorAdd();
                break;
            case "-":
                operator = new OperatorSub();
                break;
            case "*":
                operator = new OperatorMulti();
                break;
            case "/":
                operator = new OperatorDiv();
                break;
            default:
                break;
        }

        // 可能会存在为没有定义的操作符,使得operator为null,但是不在本次文章的重点中

        return operator;
    }
}

Operator接口

public interface Operator {

    String getResult(int firstInput, int secondInput);
}

四种运算操作类

public class OperatorAdd implements Operator {
    public String getResult(int firstInput, int secondInput) {
        return firstInput + secondInput + "";
    }
}
public class OperatorSub implements Operator {
    public String getResult(int firstInput, int secondInput) {
        return firstInput - secondInput + "";
    }

}
public class OperatorMulti implements Operator {
    public String getResult(int firstInput, int secondInput) {
        return firstInput * secondInput + "";
    }
}
public class OperatorMulti implements Operator {
    public String getResult(int firstInput, int secondInput) {
        return firstInput * secondInput + "";
    }
}

CalculatorMain类

public class CalculatorMain {

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

        System.out.print("请输入第一个数:");
        int firstInput = Integer.valueOf(scanner.nextLine());

        System.out.print("请输入操作符:");
        String operatorInput = scanner.nextLine();

        System.out.print("请输入第二个数:");
        int secondInput = Integer.valueOf(scanner.nextLine());

        Operator operator = OperatorFactory.getOperator(operatorInput);
        System.out.println("计算结果:" + operator.getResult(firstInput, secondInput));
    }
}

总结

好,至此一个简单工厂模式的计算器实现方法就编写完成了。
当我们需要新增一个新的操作符算法时,只需要新增加一个类,并在操作符工厂中,添加上对应的返回类型即可,将具体算法对客户端隐藏,也对工厂类隐藏,具体的运算算法只对各个操作符开放。

相关文章

  • 设计模式-工厂模式

    设计模式1 设计模式2 工厂模式 工厂模式可简单的分为三类:简单工厂,工厂方法,抽象工厂 简单工厂模式 定义 简单...

  • 设计模式一、单例模式

    系列传送门设计模式一、单例模式设计模式二、简单工厂模式设计模式三、工厂模式设计模式四、抽象工厂模式 简单单例(推荐...

  • 设计模式四、抽象工厂模式

    系列传送门设计模式一、单例模式设计模式二、简单工厂模式设计模式三、工厂模式设计模式四、抽象工厂模式 抽象工厂模式 ...

  • 设计模式三、工厂模式

    系列传送门设计模式一、单例模式设计模式二、简单工厂模式设计模式三、工厂模式设计模式四、抽象工厂模式 工厂模式 在一...

  • 设计模式

    设计模式(视频总结) [TOC] 一、简单工厂模式(Simple Factory) 简单工厂模式: 简单工厂模式属...

  • iOS设计模式-工厂模式

    工厂模式分为简单工厂模式,工厂模式、抽象工厂模式三类。 简单工厂模式 1. 定义 简单工厂模式并不是常用的设计模式...

  • Android设计模式:工厂设计模式

    目录 简单工厂模式工厂方法模式抽象工厂模式 简单工厂模式 简单工厂模式是所有工厂模式的基础,不属于23种设计模式范...

  • 相近设计模式比较

    设计模式干货: 简单工厂模式 vs. 工厂模式 vs. 抽象工厂模式简单工厂和工厂模式区别? 简单工厂没有多个子类...

  • 三、创建型模型

    简单工厂模式 工厂方法模式 抽象工厂模式 单例模式 1.简单工厂模式 简单工厂模式并不属于23种设计模式。 不难看...

  • 简单工厂模式

    Android进阶之设计模式 简单工厂模式 简单工厂模式(又叫作静态工厂方法模式), 其属于创建型设计模式,但并不...

网友评论

      本文标题:设计模式——简单工厂模式

      本文链接:https://www.haomeiwen.com/subject/hyhphftx.html