当前位置:首页 > 技术 > 正文内容

工厂方法模式详解

访客 技术 2026年5月28日 3

模式定义

工厂方法模式是创建型设计模式中的一种核心模式,它通过定义一个用于创建对象的抽象接口,让子类决定实例化哪一个具体的产品类。这种设计使得产品的创建过程延迟到子类中进行,从而实现了客户端代码与具体产品类的解耦

该模式的核心思想是将对象的创建封装在专门的工厂类中,客户端只需要与抽象接口交互,无需关心具体的产品实现细节。这种设计符合软件设计中的开闭原则,即对扩展开放,对修改关闭。

模式结构

工厂方法模式主要由以下四个角色组成:

  • 抽象产品(Product):定义产品的通用接口
  • 具体产品(Concrete Product):实现抽象产品的具体类
  • 抽象工厂(Creator):声明创建产品的抽象方法
  • 具体工厂(Concrete Creator):重写抽象工厂方法以返回具体产品实例

代码实现

步骤一:定义抽象产品接口

public interface IMessage {
    void display();
    String getContent();
}

步骤二:创建具体产品实现类

public class TextMessage implements IMessage {
    @Override
    public void display() {
        System.out.println("显示文本消息: " + getContent());
    }
    
    @Override
    public String getContent() {
        return "这是一条文本消息";
    }
}
public class ImageMessage implements IMessage {
    @Override
    public void display() {
        System.out.println("显示图片消息: " + getContent());
    }
    
    @Override
    public String getContent() {
        return "这是一张图片";
    }
}

步骤三:定义抽象工厂

public abstract class MessageFactory {
    public abstract IMessage createMessage();
    
    public void showMessage() {
        IMessage message = createMessage();
        message.display();
    }
}

步骤四:创建具体工厂类

public class TextMessageFactory extends MessageFactory {
    @Override
    public IMessage createMessage() {
        return new TextMessage();
    }
}
public class ImageMessageFactory extends MessageFactory {
    @Override
    public IMessage createMessage() {
        return new ImageMessage();
    }
}

步骤五:客户端使用

public class Client {
    public static void main(String[] args) {
        MessageFactory textFactory = new TextMessageFactory();
        textFactory.showMessage();
        
        MessageFactory imageFactory = new ImageMessageFactory();
        imageFactory.showMessage();
    }
}

执行结果

显示文本消息: 这是一条文本消息
显示图片消息: 这是一张图片

模式分析

在上述代码中,客户端代码与具体的产品类完全解耦。当需要添加新的消息类型时,只需要:

  1. 创建新的产品类实现 IMessage 接口
  2. 创建对应的工厂类继承 MessageFactory

整个过程无需修改现有代码,完美体现了开闭原则的设计理念。

优势与不足

优势

  • 用户只需知道具体工厂类名即可获取产品,无需了解创建细节
  • 新增产品只需添加对应的工厂类,系统扩展性强
  • 符合依赖倒置原则,高层模块依赖于抽象而非具体实现
  • 实现客户端与具体产品的解耦,提高代码维护性

不足

  • 类的数量会随着产品种类增加而增加
  • 增加了系统的抽象层次,理解成本上升
  • 每个抽象产品只能对应一个具体产品,当需要创建产品族时显得力不从心

适用场景

  • 客户端不关心产品创建的具体过程
  • 需要通过子类来决定创建何种产品对象
  • li>希望将产品创建逻辑集中管理,统一对外提供产品
  • 系统需要频繁扩展新的产品类型

UML类图

工厂方法模式的UML类图结构清晰展示了各角色之间的关系:抽象工厂定义了创建产品的抽象方法,具体工厂负责实例化具体产品,抽象产品定义了产品的通用接口,具体产品实现了产品的具体功能。这种清晰的层次结构使得代码易于理解和维护。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。