前言 说实话,就算是假期,每日一到两篇的更新还是有点累的,写一篇长一点的文章差不多一个下午就过去了,但是我个人觉得写文章比较适合我学习,变写的同时能知道哪些不懂,顺便再去复习一下,也算是个不错的方式吧。 今天就来聊聊抽象工厂模式。
正文 概念 之前我们讲过工厂模式,工厂模式的特点是对象的创建交给工厂来实现,隐藏内部逻辑,但是工厂模式也有相应的缺点,那就是一个工厂只能生产一类产品,但往往一个工厂需要有创建多种商品的功能,而抽象工厂模式就是为了解决这个问题。 抽象工厂模式简单说就是一个大工厂下有几个小工厂,小工厂实现大工厂的所有产品。它解决的就是工厂模式下,每个工厂只能创建一类产品的缺点。
实现 就从上次的工厂模式的案例说起,现在一个工厂既可以生产游戏,又可以生产周边,我们就从这个例子来实现抽象工厂模式。 首先是游戏接口及其实体类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public interface Game { void test () ; } public class GameA implements Game { @Override public void test () { System.out.println("this is Game A" ); } } public class GameB implements Game { @Override public void test () { System.out.println("this is Game B" ); } } public class GameC implements Game { @Override public void test () { System.out.println("this is Game C" ); } }
接下来创建周边接口及其实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public interface Hobby { public void test () ; } public class HobbyA implements Hobby { @Override public void test () { System.out.println("this is HobbyA" ); } } public class HobbyB implements Hobby { @Override public void test () { System.out.println("this is HobbyB" ); } } public class HobbyC implements Hobby { @Override public void test () { System.out.println("this is HobbyC" ); } }
接下来是创建一个抽象工厂
1 2 3 4 public abstract class AbstractFactory { public abstract Game getGame (String name) ; public abstract Hobby getHobby (String name) ; }
创建两个工厂继承抽象工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public class GameFactory extends AbstractFactory { public Game getGame (String name) { if (name == null ){ return null ; } if (name.equalsIgnoreCase("GameA" )){ return new GameA(); }else if (name.equalsIgnoreCase("GameB" )){ return new GameB(); }else if (name.equalsIgnoreCase("GameC" )){ return new GameC(); } return null ; } @Override public Hobby getHobby (String name) { return null ; } } public class HobbyFactory extends AbstractFactory { @Override public Game getGame (String name) { return null ; } @Override public Hobby getHobby (String name) { if (name == null ){ return null ; } if (name.equalsIgnoreCase("HobbyA" )){ return new HobbyA(); }else if (name.equalsIgnoreCase("HobbyB" )){ return new HobbyB(); }else if (name.equalsIgnoreCase("HobbyC" )){ return new HobbyC(); } return null ; } }
接下来是创建工厂生成器来获取相应的工厂
1 2 3 4 5 6 7 8 9 10 public class FactoryBuilder { public static AbstractFactory getFactory (String factoryName) { if (factoryName.equalsIgnoreCase("Game" )){ return new GameFactory(); }else if (factoryName.equalsIgnoreCase("Hobby" )){ return new HobbyFactory(); } return null ; } }
创建客户端进行调用
1 2 3 4 5 6 7 8 9 10 11 12 13 public class Client { public static void main (String[] args) { AbstractFactory gameFactory = FactoryBuilder.getFactory("Game" ); AbstractFactory hobbyFactory = FactoryBuilder.getFactory("Hobby" ); Game game = gameFactory.getGame("GameA" ); game.test(); Hobby hobby = hobbyFactory.getHobby("HobbyC" ); hobby.test(); } }
以上我们就简单实现了抽象工厂模式,其实原理还是很简单的。
后续思考 当抽象工厂模式中,产品只有一个的时候,抽象工厂模式就是工厂模式,反过来,当产品由一个变多个时,工厂模式变为抽象工厂模式。 那在抽象工厂模式中,添加一个工厂需要怎么操作呢? 很简单,我们只需要创建一个继承于AbstractFactory的工厂就可以了。 那添加一个新的产品呢? 首先当然需要添加一个新的接口与对应的实现类,其次抽象工厂中,需要添加该产品,导致所有继承于抽象类的工厂都必须添加这个产品,只是可以不生产而已,代码上的话,如果工厂很多,就需要添加这些工厂中的重写方法。
优缺点 抽象工厂模式的优点在于解决工厂模式中只能创建单一产品的缺点。并且拥有工厂模式的优点。 而缺点在于产品的扩展较为麻烦,上文提到,添加产品,需要修改抽象类,又需要在实现的工厂中增加代码。
总结 本文简单谈了谈抽象工厂模式,这个模式在开发中很少用到,对整体的架构不利于扩展,修改的话又十分麻烦。工厂模式对于框架的设计还是较为常用的,比如spring的getBean,又如java中的线程池(可以看看线程池的文章),等等很多例子。总之这个工厂模式还是比较重要的。