本文采用了三种工厂模式
- 简单工厂模式
- 工厂方法模式
- 应用反射实现工厂模式
存放说明如下:
- com.dyk : 包含main方法的测试类
- com.dyk.factory : 三种工厂类(具体工厂类的接口或者具体的工厂类)
- com.dyk.factory.impl : 工厂类的具体实现
- com.dyk.operate : 具体运算类的父类
- com.dyk.operate.impl : 具体的运算类
一、简单工厂模式
这里需要用到五个类,分别是:OperationFactory、Operation、OperationAdd、OperationSub、Test。
首先看Opreration这个类
package com.dyk.operate; public class Operation { private double number1; private double number2; public double getNumber1() { return number1; } public void setNumber1(double number1) { this.number1 = number1; } public double getNumber2() { return number2; } public void setNumber2(double number2) { this.number2 = number2; } public double getResult() { double result = 0; return result; } }可以看到,在Operation这个类中定义了一个getResult()方法和number1和number2两个属性。没什么太多可说的。接下来看下它的子类。OperationAdd和OperationSub。
package com.dyk.operate.impl; import com.dyk.operate.Operation; public class OperationAdd extends Operation { @Override public double getResult() { double result = 0; result = super.getNumber1() + super.getNumber2(); return result ; } } public class OperationSub extends Operation { @Override public double getResult() { double result = 0; result = super.getNumber1() - super.getNumber2(); return result ; } }可以看到OperationAdd和OperationSub都重写了Operation类的getResult()方法。在getResult()方法中执行相应的加减操作。准备工作到此完成,接下来就可以着手写我们的工厂类了
package com.dyk.factory; import com.dyk.operate.Operation; import com.dyk.operate.impl.OperationAdd; import com.dyk.operate.impl.OperationSub; public class OperationFactory { public static Operation createOperationBySimpleFactory(String operation){ Operation oper = null; switch (operation) { case "+": oper = new OperationAdd(); System.out.println("加法运算"); break; case "-": oper = new OperationSub(); System.out.println("减法运算"); break; default: break; } return oper; } }
在工厂类OperationFactory中只有一个 createOperationBySimpleFactory ( String operation) 方法。方法内部对参数operation进行判断到底是+、-还是default。然后new出相应的实例并向上转型赋给Operation对象。最后返回这个对象 oper。至此,我们获得了一个由Operation子类向上转型而来的Operation对象。最后看下Test类测试下我们的简单工厂模式。
private static void simpleFactory() { Operation oper = null; oper = OperationFactory.createOperationBySimpleFactory( "+"); oper.setNumber1(1.5d); oper.setNumber2(1.2d); System. out.println("运算结果:" + oper.getResult()); oper = OperationFactory.createOperationBySimpleFactory( "-"); oper.setNumber1(1.5d); oper.setNumber2(1.2d); System. out.println("运算结果:" + oper.getResult()); }
运算结果如右:
简单工厂模式的优点:工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。每个子类只负责自己的逻辑,不关心调用过程。业务逻辑与界面逻辑分离开,让他们之间的耦合度下降。只有分离开,才能达到统一维护或扩展。
简单工厂模式的缺点:如果需要增加一种子类,需要在工厂类中添加分支。这样违反了设计模式中的开放-封闭原则。(工厂方法模式可以解决这种缺点)
********************************************工厂方法模式**************************************************
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法模式涉及到的类有:IFactory、AddFactory、SubFactory、Operation、OperationAdd、OperationSub、Test。在简单工厂模式的基础上提取出了工厂接口。
AddFactory和SubFactory都实现了这个接口。在重写的方法中进行相应的操作,具体如下
package com.dyk.factory; import com.dyk.operate.Operation; public interface IFactory { Operation createOperationByFactory(); }
package com.dyk.factory.impl; import com.dyk.factory.IFactory; import com.dyk.operate.Operation; import com.dyk.operate.impl.OperationAdd; public class AddFactory implements IFactory { @Override public Operation createOperationByFactory() { return new OperationAdd(); } } package com.dyk.factory.impl; import com.dyk.factory.IFactory; import com.dyk.operate.Operation; import com.dyk.operate.impl.OperationAdd; public class AddFactory implements IFactory { @Override public Operation createOperationByFactory() { return new OperationAdd(); } }在AddFactory和SubFactory的createOperationByFactory()方法中分别new出了一个Operation的子类对象。在Test类中实现如下
private static void factory() { Operation mOperation = null ; IFactory iFactory = null; iFactory = new AddFactory(); mOperation = iFactory.createOperationByFactory(); mOperation.setNumber1(1.5d); mOperation.setNumber2(1.2d); System. out.println("运算结果:" + mOperation.getResult()); iFactory = new SubFactory(); mOperation = iFactory.createOperationByFactory(); mOperation.setNumber1(1.5d); mOperation.setNumber2(1.2d); System. out.println("运算结果:" + mOperation.getResult()); }
运算结果如右:
工厂方法模式的优点:工厂方法模式是简单工厂模式的进一步抽象和推广。实现了在不违背开放-封闭原则的情况下对现有程序进行拓展。
工厂方法模式的缺点:客户端需要决定实例化哪一个工厂类实现运算类,将简单工厂的内部逻辑判断移到了客户端进行。你想要加功能,本来是要修改工厂类,现在要去修改客户端。(反射工厂模式可避免此问题)
****************************************运用反射实现工厂模式**********************************************
运行反射实现工厂模式涉及的类有:ReflectFactory、Operation、OperationAdd、OperationSub、Test。
运用反射实现工厂模式非常的简单,只需两行代码。
点我下载源码
package com.dyk.factory; import com.dyk.operate.Operation; public class ReflectFactory { public static Operation createOperationByReflectFactory(String classPath ){ Operation oper = null; try { oper = (Operation) Class.forName(classPath).newInstance(); } catch (InstantiationException e ) { e.printStackTrace(); } catch (IllegalAccessException e ) { e.printStackTrace(); } catch (ClassNotFoundException e ) { try { throw new Exception("opration is not instanceof Operation"); } catch (Exception e1 ) { e1.printStackTrace(); } e.printStackTrace(); } return oper ; } }Test测试方法如下
private static void reflectFactory() { Operation mOperation =null ; String classPath = "com.dyk.operate.impl.OperationAdd" ; mOperation = ReflectFactory.createOperationByReflectFactory( classPath); mOperation.setNumber1(1.5d); mOperation.setNumber2(1.2d); System. out.println("运算结果:" + mOperation.getResult()); }运算结果如右:
运用反射实现工厂模式的优点:实现了完全解耦。
运用反射实现工厂模式的缺点:每次参数都要传入完整的包名+类名。