昨天我们说到 Factory Method模式,
然后挖了个坑…没有说 Abstract Factory,主要是因为这两种模式之间相似度比较高,一起讲容易混淆,所以就另起一篇来说了。
关于 Factory Method,可以回顾昨天的文章 Factory Method
Factory Method
Factory Method的最后说道复杂的设计模式,可以把 Factory进一步抽象,将生产实际实例的逻辑放到各个不同的 Factory里去做,使用者只关心去跟对应的 Factory实例拿实例就行。也不再需要用一个超级工厂类来管理所有的实例生产过程。
在这里,每个 Factory只关心它所生产的一个实例,就像 FactoryRed,它只需要实现一个 create()接口,返回一个 Red对象就行,
public class FactoryRed implements Factory { Color create() { return new Red(); }}
但当情况进一步复杂,Factory Method就显得不够用了。 比如这种情况,每个工程所需要生产的不仅仅只是一个实例,而是两个或以上的互相关联的实例。
还是以上面例子,拓展一下进行说明。
比如现在工厂不仅需要生产 Color对象,还需要生产 Brush对象用来刷 Color,而每个颜色需要跟对应的刷子一起用。> Red -> BrushRed Blue -> BrushBlue
对于这种情况,我们就需要将Factory再进一步抽象,提取两个接口,
interface Factory { Color createColor(); Brush createBrush();}
对于这种设计模式,通常是需要处理两个或以上的互相关联对象生成的时候,需要抽象到 Factory层面,这也就是 Abstract Factory了。
Abstract Factory
好了,现在我们有抽象好的 Factory接口,但是为了更清晰的说明思路,我们还是来完成剩下的东西。
对于 Brush,它的接口可以是这样的,
interface Brush { void brush();}
现在我们实现两个刷子,
public class BrushRed implements Brush { void brush() { System.out.println("painting red"); }}public class BrushBlue implements Brush { void brush() { System.out.println("painting blue"); }}
颜色有了,刷子也有了,工厂可以开工,
public class FactoryRed implements Factory { public Color createColor() { return new Red(); } public Brush createBrush() { return new BrushRed(); }}
对于使用者来说,再也不需要关心 Color实例和 Brush实例的对应关系,不用担心用错了Brush去操作 Color会怎样,他们知道的只是 FactoryRed 会提供所需要的 Color和Brush的实例
Factory factory = new FactoryRed();Color color = factory.createColor();Brush brush = factory.createBrush();//now we're paintingpaint(color, brush);
即使后来产品说要改需求,对于使用者来说,也只是简单修改一下使用者所使用的具体工厂类而已,不用去大幅度的修改代码,同时还要考虑各个实例之间的依赖关系。
总结
对于 Abstract Factory来说,它相对于 Factory Method在 Factory层面更抽象了一层,对于需要考虑 Factory会生产多个实例的情况, 应该使用Abstract Factory来进行隔离。
有人会说,用 ColorFactory和 BrushFactory定义单独的接口,也可以实现这种需求。虽然没错,这样其实也是 Facotry Method,但这样的缺点在于,所生产的实例之间的依赖关系就需要使用者自己去操心了。这对于面向对象封闭原则来说非常不好,你想啊,我写个代码还要关心每个对象之间的依赖关系,一不小心调错还要debug半天,这工作量太难受了。
所以其实这也是 Factory Method和 Abstract Factory之间的区别了。
