小菜成长记(一)--简单工厂设计模式

       工作两年多了,学了各种东西,android、html5、css、js、大数据、java后端,工作的坎坷,最后还是打算从事java后台,博而不精,面试有点小困难,虽然每次面试过后越来越好,但是达不到自己最想要去的公司和工作。面试了某家大型公司,最后面试官说,你工作两年了还是个初级工程师,不管技术如何更新,基础才是最重要,事情总要人去做,虽然最终落榜。沉静下来,两个月初看完了《java编程思想》、《深入理解java虚拟机》,心里大概有个底,知道什么技术解决什么问题,过段时间再看一次,知道完全理解为止,期间也看了炒股方面的书:《聪明的投资者》(美)本杰明·格雷厄姆、《在股市大崩溃前抛出的人:巴鲁克自传》、《巴菲特基金投资6招》刘建位 徐晓杰、《长盈之道》约翰.博格。现在开始学习设计模式《大话设计模式》,感谢程杰老师写的这本书。
下面的例子主要来自《大话设计模式》:
小菜面试时,要求用任何一种面相对象的设计语言c#、java、python等写一到计算器题目。小菜十分钟不到就写完了。程序如下:
import java.util.Scanner;

public class Program {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入第一个数字:");
        String numberOne = sc.next();
        System.out.println("请输入计算符:");
        //用于jdk1.7之前 获取char
        //char calcChar = sc.next().charAt(0);
        // 用于jdk1.7及之后
        String calcChar = sc.next();
        System.out.println("请输入第二个数字:");
        String numberTwo = sc.next();
        int result = 0;

        try {
            // jdk 1.7之前只能使用int 、short 、byte 、char。jdk 1.7及之后可以使用String。本示例采用jdk 1.8
            switch (calcChar){
                case "+":
                    result = Integer.parseInt(numberOne) + Integer.parseInt(numberTwo);
                    break;

                case "-":
                    result = Integer.parseInt(numberOne) - Integer.parseInt(numberTwo);
                    break;

                case "*":
                    result = Integer.parseInt(numberOne) * Integer.parseInt(numberTwo);
                    break;

                case "/":
                    result = Integer.parseInt(numberOne) / Integer.parseInt(numberTwo);
                    break;
					
				default:
					throw new RuntimeException("计算符输入错误");
            }
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("分母不能为0,或者数字输入错误,或者计算符输入错误");
            System.exit(0);
        }

        System.out.println("运算结果为:" + result);
    }
}
小菜面试完之后便跟表哥大鸟说起了这件事,大鸟说:你感觉写得怎么样,理解了面试题目的真正意思没。小菜说了自己如何如何(小菜最后当然落榜了)。大鸟就说:人家要求用面向对象语言进行设计,面向对象的特性:封装、继承、多态,界面应该要和业务分开,以后无论是手机端、web端、pc端都能公用。你达到了没。小菜想了想,就改成了如下的程序: 
(一)封装
import java.util.Scanner;

public class Program {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入第一个数字:");
        String numberOne = sc.next();
        System.out.println("请输入计算符:");
        //用于jdk1.7之前 获取char
        //char calcChar = sc.next().charAt(0);
        // 用于jdk1.7及之后
        String calcChar = sc.next();
        System.out.println("请输入第二个数字:");
        String numberTwo = sc.next();
        int result = 0;

        try {
            result = Calculator.calc(Integer.parseInt(numberOne),calcChar,Integer.parseInt(numberTwo));
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("分母不能为0,或者数字输入错误,或者计算符输入错误");
            System.exit(0);
        }

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

class Calculator {
    public static int calc(int numberOne,String calcChar, int numberTwo)throws Exception{
        int result = 0;
        // jdk 1.7之前只能使用int 、short 、byte 、char。jdk 1.7及之后可以使用String。本示例采用jdk 1.8
        switch (calcChar){
            case "+":
                result = numberOne + numberTwo;
                break;

            case "-":
                result = numberOne - numberTwo;
                break;

            case "*":
                result = numberOne * numberTwo;
                break;

            case "/":
                result = numberOne / numberTwo;
                break;

            default:
                throw new RuntimeException("计算符输入错误");
        }
        return result;
    }
}
大鸟看了之后说:”孺子可教也,实现了界面和业务的分离,用了封装这个特性,面向对象还有两个特性没用“。
小菜说:“我实在想不出这么小的程序如何用继承和多态”。
大鸟说:“慢慢来,你要学的东西多着呢,你好好想想”。
第二天,小菜说:“这么小的计算器程序怎么用到面向对象的三个特性啊!继承和多态怎么用得到我实在想不出来”。
大鸟说:“很有钻研精神嘛,你昨天写的程序能够做到灵活的可修改和扩展呢?如何增加开根(sqrt)运算”
小菜说:“在Calculator类中,switch增加一个分支就行了啊”
大鸟说:“问题是你要加一个平方根运算,却需要让加减乘除运算都得参加编译,如果不小心把加法改成了减法,这岂不是大大糟糕。比如公司让你更改一个人员层级薪资的运算,还要给你各个管理层的运算代码,你对自己的薪资不满意,稍加修改,不是问题很大了。”
(二)继承
class Calculator {
    private int numberOne;
    private int numberTwo;

