简单工厂模式
前言:这两天学习了简单工厂模式、工厂方法模式、抽象工厂模式,在这里详细说一下简单工厂模式。转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9280695.html
简单工厂模式
定义:简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
使用的设计原则:对修改关闭,对扩展开放。
优点:简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
缺点:在简单工厂模式中,工厂类与分支耦合,也就是说如果要新加一个(在工厂类中加一个分支)类,需要在工厂类里去加“Case”分支条件的,就会导致修改原有的类,违背了开放-封闭原则。
举例说明:
要求:使用面向对象实现一个计算器控制台程序,要求输入两个数字和运算符号,得到结果。
重点:使用面向对象思想。
使用简单工厂实现:
类图:
运算抽象类
/** * 运算抽象类 */ abstract class Operation{ private int num1; private int num2; public int getNum1() { return num1; } public void setNum1(int num1) { this.num1 = num1; } public int getNum2() { return num2; } public void setNum2(int num2) { this.num2 = num2; } public abstract double getResult(); }
运算具体类
/** * 加法运算 */ class AddOperation extends Operation{ @Override public double getResult() { return getNum1() + getNum2(); } } /** * 减法运算 */ class SubOperation extends Operation{ @Override public double getResult() { return getNum1() - getNum2(); } } /** * 除法运算 */ class DivOperation extends Operation{ @Override public double getResult() { return getNum1() / getNum2(); } } /** * 乘法运算 */ class MulOperation extends Operation{ @Override public double getResult() { return getNum1() * getNum2(); } }
运算简单工厂
所有在用简单工厂方法的地方,都可以考虑用反射的技术来去除 switch 或 if ,解除分支判断带来的耦合。
/** * 运算简单工厂 */ class OperationFactory{ public static Operation createOperation(String type){ Operation operation; switch (type){ case "+": operation = new AddOperation(); break; case "-": operation = new SubOperation(); break; case "*": operation = new MulOperation(); break; case "/": operation = new DivOperation(); break; default: operation = null; } return operation; } }
客户
public static void main(String[] args) throws IOException { try{ Scanner scanner = new Scanner(System.in); System.out.println("请输入第一位数字:"); int num1 = scanner.nextInt(); System.out.println("请输入操作符:"); String flag = scanner.next(); System.out.println("请输入第二位数字:"); int num2 = scanner.nextInt(); Operation operation = OperationFactory.createOperation(flag); operation.setNum1(num1); operation.setNum2(num2); System.out.println(operation.getResult()); }catch (Exception e){ e.printStackTrace(); System.out.println("您输入有误!"); } }
使用普通方式实现:
上面的例子如果不适用简单工厂则是下面这样,虽然使用了面向对象的封装,但以后一旦涉及到有开放等运算需要加进来时就不满足对修改关闭,对扩展开放的设计原则了:
class Operation{ public static double getResult(int num1, int num2, String operationFlag){ if(operationFlag.equals("+")){ return num1 + num2; }else if(operationFlag.equals("-")){ return num1 - num2; }else if(operationFlag.equals("*")){ return num1 * num2; }else if(operationFlag.equals("/")){ return num1 / num2; } return 0; } }
public static void main(String[] args) throws IOException { try{ Scanner scanner = new Scanner(System.in); System.out.println("请输入第一位数字:"); int num1 = scanner.nextInt(); System.out.println("请输入操作符:"); String flag = scanner.next(); System.out.println("请输入第二位数字:"); int num2 = scanner.nextInt(); System.out.println(Operation.getResult(num1, num2, flag)); }catch (Exception e){ e.printStackTrace(); System.out.println("您输入有误!"); } }
总结:
1、new 是在实例化一个具体类,有时需要在运行时才知道需要实例化哪一个类(如下),但是这样的代码一旦有变化和扩展(以后某一天可能会不适用具体类1,而使用一个具体类4;或者增加一个 else if)时,就必须重新考虑这段代码是否符合现有需求。所以才会想到“将变化的东西从不变的地方抽离出来”,这里不变的是方法的调用,变化的是实例化哪一个具体类。最后将变化的地方抽出来单独放在另一个对象(只管如何创建具体类)里面去,这个单独的对象为“工厂”,即工厂只做对象的创建,不管其他的。
接口 test = null; if(....){ test = new 具体类1(); }else if(...){ test = new 具体类2(); }else{ test = new 具体类3(); }
test.方法1();//每个具体类都有的方法
test.方法2();//每个具体类都有的方法
//使用test 做其他的操作.....
2、简单工厂其实不是一个设计模式,反而比较像是一种编程习惯。
3、不要因为简单工厂不是一个“真正的”设计模式,就忽略了它的用法。
其他工厂模式:https://www.cnblogs.com/yuxiaole/p/9276396.html
转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9280695.html
参考书籍:《Head First 设计模式》《大话设计模式》