设计模式之一【简单的工厂设计模式】

75 阅读2分钟

简单的工厂设计模式

 

记得在刚开始学习java时候,书上有这么一个例子:用Java实现一个计算器功能。

然后自己当时代码如下(不考虑输入的符号等):

    System.out.println("请输入第一个数:");
    Scanner in = new Scanner(System.in);
    String str1 = in.next();

    System.out.println("请输入运算符号:");
    String flag = in.next();

    System.out.println("请输入第二个数:");
    String str2 = in.next();


    if(flag.equals("-")){
        System.out.println(Double.parseDouble(str1) - Double.parseDouble(str2));
    }

    if(flag.equals("/")){
        if (Double.parseDouble(str2) == 0) {
            throw new Exception("除数不能为0!");
        }else {
            System.out.println(Double.parseDouble(str1) / Double.parseDouble(str2));
        }
    }

    if(flag.equals("*")){
        System.out.println(Double.parseDouble(str1) * Double.parseDouble(str2));
    }

    if(flag.equals("+")){
        System.out.println(Double.parseDouble(str1) + Double.parseDouble(str2));
    }

}

不输入一些怪异的特殊符号运行:

功能大致上没有问题,但是现在看来也觉得没有什么大的问题。

但是考虑到扩展问题,而且现实中并不是一些加减乘除的算法。还有一些特殊比如平方运算,开方,指数,对数等!

这个时候我们需要怎么写?

我们去写的这个后面添加一个if分支,然后每次在进行扩展。这样子也可以实现,但是每次在原有的代码上继续写,每次添加运算运算符。 输入输出代码混在一起,很难维护和扩展。

 

这时候我们改怎么办?

我们想办法用上面向对象的特征,然后将输入输出和运算进行拆分。

 

首先我们定义一个参数接口:

public interface Param {

    double getResult( double d1 ,double d2);
}

然后定义需要实现的各个运算类型的对象类

Add 

public class Add implements   Param {


    @Override
    public double getResult(double d1 ,double d2){

        double result = d1 + d2 ;
        return result;
    }
}

Division

public class Division implements   Param {

    @Override
    public double getResult(double d1 ,double d2){


        if (d2 == 0)

            try {
                throw  new Exception(" is not  0 ");
            } catch (Exception e) {
                e.printStackTrace();

            }

        double result = d1 / d2 ;

        return result;
    }
}

Multi

public class Multi implements   Param {


    @Override
    public double getResult(double d1 ,double d2){

        double result = d1 * d2 ;
        return result;
    }
}

 

Subtraction

public class Subtraction implements   Param {

    @Override
    public double getResult(double d1 ,double d2){

        double result = d1 - d2 ;
        return result;
    }
}

 

定义一个实现的工厂去处理选择那个对象,然后去实现那个方法,返回哪个结果运算。

 

 

最后调用

    public static void main(String args []){


  System.out.println("请输入第一个数:");
        Scanner in = new Scanner(System.in);
        double d1 = in.nextDouble();

        System.out.println("请输入运算符号:");
        String flag = in.next();

        System.out.println("请输入第二个数:");
        double d2 = in.nextDouble();

        Param param = null;

        /* 根据运算符不一致,创建不同的对象 , 目的是为了创建对象  */
        switch (flag) {

            case "+":
                param = new Add();
                break;
            case "-":
                param = new Subtraction();
                break;
            case "/":
                param = new Division();
                break;
            case "*":
                param = new Multi();
                break;
        }



        double result = param.getResult( d1 , d2 );
        System.out.println(result);

}

 

工厂的目的是为了创建对象 , 根据子类去实例化哪个对象。

这样做的目的是为了解耦合,让代码的耦合度降低,达到易于扩展的目的。

 

 

 

这样子如果我们有别的运算,我们只需新建一个新的运算类,然后在工厂里面进行对象创建即可。