工厂方法属于创建型设计模式。
设计意图:定义一个用于创建对象的接口。让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
静态工厂使用面向对象的方式,有效的攻克了添加新产品给client和实现类带来的代码改动问题。封装了创建过程,减低了添加新产品带来的代码改动错误。可是新增功能须要改动client代码和工厂创建类的推断逻辑,这种设计违背了开放-封闭原则。对扩展开放。对改动封闭,那我们就须要找一种方式避免添加新的功能时改动工厂创建方法的逻辑。(毕竟会对原有代码做改动难免会有失误)
工厂方法就是有效解决问题的设计模式。
类图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">
通过工厂方法模式的类图能够看到。工厂方法模式有四个要素:
- 工厂接口。工厂接口是工厂方法模式的核心,与调用者直接交互用来提供产品的创建。
- 工厂实现。在编程中,工厂实现决定怎样实例化产品。是实现扩展的途径,须要有多少种产品。就有多少个详细的工厂实现类,每一个工厂实现类负责创建一种产品。
- 产品接口。
产品接口的主要目的是定义产品的规范,全部的产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的。产品接口定义的优劣直接决定了调用者代码的稳定性。
- 产品实现。
实现产品接口的详细类,不同的产品也须要不同的产品实现类。产品实现类与功能创建类相相应。
通过类图我们还能够看到。每添加一个产品就添加一个相应的工厂来创建它,这样整个工厂和产品体系都没有什么变化,而仅仅是扩展的变化,这就全然符合开放-封闭的原则了。
我来看代码实例:
package com.factory.staticfactory.extend; /** * @author gaoxu * 实践出真知!产品接口 */ public interface IOperation { /**计算方法 * @author gaoxu * @return */ public double calculate(); }
产品接口定义产品的处理方式。
package com.factory.staticfactory.extend; /** * @author gaoxu * 实践出真知!抽象父类 */ public abstract class AbstractOperation implements IOperation{ double numA = 0; double numB = 0; public double getNumA() { return numA; } public void setNumA(double numA) { this.numA = numA; } public double getNumB() { return numB; } public void setNumB(double numB) { this.numB = numB; } }
实现接口并提供数据设置公共的方法。
package com.factory.staticfactory.extend; /** * @author gaoxu * 实践出真知! */ public class OperationAdd extends AbstractOperation{ @Override public double calculate() { return numA+numB; } }
package com.factory.staticfactory.extend; /** * @author gaoxu * 实践出真知。 */ public class OperationSub extends AbstractOperation{ @Override public double calculate() { return numA-numB; } }
加法、减发类实现各自的业务逻辑。
package com.factory.factorymethod; import com.factory.staticfactory.extend.IOperation; /**工厂方法接口 * @author gaoxu * 实践出真知。 */ public interface IFactory { public IOperation createOperation(); }
package com.factory.factorymethod; import com.factory.staticfactory.extend.IOperation; import com.factory.staticfactory.extend.OperationAdd; /**加法工厂类 * @author gaoxu * 实践出真知! */ public class AddFactory implements IFactory{ public IOperation createOperation(){ return new OperationAdd(); } }
package com.factory.factorymethod; import com.factory.staticfactory.extend.IOperation; import com.factory.staticfactory.extend.OperationSub; /**减发工厂类 * @author gaoxu * 实践出真知! */ public class SubFactory implements IFactory{ public IOperation createOperation(){ return new OperationSub(); } }
工厂方法的长处:
1:严格遵循面向对象类的设计原则。比方单一职能原则、开-闭原则、依赖倒置原则、迪米特原则。
2:业务实现解耦。
工厂方法是静态工厂的进一步抽象与推广,因为使用了多态性。工厂方法模式保持了静态工厂的长处同一时候又克服了它的缺点,只是工厂方法自己的缺点是每加一个产品都须要添加一个工厂类。添加了大量的开发工作量。