本篇文章主要介绍抽象工厂模式。
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。
我们先看下结构图:
AbstractProductA和AbstractProductB是俩个抽象产品,之所有抽象,是因为它们都有可能有俩种不同的实现;而ProductA1、ProductA2和ProductB1、ProductB2就是对俩个抽象产品的具体分类实现。AbstractFactory是一个抽象工厂接口,它里面应该包含所有产品创建的抽象方法,而ConcreteFactory1和ConcreteFactory2就是具体的工厂了。
下面我们参照类图给出基本的java代码。
首先是产品部分的代码。
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:16 */ public interface AbstractProductA { void methodA(); }
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:19 */ public class ProductA1 implements AbstractProductA { @Override public void methodA() { System.out.println("产品A系列1型号产品的方法"); } }
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:20 */ public class ProductA2 implements AbstractProductA { @Override public void methodA() { System.out.println("产品A系列2型号产品的方法"); } }
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:18 */ public interface AbstractProductB { void methodB(); }
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:21 */ public class ProductB1 implements AbstractProductB { @Override public void methodB() { System.out.println("产品B系列1型号产品的方法"); } }
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:21 */ public class ProductB2 implements AbstractProductB { @Override public void methodB() { System.out.println("产品B系列2型号产品的方法"); } }
然后是工厂部分代码。
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:15 */ public interface AbstractFactory { AbstractProductA createProductA(); AbstractProductB createProductB(); }
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:16 */ public interface AbstractProductA { void methodA(); }
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:18 */ public interface AbstractProductB { void methodB(); }
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:23 */ public class ConcreteFactory1 implements AbstractFactory { @Override public AbstractProductA createProductA() { return new ProductA1(); } @Override public AbstractProductB createProductB() { return new ProductB1(); } }
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:24 */ public class ConcreteFactory2 implements AbstractFactory{ @Override public AbstractProductA createProductA() { return new ProductA2(); } @Override public AbstractProductB createProductB() { return new ProductB2(); } }
最后是测试类和运行结果。
package com.lwx.abstract_factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 16:25 */ public class Client { public static void main(String[] args) { AbstractFactory factory1 = new ConcreteFactory1(); factory1.createProductA().methodA(); factory1.createProductB().methodB(); AbstractFactory factory2 = new ConcreteFactory2(); factory2.createProductA().methodA(); factory2.createProductB().methodB(); } }
上面的代码比较简单,下面我们将上次工厂方法模式中的例子改成抽象工厂模式。
首先是运算总接口。
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:57 */ public interface Operation { double getResult(double a, double b); }
然后是加、减、乘、除四种运算的抽象接口和具体实现。
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:44 */ public interface OperationAdd extends Operation { double getResult(double a, double b); }
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:45 */ public class ConcreteOperationAdd implements OperationAdd { @Override public double getResult(double a, double b) { return a + b; } }
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:46 */ public interface OperationSub extends Operation { double getResult(double a, double b); }
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:46 */ public class ConcreteOperationSub implements OperationSub { @Override public double getResult(double a, double b) { return a - b; } }
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:47 */ public interface OperationMul extends Operation { double getResult(double a, double b); }
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:47 */ public class ConcreteOperationMul implements OperationMul { @Override public double getResult(double a, double b) { return a * b; } }
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:48 */ public interface OperationDiv extends Operation { double getResult(double a, double b); }
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:49 */ public class ConcreteOperationDiv implements OperationDiv{ @Override public double getResult(double a, double b) { if (b == 0){ throw new ArithmeticException("除数不能为0"); } return a / b; } }
然后是工厂类总接口,以及四种运算的具体工厂实现类。
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:24 */ public interface Factory { Operation createOperation(); }
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:52 */ public class AddFactory implements Factory { @Override public Operation createOperation() { return new ConcreteOperationAdd(); } }
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:54 */ public class SubFactory implements Factory { @Override public Operation createOperation() { return new ConcreteOperationSub(); } }
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:59 */ public class MulFactory implements Factory { @Override public Operation createOperation() { return new ConcreteOperationMul(); } }
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:59 */ public class DivFactory implements Factory { @Override public Operation createOperation() { return new ConcreteOperationDiv(); } }
最后是测试类和运行结果。
package com.lwx.abstract_factory.example; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-04-07 * Time: 17:59 */ public class Client { public static void main(String[] args) { double a = 10; double b = 20; Factory factory = null; factory = new AddFactory(); Operation addOperation = factory.createOperation(); System.out.println("加法:" + addOperation.getResult(a, b)); factory = new SubFactory(); Operation subOperation = factory.createOperation(); System.out.println("减法:" + subOperation.getResult(a, b)); factory = new MulFactory(); Operation mulOperation = factory.createOperation(); System.out.println("乘法:" + mulOperation.getResult(a, b)); factory = new DivFactory(); Operation divOperation = factory.createOperation(); System.out.println("除法:" + divOperation.getResult(a, b)); } }
总结一下抽象工厂的优点和缺点:
优点:
1.抽象工厂模式易于交换产品系列,由于具体工厂类在一个应用中只需要再初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
2.抽象工厂模式让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。
缺点:
添加新的行为时比较麻烦。如果需要添加一个新产品族对象时,需要更改接口及其下所有子类。
最后附上demo的githup地址:https://github.com/yijinqincai/design_patterns