设计模式学习之简单工厂模式
2017-05-15 09:02
459 查看
先说一个简单的案例:
实现一个控制台程序,输入两个数字和一个运算符,输出其计算结果。
案例很简单
但是这样写真的很好吗?java语言的面向对象的优越性就这样放弃了??这样算是业务逻辑和界面逻辑分离了???
基于上述考虑我们可以对这个案例进行重新设计
先考虑业务与逻辑的分离:
使用面向对象的三大特性:
现在问题是我该如何让程序知道我该实现哪个类完成计算
这里就需要用到简单工厂模式
建立工厂类
在main方法中就可以应用该工厂完成Operate的实例化
从上述的例子中不难看出
简单工厂模式解决的问题是:如何根据需要实例化合适的类
其核心思想:用一个专门的类去产生实例
优缺点分析:
优点:
工厂类是整个模式的关键所在。
包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。
用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。
有利于整个软件体系结构的优化。
缺点:
工厂类集中了所有实例的创建逻辑,这就直接导致一旦这个工厂出了问题,所有的客户端都会受到牵连;
简单工厂模式的产品室基于一个共同的抽象类或者接口,这样一来,但产品的种类增加的时候,
即有不同的产品接口或者抽象类的时候,工厂类就需要判断何时创建何种种类的产品,
这就和创建何种种类产品的产品相互混淆在了一起,违背了单一职责,导致系统丧失灵活性和可维护性。
而且更重要的是,简单工厂模式违背了“开放封闭原则”,就是违背了“系统对扩展开放,对修改关闭”的原则,
因为当我新增加一个产品的时候必须修改工厂类,相应的工厂类就需要重新编译一遍。
实现一个控制台程序,输入两个数字和一个运算符,输出其计算结果。
案例很简单
Class Main{ public static void main(String args){ Scanner scan = new Scanner(System.in); System.out.print("请输入数字A:"); double numberA = scan.nextDouble(); System.out.print("请输入操作符(+ - * /):"); String operate = scan.next(); System.out.print("请输入数字B:"); double numberB = scan.nextDouble(); scan.close(); switch(operate){ case "+": System.out.println("计算结果是"+(numberA+numberB)); break; case "-": System.out.println("计算结果是"+(numberA-numberB)); break; case "*": System.out.println("计算结果是"+(numberA*numberB)); break; case "/": System.out.println("计算结果是"+(numberA/numberB)); break; default: System.out.println("操作符有误"); break; } } }
但是这样写真的很好吗?java语言的面向对象的优越性就这样放弃了??这样算是业务逻辑和界面逻辑分离了???
基于上述考虑我们可以对这个案例进行重新设计
先考虑业务与逻辑的分离:
Class Main{ public static void main(String args){ Scanner scan = new Scanner(System.in); System.out.print("请输入数字A:"); double numberA = scan.nextDouble(); System.out.print("请输入操作符(+ - * /):"); String operate = scan.next(); System.out.print("请输入数字B:"); double numberB = scan.nextDouble(); scan.close(); Operate op = new Operate(numberA, numberB, operate); System.out.println("计算结果是"+op.getResult()); } } class Operate{ private double numberA; private double numberB; private String operate; public Operate(double numberA, double numberB, String operate){ this.numberA = numberA; this.numberB = numberB; this.operate = operate; } public double getResult(){ switch(operate){ case "+": return (numberA+numberB); break; case "-": return (numberA-numberB); break; case "*": return(numberA*numberB); break; case "/": return (numberA/numberB); break; default: break; } } }
使用面向对象的三大特性:
public abstract class Operator { private double numberA; private double numberB; public double getNumberA() { return numberA; } public void setNumberA(double numberA) { this.numberA = numberA; } public double getNumberB() { return numberB; } public void setNumberB(double numberB) { this.numberB = numberB; } public abstract double getResult() throws Exception; } class AddOperator extends Operator{ @Override public double getResult() { return this.getNumberA()+this.getNumberB(); } } class MinusOperator extends Operator{ @Override public double getResult() { return this.getNumberA()-this.getNumberB(); } } class MultiplyOperator extends Operator{ @Override public double getResult() { return this.getNumberA()* this.getNumberB(); } } class DivideOperator extends Operator{ @Override public double getResult() throws Exception { if(this.getNumberB() == 0) throw new Exception("除数不能为零"); return this.getNumberA()/ this.getNumberB(); } }
现在问题是我该如何让程序知道我该实现哪个类完成计算
这里就需要用到简单工厂模式
建立工厂类
public class OperateFactory { public static Operator createOperator(String operate){ switch (operate) { case "+":return new AddOperator(); case "-":return new MinusOperator(); case "*":return new MultiplyOperator(); case "/":return new DivideOperator(); default:return null; } } }
在main方法中就可以应用该工厂完成Operate的实例化
class Main{ public static void main(String[] args) { Scanner scan = new Scanner(System.in); System.out.print("输入数字A:"); double numberA = scan.nextDouble(); System.out.print("输入操作符(+ - * / ):"); String operate = scan.next(); System.out.print("输入数字B:"); double numberB = scan.nextDouble(); scan.close(); Operator op = TestFactoryPattern.createOperator(operate); op.setNumberA(numberA);op.setNumberB(numberB); try { System.out.println("计算结果:"+op.getResult()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
从上述的例子中不难看出
简单工厂模式解决的问题是:如何根据需要实例化合适的类
其核心思想:用一个专门的类去产生实例
优缺点分析:
优点:
工厂类是整个模式的关键所在。
包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。
用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。
有利于整个软件体系结构的优化。
缺点:
工厂类集中了所有实例的创建逻辑,这就直接导致一旦这个工厂出了问题,所有的客户端都会受到牵连;
简单工厂模式的产品室基于一个共同的抽象类或者接口,这样一来,但产品的种类增加的时候,
即有不同的产品接口或者抽象类的时候,工厂类就需要判断何时创建何种种类的产品,
这就和创建何种种类产品的产品相互混淆在了一起,违背了单一职责,导致系统丧失灵活性和可维护性。
而且更重要的是,简单工厂模式违背了“开放封闭原则”,就是违背了“系统对扩展开放,对修改关闭”的原则,
因为当我新增加一个产品的时候必须修改工厂类,相应的工厂类就需要重新编译一遍。
相关文章推荐
- 设计模式学习——简单工厂模式(开篇)
- 设计模式之简单工厂模式(“从头开始学习设计模式”系列)
- 设计模式学习-简单工厂模式
- 设计模式学习—简单工厂模式
- 设计模式学习之策略模式和简单工厂模式的区别和联系
- 设计模式学习之简单工厂模式(java)
- 学习23种设计模式之简单工厂模式
- 设计模式之简单工厂模式学习案例代码
- 设计模式学习笔记之简单工厂模式
- [设计模式]学习设计模式之一(简单工厂模式)
- 设计模式学习(1) 简单工厂模式
- 设计模式学习笔记--简单工厂模式
- 【设计模式】简单工厂模式学习笔记
- 设计模式学习之策略模式和简单工厂模式的区别和联系
- 设计模式学习(二)简单工厂模式-工厂模式-抽象工厂模式
- 设计模式学习笔记 简单工厂模式
- 设计模式学习之简单工厂模式和策略模式
- 设计模式学习笔记一:Simple factory pattern,简单工厂模式
- 设计模式学习笔记--简单工厂模式
- JAVA设计模式学习4——简单工厂模式