设计模式-简单工厂模式
来源:互联网 发布:单桂敏淘宝店铺7205286 编辑:程序博客网 时间:2024/05/16 23:58
设计模式-简单工厂模式
概念:
1、简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
2、简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
3、该模式中包含的角色及其职责:
工厂(Factory)角色:
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
抽象产品(AbstarctProduct)角色:
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品(SpecificProduct)角色:
是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
优点
工厂类是整个模式的核心类; 包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件结构的优化
缺点
当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;利用反射可以使得这些缺点在工厂方法模式中得到了一定的克服。
使用场景
工厂类负责创建的对象比较少;
客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
UML类图结构:
图背景介绍:
上图利用简单工厂模式实现一个控制台计算器功能
图解说明:
工厂(Factory)角色:
类:OperationFactory
说明:通过传入操作符‘+’ | ‘-’ | ‘*’ | ‘/’ 给方法buildOperation,告诉工厂我要哪个具体产品,内部使用swith语句实现(关注我的博客,后续有关于使用反射实现的方式)
代码:
/** * Created by laizhiyuan on 2017/6/1. * * 设计模式-简单工厂模式-工厂类 */public abstract class OperationFactory { public static final AbstractOperation buildOperation(char oper){ switch (oper){ case '+': return new AddOperation(); case '-': return new SubOperation(); case '*': return new MultOperation(); case '/': return new DivisionOperation(); default: throw new RuntimeException("input oper error"); } }}
抽象产品(AbstarctProduct)角色:
类: AbstractOperation
说明:产品基类,可以使用普通类或抽象类,定义产品模板和统一工厂方法的返回值;这里我使用抽象类作为基类;
代码:
/** * Created by laizhiyuan on 2017/5/31. * * 设计模式-简单工厂模式-产品基类-运算逻辑抽象 */public abstract class AbstractOperation { /** * 操作数A */ private double countA; /** * 操作数B */ private double countB; public double getCountA() { return countA; } public void setCountA(double countA) { this.countA = countA; } public double getCountB() { return countB; } public void setCountB(double countB) { this.countB = countB; } /** * 抽象运算接口,由子类实现 * @return */ public abstract double countResult();}
具体产品(SpecificProduct)角色:
类:AddOperation DivisionOperation SubOperation MultOperation
说明:具体实现
代码:
/** * Created by laizhiyuan on 2017/6/1. * * 设计模式-简单工厂模式-产品子类(加法运算实现) */public class AddOperation extends AbstractOperation{ /** * 加法运算实现 * @return */ @Override public double countResult() { if (this.getCountA() == 0){ return this.getCountB(); } if (this.getCountB() == 0){ return this.getCountA(); } return this.getCountA() + this.getCountB(); }}
/** * Created by laizhiyuan on 2017/6/1. * * 设计模式-简单工厂模式-产品子类(除法运算实现) */public class DivisionOperation extends AbstractOperation{ /** * 除法运算实现 * @return */ @Override public double countResult() { if (this.getCountB() == 0){ /** * 除数不能为0 */ throw new RuntimeException("Divisor cannot be zero"); } return this.getCountA() / this.getCountB(); }}
/** * Created by laizhiyuan on 2017/6/1. * * 设计模式-简单工厂模式-产品子类(乘法运算实现) */public class MultOperation extends AbstractOperation{ /** * 乘法运算实现 * @return */ @Override public double countResult() { if (this.getCountA() == 0 || this.getCountB() == 0){ return 0; } return this.getCountA() * this.getCountB(); }}
/** * Created by laizhiyuan on 2017/6/1. * * 设计模式-简单工厂模式-产品子类(减法运算实现) */public class SubOperation extends AbstractOperation{ /** * 减法运算实现 * @return */ @Override public double countResult() { if (this.getCountA() == 0){ return 0; } if (this.getCountB() == 0){ return this.getCountA(); } return this.getCountA() - this.getCountB(); }}
测试
/** * Main方法测试 * * Created by laizhiyuan on 2017/6/1. */public class Main { public static void main(String[] args) { System.out.println("请输入第一个操作数:"); Scanner scanner = new Scanner(System.in); String operA = scanner.nextLine(); try{ System.out.println("请输入操作符:"); String oper = scanner.nextLine(); char operChar = oper.charAt(0); boolean tag = false; if (operChar != '+' && operChar != '-' && operChar != '*' && operChar != '/'){ tag = true; } while (tag){ System.out.println("输入操作符错误,请重新输入!"); oper = scanner.nextLine(); operChar = oper.charAt(0); if (operChar != '+' && operChar != '-' && operChar != '*' && operChar != '/'){ tag = true; }else{ tag = false; } } System.out.println("请输入第二个操作数:"); String operB = scanner.nextLine(); AbstractOperation operation = OperationFactory.buildOperation(operChar); operation.setCountA(Double.valueOf(operA)); operation.setCountB(Double.valueOf(operB)); double resultCount = operation.countResult(); System.out.println("计算结果是=======> " + resultCount); }catch (Exception ex){ System.out.printf("输入有误!"); System.exit(1); } }}
控制台输出
阅读全文
0 0
- 简单工厂设计模式
- 设计模式-----简单工厂
- 简单工厂设计模式
- 设计模式:简单工厂
- 设计模式 - 简单工厂
- 设计模式 简单工厂
- 【设计模式】【简单工厂】
- 简单工厂设计模式
- 简单工厂设计模式
- 设计模式--简单工厂
- 简单工厂设计模式
- 简单工厂设计模式
- 设计模式------------简单工厂
- 设计模式--简单工厂
- 简单工厂设计模式
- 设计模式---------简单工厂
- 设计模式--简单工厂
- 简单工厂设计模式
- The superclass "javax.servlet.http.HttpServlet" was not found on the Java
- LeetCode 264. Ugly Number II
- 实用的添加购物车抛物线动画和自由落体类型动画
- 【混得好的都有这 5 种特质】优秀的年轻人都有这 5 大特质
- 使用Fragment时,遇到的问题
- 设计模式-简单工厂模式
- 分东西
- 组合模式
- Logger日志级别说明及设置方法、说明(转)
- 现代起亚的中立模式
- label长度过长
- 动态规划的一个简单实例java
- cocos-js 麻将(二)
- 6月1日《网络安全法》出台_让被攻击者投诉有门!