博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单工厂模式
阅读量:5311 次
发布时间:2019-06-14

本文共 6910 字,大约阅读时间需要 23 分钟。

一、举例

做一个非常简单的计算机,实现加减乘除运算即可,大家自然而然的会写出如下代码

1 public static void Main(String[] args) { 2   Scanner scanner = new Scanner(System.in); 3   System.out.println("请输入数字A:"); 4   double strNumA = scanner.nextDouble(); 5   System.out.println("请选择运算符号(+、-、*、/、)"); 6   String strOperate = scanner.next(); 7   System.out.println("请输入数字C:"); 8   double strNumB = scanner.nextDouble(); 9   double strResult = 0;10   if ("+".equals(strOperate)) {11    strResult = strNumA + strNumB;12   }13   if ("-".equals(strOperate)) {14    strResult = strNumA - strNumB;15   }16   if ("*".equals(strOperate)) {17    strResult = strNumA * strNumB;18   }19   if ("/".equals(strOperate)) {20    strResult = strNumA / strNumB;21   }22   System.out.println("结果是:" + strResult);23  }

 

 

二,优化

1,第一步

①由于在判断运算符时,用的是if语句,这意味着每个条件都需要做判断,相当于计算机做了三次无用功。

②没有输入校验,例如,除数不能为零的问题等等

就上述两个问题,做如下修改:

