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

一、什么是工厂方法模式

工厂方法模式(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
    }
} 

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

相关推荐
柯南二号2 分钟前
【Java后端】MyBatis-Plus 原理解析
java·开发语言·mybatis
又是努力搬砖的一年11 分钟前
SpringBoot中,接口加解密
java·spring boot·后端
:-)13 分钟前
idea配置maven国内镜像
java·ide·maven·intellij-idea
ikkkkkkkl17 分钟前
C++设计模式:面向对象设计原则
c++·设计模式·面向对象
啊阿狸不会拉杆1 小时前
《算法导论》第 27 章 - 多线程算法
java·jvm·c++·算法·图论
用户802973565411 小时前
【水平:编写简单的SpringCloud】用一篇文章精通SpringCloud-1
java
蔡俊锋1 小时前
Javar如何用RabbitMQ订单超时处理
java·python·rabbitmq·ruby
天天摸鱼的java工程师1 小时前
Snowflake 雪花算法优缺点(Java老司机实战总结)
java·后端·面试
Miraitowa_cheems2 小时前
LeetCode算法日记 - Day 11: 寻找峰值、山脉数组的峰顶索引
java·算法·leetcode
海梨花2 小时前
【从零开始学习Redis】项目实战-黑马点评D2
java·数据库·redis·后端·缓存