一、什么是工厂方法模式
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,其核心目的是定义一个创建对象的接口,但让实现这个接口的子类来决定实例化哪一个类。工厂方法模式让类的实例化推迟到子类中进行,从而提高了代码的灵活性和可扩展性。
二、工厂方法模式的角色
-
-
抽象工厂(Creator):定义创建产品的接口,它声明了工厂方法,该方法返回一个抽象产品类型的实例。抽象工厂的目的是制定所有具体工厂类必须遵循的接口
-
具体工厂(Concrete Creator):实现抽象工厂的接口,它实现了工厂方法,该方法返回一个具体产品的实例。具体工厂负责创建具体的产品对象,并返回这个对象
-
抽象产品(Product):定义了产品的接口或抽象类,这个接口或抽象类是所有具体产品类的共同父类。它声明了产品对象必须实现的接口。
-
具体产品(Concrete Product):实现或继承抽象产品的接口或抽象类,它提供了抽象产品的具体实现。具体产品是最终由具体工厂创建的对象。
-
三、工厂方法模式的典型应用场景
-
客户端不依赖产品类实例的创建细节: 当客户端不需要知道具体产品类的创建细节时,工厂方法模式可以提供给客户端一个统一的接口,客户端只需要关心产品的接口,而不需要知道具体的实现类 。
-
创建对象需要大量重复的代码: 当创建某个对象的过程需要执行一系列复杂的操作时,使用工厂方法模式可以将这些操作封装在具体工厂类中,避免在多个地方重复这些操作 。
四、工厂方法模式在NumberFormat中的应用
这里以NumberFormat为例,展示一下工厂方法模式的应用,主要包含以下几个部分:
- 抽象产品(NumberFormatter 接口):定义了数字格式化的统一接口。
- 具体产品(DecimalFormatter、IntegerFormatter、CurrencyFormatter):实现了不同的格式化逻辑。
- 工厂类(NumberFormat):提供了静态工厂方法 getFormatter(),根据传入的格式化类型返回相应的格式化器实例,使用枚举 FormatType 来定义支持的格式化类型。
我们先来创建抽象的 NumberFormatter 接口:
public interface NumberFormatter {
String format(Number number);
}
然后创建具体的格式化实现类(这里以DecimalFormatter、IntegerFormatter为例):
public class DecimalFormatter implements NumberFormatter {
@Override
public String format(Number number) {
return String.format("%.2f", number.doubleValue());
}
}
public class IntegerFormatter implements NumberFormatter {
@Override
public String format(Number number) {
return String.format("%d", number.intValue());
}
}
public class CurrencyFormatter implements NumberFormatter {
@Override
public String format(Number number) {
return String.format("$%.2f", number.doubleValue());
}
}
创建一个具体工厂类:
public class NumberFormat {
// 工厂方法,根据不同类型返回对应的格式化器
public static NumberFormatter getFormatter(FormatType type) {
switch (type) {
case DECIMAL:
return new DecimalFormatter();
case INTEGER:
return new IntegerFormatter();
case CURRENCY:
return new CurrencyFormatter();
default:
throw new IllegalArgumentException("Unsupported format type");
}
}
// 格式化类型枚举
public enum FormatType {
DECIMAL,
INTEGER,
CURRENCY
}
}
最后,写一个客户端方法:
public class NumberFormatDemo {
public static void main(String[] args) {
double number = 1234.5678;
// 获取不同的格式化器
NumberFormatter decimalFormatter = NumberFormat.getFormatter(NumberFormat.FormatType.DECIMAL);
NumberFormatter integerFormatter = NumberFormat.getFormatter(NumberFormat.FormatType.INTEGER);
NumberFormatter currencyFormatter = NumberFormat.getFormatter(NumberFormat.FormatType.CURRENCY);
// 使用不同的格式化器格式化数字
System.out.println("Decimal format: " + decimalFormatter.format(number)); // 输出:1234.57
System.out.println("Integer format: " + integerFormatter.format(number)); // 输出:1234
System.out.println("Currency format: " + currencyFormatter.format(number)); // 输出:$1234.57
}
}
使用这种模式,我们可以轻松地管理不同的数字格式化需求,并且在需要添加新的格式化方式时,不会影响到现有的代码。