大话设计模式之简单工厂模式(代码片段)

tyha-nobody tyha-nobody     2022-11-29     733

关键词:

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

--参考自《大话设计模式》

需求

现在有一个需求,实现一个简单的计算器

对于一般的初学者来说可能会这么实现:

public class calculate 
    public static void main(String[] args) 
        Scanner cin = new Scanner(System.in);
        System.out.println("请输入数字A:");
        String numberA = cin.next();

        System.out.println("请输入运算符号(+,-,*,/):");
        char op = cin.next().charAt(0);
        System.out.println("请输入数字B:");
        String numberB = cin.next();
        String rst = null;
        if(op == ‘+‘)
            rst = String.valueOf(Integer.parseInt(numberA)+Integer.parseInt(numberB));
        
        if(op == ‘-‘)
            rst = String.valueOf(Integer.parseInt(numberA)-Integer.parseInt(numberB));
        
        if(op == ‘*‘)
            rst = String.valueOf(Integer.parseInt(numberA)*Integer.parseInt(numberB));
        
        if(op == ‘/‘)
            rst = String.valueOf(Integer.parseInt(numberA)/Integer.parseInt(numberB));
        
        System.out.println("结果是: " + rst);
    

技术图片

修改后的版本:

public class calculate2 
    public static void main(String[] args) 
        Scanner cin = new Scanner(System.in);

        try 
            System.out.println("请输入数字A:");
            String numberA = cin.next();
            System.out.println("请输入运算符号(+,-,*,/):");
            char op = cin.next().charAt(0);
            System.out.println("请输入数字B:");
            String numberB = cin.next();
            String rst = null;
            switch (op)
                case ‘+‘:rst = String.valueOf(Integer.parseInt(numberA)+Integer.parseInt(numberB));break;
                case ‘-‘:rst = String.valueOf(Integer.parseInt(numberA)-Integer.parseInt(numberB));break;
                case ‘*‘:rst = String.valueOf(Integer.parseInt(numberA)*Integer.parseInt(numberB));break;
                case ‘/‘:
                    if(!numberB.equals("0"))
                        rst = String.valueOf(Integer.parseInt(numberA)/Integer.parseInt(numberB));
                    else
                        rst = "除数不能为0!";
                    
                    break;
            
            System.out.println("结果是: " + rst);
        catch (Exception e)
            System.out.println("您的输入有错:"+e.getMessage());
        
    

已经改的不错了,但是这种代码相对来说,可维护性和可扩展性低,如果现在需要重新写一个计算器,那么想一想我们的代码能不能复用呢?

那....Crtl+C和Crtl+V大法呀,多香呀。

有人说初级程序员的工作就是Crtl+C和Crtl+V,其实这是非常不好的编码习惯,想想当你的项目中,重复代码很多的时候,这就是一场灾难,有一个需求发生变化,那么你想想你得修改多少代码?

如果我们能将业务逻辑和客户端代码分开,让他们的耦合度下降,这样才能达到容易维护和扩展的目的。

我们将代码进行修改:

Operation类:

public class Operation 
    public static double getResult(double numberA,double numberB,String operate)
        double rst = 0.0;
        switch (operate.charAt(0))
            case ‘+‘:
                rst = numberA + numberB;
                break;
            case ‘-‘:
                rst = numberA - numberB;
                break;
            case ‘*‘:
                rst = numberA * numberB;
                break;
            case ‘/‘:
                rst = numberA / numberB;
                break;
        
        return rst;
    

客户端逻辑代码:

public class testOperation 
    public static void main(String[] args) 
        Scanner cin = new Scanner(System.in);
        try
            System.out.println("请输入数字A:");
            String numberA = cin.next();
            System.out.println("请输入运算符号(+,-,*,/):");
            String op = null;
            op = cin.next();
            System.out.println("请输入数字B:");
            String numberB = cin.next();
            System.out.println("结果是: "+ Operation.getResult(Double.parseDouble(numberA),Double.parseDouble(numberB),op));
        catch (Exception e)
            System.out.println("您的输入有误:"+e.getMessage());
        
    

将业务逻辑和界面逻辑分离开,感觉维护性高多了,卧槽,牛逼呀。


