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

简单工厂模式

工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类。也就是说工厂提供不同的产品,可以根据具体的需求来从工厂中拿出相应的产品

通过一个简单的例子,来认识这种设计模式

下面是一道编程题:

用java实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果

看到这道题的第一反应,肯定是从控制台获取三个参数,两个数字,一个运算符,判断运算符号,根据运算符号来算出运算结果

实现代码 V 1.0

package Factory;

import java.io.Console;
import java.util.Scanner;

public class Factory_v_1 {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        System.out.println("请输入数字A:");
        String strNumberA = input.nextLine();
        System.out.println("请选择运算符号(+、-、*、/):");
        String strOperate = input.nextLine();
        System.out.println("请输入数字B:");
        String strNumberB = input.nextLine();
        String strResult="";
        if (strOperate=="+")
            strResult= String.valueOf(Double.parseDouble(strNumberA)+Double.parseDouble(strNumberB));
        if (strOperate=="-")
            strResult= String.valueOf(Double.parseDouble(strNumberA)-Double.parseDouble(strNumberB));
        if (strOperate=="*")
            strResult= String.valueOf(Double.parseDouble(strNumberA)*Double.parseDouble(strNumberB));
        if (strOperate=="/")
            strResult= String.valueOf(Double.parseDouble(strNumberA)/Double.parseDouble(strNumberB));

        System.out.println("结果是:"+strResult);

    }
}

上面这段代码虽然能够计算出算式结果,但是却存在着几个问题:

1. 判断语句,每个判断条件都需要判断,然而实际情况下,只需要判断一次,这样做会多做一些无用功

2. 除数为0的情况需要特别考虑,这里没有注意这一点,会出现异常

所以需要对代码进行改进,下面是改进代码

实现代码 V 2.0

package Factory;

import java.util.Scanner;

public class Factory_v_2 {
    public static void main(String[] args) {
        try{
            Scanner input=new Scanner(System.in);
            System.out.println("请输入数字A:");
            String strNumberA = input.nextLine();
            System.out.println("请选择运算符号(+、-、*、/):");
            String strOperate = input.nextLine();
            System.out.println("请输入数字B:");
            String strNumberB = input.nextLine();
            String strResult="";
            switch (strOperate)
            {
                case "+":
                    strResult= String.valueOf(Double.parseDouble(strNumberA)+Double.parseDouble(strNumberB));
                    break;
                case "-":
                    strResult= String.valueOf(Double.parseDouble(strNumberA)-Double.parseDouble(strNumberB));
                    break;
                case "*":
                    strResult= String.valueOf(Double.parseDouble(strNumberA)*Double.parseDouble(strNumberB));
                    break;
                case "/":
                    if (strNumberB!="0"){
                        strResult= String.valueOf(Double.parseDouble(strNumberA)/Double.parseDouble(strNumberB));

                    }else
                        strResult="除数不能为0";
                    break;

            }
            System.out.println("结果是:"+strResult);
        }
        catch (Exception ex){
            System.out.println("您的输入有错:"+ex.getMessage());
        }
        
    }
}

上面代码解决了上面两个问题,但是这样的代码却不能复用,应该采用面向对象的编程方法来解决该问题

面向对象的编程方法有以下的特点:

可维护、可复用、可扩展、灵活性好,采用封装、继承、多台把程序的耦合度降低,并且可以采用设计模式将程序变得更加灵活

对上面代码进行运算类的封装,将业务逻辑和界面逻辑分开,实现代码 v3.0

Operation类

package Factory;

public class Factory_Operation {
    public static String GetResult(double numberA,double numberB,String operate)
    {
        String result="";
        switch (operate)
        {
            case "+":
                result= String.valueOf(numberA+numberB);
                break;
            case "-":
                result= String.valueOf(numberA-numberB);
                break;
            case "*":
                result= String.valueOf(numberA*numberB);
                break;
            case "/":
                if (numberB!=0)
                    result= String.valueOf(numberA/numberB);
                else
                    result="除数不能为0";
                break;
        }
        return result;
    }
}

