设计模式 简单工厂模式的进化过程

先看一个小故事:
你是一个工匠,得到一个紧急的任务,要求刻版印刷 “喝酒唱歌 人生真爽” ,由于任务紧急,你不得不通宵,终于刻好了。

第二天,客户突然觉得 “喝酒唱歌” 这几个字有点俗,觉得改成 “对酒当歌 人生真爽” 比较好,你又熬夜刻制好了。

第三天,客户想了想,觉得 “人生真爽” ,太过直接,要求改成 “对酒当歌 人生几何” ,虽然你很生气,但是你只能忍着,你又熬夜重新刻制好。

任务完事了,你就想,如果再遇到了改来改去的客户,有什么好办法能减少你的工作量呢?

没错,你可以把几个字分开刻,不要把所有字都刻在一起,而是刻八个板,每个板刻一个字,如果有变动,不用所有的工作都重头做,只需要修改变动的部分就可以。工作量一下减少了一半。

这就是中国古代的活字印刷啊。

通过这样的方法,可以做到 可维护(只需要修改有变动的字)、可复用(两次需求重复的字不用再刻制一遍)、可扩展(若要加字,只需要另外刻字加入即可)、灵活性好(字的排列方式横竖可以随意改)

看完这个小故事,下面思考一个题目:

使用面向对象的语言,要求输入两个数和运算符号,得到结果。

1

最简单的做法,我们可以获取用户输入的两个数字和运算符号,判断运算符号直接进行运算就可以得到结果;

(此处为了偷懒,我只写了加法和乘法两种运算)

//此处我只写了加法和乘法两种运算
public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        System.out.println("请输入第一个数字:");
        int num1=input.nextInt();
        System.out.println("请输入运算符:");
        String yunsuanfu=input.next();
        System.out.println("请输入第二个数字:");
        int num2=input.nextInt();
        switch(yunsuanfu){
            case "+":
                System.out.println(num1+yunsuanfu+num2+"="+(num1+num2));
                break;
            case "*":
                System.out.println(num1+yunsuanfu+num2+"="+(num1*num2));
                break;

        }

    }

但这显然有问题,根本没有使用到面向对象的思想。假如把需求修改成写一个计算器,现在的代码能不能复用呢?

2

下面我们尝试修改,先让业务逻辑和界面逻辑分开

业务逻辑代码:

public class Yunsuan1 {
    public static int getResult(int num1, int num2, String yunsuanfu) {
        int result = 0;
        switch (yunsuanfu) {
            case "+":
                result = num1 + num2;
                break;
            case "*":
                result = num1 * num2;
                break;

        }
        return result;
    }
}

界面逻辑代码:

import java.util.Scanner;

public class Test1 {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        System.out.println("请输入第一个数字:");
        int num1=input.nextInt();
        System.out.println("请输入运算符:");
        String yunsuanfu=input.next();
        System.out.println("请输入第二个数字:");
        int num2=input.nextInt();
        int result= Yunsuan1.getResult(num1,num2,yunsuanfu);
        System.out.println("结果是:"+result);

    }
}

如上的代码使用了面向对象的封装

现在假如要写一个计算器的应用程序,就可以把业务逻辑的代码复用了。

不单是web程序、手机等移动系统的软件也可以复用。

3

现在我们来思考,假如要添加一个指数运算,此时就要修改整个逻辑代码文件,有可能失误把已经写好的加法运算改错,又比如,公司新增了一个岗位,现在要求你为公司的薪资管理做维护,公司就必须把整个逻辑代码文件给你修改,你心中小算盘一打,“TMD,公司给我的工资这么低,这下有机会了。”

比如switch是你自己的时候,你把你的工资加20%。本来是让你加一个功能,却使得原来良好的功能代码发生了变化,这风险太大了。

那么我们应该做到 修改其中一种运算,不影响其他运算。我们来使用面向对象的继承和多态。

从不同的运算抽象出Yunsuan父类

package com.qing.jdgc;

public abstract class Yunsuan {
    public abstract void getResult(int num1,int num2);
}

子类继承 Yunsuan父类,不同的运算(加法、乘法、指数运算)执行的运算操作是不一样的,重写计算的方法。

package com.qing.jdgc;

public class Jiafa extends Yunsuan{
    @Override
    public void getResult(int num1, int num2) {
        System.out.println(num1+"和"+num2+"执行加法运算后结果是:"+(num1+num2));

    }
}
package com.qing.jdgc;

public class Chengfa extends Yunsuan {

    @Override
    public void getResult(int num1, int num2) {
        System.out.println(num1 + "和" + num2 + "执行乘法运算后结果是:" + (num1 * num2));
    }
}
package com.qing.jdgc;

public class Zhishu extends Yunsuan{
    @Override
    public void getResult(int num1, int num2) {
        System.out.println(num1+"和"+num2+"执行指数运算后结果是:"+(Math.pow(num1,num2)));
    }
}

 根据不同的运算符号实例化出不同的对象(多态),接下来执行不同的运算

package com.qing.jdgc;

public class Factory {

    public static Yunsuan createYunsuan(String yunsuanfu){
        Yunsuan yunsuan = null;
        switch(yunsuanfu){
            case "+":
                yunsuan=new Jiafa();
                break;
            case "*":
                yunsuan=new Chengfa();
                break;
            case "^":
                yunsuan=new Zhishu();
                break;

        }
        return yunsuan;
    }



}

 界面逻辑

package com.qing.jdgc;

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        System.out.println("请输入第一个数字:");
        int num1=input.nextInt();
        System.out.println("请输入运算符:");
        String yunsuanfu=input.next();
        System.out.println("请输入第二个数字:");
        int num2=input.nextInt();
        Factory.createYunsuan(yunsuanfu).getResult(num1,num2);
    }
}

结果

 

 

接下来,回到正题,简单工厂模式。

简单工厂模式又叫静态工厂方法,属于类创建型模式。

特点如下

可以根据参数的不同,返回不同的实例。


简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

如上的最后一次的代码就使用了简单工厂模式,Factory类就可以根据不同的运算符返回不同的实例。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值