创建型模式(Creational Patterns)之工厂模式(Factory Pattern)之工厂方法模式(Factory Method Pattern)

news2024/9/20 20:50:45

1. 工厂方法模式(Factory Method Pattern)

        将对象的创建延迟到子类中实现,每个具体产品类都有一个对应的工厂类负责创建,从而使得系统更加灵活。客户端可以通过调用工厂方法来创建所需的产品,而不必关心具体的实现细节。这种模式符合开放-封闭原则,对扩展开放、对修改关闭。

        不同于 简单工厂模式 定义一个工厂方法来创建产品,工厂方法模式 的 每个产品都有一个对应的工厂类来创建。这样每个产品类和工厂类相互独立,可以独立进行扩展,符合开放-封闭原则。例如,在一个图形绘制软件中,可以使用 工厂方法模式 来创建不同类型的图形对象,如圆形、矩形、三角形等,每个图形都有一个对应的工厂类来创建。

假设我们要设计一个电子产品工厂来生产不同类型的产品,如手机、电视、电脑等。如果使用 简单工厂模式,我们需要一个工厂类来创建所有不同类型的电子产品,客户端代码需要指定电子产品类型,工厂类根据类型来创建相应的产品对象。但是,随着产品类型的增加,工厂类的代码会越来越复杂,难以维护和扩展。

相反,如果使用 工厂方法模式,每个产品类型都有一个对应的工厂类来创建,工厂方法 可以独立进行扩展,每个工厂类只需要关心自己负责的产品类型,代码更加清晰和易于维护。例如,手机工厂类负责创建手机产品对象,电视工厂类负责创建电视产品对象,电脑工厂类负责创建电脑产品对象等。客户端代码只需要知道所需的产品类型,选择对应的工厂类即可,不需要知道具体的创建细节。

2. 结构

2.1 角色

工厂方法模式是在简单工厂模式上的改进,主要包含如下几个角色及组件

  • 抽象工厂(Creator):整个工厂模式的核心角色,它与应用无关,主要在创建模式中规范和产品对应的工厂对象的标准化定义。
  • 具体工厂(Concrete Creator):实现了抽象工厂的具体工厂类,该类型是和应用直接交互的具体实现类,在应用程序中调用,用于创建产品对象。
  • 抽象产品(Product):工厂方法模式创建的所有类型的超级父类,该类型和具体业务有关,用于规范工厂方法模式中创建的方法对象具备的公共特征行为。
  • 具体产品(Concrete Product):该类型实现了抽象产品 父类,是工厂方法模式中具体创建的实例对象。

2.2 类图

3.优缺点

优点:‌

  • 遵循开闭原则:‌工厂方法模式允许在不修改原有代码的情况下增加新的产品,‌这符合软件工程中的开闭原则,‌即对扩展开放,‌对修改关闭。‌当需要添加新产品时,‌只需要添加具体的产品类和对应的工厂类,‌而不需要修改已有的抽象工厂和客户端代码。
  • 高扩展性:‌由于所有的具体工厂类都继承自同一个抽象父类,‌这使得系统在加入新产品时具有良好的扩展性。‌这种模式鼓励使用多态性,‌允许工厂自主确定创建何种产品对象,‌而如何创建这个对象的细节则完全封装在具体工厂内部。
  • 隐藏了创建对象的复杂性:‌用户或客户端不需要关心创建对象的细节,‌甚至不需要知道具体产品类的类名,‌只需要关心所需产品对应的工厂即可。‌这有助于减少客户端与具体产品类之间的耦合度

缺点:‌

  1. 增加了类的数量:‌当有成千上万个类型的产品时,‌就需要有成千上万个工厂类来生产这些产品。‌这会增加系统的复杂度,‌需要编译和运行的类数量增加,‌可能会给系统带来额外的开销。‌
  2. 增加了系统的复杂度:‌在添加新产品时,‌需要编写新的具体产品类,‌并且还要提供与之对应的具体工厂类。‌这会导致系统中类的个数成对增加,‌从而增加了系统的复杂度。‌

4.示例

#include <iostream>
#include <string>

// 产品接口
class Animal {
public:
    virtual void makeSound() = 0; // 纯虚函数
    virtual ~Animal() {} // 虚析构函数
};

// 具体产品
class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Woof!" << std::endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        std::cout << "Meow!" << std::endl;
    }
};

// 工厂接口
class AnimalFactory {
public:
    virtual Animal* createAnimal() = 0; // 纯虚函数,工厂方法
    virtual ~AnimalFactory() {} // 虚析构函数
};

// 具体工厂
class DogFactory : public AnimalFactory {
public:
    Animal* createAnimal() override {
        return new Dog();
    }
};

class CatFactory : public AnimalFactory {
public:
    Animal* createAnimal() override {
        return new Cat();
    }
};

