zoukankan      html  css  js  c++  java
  • 大话设计模式--(1)简单工厂模式

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

    我的第一反应是和书里的是一样的就是向下面这样写

    /*
    * 要求输入两个数和运算符号,得到结果
    * */
    public class Test {
        public static void main(String []args) throws IOException {
            System.out.print("输入第一个数:");
            Scanner scan = new Scanner(System.in);
            String read1 = scan.nextLine();
            System.out.print("输入运算方式:");
            Scanner scan2 = new Scanner(System.in);
            String read2 = scan2.nextLine();
            System.out.print("输入第二个数:");
            Scanner scan3 = new Scanner(System.in);
            String read3 = scan3.nextLine();
            int result=0;
            if(read2.equals("+")){
                result=Integer.parseInt(read1)+Integer.parseInt(read3);
            }else if (read2.equals("-")){
                result=Integer.parseInt(read1)-Integer.parseInt(read3);
            }else if (read2.equals("*")){
                result=Integer.parseInt(read1)*Integer.parseInt(read3);
            }else if (read2.equals("/")){
                result=Integer.parseInt(read1)/Integer.parseInt(read3);
            }
            System.out.print("计算结果为:"+result);
        }
    }

    继续看,初学者的毛病,命名不规范,判断分支(假如说是除法,那么前面三次就相当于做了无用功),然后出发的除数有可能为0会抛异常

    public class Test {
        public static void main(String []args)  {
            try {
                System.out.print("输入第一个数:");
                Scanner scan = new Scanner(System.in);
                String read1 = scan.nextLine();
                System.out.print("输入运算方式:");
                Scanner scan2 = new Scanner(System.in);
                String read2 = scan2.nextLine();
                System.out.print("输入第二个数:");
                Scanner scan3 = new Scanner(System.in);
                String read3 = scan3.nextLine();
                int result=0;
                switch (read2){
                    case "+":
                        result=Integer.parseInt(read1)+Integer.parseInt(read3);
                        break;
                    case "-":
                        result=Integer.parseInt(read1)-Integer.parseInt(read3);
                        break;
                    case "*":
                        result=Integer.parseInt(read1)*Integer.parseInt(read3);
                        break;
                    case "/":
                        if (Integer.parseInt(read3)!=0){
                            result=Integer.parseInt(read1)+Integer.parseInt(read3);
                        }else {
                            System.out.print("被除数不可为0");
                        }
                        break;
                }
                System.out.print("计算结果为:"+result);
            }catch (Exception ex){
                System.out.print("输入的参数有误,请重新输入");
            }
        }
    }

    至少就目前代码来看,实现了基本的计算器功能,但是是否符合出题人的意思,意思是是否符合“面向对象”。书里原话:所有的初学者就是碰到问题就直觉的用计算能够理解的逻辑来描述和表达待解决的问题以及具体的求解过程,这其实是用计算机的方式去思考,比如计算器这个程序,现要求输入两个数和运算符号,然后再根据运算符号判断选择如何运算,得到结果,这个本身没错,但这样的思维却使得我们的程序只为了满足当前的需求,程序不容易维护,不容器扩展,更不易服用,从而达不到高质量代码的要求。

      代码中的重复代码多到一定程度,维护的时候,可能就是一场灾难,越大的系统,这种方式带来的问题越严重,编程有一原则,就是用尽可能的方法去避免重复。查看那些是和控制台无关的,那些只是和计算有关的,准确的说让业务逻辑与界面逻辑分开,让他们之间的耦合度下降,只有分离开,才可以达到容易维护和扩展

    /*
    * 要求输入两个数和运算符号,得到结果
    * */
    public class Test {
        /*
         *运算方法
         * */
        public static int getResult(String one, String two, String middle){
            int result=0;
            switch (middle){
                case "+":
                        result=Integer.parseInt(one)+Integer.parseInt(two);
                    break;
                case "-":
                    result=Integer.parseInt(one)-Integer.parseInt(two);
                    break;
                case "*":
                    result=Integer.parseInt(one)*Integer.parseInt(two);
                    break;
                case "/":
                    if (Integer.parseInt(two)!=0){
                        result=Integer.parseInt(one)+Integer.parseInt(two);
                    }else {
                        System.out.print("被除数不可为0");
                    }
                    break;
            }
            return result;
        }
        public static void main(String []args)  {
            try {
                System.out.print("输入第一个数:");
                Scanner scan = new Scanner(System.in);
                String read1 = scan.nextLine();
                System.out.print("输入运算方式:");
                Scanner scan2 = new Scanner(System.in);
                String read2 = scan2.nextLine();
                System.out.print("输入第二个数:");
                Scanner scan3 = new Scanner(System.in);
                String read3 = scan3.nextLine();
                int result=0;
                result=getResult(read1,read3,read2);
                System.out.print("计算结果为:"+result);
            }catch (Exception ex){
                System.out.print("输入的参数有误,请重新输入");
            }
        }
    }

    如果新添加一个运算规则,需要修改swich里面代码,很有可能会动到原来运行稳定的代码,这样风险太大。要运用继承,多态,

    首先写了一个算法类,里面只有2个数,然后再用加减乘除类继承并重写算法类里面的一个方法

    public class Operation {
        private double _numberA=0;
        private double _numberB=0;
    
        public double get_numberB() {
            return _numberB;
        }
    
        public void set_numberB(double _numberB) {
            this._numberB = _numberB;
        }
    
        public double get_numberA() {
            return _numberA;
        }
    
        public void set_numberA(double _numberA) {
            this._numberA = _numberA;
        }
        public double GetResult(){
            double result=0;
            return result;
        }
    }
    
    /*
     * 加法
     * */
    class add extends Operation{
        @Override
        public double GetResult() {
            double result=0;
            result=get_numberA()+get_numberB();
            return result;
        }
    }
    /*
     * 减法
     * */
    class Subtraction extends Operation{
        @Override
        public double GetResult() {
            double result=0;
            result=get_numberA()-get_numberB();
            return result;
        }
    }
    /*
     * 乘法
     * */
    class multiplication extends Operation{
        @Override
        public double GetResult() {
            double result=0;
            result=get_numberA()*get_numberB();
            return result;
        }
    }
    /*
    * 除法
    * */
    class division extends Operation{
        @Override
        public double GetResult() {
            double result=0;
            if (get_numberB()!=0){
                result=get_numberA()/get_numberB();
            }else{
                System.out.print("被除数不可为0");
            }
            return result;
        }
    }

    然后再写一个简单工厂类就可以了,只需要输入运算符号,工厂就实例化出合适的对象,通过多态返回父类的方式实现了计算器的结果

    public class OperationFactory {
        public static Operation createOperate(String operate){
            Operation operation=null;
                switch (operate){
                    case "+":
                        operation=new add();
                        break;
                    case "-":
                        operation=new Subtraction();
                        break;
                    case "*":
                        operation= new multiplication();
                        break;
                    case "/":
                         operation=new division();
                        break;
                }
                return operation;
        }
    }

    测试:

    public class Test {
        public static void main(String []args) {
            Operation operate = OperationFactory.createOperate("+");
            operate.set_numberA(5);
            operate.set_numberB(2);
            System.out.println(operate.GetResult());
        }
    }

     
  • 相关阅读:
    FreeCommander 学习手册
    String详解, String和CharSequence区别, StringBuilder和StringBuffer的区别 (String系列之1)
    StringBuffer 详解 (String系列之3)
    StringBuilder 详解 (String系列之2)
    java io系列26之 RandomAccessFile
    java io系列25之 PrintWriter (字符打印输出流)
    java io系列24之 BufferedWriter(字符缓冲输出流)
    java io系列23之 BufferedReader(字符缓冲输入流)
    java io系列22之 FileReader和FileWriter
    java io系列21之 InputStreamReader和OutputStreamWriter
  • 原文地址:https://www.cnblogs.com/lkeji388/p/10108483.html
Copyright © 2011-2022 走看看