版权声明 :
本文为博主原创文章,如需转载,请注明出处(https://blog.csdn.net/F1004145107/article/details/99861531)
-
/ 前言 /
到了这篇文章我会用更多的心思和篇幅在演化之路上,因为我觉得思路比固定的模式重要的,话不多说,我们直接开始
-
/ 1 / 为什么要使用抽象工厂模式
既然在有了工厂方法模式的前提下还衍生出来了抽象工厂,那说明是用来解决某些特定问题的,经过前文的铺垫设计模式(一) - 简单工厂与工厂方法我们明白了什么是简单工厂以及什么是工厂方法,上一篇文章我们也说到了工厂方法的不足,无法简单的解决要生产系列产品的问题,抽象工厂被发明出来就是用来解决这一问题的
-
/ 2 / 抽象工厂模式怎么用
什么是系列产品呢,一个品牌下不同型号的产品,比如我们都喜欢机械键盘,但是机械键盘也拥有不同的款式,比如樱桃(Cherry)的87键键盘和104键键盘
受限于篇幅,我们删减掉了上一篇文章中部分代码,并将抽象类改为接口,但是例子还是同一个例子,话不多说我们直接上代码看一下
产品的全部代码
俩个产品接口 :
KeyBoard87
,KeyBoard104
具体的产品实现类 :
Razer87
,Cherry87
,Razer104
,Cherry104
//87键键盘产品 public interface KeyBoard87 { void introduce87(); } //雷蛇87键键盘 public class Razer87 implements KeyBoard87 { @Override public void introduce87() { System.out.println("雷蛇87键键盘"); } } //樱桃87键键盘 public class Cherry87 implements KeyBoard87 { @Override public void introduce87() { System.out.println("樱桃87键键盘"); } } //104键键盘产品 public interface KeyBoard104 { void introduce104(); } //雷蛇104键键盘 public class Razer104 implements KeyBoard104 { @Override public void introduce104() { System.out.println("雷蛇104键键盘"); } } //樱桃104键键盘 public class Cherry104 implements KeyBoard104 { @Override public void introduce104() { System.out.println("樱桃104键键盘"); } }
工厂的全部代码,这里是和工厂方法最大的不同之处,一个工厂中生产多种同系列的产品
一个工厂的接口 :
KeyBoardFactory
具体工厂的实现类 :
RazerFactory
,CherryFactory
//工厂接口 :定义产品生产接口 public interface KeyBoardFactory { KeyBoard87 createKeyBoard87(); KeyBoard104 createKeyBoard104(); } //雷蛇键盘工厂 :生产雷蛇87键及104键键盘 public class RazerFactory implements KeyBoardFactory { //生产雷蛇87键键盘 @Override public KeyBoard87 createKeyBoard87() { return new Razer87(); } //生产雷蛇104键键盘 @Override public KeyBoard104 createKeyBoard104() { return new Razer104(); } //樱桃键盘工厂 :生产樱桃87键及104键键盘 public class CherryFactory implements KeyBoardFactory { //生产樱桃87键键盘 @Override public KeyBoard87 createKeyBoard87() { return new Cherry87(); } //生产樱桃104键键盘 @Override public KeyBoard104 createKeyBoard104() { return new Cherry104(); }
测试代码
public class Demo { public static void main(String[] args) { //生产Razer87键 RazerFactory razerFactory = new RazerFactory(); KeyBoard87 keyBoard87 = razerFactory.createKeyBoard87(); keyBoard87.introduce87(); //生产Razer104键 KeyBoard104 keyBoard104 = razerFactory.createKeyBoard104(); keyBoard104.introduce104(); //生产Cherry87键 CherryFactory cherryFactory = new CherryFactory(); keyBoard87 = cherryFactory.createKeyBoard87(); keyBoard87.introduce87(); //生产Cherry104键 keyBoard104 = cherryFactory.createKeyBoard104(); keyBoard104.introduce104(); } }
输出结果
雷蛇87键键盘
雷蛇104键键盘
樱桃87键键盘
樱桃104键键盘
我们来看一下抽象工厂的思路
1.我们发现雷蛇87键和樱桃87键都有一个共同的特性,那就是都是87的键盘,那我们就将这一特性抽象成一个接口中并让具体的产品去实现这一个接口和特性
2.按照工厂方法模式我们应该定义的分别是雷蛇87工厂以及雷蛇104工厂,但是我们发现它们有一个共同点那就是都是雷蛇旗下的产品,那我们就将这一特性抽象成一个新的工厂雷蛇工厂
3.既然雷蛇工厂都抽象出来了,那我们为何不将雷蛇87和104的生产都放到雷蛇工厂呢,没必要再单独建立工厂
4.调用时我们只需要创建该品牌工厂的对象就可以生产该品牌所有的产品
至于我们在什么时候使用抽象工厂大家应该非常清晰了,只要出现了上述的场景,毫不犹豫的使用抽象工厂,不需要通过简单工厂 → 工厂方法 → 抽象工厂一步一步的来
-
/ 3 / 演化之路
终于来到了这部分,在这里我既要解释清楚工厂方法的演化之路,也要表达出我对架构的看法,希望能为大家提供多一个角度的看法,我会尽量的写的明白
我们先来看工厂的演化之路,我将会将之前的例子的代码大量删除,只留下结构来表示每个工厂的不同
简单工厂
//产品 public class Keyboard {} //工厂 public class SimpleFactory { public static Keyboard getKeyboard (String name) {} }
抽象工厂
//抽象产品 public interface Keyboard {} //具体的产品 public class Cherry extends Keyboard{} public class Razer extends Keyboard {} //工厂的抽象类 public interface KeyboardFactory {} //具体的工厂实现 public class CherryFactory implements KeyboardFactory{} public class RazerFactory implements KeyboardFactory{}
工厂方法
//87键键盘抽象产品 public interface KeyBoard87 {} //具体的87键键盘产品的实现 public class Razer87 implements KeyBoard87 {} public class Cherry87 implements KeyBoard87 {} //104键键盘抽象产品 public interface KeyBoard104 {} //具体的104键键盘产品的实现 public class Razer104 implements KeyBoard104 {} public class Cherry104 implements KeyBoard104 {} //工厂的抽象,生产俩种抽象产品 public interface KeyBoardFactory { KeyBoard87 createKeyBoard87(); KeyBoard104 createKeyBoard104(); } //具体生产产品的工厂实现 public class RazerFactory implements KeyBoardFactory { //生产87键产品 @Override public KeyBoard87 createKeyBoard87() { return new Razer87(); } //生产104键产品 @Override public KeyBoard104 createKeyBoard104() { return new Razer104(); } public class CherryFactory implements KeyBoardFactory { @Override public KeyBoard87 createKeyBoard87() { return new Cherry87(); } @Override public KeyBoard104 createKeyBoard104() { return new Cherry104(); } }
在我看来一个架构最重要的是其健壮性及扩展性,其中健壮性放在最前面,如果你的设计可以让使用者非常方便的扩展但是可能会破坏内部的结构,那么这个设计一定是失败的,因为你要明白你的设计最终会被部署到线上的平台,而线上的平台是不允许被破坏的
罗马不是一天建成的,一个完善的系统也不是在开发伊始就能设计出来的,我们需要在后期进行不断的优化、迭代来完善我们的系统,当系统发展到一定规模时,我们就需要抽取那些重要的功能来形成一个组件,当我们把所有的组件拼装到一起时就是我们的系统,我习惯与在设计时就考虑怎么样才能让这个组件被‘大众’所用,这里的大众指的是现在的以及未来的同事,如何让他们能快速的根据当前业务场景来定制化他们所需要的,这里就需要我们设计出足够优秀的架构来支撑组件的快速扩展
关于工厂方法 → 抽象工厂我们上面说的已经非常清楚了,但是上面没有重点说的就是抽象,架构的演化之路就相当于西天取经之路,我们需要明确知道我们的目标(西天),中间通过各种方式来达到我们的目标(法宝),在我看来抽象就是推进架构演化的一个重要法宝
相信大家通过上面的架构代码看出来了简单工厂 → 工厂方法的演化就是将不同的产品放到不同的工厂生产,我们所采用的方法就是抽象,将共有的特性抽取出来,形成标准,我们虽然将产品的生产分离了但是我们需要为其制定标准以保证所有的工厂和产品都符合我们的要求
-
/ 4 / 结语
工厂模式是一个非常有意义的模式,简单、高效、使用率高,非常适合拿来做设计模式的入门,希望大家可以完全的消化工厂模式的演化,我个人认为这个是比较有意义的,整个设计模式体系中只有工厂模式可以体现出演化的过程
我们使用设计模式不是为了用而用,而是为了方便我们的开发
工厂模式到此结束~