工厂模式
工厂方法模式:工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂模式的缺点就是没次都会创建一个新的对象,无法实现单例。Spring的Ioc解决了这个问题。
一、简单工厂方法
有很多个类(ConcreteProduct)都实现了同一个接口(Product),不必在每用到子类的地方直接new 一个子类,这样不利于管理和维护。比如某个ConcreteProduct的名字变了,那么所有使用到这个类的地方都需要进行更改维护,使用简单工厂方法就不会存在这种情况:

示例:
1. Product接口
1 | public interface Product { |
2. ConcreteProduct实现类
- (1) GoodProduct
1 | public class GoodProduct implements Product { |
- (2) BadProduct
1 | public class BadProduct implements Product { |
3.简单工厂
1 | public class ProductFactory {//简单工厂类 |
使用的时候就很简单了,只需要通过:
1 | Product product = ProductFactory.createProduct("good"); |
即可得到一个GoodProduct示例,这样即使GoodProduct名字变量,使用的客户端也不必知道。
二、工厂方法
简单工厂方法的缺点就是需要不断的维护简单工厂类,随着实现子类的增多,简单工厂类会变得越来越臃肿,因此在很大程度上,简单工厂类具有很强的耦合性,还可以进行优化,那就是为每一个具体的ConcreteProduct都创建一个工厂类:

示例:
1.Product接口
同上
2.ConcreteProduct实现类
同上
3.Factory接口/抽象类
1 | public abstract class Factory { |
如果使用了抽象类,还可以在工厂里面定义一些方法,用于实现回调。
4.ConcreteFactory实现类
- GoodFactory
1 | public class GoodFactory extends Factory { |
- BadFactory
1 | public class BadFactory extends Factory { |
使用的时候需要先创建对应的工厂,那么创建具体的对象就转为创建了对应的工厂了。感觉是进行了耦合的转移,并没有解耦。不过可以通过反射的方式创建:
1 | Factory badFactory = (Factory) Class.forName("com.design.factory.factorymethod.BadFactory").newInstance(); |
我感觉工厂方法模式最大的作用可能就是回调吧。
三、抽象工厂
抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象,这和抽象工厂模式有很大不同。
抽象工厂模式用到了工厂方法模式来创建单一对象,AbstractFactory 中的 createProductA() 和 createProductB() 方法都是让子类来实现,这两个方法单独来看就是在创建一个对象,这符合工厂方法模式的定义。
至于创建对象的家族这一概念是在 Client 体现,Client 要通过 AbstractFactory 同时调用两个方法来创建出两个对象,在这里这两个对象就有很大的相关性,Client 需要同时创建出这两个对象。
从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory,而工厂方法模式使用了继承。

示例:
1.Product接口/抽象类/普通类-家族
- ProductA
1 | public interface ProductA { |
- ProductB
1 | public interface ProductB { |
2.ConcreteProduct实现类
- GoodProductA
1 | public class GoodProductA implements ProductA { |
- GoodProductB
1 | public class GoodProductB implements ProductB { |
- BadProductA
1 | public class BadProductA implements ProductA { |
- BadProductB
1 | public class BadProductB implements ProductB { |
3. AbstractFactory(抽象工厂)
创建对象的家族
1 | abstract class AbstractFactory { |
4.ConcreteFactory实现类
- GoodFactory
1 | public class GoodFactory extends AbstractFactory { |
- BadFactory
1 | public class BadFactory extends AbstractFactory { |
使用的时候,通过:
1 | AbstractFactory af = new GoodFactory();//GoodFactory |
可以创建不同的对象族。
比较
个人觉得这个区别在于产品,如果产品单一,最合适用工厂模式;如果有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
再通俗深化理解下:工厂模式针对的是一个产品等级结构 ,抽象工厂模式针对的是面向多个产品等级结构的。
例子
用种蔬菜的例子来说明事实:
(1)最初的时候,由于规模小,只种植一种蔬菜,根菜类蔬菜,这个时候由于种植方式比较简单,采用简单工厂模式即可,主要目的是让工人轻松,下达工厂种植即可:

(2)但是随着种植厂的发展以及市场的需求,要增加一种蔬菜类型种植了,茎菜,由于茎菜与根菜种植方式不一致,就需要两个专门的种植工厂来进行管理,那么就采用工厂模式来管理,一个工厂负责一种作物的种植,这个时候产品可以理解为仍然在一个层次。

(3)但是随着科技的发展,我们逐步要种植转基因与非转基因食品了,在以前的蔬菜种类上又增加了一个层次,这个时候无法将其作为一个层次来解决,所以必须采用抽象工厂的方式来解决。

总结
在简单工厂模式下,工人要想到种植萝卜还是白菜,在工厂模式下,工人想到是种植根菜还是茎菜,而在抽象工厂模式下,则关心种植基因菜还是非基因菜。
参考文章:
评论加载中