简单工厂模式

什么是设计模式?设计模式的好处

设计模式(Design Patterns),就是设计过程中可以反复使用的、可以解决特定问题的设计方法

在软件领域,GOF(“四人帮”)首次系统化地提出了3大类(创建模式、行为模式、组合模式)共23种经典的,可以解决常见软件设计问题的可复用设计方案,为可复用软件设计奠定了一定的理论基础。

其实说明白了,设计模式就是说从代码的设计中提取出一些好的设计思想,实现代码的高内聚,低耦合,可复用的特性,也就是说模块间的内聚性高了,同时模块间的耦合度低了,那么在重用代码或者移植代码时将会更加轻松。

其实我们在编程过程中很多时候都是用到了设计模式的,只是我们不清楚,这里提出来,会让你更加的清晰认识什么是面向对象,封装,继承,多态等。

当然现在的技术发展那么快,设计模式已经不再局限于这23种了,还有很多新的设计模式出现,但是我这里就先不说了,还是先从经典开始,经典能成为经典毕竟是有一些道理的,废话不多说,进入正题。

代码无错便是优?

在我刚刚做软件开发的时候,通常的原则就是能够快速完成任务,不出错就是完美的,因此一个功能或许就一个类,一个方法就写了,那么当我想要重新复制这个功能,修改一点东西的时候,就必须全部复制下来,然后修改一点,这样其实有很多的冗余代码,这里大家可能印象还不够直观,我们用代码来说明一下(这里思路参考《大话设计模式》)。

当我们想要实现一个简单的计算器的时候,最基本的方法应该是加减乘除对吧,那么我们这里就来实现一下:

public class Design {
  @SuppressWarnings("resource")
  public static void main(String args[]) {
    System.out.println("请输入数学表达,每输入一个字符回车确认");
    Scanner scanner = new Scanner(System.in);
    double numA = scanner.nextDouble();
    String operate = scanner.next();
    double numB = scanner.nextDouble();
    double result = 0;
    
    switch (operate) {
      case "+":
        result = numA + numB;
        break;
      case "-":
        result = numA - numB;
        break;
      case "*":
        result = numA * numB;
        break;
      case "/":
        if (numB == 0) {
          try {
            throw new Exception("被除数不能为0");
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
        result = numA / numB;
        break;
    }
    System.out.println("= " + result);
  }
}

运行结果:
在这里插入图片描述
上面的程序是个最简单的运算程序,看来好像没什么大的问题,但是假如这里需要增加开方的功能,那么你必须又去改核心代码;假如又要增加平方的功能,你又必须改核心源代码,这样改着改着很容易就增加一堆代码,揉在一起变成了几千行,几万行,假如以后你离职了,有人来接手你的代码,看着这些代码,我的天哪,别人看着只有说不敢动,不敢动。。。很多祖传代码也就是这样诞生的。

同时最重要的问题是上面代码是面向过程编码,就是按照我们常规的计算逻辑来的,满足了我们当前的需求,但是不容易维护,不容易扩展,更不容易复用,而且忽视了java很重要的一个思想:面对对象编程,你的对象呢?

面向对象编程

你想假如我们把操作的方法改成一个操作类,然后再分离一个操作客户端出来是不是会好很多呢?就是将业务逻辑与界面逻辑分开来,让代码之间的耦合度下降,这样才能够便于扩展。

如下所示:

操作类

public class Operate {
  public Double getRequest(Double numA, Double numB, String operate) {
    double result = 0;

    switch(operate) {
      case "+":
        result = numA + numB;
        break;
      case "-":
        result = numA - numB;
        break;
      case "*":
        result = numA * numB;
        break;
      case "/":
        if (numB == 0) {
          try {
            throw new Exception("被除数不能为0");
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
        result = numA / numB;
        break;
    }

    return result;
  }
}

客户端类:

public class NewClient {
  @SuppressWarnings("resource")
  public static void main(String args[]) {
    System.out.println("请输入数学表达,每输入一个字符回车确认:");
    Scanner scanner = new Scanner(System.in);
    double numA = scanner.nextDouble();
    String operate = scanner.next();
    double numB = scanner.nextDouble();
    double result = 0;

    Operate model = new Operate();
    result = model.getRequest(numA, numB, operate);

    System.out.println("= " + result);
  }
}

运行结果:
在这里插入图片描述
这样分开以后对于客户端来说是不是就清爽多了,我不管你是怎么操作的,反正我把值传给操作类对象,然后你再把结果返回给我就行,上面简单的分离代码不但体现了面对对象编程,同时还体现了封装,就是我将操作方法封装起来,你只需要调用就行了,看上面简单的一改就体现了Java的面对对象思想,封装等,而且便于扩展,便于复用,如果你还需要什么其它的客户端操作,你直接重新写个客户端,然后调用操作类方法就行了。

但是上面的代码还是回避不了我们刚才的问题,假如我们要添加开方功能,或者平方功能,那么我们还是要去修改操作类,假如我们在修改的过程中不小心改了加法或者减法的逻辑,别人的在用的时候那就肯定会出问题,那么有没有更好的方法来解决这个问题呢?我们来试试简单工厂模式。

什么是简单工厂模式

简单工厂模式就是将我们需要调用的类交给工厂类来生成,客户端只需要传参数,然后获取最终结果,就像我们把材料交给工厂,然后工厂把最后产品给我们,依然是上面的例子,我们通过代码来看下简单工厂模式:

操作方法实体类:

public class Operation {
  private double numA = 0;
  private double numB = 0;

  public double getNumA() {
    return numA;
  }

  public void setNumA(double numA) {
    this.numA = numA;
  }

  public double getNumB() {
    return numB;
  }

  public void setNumB(double numB) {
    this.numB = numB;
  }

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

加法类继承操作类:

public class OperationAdd extends Operation {

  @Override
  public double getResult() {
    double result = getNumA() + getNumB();

    return result;
  }
}

减法类继承操作类:

public class OperationDelete extends Operation {
  @Override
  public double getResult() {
    double result = getNumA() - getNumB();

    return result;
  }
}

工厂类:

public class OperationFactory {
  public static Operation create(String operate) {
    Operation opera = null;
    switch (operate) {
      case "+":
        opera = new OperationAdd();
        break;
      case "-":
        opera = new OperationDelete();
        break;
      default:
        opera = null;
    }

    return opera;
  }
}

客户端类:

public class Client {

  @SuppressWarnings("resource")
  public static void main(String args[]) {

    System.out.println("请输入数学表达,每输入一个字符回车确认:");
    Scanner scanner = new Scanner(System.in);
    double numA = scanner.nextDouble();
    String operate = scanner.next();
    double numB = scanner.nextDouble();
    double result = 0;

    Operation op = OperationFactory.create(operate);
    op.setNumA(numA);
    op.setNumB(numB);
    result = op.getResult();
    System.out.println("=" + result);
  }
}

运行结果:
在这里插入图片描述
上面的方法看起来麻烦了很多,但是体现了Java的封装,继承,多态等三大特性,同时还体现了Java的面向对象编程的特点,便于扩展与维护。

不管你有多少操作方法,只需要将具体的操作类继承操作类就行,同时修改一下工厂类就行了,完全不会影响其它的计算类,这个就是设计模式的魅力。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值