一、简介
1.1 什么是工厂方法模式
在软件开发中,我们经常需要根据不同的需求创建不同的对象或者实例,为了实现这一目的,我们通常会采用工厂模式。工厂模式是一种创建型模式,它提供了一种创建对象的最佳方式。
工厂模式分为简单工厂、工厂方法和抽象工厂三种,本文将重点介绍工厂方法模式。
工厂方法模式是一种创建型设计模式,它将对象的创建委托给工厂类。工厂类负责创建对象,并返回对象的实例。这种方式可以将对象的创建与使用分离,使得代码更加灵活。
工厂方法模式只有一个抽象产品类,且具体工厂类只能创建一个具体产品类的实例。
1.2 工厂方法模式的组成部分
抽象产品接口
(Product Interface):定义产品的接口,即产品所具有的属性和方法。具体产品类
(Concrete Product):实现抽象产品接口中定义的属性和方法。抽象工厂类
(Abstract Factory):定义一个抽象工厂方法,该方法返回一个抽象产品接口类型的对象。具体工厂类
(Concrete Factory):实现抽象工厂类中定义的抽象工厂方法,返回一个具体产品类的实例。客户端
(Client):通过具体工厂类来创建具体产品类的实例,然后使用产品的属性和方法。
1.3 工厂方法模式的应用场景
- 需要灵活地增加新的产品类型。
- 需要将产品的创建与使用分离。
- 需要控制产品的实例化过程,避免因为创建对象时可能发生的错误。
- 需要在运行时动态地指定产品类型。
- 需要在不同的平台上,使用不同的实现。
- 需要支持多种风格的用户界面。
- 需要在框架中使用插件,以便在运行时动态地添加功能。
1.4 工厂方法模式的优缺点
1.4.1 优点:
- 可以将产品的创建与使用分离,使得代码更加灵活。
- 可以在不改变原有代码的情况下,灵活地增加新的产品类型。
- 可以通过工厂类来控制产品的实例化,从而避免了因为创建对象时可能发生的错误。
1.4.2 缺点:
- 需要定义很多的类,增加了代码的复杂度。
- 如果产品类型很多,那么就需要定义很多的工厂类,增加了代码的复杂度。
二、示例
我们通过一个简单的例子来说明工厂方法模式的使用。
先创建一组具有相同约束的产品,比如
产品A
、产品B
和产品C
,它们都实现了同一个接口IProduct
。同时,我们需要创建三个工厂来生产这一组产品,分别是FactoryA
、FactoryB
和FactoryC
。
2.1 定义一个抽象产品接口
首先定义一个抽象产品接口
IProduct
,它定义了一个抽象的使用方法use()
,留给实现类去实现。
/**
* 定义一个抽象产品接口
*/
public interface IProduct {
// 定义一个抽象的使用方法,留给实现类去实现
void use();
}
2.2 定义三个具体产品A、B和C
然后,定义三个具体的产品类
ProductA
、ProductB
和ProductC
,它们实现了抽象产品接口IProduct
中定义的use()
方法。
产品A
import com.qfx.modules.factory.model.IProduct;
/**
* 定义一个产品A
*/
public class ProductA implements IProduct {
@Override
public void use() {
// 实现了抽象产品接口定义的use方法
System.out.println("生产 ProductA");
}
}
产品B
import com.qfx.modules.factory.model.IProduct;
/**
* 定义一个产品B
*/
public class ProductB implements IProduct {
@Override
public void use() {
// 实现了抽象产品接口定义的use方法
System.out.println("生产 ProductB");
}
}
产品C
import com.qfx.modules.factory.model.IProduct;
/**
* 定义一个产品C
*/
public class ProductC implements IProduct {
@Override
public void use() {
// 实现了抽象产品接口定义的use方法
System.out.println("生产 ProductC");
}
}
2.3 定义一个抽象工厂接口
接下来,定义一个抽象工厂类
FmFactory
,它定义了一个抽象的工厂方法createProduct()
,留给具体的工厂类去实现。该接口是工厂方法模式的核心,负责实现创建所有的具体产品(
ProductA
、ProductB
、ProductC
)的内部逻辑。
import com.qfx.modules.factory.model.IProduct;
/**
* 定义工厂接口.该接口是工厂方法模式的核心,负责实现创建所有的具体产品(ProductA、ProductB、ProductC)的内部逻辑
*/
public interface FmFactory {
// 定义一个抽象的使用方法,留给实现类去实现
IProduct createProduct();
}
2.4 定义三个具体工厂类
然后,定义三个具体的工厂类
FactoryA
、FactoryB
和FactoryC
,它们分别创建ProductA
、ProductB
和ProductC
的实例。
工厂A
import com.qfx.modules.factory.abstractFactory.FmFactory;
import com.qfx.modules.factory.model.IProduct;
import com.qfx.modules.factory.model.impl.ProductA;
/**
* 该类实现了FmFactory接口,用于生产ProductA类的实例
*/
public class FactoryA implements FmFactory {
@Override
public IProduct createProduct() {
return new ProductA();
}
}
工厂B
import com.qfx.modules.factory.abstractFactory.FmFactory;
import com.qfx.modules.factory.model.IProduct;
import com.qfx.modules.factory.model.impl.ProductB;
/**
* 该类实现了FmFactory接口,用于生产ProductB类的实例
*/
public class FactoryB implements FmFactory {
@Override
public IProduct createProduct() {
return new ProductB();
}
}
工厂C
import com.qfx.modules.factory.abstractFactory.FmFactory;
import com.qfx.modules.factory.model.IProduct;
import com.qfx.modules.factory.model.impl.ProductC;
/**
* 该类实现了FmFactory接口,用于生产ProductC类的实例
*/
public class FactoryC implements FmFactory {
@Override
public IProduct createProduct() {
return new ProductC();
}
}
2.5 客户端调用
最后,定义一个客户端类
FactoryMethodDemo
,它通过工厂类创建产品的实例,并调用产品的方法。先创建三个具体工厂的实例,然后通过调用它们的
createProduct
方法来创建具体产品的实例,并且调用它们的use
方法。
import com.qfx.modules.factory.abstractFactory.FmFactory;
import com.qfx.modules.factory.abstractFactory.impl.FactoryA;
import com.qfx.modules.factory.abstractFactory.impl.FactoryB;
import com.qfx.modules.factory.abstractFactory.impl.FactoryC;
import com.qfx.modules.factory.model.IProduct;
/**
* 工厂方法模式测试
*/
public class FactoryMethodDemo {
/**
* 测试工厂方法模式的功能:
* 它使用FactoryA、FactoryB、FactoryC三个具体工厂分别生产
* ProductA、ProductB、ProductC三个具体产品,并调用它们的use()方法。
*/
public static void main(String[] args) {
// 创建FactoryA具体工厂的实例
FmFactory factoryA = new FactoryA();
// 通过调用createProduct()方法生产具体产品ProductA
IProduct productA = factoryA.createProduct();
// 调用ProductA的use()方法
productA.use();
// 创建FactoryB具体工厂的实例
FmFactory factoryB = new FactoryB();
// 通过调用createProduct()方法生产具体产品ProductB
IProduct productB = factoryB.createProduct();
// 调用ProductB的use()方法
productB.use();
// 创建FactoryC具体工厂的实例
FmFactory factoryC = new FactoryC();
// 通过调用createProduct()方法生产具体产品ProductB
IProduct productC = factoryC.createProduct();
// 调用ProductB的use()方法
productC.use();
}
}
执行结果:
三、解析
- 以上文章介绍了如何使用 Java 代码实现工厂方法设计模式。
- 首先定义了一个抽象产品接口
IProduct
,然后定义了三个具体的产品类,它们实现了抽象产品接口中定义的use()
方法。- 接下来定义了一个抽象工厂类
FmFactory
,它定义了一个抽象的工厂方法createProduct()
,留给具体的工厂类去实现。- 然后,定义了三个具体的工厂类,它们分别创建
ProductA
、ProductB
和ProductC
的实例。- 最后,通过工厂类创建产品的实例,并调用产品的方法。
四、总结
- 工厂方法模式是一种创建型设计模式,它将对象的创建委托给工厂类。工厂类负责创建对象,并返回对象的实例。这种方式可以将对象的创建与使用分离,使得代码更加灵活。
- 组成部分包括抽象产品接口、具体产品类、抽象工厂类、具体工厂类和客户端。其中,抽象产品接口定义了产品的接口,具体产品类实现了抽象产品接口中定义的属性和方法,抽象工厂类定义了一个抽象工厂方法,具体工厂类实现了抽象工厂类中定义的抽象工厂方法,返回一个具体产品类的实例,客户端通过具体工厂类来创建具体产品类的实例,然后使用产品的属性和方法。
- 工厂方法模式的优点包括可以将产品的创建与使用分离,使得代码更加灵活,可以在不改变原有代码的情况下,灵活地增加新的产品类型,可以通过工厂类来控制产品的实例化,从而避免了因为创建对象时可能发生的错误。工厂方法模式的缺点包括需要定义很多的类,增加了代码的复杂度,如果产品类型很多,那么就需要定义很多的工厂类,增加了代码的复杂度。
- 工厂方法模式适用于需要灵活地增加新的产品类型,需要将产品的创建与使用分离,需要控制产品的实例化过程,需要在运行时动态地指定产品类型等场景。
五、与抽象工厂模式的区别
- 抽象工厂设计模式是工厂方法设计模式的扩展,它定义了一个抽象工厂类,它可以创建一组相关的产品,而不是单一的产品
(抽象工厂模式有多个抽象产品类)
。而工厂方法设计模式只定义了一个抽象工厂方法,它只能创建一种产品(工厂方法模式只有一个抽象产品类)
。
- 在抽象工厂设计模式中,客户端通过抽象工厂类来创建一组相关的产品
(抽象工厂模式可以创建多个具体产品类的实例)
。而在工厂方法设计模式中,客户端通过具体的工厂类来创建单一的产品(工厂方法模式只能创建一个具体产品类的实例)
。
- 抽象工厂设计模式需要定义更多的抽象类和实现类,因此它的代码结构比工厂方法设计模式更加复杂。
- 抽象工厂设计模式适用于创建一组相关的产品,而工厂方法设计模式适用于创建单一的产品。