【设计模式系列】工厂方法模式(二十一)

一、什么是工厂方法模式

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,其核心目的是定义一个创建对象的接口,但让实现这个接口的子类来决定实例化哪一个类。工厂方法模式让类的实例化推迟到子类中进行,从而提高了代码的灵活性和可扩展性。

二、工厂方法模式的角色

    • 抽象工厂(Creator):定义创建产品的接口,它声明了工厂方法,该方法返回一个抽象产品类型的实例。抽象工厂的目的是制定所有具体工厂类必须遵循的接口

    • 具体工厂(Concrete Creator):实现抽象工厂的接口,它实现了工厂方法,该方法返回一个具体产品的实例。具体工厂负责创建具体的产品对象,并返回这个对象

    • 抽象产品(Product):定义了产品的接口或抽象类,这个接口或抽象类是所有具体产品类的共同父类。它声明了产品对象必须实现的接口。

    • 具体产品(Concrete Product):实现或继承抽象产品的接口或抽象类,它提供了抽象产品的具体实现。具体产品是最终由具体工厂创建的对象。

三、工厂方法模式的典型应用场景

  1. 客户端不依赖产品类实例的创建细节: 当客户端不需要知道具体产品类的创建细节时,工厂方法模式可以提供给客户端一个统一的接口,客户端只需要关心产品的接口,而不需要知道具体的实现类 。

  2. 创建对象需要大量重复的代码: 当创建某个对象的过程需要执行一系列复杂的操作时,使用工厂方法模式可以将这些操作封装在具体工厂类中,避免在多个地方重复这些操作 。

四、工厂方法模式在NumberFormat中的应用

这里以NumberFormat为例,展示一下工厂方法模式的应用,主要包含以下几个部分:

  • 抽象产品(NumberFormatter 接口):定义了数字格式化的统一接口。
  • 具体产品(DecimalFormatter、IntegerFormatter、CurrencyFormatter):实现了不同的格式化逻辑。
  • 工厂类(NumberFormat):提供了静态工厂方法 getFormatter(),根据传入的格式化类型返回相应的格式化器实例,使用枚举 FormatType 来定义支持的格式化类型。

我们先来创建抽象的 NumberFormatter 接口:

java 复制代码
public interface NumberFormatter {
    String format(Number number);
} 

然后创建具体的格式化实现类(这里以DecimalFormatter、IntegerFormatter为例):

java 复制代码
public class DecimalFormatter implements NumberFormatter {
    @Override
    public String format(Number number) {
        return String.format("%.2f", number.doubleValue());
    }
} 
java 复制代码
public class IntegerFormatter implements NumberFormatter {
    @Override
    public String format(Number number) {
        return String.format("%d", number.intValue());
    }
} 
java 复制代码
public class CurrencyFormatter implements NumberFormatter {
    @Override
    public String format(Number number) {
        return String.format("$%.2f", number.doubleValue());
    }
} 

创建一个具体工厂类:

java 复制代码
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
    }
} 

最后,写一个客户端方法:

java 复制代码
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
    }
} 

使用这种模式,我们可以轻松地管理不同的数字格式化需求,并且在需要添加新的格式化方式时,不会影响到现有的代码。

相关推荐
IT_Octopus1 小时前
IntelliJ 本地日志路径自定义:`-DLOG_PATH=./logs` 为什么总“不听话“
java·log4j·intellij-idea
长征coder2 小时前
【无标题】
java·性能优化
新时代牛马3 小时前
PCI与PCIe 硬件原理、配置空间/BAR 与 Linux 驱动完整篇:从 LTSSM、TLP 到 ECAM 与probe
java·linux·服务器
Bs_MoneyMagnet3 小时前
基于springboot+vue的医疗健康便民服务平台的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring
sunshine22 girl3 小时前
Java学习一 环境配置2 Idea的入门使用和maven配置,项目启动脚本配置
java·maven
有点。4 小时前
*C++哈夫曼树与哈夫曼编码
java·c++·servlet
CRMEB系统商城5 小时前
CRMEB标准版系统(Java)v3.1正式发布
java·spring·微信小程序·php·教育电商
写后端的胖头鱼5 小时前
【高频面试题】Java 基础类型 + 包装类 + String 互相转换
java·开发语言
weixin_460443565 小时前
企业考试系统从.NET迁移到Java+Linux:数据库迁移、接口兼容与灰度切换实践
java·煤矿培训考试系统·煤矿在线考试系统·煤矿安全培训·煤矿考试系统·一人一档
香菜TTT6 小时前
Redis的哨兵机制
java·数据库·redis