1 public static void Main(String[] args) { 2     { 3       Scanner scanner = new Scanner(System.in); 4       System.out.println("请输入数字A:"); 5       double strNumA = scanner.nextDouble(); 6       System.out.println("请选择运算符号(+、-、*、/、)"); 7       String strOperate = scanner.next(); 8       System.out.println("请输入数字C:"); 9       double strNumB = scanner.nextDouble();10       double strResult = 0;11         switch (strOperate)12         {13             case "+":14              strResult = strNumA + strNumB;15                 break;16             case "-":17              strResult = strNumA - strNumB;18                 break;19             case "*":20              strResult = strNumA * strNumB;21                 break;22             case "/":23                 if (strNumB != 0)24                 {25                  strResult = strNumA / strNumB;26                 }27                 else28                 {29                     System.out.println("除数不能为0");30                 }31                 break;32         }33         System.out.println("结果是:" + strResult);34     }

 2、第二步

①上述写的简单的计算器仅仅体现了面向过程的编程,没有体现面向对象的编程

②上述代码使用控制台应用实现的,假如有一天我需要用Web 等实现一模一样的需求,那么,上述代码则需要重新编写,好可怕。

就上述问题,做如下修改:(将业务逻辑与界面分离)

Operation运算类

1 public class Operation 2     { 3         public static double getResult(double numA, double numB, String strOperate) 4         { 5             double result = 0; 6             switch (strOperate) 7             { 8                 case "+": 9                     result = numA + numB;10                     break;11                 case "-":12                     result = numA - numB;13                     break;14                 case "*":15                     result = numA * numB;16                     break;17                 case "/":18                     result = numA / numB;19                     break;20             }21             return result;22         }23     }

客户端

1     public static void Main(String[] args) { 2     { 3         try 4         { 5             Scanner scanner = new Scanner(System.in); 6             System.out.println("请输入数字A:"); 7             double strNumA = scanner.nextDouble(); 8             System.out.println("请选择运算符号(+、-、*、/、)"); 9             String strOperate = scanner.next();10             System.out.println("请输入数字C:");11             double strNumB = scanner.nextDouble();12             double strResult = 0;13             strResult =Operation.getResult(strNumA, strNumB, strOperate);14             System.out.println("结果是:" + strResult);15         }16         catch (Exception ex)17         {18             System.out.println("您的输入有错:"+ex.getMessage());19         }20     }

这样的话,无论是控制台,还是WEB以及其他应用,只需要调用 Operation 这个类即可了。实现了业务逻辑与界面的分离。这里,也用到了面向对象编程的三大特性之一的封装。

3、第三步

①如果我想增加一种计算方式,例如开根号(sqrt)运算怎么办,只能是修改Operation类,在switch中增加一种情况。

②针对①问题做修改的话,那么另一个问题就来了,我修改Oeration类的时候,之前写好的加减乘除功能全在其中,如果我不小心,或者有意搞破坏,将本来运行的好好的加减乘除功能改掉,怎么办?(此例中仅仅是计算器,如果换做是成熟的产品,或者涉及到资金运算等等的代码,运行的好好的,不可能会让程序员在其中胡作非为的)

针对上述问题,作如下修改:

我可以将加减乘除各种运算分别封装到不同的类里面,这样,就能解决②的问题,每增加一种运算,我就增加一个类,这样①问题也解决了。

首先,将不同的运算抽象出一个共同的类,即父类

1 public class Operation { 2     private double numberA; 3     private double numberB; 4  5     public double getNumberA() { 6         return numberA; 7     } 8  9     public void setNumberA(double numberA) {10         this.numberA = numberA;11     }12 13     public double getNumberB() {14         return numberB;15     }16 17     public void setNumberB(double numberB) {18         this.numberB = numberB;19     }20 21     public double getResult() {22         double result = 0;23         return result;24     }25 26 }

其次,让不同的运算继承这个父类,然后根据不同的运算,重写父类中的GetResult方法

1 // 加法类 2     public class OperationAdd extends Operation { 3         @Override 4         public double getResult() { 5             double result = 0; 6             result = numberA + numberB; 7             return result; 8         } 9     }10 11     // 减法类12     public class OperationSub extends Operation {13         @Override14         public double getResult() {15             double result = 0;16             result = numberA - numberB;17             return result;18         }19     }20 21     // 乘法类22     public class OperationMul extends Operation {23         @Override24         public double getResult() {25             double result = 0;26             result = numberA * numberB;27             return result;28         }29     }30 31     // 除法类32     public class OperationDiv extends Operation {33         @Override34         public double getResult() {35             double result = 0;36             if (numberB == 0) {37                 System.out.println("除数不能为0");38             }39             result = numberA / numberB;40             return result;41         }42     }

4、第四步

到了简单工厂最核心的地方了。

 这么多的类,客户端该如何用这些类呢,换句话说,客户端如何实例化这些类呢?那么,就需要一个核心的东西——工厂,这个工厂负责给客户端提供他想要的类的实例。我想要实例化什么类,告诉工厂就可以了。

代码如下:

1 public class OperationFactory 2     { 3         public static Operation createOperate(String operate) 4         { 5             Operation oper = null; 6             switch (operate) 7             { 8                 case "+": 9                     oper = new OperationAdd();10                     break;11                 case "-":12                     oper = new OperationSub();13                     break;14                 case "*":15                     oper = new OperationMul();16                     break;17                 case "/":18                     oper = new OperationDiv();19                     break;20             }21             return oper;22         }23     }

注意:这个工厂中的方法,返回的是加减乘除这些类的父类.

制造类实例的工厂有了,那么,客户端只需要告诉工厂,给我造一个什么类的实例,然后用这个实例就可以了。

客户端代码如下:

1 public static void Main(String[] args) 2     { 3         Operation oper; 4         //告诉工厂,给我一个加法类的实例 5         oper = OperationFactory.createOperate("+"); 6         oper.setNumberA(1); 7         oper.setNumberB(2); 8         double result = oper.getResult(); 9         System.out.println(result);10     }

经过上述一系列的修改,也就形成了简单工厂模式。

三、总结

简单工厂模式,即 通过一个‘工厂类’,用于子类返回父类类型或接口类型。


简单工厂模式结束,下一次,将讲解复杂工厂模式

 

转载于:https://www.cnblogs.com/hpxiaokang/p/6403333.html

你可能感兴趣的文章
zabbix监控日志文件
查看>>
正则表达式
查看>>
pip install torch on windows, and the 'from torch._C import * ImportError: DLL load failed:' s...
查看>>
java基础(一):我对java的三个环境变量的简单理解和配置
查看>>
arcgis api 4.x for js 结合 Echarts4 实现散点图效果(附源码下载)
查看>>
YTU 2625: B 构造函数和析构函数
查看>>
apache自带压力测试工具ab的使用及解析
查看>>
C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码
查看>>
jenkins搭建
查看>>
C#中使用Split分隔字符串的技巧
查看>>
eclipse的调试方法的简单介绍
查看>>
加固linux
查看>>
IPSP问题
查看>>
10.17动手动脑
查看>>
WPF中Image显示本地图片
查看>>
Windows Phone 7你不知道的8件事
查看>>
实用拜占庭容错算法PBFT
查看>>
java的二叉树树一层层输出,Java构造二叉树、树形结构先序遍历、中序遍历、后序遍历...
查看>>
php仿阿里巴巴,php实现的仿阿里巴巴实现同类产品翻页
查看>>
Node 中异常收集与监控
查看>>