    public int getNumberOne() {
        return numberOne;
    }

    public void setNumberOne(int numberOne) {
        this.numberOne = numberOne;
    }

    public int getNumberTwo() {
        return numberTwo;
    }

    public void setNumberTwo(int numberTwo) {
        this.numberTwo = numberTwo;
    }

    public int getResult(){
        int result = 0;
        return result;
    }
}

class AddCalculator extends Calculator{
    @Override
    public int getResult() {
        return getNumberOne() + getNumberTwo();
    }
}

class SubCalculator extends Calculator{
    @Override
    public int getResult() {
        return getNumberOne() - getNumberTwo();
    }
}

class MulCalculator extends Calculator{
    @Override
    public int getResult() {
        return getNumberOne() * getNumberTwo();
    }
}

class DivCalculator extends Calculator{
    @Override
    public int getResult(){
        if(getNumberTwo() == 0)
            throw new RuntimeException("除数不能为0");
        return getNumberOne() / getNumberTwo();
    }
}
大鸟说:“写得不错嘛,大大超过了我的预想,你现在未解决的问题就是去实例化的问题,采用“简单工厂模式”就可解决”。
import java.util.Scanner;

public class Program {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入第一个数字:");
        String numberOne = sc.next();
        System.out.println("请输入计算符:");
        //用于jdk1.7之前 获取char
        //char calcChar = sc.next().charAt(0);
        // 用于jdk1.7及之后
        String calcChar = sc.next();
        System.out.println("请输入第二个数字:");
        String numberTwo = sc.next();
        int result = 0;

        try {
            Calculator calculator = CalculatorFactory.createCalculator(calcChar);
            calculator.setNumberOne(Integer.parseInt(numberOne));
            calculator.setNumberTwo(Integer.parseInt(numberTwo));
            result = calculator.getResult();
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("分母不能为0,或者数字输入错误,或者计算符输入错误");
            System.exit(0);
        }

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

class Calculator {
    private int numberOne;
    private int numberTwo;

    public int getNumberOne() {
        return numberOne;
    }

    public void setNumberOne(int numberOne) {
        this.numberOne = numberOne;
    }

    public int getNumberTwo() {
        return numberTwo;
    }

    public void setNumberTwo(int numberTwo) {
        this.numberTwo = numberTwo;
    }

    public int getResult(){
        int result = 0;
        return result;
    }
}

class AddCalculator extends Calculator{
    @Override
    public int getResult() {
        return getNumberOne() + getNumberTwo();
    }
}

class SubCalculator extends Calculator{
    @Override
    public int getResult() {
        return getNumberOne() - getNumberTwo();
    }
}

class MulCalculator extends Calculator{
    @Override
    public int getResult() {
        return getNumberOne() * getNumberTwo();
    }
}

class DivCalculator extends Calculator{
    @Override
    public int getResult(){
        if(getNumberTwo() == 0)
            throw new RuntimeException("除数不能为0");
        return getNumberOne() / getNumberTwo();
    }
}

class CalculatorFactory{
    public static Calculator createCalculator(String calcChar){
        Calculator calculator = null;
        // jdk 1.7之前只能使用int 、short 、byte 、char。jdk 1.7及之后可以使用String。本示例采用jdk 1.8
        switch (calcChar){
            case "+":
                calculator = new AddCalculator();
                break;


            case "-":
                calculator = new SubCalculator();
                break;


            case "*":
                calculator = new MulCalculator();
                break;


            case "/":
                calculator = new DivCalculator();
                break;


            default:
                throw new RuntimeException("计算符输入错误");
        }
        return calculator;
    }
}
自己的感悟,以后碰到switch想想用这个方法改写。先做到“有剑胜无剑”,最后做到“无剑胜有剑”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值