// 客户端代码,使用工厂方法模式
int main() {
    AnimalFactory* factory;

    // 根据用户输入或条件选择具体的工厂
    std::string type;
    std::cout << "Enter the type of animal factory ('dog' or 'cat'): ";
    std::cin >> type;

    if (type == "dog") {
        factory = new DogFactory();
    } else if (type == "cat") {
        factory = new CatFactory();
    } else {
        std::cout << "Invalid factory type." << std::endl;
        return 1;
    }

    // 使用工厂创建对象
    Animal* animal = factory->createAnimal();
    animal->makeSound();
    delete animal; // 使用完对象后,记得释放内存
    delete factory; // 释放工厂对象

    return 0;
}
  • Animal 是一个产品接口,声明了所有动物必须实现的 makeSound 方法。
  • DogCat 是具体产品,它们继承自 Animal 并实现了 makeSound 方法。
  • AnimalFactory 是工厂接口,声明了 createAnimal 方法用于创建动物对象。
  • DogFactoryCatFactory 是具体工厂,它们继承自 AnimalFactory 并实现了 createAnimal 方法,分别返回 DogCat 的实例。
  • main 函数中,我们根据用户输入来创建相应的工厂对象,然后使用该工厂对象创建动物对象。

        工厂方法模式允许系统在不修改客户端代码的情况下引入新的产品,提高了系统的扩展性和可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1983139.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

客户数据分析模型:RFM模型的深度解析与应用探索

RFM模型&#xff0c;作为客户数据分析中的经典工具&#xff0c;凭借其简单而强大的分析能力&#xff0c;被广泛应用于各行各业。本文旨在深入探讨RFM模型的核心原理、应用价值&#xff0c;并详细阐述其在2C&#xff08;面向消费者&#xff09;和2B&#xff08;面向企业&#xf…

Lumerical 光束重叠率计算

Lumerical 光束重叠率计算 引言正文不同位置处 FDE Solver 对仿真结果的影响FDE Solver 不同尺寸下的光束重叠率计算引言 在 Lumerical 光纤模式仿真 一文中我们介绍了如何进行光纤模式的仿真。本文,我们将继续使用 SMF28 来进行光束重叠率计算说明。 正文 不同位置处 FDE …

大数据技术原理-spark的安装

摘要 本实验报告详细记录了在"大数据技术原理"课程中进行的Spark安装与应用实验。实验环境包括Spark、Hadoop和Java。实验内容涵盖了Spark的安装、配置、启动&#xff0c;以及使用Spark进行基本的数据操作&#xff0c;如读取本地文件、文件内容计数、模式匹配和行数…

【未授权访问漏洞复现~~~】

一: Redis未授权访问漏洞 步骤一:进入vulhub目录使用以下命令启动靶机… 进入目录:cd /vulhub-master/redis/4-unacc 启动:docker-compose up-d 检查:docker-compose ps步骤二:在Kali上安装redis程序进行服务的链接. #安装redis apt-get install redis #redis链接 redis-cli…

【Linux进程篇】并发艺术:Linux条件变量与生产消费者模型的完美融合

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 前言&#xff1a;我们上篇博客中提到了线程互斥、引出了互斥锁解决了线程中的未将临界资源保护的问题。但是随之出来的问题——竞争锁是自由竞争的&#xff0c;竞争锁的能力太强的线程会导致其他线程抢不到票&#xff0…

Linux——线程互斥与同步

一、线程互斥 1.1 线程间互斥的概念 在学习管道的时候&#xff0c;管道是自带同步与互斥的。而在线程中&#xff0c;当多个线程没有加锁的情况下同时访问临界资源时会发生混乱。在举例之前&#xff0c;先了解几个概念。 临界资源&#xff1a;多个线程执行流共享的资源叫做临…

软甲测试定义和分类

软件测试定义 使用人工和自动手段来运行或测试某个系统的过程&#xff0c;其目的在于检验他是否满足规定的需求或弄清预期结果与实际结果之间的差别 软件测试目的 为了发现程序存在的代码或业务逻辑错误 – 第一优先级发现错误为了检验产品是否符合用户需求 – 跟用户要求实…

WPF学习(3)- WrapPanel控件(瀑布流布局)+DockPanel控件(停靠布局)

WrapPanel控件&#xff08;瀑布流布局&#xff09; WrapPanel控件表示将其子控件从左到右的顺序排列&#xff0c;如果第一行显示不了&#xff0c;则自动换至第二行&#xff0c;继续显示剩余的子控件。我们来看看它的结构定义&#xff1a; public class WrapPanel : Panel {pub…

【网页设计】基于HTML+CSS上海旅游网站网页作业制作