问题又来了,如果现在要增加一个sqrt运算的需求怎么办,如何改?

只要修改Operation类,然后再switch里加一个分支就行了。

就增加了一个功能,就要让其他加减乘除所有的功能都参与运算,如果不小心改到加法运算里了怎么办?如果这是一个公司的计算工资的业务代码,如果参与维护的那个员工有私心,在完成sqrt运算的时候偷偷改了别的代码,改变了自己工资的计算方式,那岂不是风险太大了?

如果我们引入继承和多态,修改一个功能的时候不影响其他功能,这样风险就小很多。

operactionClass计算类:

public abstract  class operationClass 
    private double number_a = 0;
    private double number_b = 0;
    public  abstract double getResult();
    public operationClass() 
    

    public double getNumber_a() 
        return number_a;
    

    public void setNumber_a(double number_a) 
        this.number_a = number_a;
    

    public double getNumber_b() 
        return number_b;
    

    public void setNumber_b(double number_b) 
        this.number_b = number_b;
    

加减乘除类都继承自运算类:

public class operationAdd extends operationClass 
    @Override
    public double getResult() 
        return getNumber_a() + getNumber_b();
    


public class operationSub extends operationClass 
    @Override
    public double getResult() 
        return getNumber_a() + getNumber_b();
    

public class operationMul extends operationClass
    @Override
    public double getResult() 
        return getNumber_a() + getNumber_b();
    

public class operationDiv  extends  operationClass
    @Override
    public double getResult() throws Exception 
        if(getNumber_b() == 0)
            throw new Exception("被除数不能为0!");
        
        return getNumber_a() + getNumber_b();
    

实现了一部分,但是问题来了,我们如果让计算机知道我希望用哪一个算法呢?

简单工厂类##

现在就是到底要实例化谁?将来不会增加实例化的对象,比如增加sqrt功能,这是很容易变化的地方,应该用一个单独的类来做创造实例化的过程,这就是工厂。

简单工厂运算类:

public class operationFactory 
    public static operationClass createOperate(String op)
        operationClass operation = null;
        switch (op.charAt(0))
            case ‘+‘:
                operation = new operationAdd();
                break;
            case ‘-‘:
                operation = new operationSub();
                break;
            case ‘*‘:
                operation = new operationMul();
                break;
            case ‘/‘:
                operation = new operationDiv();
                break;
        
        return operation;
    


只需要提供符号,就能生产出合适的实例化对象,通过多态,返回父类的方式实现了计算机的结果。

客户端代码实现 测试:

public class test 
    @Test
    public void testFactory() throws Exception 
        operationClass oper;
        oper = operationFactory.createOperate("+");
        oper.setNumber_a(11);
        oper.setNumber_b(22);
        System.out.println(oper.getResult());
    

通过工厂模式,如果我们要增加复杂的运算,比如开根号,平方运算,只要增加相应的子类并且改造工厂的分支就可以了。这样就实现了业务逻辑和界面逻辑分离,功能模块之间的耦合也降低了。




大话设计模式之简单工厂读后感(代码片段)

引言:让我们重温经典,致敬经典简单工厂模式:根据调用端传参来有选择的实例化目标对象。UML类图:我们知道简单工厂就是为我们生成我们需要的对象。举个栗子:我们在舞台看表演的时候,一场场表演下来,我们可以总结... 查看详情

python大话设计模式:简单工厂模式(蟒版)(代码片段)

查看详情

