前提:思考
请你用java实现计算器的加减乘除功能,这个题看着很简单,也很好实现,但是假设这是个面试题的话,你觉得面试官真正的目的在哪?
一:模式说明
1:简单工厂模式,它是工厂模式的一种特殊实现,属于创造型模式,又称静态工厂模式,但不属于GOF设计模式之一;简单模式是有一个工厂对象来决定创建出哪一种商品的实例;
二:UML类图(案例UML图)
三:代码实现(创建一个加减乘除运算的模块)
1:简单工厂类 easyFactory,createOperator() 方法用于创建对应的运算对像(我用的jdk1.8,如果是jdk1.6 switch中不可用String,只可用 enum,int,short,byte,char)
/*
* 简单工厂类
*/
public class EasyFactory {
public static Operator createOperator(String operationType) {
Operator operator = null;
switch (operationType) {
case "+":
operator = new OperatorAdd();
break;
case "-":
operator = new OperatorSub();
break;
case "*":
operator = new OperatorMul();
break;
case "/":
operator = new OperatorDiv();
break;
}
return operator;
}
}
接口:operator用于
/**
* Project Name:design
* File Name:Operator.java
* Package Name:com.cn.easyFactory
* Date:2018年7月23日下午10:29:49
* Copyright @ 2010-2018 SUN All Rights Reserved.
*
*/
package com.cn.easyFactory;
/**
* ClassName:Operator <br/>
* Description: 简单工厂模式中 所有抽象产品的父类. <br/>
* Date: 2018年7月23日 下午10:29:49 <br/>
*
* @version
* @since JDK 1.8
* @see
*/
public abstract class Operator {
public int numberA;
public int numberB;
public int getNumberA() {
return numberA;
}
public int getNumberB() {
return numberB;
}
/**
* getResult:(运算方法). <br/>
*
* @Date: 2019年3月12日 下午9:55:11
* @return
* @since JDK 1.8
*/
public abstract int getResult();
public void setNumberA(int numberA) {
this.numberA = numberA;
}
public void setNumberB(int numberB) {
this.numberB = numberB;
}
}
加法类:
public class OperatorAdd extends Operator {
@Override
public int getResult() {
int result = super.getNumberA() + super.getNumberB();
return result;
}
}
减法类:
public class OperatorSub extends Operator {
@Override
public int getResult() {
int result = super.getNumberA() - super.getNumberB();
return result;
}
}
客户端:
/**
* main:客户端.执行加法 <br/>
*
* @param args
* @since JDK 1.8
*/
public static void main(String[] args) {
Operator operator = EasyFactory.createOperator("+");
operator.setNumberA(1);
operator.setNumberB(2);
System.out.println(operator.getResult());
}
四:适用范围及优缺点
优点:1、客户端不必关心对象如何创建,由工厂类来决定创建哪个具体对象;
2、明确区分了各自的职责和权利,有利于整个软件体系结构的优化;
缺点:1、创建对像的方法,集中在工厂类中,后续增加对像,必须要对工厂类进行修改和增加,这就使得创建对象方法容易混乱,越来越繁琐,不利于系统的维护和扩展;
2、违反了开闭原则(如果demo中想增加其他运算,比如乘方,求导,那么我们必然要修改switch方法,这时候,我们不仅对扩展开放了,也对修改开放了);
适用范围: 1、使用与创建对象较少
2、客户端只知道传入工厂类参数,不在乎创建逻辑
五:优化静态工厂(enum和反射)
1:创建OperatorEnum类
public class OperatorEnum {
public enum Operator_status {
add("com.cn.easyFactory.OperatorAdd"), div("com.cn.easyFactory.OperatorDiv"),
mul("com.cn.easyFactory.OperatorMul"), sub("com.cn.easyFactory.OperatorSub"), errorVal("error");
public static String getOperator(String val) {
try {
String filePath = valueOf(val).getValue();
return filePath;
} catch (Exception e) {
return valueOf("errorVal").getValue();
}
}
String value;
private Operator_status(String val) {
this.value = val;
}
private String getValue() {
return this.value = value;
}
}
}
2:EasyFactory 新增createOperator1() 方法 修改如下:
/**
* createOperator1:(使用enum和反射优化静态工厂). <br/>
* 参数不能是 +-/* ,改为add, div,sub 等等
*
* @author:xx Date: 2019年4月11日 下午11:45:26
* @param operationType
* @return
* @throws Exception
* @since JDK 1.8
*/
public static Operator createOperator1(String operationType) throws Exception {
//调用枚举
String filePath = OperatorEnum.Operator_status.getOperator(operationType);
if ("error".equals(filePath)) {
return null;
}
//利用反射
Class<?> class1 = Class.forName(filePath);
Operator operator = (Operator) class1.newInstance();
return operator;
}
优化过后我们就不用再担心swith语句不断增加case的问题了;