一、&#x1f468;‍&#x1f393;网站题目 旅游&#xff0c;当地特色&#xff0c;历史文化&#xff0c;特色小吃等网站的设计与制作。 二、✍️网站描述 &#x1f468;‍&#x1f393;静态网站的编写主要是用HTML DIVCSS 等来完成页面的排版设计&#x1f469;‍&#x1f39…

CSP初赛知识点讲解(一)

CSP初赛知识点讲解&#xff08;一&#xff09; 信息学竞赛哈夫曼树 哈夫曼编码冯.诺依曼理论计算机奖项例题训练&#xff08;一&#xff09;操作系统例题训练&#xff08;二&#xff09;计算机语言例题训练&#xff08;三&#xff09; 信息学竞赛 全国青少年计算机程序设计竞赛…

VINS-Fusion 多传感器全局位姿估计的一种通用优化框架

摘要 对于自动导航的机器人来说,精确的状态估计是基本问题。为了实现局部精确和全局无漂移的位姿估计,通常将具有互补属性的多个传感器进行融合。在一个小的区域内,局部传感器,如相机、IMU、Lidar等,提供了精确的位姿,而在一个大场景环境下,全局传感器,如gps、magneto…

java 变量及其常量

变量 数据类型关键字内存占用取值范围字节型byte1个字节-128 至 127 定义byte变量时超出范围,废了短整型short2个字节-32768 至 32767整型int&#xff08;默认&#xff09;4个字节-231 至 231-1 正负21个亿-2147483648——2147483647长整型long8个字节-263 至 263-1 19位数字-9…

【51单片机DS1302时钟芯片读取数码管显示打造小成本高品质】2022-12-23

缘由https://ask.csdn.net/questions/7867303 /*写回复缘由https://ask.csdn.net/questions/7867303*/ #include "reg52.h" sbit RSTP3^5;//DS1302允许(读/写)当RST为高电平时&#xff0c;所有的数据传送被初始化&#xff0c;允许对DS1302进行操作。如果在传送过程中…

不用PS也能抠图?点哪抠哪,简直是职场人的最强助手

抠图你还在用 PS 一点点抠吗&#xff1f; 不仅费时费力&#xff0c;还常常达不到理想效果&#xff0c;真的太让人崩溃了 但别担心&#xff0c;我找到了一个超棒的工具——千鹿设计助手的AI智能抠图插件。它就像你的私人设计小助手&#xff0c;能快速帮你把想要的元素抠出来&…

Mendix 创客访谈录|Mendix 如何化解工业企业数字化转型的复杂性

本期创客 田月萍 西门子 Advanta研发部门 大家好&#xff0c;我是田月萍&#xff0c;来自西门子Advanta的研发部门&#xff0c;专注于工业数字化转型。在我的职业生涯中&#xff0c;参与了多个关键项目的开发&#xff0c;涵盖了制造执行系统&#xff08;MES&#xff09;的实施&…

ECMA6Script学习笔记(六)

【摘要】 本文是对自己学习ES6的学习笔记回顾,后面是概要:文章深入探讨了ES6模块化处理&#xff0c;强调模块化在提高代码可维护性、可复用性和可扩展性方面的重要性。介绍了ES6模块化的三种导出方式&#xff1a;分别导出、统一导出和默认导出&#xff0c;并通过具体的代码示例…

3.特征工程-特征抽取、特征预处理、特征降维

文章目录 环境配置&#xff08;必看&#xff09;头文件引用1.数据集: sklearn代码运行结果 2.字典特征抽取: DictVectorizer代码运行结果稀疏矩阵 3.文本特征抽取(英文文本): CountVectorizer()代码运行结果 4.中文文本分词(中文文本特征抽取使用)代码运行结果 5.中文文本特征抽…

一款功能强大且免费的Windows系统优化工具

TweakPower是一款功能强大的Windows系统优化工具&#xff0c;旨在帮助用户提升电脑性能、清理垃圾文件、备份数据以及修复系统问题。该软件提供了多种实用功能&#xff0c;包括内存管理、垃圾清理、数据备份、数据擦除、硬盘维护和性能调度调整等。 TweakPower的主要界面或仪表…

如意玲珑支持发行版再添新成员,openEuler安装使用如意玲珑操作指南

查看原文 如意玲珑&#xff08;Linyaps&#xff09;项目已与开放原子开源基金会完成捐赠协议签署&#xff0c;目前如意玲珑已成为基金会的正式孵化期项目。 如意玲珑是开源软件包格式&#xff0c;用于替代 deb、rpm等包管理工具&#xff0c;实现应用包管理、分发、容器、集成开…

数据产品价值评估体系搭建

00前言 随着数据在企业的重要性越来越高&#xff0c;数据赋予的价值和意义在企业内部也深入人心&#xff0c;不仅纳入到了企业战略中去&#xff0c;在日常的工作中&#xff0c;各个业务部门也会不断的提出五花八门的数据需求&#xff08;数据分析、数据治理、数据应用等等&…