工厂方法模式属于创建型模式的一种。
工厂方法模式通过一个工厂方法来决定实例化哪个类对象,而不是直接在代码中使用 new 来创建对象。这样可以将对象的创建和使用分离,增加代码的灵活性和可维护性。定义一个接口或抽象类,用于声明创建对象的方法,而具体的子类负责实现这个方法并返回相应的对象。这样,客户端代码只需要依赖于工厂接口,而不需要关心具体的实现细节。
工厂方法返回的对象通常被称作 “产品”。调用工厂方法的代码,通常被称为客户端代码。
工厂方法模式通常包含以下几个角色:
- 产品接口:定义了产品的接口或抽象类;
- 具体产品类:实现了产品接口,定义了具体的产品;
- 工厂接口:声明了一个工厂方法,用于返回产品对象;
- 具体工厂类:实现了工厂接口,返回具体的产品对象。
创建不同类型的汽车(如轿车和SUV),使用工厂方法模式来实现这个需求。
1、定义产品接口
// 汽车接口
public interface Car {
void drive();
}
2、实现具体产品类
// 具体产品:轿车
public class Sedan implements Car {
@Override
public void drive() {
System.out.println("Driving a Sedan");
}
}
// 具体产品:SUV
public class SUV implements Car {
@Override
public void drive() {
System.out.println("Driving an SUV");
}
}
3、定义工厂接口
// 工厂接口
public interface CarFactory {
Car createCar();
}
4、实现具体工厂类
// 具体工厂:轿车工厂
public class SedanFactory implements CarFactory {
@Override
public Car createCar() {
return new Sedan();
}
}
// 具体工厂:SUV工厂
public class SUVFactory implements CarFactory {
@Override
public Car createCar() {
return new SUV();
}
}
5、使用工厂方法模式
public class Main {
public static void main(String[] args) {
// 使用轿车工厂
CarFactory sedanFactory = new SedanFactory();
Car sedan = sedanFactory.createCar();
sedan.drive(); // 输出:Driving a Sedan
// 使用SUV工厂
CarFactory suvFactory = new SUVFactory();
Car suv = suvFactory.createCar();
suv.drive(); // 输出:Driving an SUV
}
}
在这个例子中,CarFactory 是一个工厂接口,它定义了创建 Car 对象的方法。SedanFactory 和 SUVFactory 是具体工厂类,它们实现了 CarFactory 接口,并创建具体的 Sedan 和 SUV 对象。客户端代码(Main
类)只需依赖于 SUV 接口,而不需要关心具体的实现细节。
简单工厂模式又称为静态工厂方法模式。有时我们并不需要抽象工厂,而是通过静态方法直接进行返回。这种简化的使用静态方法的方式称为静态工厂方法。静态工厂方法广泛地应用在Java标准库中。比如:
Long l1 = Long.valueOf(100);
工厂方法可以隐藏创建类的细节,且不一定每次都会真正创建,完全可以返回缓存的实例,从而提升速度并减少内存消耗。如果有场景需要动态决定创建哪种类型的对象,此时使用工厂方法模式可以解决。
工厂方法模式可以演化为抽象工厂模式、 原型模式或生成器模式,更灵活但更加复杂。
工厂方法模式是模板方法模式的一种特殊形式。
工厂方法模式的优缺点。
优点:
- 解耦合:对象的创建和使用进行了分离;
- 易于扩展:增加新的产品,只需新增具体的产品类和对应的工厂类即可,无需修改客户端代码;
- 集中管理对象创建:对象的创建逻辑集中在工厂类中;
- 提高代码的灵活性:可以动态决定实例化哪个具体类;
- 易于测试和维护:可以模拟工厂接口来测试客户端代码。
缺点:
- 增加了代码复杂度:引入了多个类(如工厂接口、具体工厂类、产品接口和具体产品类),使得系统的结构复杂度增加;
- 类的数量增加:每新增一种产品,就需要创建一个新的具体工厂类和具体产品类;
- 不适用于所有场景:对于简单的对象创建,可能会显得过于繁琐;
- 难以维护工厂类:如果创建的产品非常多且复杂,当进行逻辑调整时,可能需要修改多个具体类。
在选择是否使用工厂方法模式时,需要权衡其优缺点,并根据具体的需求和情况做出决策。在复杂的系统中,工厂方法模式可以有效地帮助管理和组织代码,但在简单的场景下,我们可以考虑是否有更简单的设计方案。
做你想做的那个人和那件事,无论什么时候,都不算晚。-- 烟沙九洲