工厂模式可以将对象的创建封装起来,以便于得到更松耦合,更有弹性的设计。所有工厂模式都通过减少应用程序和具体类之间的依赖促进耦合。
1.针对抽象编程,而不要针对具体类编程。
2.依赖倒置原则,指导避免依赖具体类型,而要尽量依赖抽象。
简单工厂模式
简单工厂模式不属于 GoF 23个经典设计模式。
简单工厂模式(Simple Factory Pattern)定义:定义一个工厂类,它可以根据传入的不同参数来返回不同的类的实例。
由于在简单工厂模式中用于创建实例的方法是静态方法,因而又被称为静态工厂方法模式,属于类创建型模式。
每更换一个生产的产品需要更改代码中传入的type参数,违反了“开闭原则”,可以通过将该参数存储在配置文件中。
简化的简单工厂模式:可以将抽象产品类 Product 和工厂类 Factory 合并,将静态工厂方法移至 Product 类中。
- 优点
- 实现了对象创建和使用的分离。
- 引入配置文件,可以在不修改代码的情况下更换 Product 实现类型,提高了灵活性。
- 缺点
- 工厂类职责过重,集中了所有产品的创建逻辑,某一环节出错可能会影响整个系统。
- 系统扩展和维护困难,添加新产品必须修改工厂逻辑。
- 适用场景
- 工厂类负责创建的对象比较少,不会造成工厂方法中的业务逻辑过于复杂。
工厂方法模式
工厂方法模式(Factory Method Pattern):定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象,不再像简单工厂模式中将所有逻辑集中在一个工厂类里。
对于应该使用哪个具体的工厂类实现来生成具体的产品实例,可以通过配置文件存储工厂类的类名。
- 优点
- 工厂方法隐藏了哪种具体产品类将被实例化。
- 基于工厂角色和产品角色的多态性是工厂方法模式的关键,隐藏了产品被实例化的细节。
- 新产品加入时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他具体工厂和具体产品,只需要添加一个具体产品和相应的具体工厂即可。扩展性好,符合“开闭原则”。
- 缺点
- 添加新产品时,需要编写新的具体产品类及其具体工厂类,会导致系统中类的个数成对增加,增加了系统复杂度和额外开销。
- 由于引入了抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,实现时可能会使用反射、DOM等技术根据配置文件来实例化具体工厂,增加了实现难度。
- 使适用场景
- 客户端不知道所需的具体产品类,只要知道所对应的工厂即可。
- 抽象工厂类通过其子类来指定创建哪个对象,利用面向对象的多态性和里氏代换原则,使系统更容易扩展。
实例:
|
|
|
|
抽象工厂模式
抽象工厂模式(Abstract Factory Pattern):提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。为创建一组对象提供了解决方案,,而不是像工厂方法中为每个工厂只创建一个产品。
产品等级结构:即产品的继承结构。
产品族:指由一个工厂生产的,位于不同产品等级结构的一组产品,如海尔工厂生产海尔电视机、海尔电冰箱,电视机和电冰箱分别位于不同的产品等级结构,且构成了一个产品族。
抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中。
- 优点
- 多个产品对象组成一个产品族,可以保证客户端始终只使用一个产品族。
- 增加新的产品族很方便,符合“开闭原则”。
- 缺点
- 增加新的产品等级结构比较麻烦,需要对原系统进行较大的修改,甚至需要修改抽象层的代码,这点违背了“开闭原则”。
- 适用场景
- 系统不依赖于产品类如何创建、组合的细节,用户无需关心对象的创建过程。
- 系统有多个产品族,每次只使用一个产品族,可以通过配置文件方式来动态改变产品族。
- 产品的等级结构稳定。
实例:
|
|
|
|
|
|