在前面的“设计模式”示例中,我们解释了当今常用的“工厂”模式。 在本节中,我们将了解具有更多抽象的更高级的解决方案。 该模式称为工厂方法设计模式。
定义: |
---|
Factory方法模式提供了一种用于创建对象的方法,但是将对象创建委托给了子类。 工厂方法设计模式以类似于工厂模式的方式解决了这些问题,并附加了抽象级别。 |
可以使用new关键字实例化该对象。 例如,对象A使用以下方法创建另一个对象B:
ClassB objB = new ClassB();
因此,对象A拥有对对象B的引用。
由于如果后来修改了对象A,则对象A现在依赖于对象B,那么我们将不得不重新编译对象A。 对象的创建可能会更加复杂,如果存在更多的耦合,那么维护将是软件开发中一项痛苦而昂贵的工作。
为了避免这种最坏的情况,我们提供了新颖的设计模式来进行救援。 他们试图在客户端和对象创建者之间创建松散的耦合,并为开发人员提供其他一些设计优势。 工厂方法模式就是解决设计问题的一种模式。
常用: |
---|
工厂方法设计模式通常与装饰器设计模式一起用于各种框架(例如Struts,Spring,Apache)中。 有许多基于此Factory模式的J2EE模式,例如DAO模式。 |
让我们以服装工厂为例,我们正在创建各种类型的服装,但是客户完全不知道这些产品是如何创建的。 即使我们必须添加新的服装类型(例如夹克),也无需更改客户端代码,从而增加了应用程序的灵活性。
何时使用工厂方法模式?
- 对象的创建需要代码的重用,而无需大量重复代码。
- 一个类将不知道需要创建哪些子类。
- 子类可以指定应创建的对象。
- 父类会将对象的创建委托给其子类。
结构体
下图突出显示了工厂方法设计模式的典型结构。 与上述示例不同,已添加了一个附加的Factory Abstract(Factory)类。
在上图中,以下是参与者:
- 产品:这为工厂方法创建的对象定义了一个接口。
- 具体产品:实现产品接口。
- 工厂(创建者):这是一个抽象类,定义了返回产品对象的工厂方法。
- 具体工厂:此类实现并覆盖由父工厂类声明的方法。
客户(例如,对象类A)将要使用由ConcreteFactory类(对象类B)创建的产品。 但是,在这种情况下,客户端仅持有对接口B的引用,而不是对象“类B”,因此它不需要了解有关类B的任何信息。 实际上,可以有多个类可以实现抽象类。
Factory Method模式允许子类决定实例化哪个类的含义是什么? |
从根本上讲,这意味着对工厂抽象类进行编码,而无需知道将实例化哪些实际的ConcreteProduct类,即它是Trouser还是Shirt。 这完全由ConcreteFactory类确定。 |
现在,将上述模式实现到我们的GarmentFactory示例中。
让我们开始吧。 我们不会重复在Factory Pattern文章中找到的具体产品的代码,例如Shirt.java和Trouser.java。
已创建一个面向客户的新Factory抽象类。
public abstract class Factory {
protected abstract GarmentType createGarments(String selection);
}
需要修改GarmentFactory类以继承抽象类Factory。
public class GarmentFactory extends Factory{
public GarmentType createGarments(String selection) {
if (selection.equalsIgnoreCase('Trouser')) {
return new Trouser();
} else if (selection.equalsIgnoreCase('Shirt')) {
return new Shirt();
}
throw new IllegalArgumentException('Selection doesnot exist');
}
}
客户端类引用Factory类,并对Factory的createGarments(selection)方法进行分类以在运行时创建产品。
Factory factory = new GarmentFactory();
GarmentType objGarmentType = factory.createGarments(selection);
System.out.println(objGarmentType.print());
优点:
- 通过将对象创建从客户端代码移到Factory类及其子类,代码可以灵活,松耦合和可重用。 由于异议创建是集中的,因此维护此类代码更加容易。
- 客户代码仅处理产品接口,因此无需修改客户代码逻辑即可添加任何具体产品。
- Factory Method的优点是它可以多次返回相同的实例,或者可以返回子类而不是该确切类型的对象。
- 它通过在工厂中创建对象来鼓励代码的一致性,该工厂强制执行每个人都必须遵循的一组明确的规则。 这样可以避免在不同的客户端使用不同的构造函数。
例:
JDBC是这种模式的一个很好的例子。 应用程序代码不需要知道将与哪个数据库一起使用,因此不需要知道应使用哪些特定于数据库的驱动程序类。 相反,它使用工厂方法来获取连接,语句和其他可使用的对象。 这提供了更改后端数据库的灵活性,而无需更改您的DAO层。
以下是SDK中的一些示例:
valueOf()方法,返回由工厂创建的对象,该对象与传递的参数值相等。 getInstance()方法,该方法创建Singleton类的实例。 newInstance()方法,该方法用于每次调用时从工厂方法创建和返回新实例。 下载示例代码
参考: Idiotechie博客上来自JCG合作伙伴 Mainak Goswami的使用Factory Method Pattern设计最佳实践 。
翻译自: https://www.javacodegeeks.com/2012/10/design-best-practices-using-factory-method-pattern.html