建议结合示例源码理解
1 简单工厂模式
简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式
- 简单工厂模式的要点在于:当你需要什么,只需要传入一个参数,就可以获取你所需要的对象,而无须知道其创建细节
- 类图:
- 主要优点:
- 客户端免除直接创建对象,实现对象创建于使用的分离
- 客户端无需知道具体产品类的类名,只需要知道对应的参数即可
- 通过引入配置文件,可以在不修改客户端代码的情况下更换新的产品类
- 主要缺点:
- 由于产品类中集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要收到影响
- 增加系统中类的个数,增加了系统的复杂度
- 系统拓展困难,一旦有新产品就不得不修改工厂逻辑,不利于拓展与维护
- 使用场景:
- 工厂类负责创建的对象比较少,
- 客户端只知道传入工厂类的参数,对于如何创建对象不关心
2 工厂方法模式
简单工厂模式最大的缺点是当有新产品要加入到系统中时,必须修改工厂类,需要在其中加入必要的业务逻辑,这违背了“开闭原则” 。 在工厂方法中,我们不在提供统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,
一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类
工厂方法模式是简单工厂模式的延伸,它继承了简单工厂模式的优点,同时还弥补了简单工厂模式的不足,工厂方法模式是使用频率最高的设计模式之一,是很多开源框架与API类库的核心模式
-
类图:
-
主要优点:
- 用户创建产品,只需要关心产品对应的工厂,无需关心细节,甚至无需知道具体产品类的类名
- 在加入新产品时,无需修改客户端,只需要增加一个具体工厂与具体产品就可以,符合开闭原则
-
主要缺点:
- 增加新产品时,需要编写具体的产品类,还需要提供对应的工厂类,增加了系统的复杂度
- 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度
-
适用场景:
- 客户端不知道它所需要的对象的类 ,只知道对应的工厂名称
- 抽象工厂类通过其子类来指定创建哪个对象。在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展
3 抽象工厂模式
工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。此时,我们可以考虑将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产
抽象工厂模式是工厂模式的进一步的延伸,由于它提供了功能更为强大的工厂类,并具备较好的可拓展性,在软件开发张得以广泛应用
-
类图
-
主要优点:
- 增加新产品很方便,符合“开闭原则”,
-
主要缺点:
- 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则
-
适用场景:
- 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是很重要的,用户无须关心对象的创建过程,将对象的创建和使用解耦
- 系统中有多于一个的产品族,而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族
- 产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。
相关链接:
- 推荐书籍(原文):设计模式Java版
- 实例源码:/src/java/design_patterns