csharp大话设计模式:简单工厂模式(c#版)(代码片段)

查看详情

大话设计模式之简单工厂模式

简单工厂模式  最近朋友推荐了一本书《大话设计模式》,此书刚刚到,博主也还没开始看,希望以博文的方式与大家一起分享,一起学习.简单工厂模式,也就是说,到底要实列化谁,将来会不会增加实列化的对象,比如增加开根运算,... 查看详情

大话设计模式第八章之简单工厂模式

   简单工厂模式 工厂方法模式     packagecom.dp.factory;interfaceIFactory{CalculatorCreateCalculator();}classAddFactoryimplementsIFactory{@OverridepublicCalculatorCreat 查看详情

大话设计模式之工厂方法模式读后感(代码片段)

引言:让我们重温经典,致敬经典工厂方法模式:定义一个用于创建对象的接口,让子类来决定实例化哪一个类,工厂方法使一个类的实例化延迟到了子类。UML图:1packagecom.dzf.designtest;23/**4*<desc>5*工厂方法:定义一个创建对... 查看详情

大话设计模式--第一章简单工厂设计模式(代码片段)

简单工厂设计模式案例:写一个计算器,实现加减乘除.第一步:写一份简单的代码packagecom.chapter1;publicclassCaculator1publicstaticvoidmain(String[]args)if(args.length<3)System.out.println("参数个数异常");return;Doublenum1=Double.parseDoubl 查看详情

大话设计模式--简单工厂模式(代码片段)

问题:请用C++,JAVA,C#任意一种以面向对象语言实现一个计算器控制台程序:要求输入2个数和运算符号,得到结果第一次编码:publicclassProgrampublicstaticvoidmain(String[]args)throwsIOExceptionSystem.out.println("请 查看详情

大话设计模式第一章之简单工厂模式

packagecom.dp.simpleFactory;//计算器作为抽象类定义一个计算需要什么子类继承了两个数字并且要有自己的计算实现方法publicabstractclassCalculator{protecteddoublenumberA=0;protecteddoublenumberB=0;publicdoublegetNumberA(){returnnumberA;}publicvoid 查看详情

java之抽象工厂模式(大话设计模式)

...们还是要吸取其思想而不是生搬硬套。来看下类图:大话设计模式-类图看类图已经很乱了,来简单的梳理下。我们只看接口,这样就不难看出实际上是抽象工厂生产抽象产品的过程,而具体实现都是各自的实现类来做。看下具... 查看详情

设计模式之简单工厂模式(代码片段)

简单来说,工厂模式就是按照需求来返回一个类型的对象,使用工厂模式的意义就是,如果对象的实例化与代码依赖太大的话,不方便进行扩展和维护,使用工厂的目的就是使对象的实例化与主程序代码就行解耦.1.简单工厂模式简介简... 查看详情

设计模式之简单工厂模式(代码片段)

引言   所属:创建型模式,常用设计模式之一  工厂模式分为:简单工厂模式、工厂方法模式、静态工厂模式、抽象工厂模式。  下面为简单工厂模式。 工厂模式概述   通过使用一个公共接口来指向不同方... 查看详情

设计模式之简单工厂模式(代码片段)

简单画图理解//设计模式之简单工厂模式//创建一个食物类interfaceFoodvoideat();//我今天想吃薯条或汉堡classHamburgerimplementsFood@Overridepublicvoideat()System.out.println("我吃汉堡");classFrenchFriesimplementsFood@Overridepublicvoidea 查看详情

设计模式之简单工厂模式(代码片段)

    今天学习了简单工厂模式,总结一下。    简单工厂模式的核心思想是:由一个工厂实体决定创建出哪一种产品的实例。    比较简单,因此直接上代码:  这个例子我们实现一个简单的计算器。我们先... 查看详情

设计模式之简单工厂模式(代码片段)

2018-09-16 23:50:57简单工厂模式概述  简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。    UML类图如下:     该模式中包含的角色及其职责(摘自:百度百科)   工厂(Creator)角色 ... 查看详情

设计模式之简单工厂模式(创建型)(代码片段)

定义简单工厂模式又称静态工厂模式。可以根据参数的不同返回不同类的实例。定义一个类来创建其它类的实例。角色简单工厂模式包含如下角色Factory:工厂角色Product:抽象产品角色ConcreteProduct:具体产品角色简单实例publicabst... 查看详情

设计模式从青铜到王者第五篇:创建型模式之简单工厂模式(simplefactorypattern)(代码片段)

系列文章目录文章目录系列文章目录前言一、简单工厂模式模式动机二、简单工厂模式模式定义三、简单工厂模式模式结构四、简单工厂模式时序图五、简单工厂模式代码分析六、简单工厂模式模式分析七、简单工厂模式优点八... 查看详情

设计模式之工厂模式(代码片段)

工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。简单工厂模式与工厂模式区别:  (1)简单工厂模式的优点在于工厂类中包含了必要的逻辑判断,根据客户... 查看详情