调用Operation

package Factory;

import java.util.Scanner;

public class Factory_Interface {
    public static void main(String[] args) {
        try{
            Scanner input=new Scanner(System.in);
            System.out.println("请输入数字A:");
            String strNumberA = input.nextLine();
            System.out.println("请选择运算符号(+、-、*、/):");
            String strOperate = input.nextLine();
            System.out.println("请输入数字B:");
            String strNumberB = input.nextLine();
            String strResult="";
            strResult = Factory_Operation.GetResult(Double.parseDouble(strNumberA), Double.parseDouble(strNumberB), strOperate);
            System.out.println("结果是:"+strResult);
        }
        catch (Exception ex){
            System.out.println("您输入的有错:"+ex.getMessage());
        }

    }
}

但是这个时候如果要增加计算器的一些功能该怎么办呢?

第一反应无疑是在Operation类里面的switch分支里面添加一个开根分支

但是这样会存在很大问题,咱要添加的是开根运算,然而却需要让加减乘除的运算都得参与编译,如果一不小心改变了其他的分支,岂不是前功尽弃。所以这里面要把加减乘除运算分离,做到修改其中一个不影响另外的几个运算,增加运算算法也不会影响其他代码。

采用继承和多态实现 代码V 3.0

Operation_pro类

package Factory;

public class Operation_pro {
    private double _numberA=0;
    private double _numberB=0;

    public double get_numberA() {
        return _numberA;
    }

    public void set_numberA(double _numberA) {
        this._numberA = _numberA;
    }

    public double get_numberB() {
        return _numberB;
    }

    public void set_numberB(double _numberB) {
        this._numberB = _numberB;
    }
    public double GetResult() throws Exception {
        double result=0;
        return result;
    }
}

加减乘除类

class Factory_OperationAdd  extends Operation_pro {
    @Override
    public double GetResult() {
        double  result=0;
        result=get_numberA()+get_numberB();
        return result;
    }
}
class Factory_OperationSub  extends Operation_pro {
    @Override
    public double GetResult() {
        double  result=0;
        result=get_numberA()-get_numberB();
        return result;
    }
}

class Factory_OperationMul  extends Operation_pro {
    @Override
    public double GetResult() {
        double  result=0;
        result=get_numberA()*get_numberB();
        return result;
    }
}
class Factory_OperationDiv  extends Operation_pro {
    @Override
    public double GetResult() throws Exception {
        double  result=0;
        if (get_numberB()==0)
            throw new Exception("除数不能为0.");
        result=get_numberA()/get_numberB();
        return result;
    }
}

简单工厂类

public class OperationFactory {
    public static Operation_pro createOperate(String operate) throws Exception {
        Operation_pro operation=null;
        switch (operate)
        {
            case "+":
                operation=new Factory_OperationAdd();
                break;
            case "-":
                operation=new Factory_OperationSub();
                break;
            case "*":
                operation=new Factory_OperationMul();
                break;
            case "/":
                operation=new Factory_OperationDiv();
                break;
            default:
                throw new Exception("请输入正确运算符号!!");
        }
        return operation;
    }
}

客户端代码:

        Scanner input=new Scanner(System.in);
        System.out.println("请选择运算符号(+、-、*、/):");
        String strOperate = input.nextLine();

        Operation_pro operation;
        operation = OperationFactory.createOperate(strOperate);
        operation.set_numberA(1);
        operation.set_numberB(0);
        double result=operation.GetResult();
        System.out.println("结果是:"+result);

假设有一天,需要对某个算术方法进行修改,那么我们只需要改响应的OperationXxx类即可

如果想要增加一些新的算术,则只需要添加新的Operation_pro子类即可,另外还需要去工厂类中switch中添加相应分支,如果要修改界面,则仅仅修改界面代码即可,跟运算代码完全无关,下面是这几个类的UML类图

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值