5分钟学设计模式:简单工厂与美食街的不期而遇

news2024/11/28 21:55:31

大家好,我是知微。

写代码好几年,是不是还纠结于这些问题:

  • 面对一堆if-else,代码越写越长,维护起来比攀登珠穆朗玛峰还难
  • 每次只敢小心翼翼改个小功能,生怕程序突然“嘭”一声,全炸了
  • 想学习大佬们的代码,却总是看得一头雾水,不知如何下手。

别急,优秀的代码设计往往有秘诀——设计模式。模仿只是表面,理解背后的设计哲学才是关键。

设计模式,何方神圣?

在编程的江湖里,设计模式就是解决问题的宝典,是前辈们在软件开发中留下的宝贵经验,帮我们写出可复用、灵活、高效的代码。

设计模式,三分天下

设计模式大致分为三类:

  1. 创建型模式:关注对象的诞生,如何优雅地创建和管理对象。
  2. 结构型模式:关注类和对象的“排列组合”,化简为繁,构建复杂系统。
  3. 行为型模式:关注对象之间的“互动”,定义它们如何协同工作。

“唉,又来这些概念,头都大了!”

行了行了,不卖关子了,咱们直接进入正题:简单工厂模式

第一幕:美食街的邂逅

晚上11点,你终于结束了一天的工作,疲惫地走在回家的路上。经过一条热闹的美食街,空气中弥漫着各种美食的香味,让你不由自主地停下了脚步。

你心想:“万事皆空,唯美食不可辜负,今天一定要好好犒劳自己!”但打开微信钱包一看,发现余额只剩下5块。你叹了口气,只能找个小吃摊随便吃点。

你走向最近的一个摊位,对老板说:“老板,来份煎饼果子!”

老板热情地回应:“好嘞,加不加鸡蛋?”

你摆了摆手,老板见状,便开始熟练地制作起来。

用代码表示

class Pancake {
public:
    void serve() {
        std::cout << "你的煎饼果子好了!" << std::endl;
    }
};

int main() {
    Pancake p;
    p.serve(); // 顾客:老板,来份煎饼果子!
    return 0;
}

第二幕:美食街的新品

几周后,你再次来到美食街,老板热情地向你推荐:“我们最近新增了鸡蛋灌饼,要不要尝尝?”你心想,既然来了,不妨试试新口味。

你对老板说:“老板,那就来份鸡蛋灌饼吧!”

老板手脚麻利,很快为你准备好了热腾腾的鸡蛋灌饼。

用代码表示

// ...之前的煎饼果子的代码

class EggPancake {
public:
    void serve() {
        std::cout << "热腾腾的鸡蛋灌饼好了!" << std::endl;
    }
};

int main() {
	// ...之前的煎饼果子的代码
    
    EggPancake ep;
    ep.serve(); // 顾客:老板,来份鸡蛋灌饼吧!
    return 0;
}

第三幕:美食街的繁荣

随着时间的流逝,美食街越来越繁荣,小吃摊也增加了更多的小吃品种,如手抓饼和肉夹馍。每次光顾,你都能尝试不同的美食。

用代码表示

// ...之前的煎饼果子和鸡蛋灌饼的代码
class HandPies {
public:
    void serve() {
        std::cout << "香脆的手抓饼好了!" << std::endl;
    }
};

class RouJiaMo {
public:
    void serve() {
        std::cout << "美味的肉夹馍好了!" << std::endl;
    }
};

int main() {
    // ...之前的煎饼果子和鸡蛋灌饼的代码

    HandPies hp;
    hp.serve(); // 顾客:老板,来份手抓饼!

    RouJiaMo rjm;
    rjm.serve(); // 顾客:老板,来个肉夹馍!
    return 0;
}

第四幕:简单工厂的引入

你注意到,随着小吃种类的增加,老板开始使用一张菜单,上面列出了所有可以提供的小吃。每次你只需要告诉老板你想要什么,老板就会从菜单上找到对应的小吃,然后为你准备。

你突然灵光一闪,这不正是编程中的简单工厂模式吗?通过一个统一的接口来创建不同的对象。

引入简单工厂模式

#include <memory>
#include <string>
#include <iostream>

class Snack {
public:
    virtual void serve() = 0;
    virtual ~Snack() {}
};

class Pancake : public Snack {
public:
    void serve() override {
        std::cout << "你的煎饼果子好了!" << std::endl;
    }
};

class EggPancake : public Snack {
public:
    void serve() override {
        std::cout << "热腾腾的鸡蛋灌饼好了!" << std::endl;
    }
};

// ...其他小吃类

class SnackFactory {
public:
    static std::unique_ptr<Snack> createSnack(const std::string& type) {
        if (type == "PANCAKE") {
            return std::make_unique<Pancake>();
        }
        // ...根据类型创建其他小吃
        return nullptr;
    }
};

int main() {
    auto snack = SnackFactory::createSnack("PANCAKE");
    snack->serve(); // 顾客:老板,来份煎饼果子!

    // ...根据顾客的选择,创建其他小吃

    return 0;
}

采用简单工厂模式,美食街的老板就能轻松满足顾客的各种小吃需求,顾客点餐也变得更快捷。

这个模式的妙处在于,它把创建小吃对象的过程从原来的地方挪到了一个专门的“工厂”里。一开始,你可能觉得这个改变没啥大不了的,特别是当你的程序还很简单,只有几个类的时候。但是,随着你的程序越来越庞大和复杂,这个模式的好处就会慢慢显现出来。

  • 简化代码:你不用再代码的各个角落重复写创建对象的代码了。
  • 易于管理:所有的创建逻辑都集中在工厂类里,改起来简单多了。
  • 扩展方便:想加个新小吃?在工厂类里添几行代码就行,不用满世界找代码改。
  • 减少依赖:你的代码块之间互相依赖少了,更像是独立的模块。

值得注意的是,尽管简单工厂模式没有被列入GoF的23种经典设计模式,但它在软件开发实践中仍然非常有用,特别是对于新手来说,它是学习面向对象设计原则和设计模式的一个很好的起点。

以上就是简单工厂模式的全部内容了,后面我会接着介绍GoF的23种经典设计模式,敬请期待!

📢你的每一次👍点赞 ⭐收藏 📝评论,都是我更新的动力,如有错误请留言指正,非常感谢!

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

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

相关文章

基于SPWM控制策略的二极管钳位型NPC逆变器的并网simulink仿真

本人搭建了二极管钳位型NPC并网逆变器simulink仿真模型&#xff0c;该模型型采用d、q轴&#xff0c;电压前馈解耦控制&#xff0c;三相逆变并网&#xff0c;PI控制&#xff0c;仿真复现&#xff0c;效果优异&#xff0c;适合新手学习使用。 模型获取链接&#xff1a;基于SPWM…

探秘钱塘高中,筑梦未来之旅————杭州市钱塘高级中学

晨曦微露&#xff0c;书生琅琅&#xff0c;古韵今风交织在这方学府&#xff0c;滔滔的钱塘江畔&#xff0c;杭州市钱塘高级中学屹立于此。这所学校自1958年建校伊始&#xff0c;走过几十年的光辉岁月&#xff0c;一直致力于提供优质的教育资源。 近年来&#xff0c;学校获得多项…

鸿蒙内核源码分析(消息封装篇) | 剖析LiteIpc(上)进程通讯内容

基本概念 LiteIPC是OpenHarmony LiteOS-A内核提供的一种新型IPC&#xff08;Inter-Process Communication&#xff0c;即进程间通信&#xff09;机制&#xff0c;为轻量级进程间通信组件&#xff0c;为面向服务的系统服务框架提供进程间通信能力&#xff0c;分为内核实现和用户…

电商数据接口|如何获取电商数据?

随着互联网的发展&#xff0c;电商的运营方式也逐渐数据化&#xff0c;在大数据的影响下&#xff0c;电商领域很大程度上改变了传统的运营模式。很多商家如今都非常重视数据&#xff0c;并将数据贯穿于整个店铺的运营之中。 那么&#xff0c;具体来说电商大数据有哪些妙用呢&a…

C++ 对象型参数和返回值

对象型参数和返回值 1.对象型类型作为函数的参数2.对象型参数作为函数的返回值 1.对象型类型作为函数的参数 使用对象类型作为函数的参数或者返回值&#xff0c;可能会产生一些不必要的中间对象 例子&#xff1a; // 使用对象类型作为函数的参数 void test1(Car car) {}完整代…

空号检测-号码批量检测API接口-关机停机风险号检测

手机空号检测分为普通空号检测和实时检测两种类型&#xff1a; 普通空号检测返回结果&#xff1a;实号、风险号、空号、沉默号 。 1.普通版的检测不会实时更新数据&#xff0c;因此其数据库中的信息可能不是最新的。 2.覆盖基础运营商的数据库&#xff0c;检测范围相对有限&…

MSMQ消息队列

MQ是一种企业服务的消息中间节技术&#xff0c;这种技术常常伴随着企业服务总线相互使用&#xff0c;构成了企业分布式开发的一部分&#xff0c;如果考虑到消息的发送和传送之间是可以相互不联系的并且需要分布式架构&#xff0c;则可以考虑使用MQ做消息的中间价技术&#xff0…

【云原生】kubernetes核心组件

引言&#xff1a; Kubernetes 是为运行分布式集群而建立的&#xff0c;分布式系统的本质使得网络成为 Kubernetes 的核心和必要组成部分&#xff0c;了解 Kubernetes 网络模型可以使你能够正确运行、监控和排查应用程序故障。 一、Kubernetes的核心组件 1.1、Master组件 1.1.…

C# WinForm —— 18 NumericUpDown 介绍

1. 简介 数字显示框&#xff0c;通过向上、向下按钮来 增加/减小 显示的数值 2. 常用属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般以 numUD 开头Hexadecimal数值 up-down 控件的值是否应以十六进制显示Increment每单击一下按钮&#xff0c;增加或减…

0508GoodsContent的Maven项目

0508GoodsContent的Maven项目包-CSDN博客 数据库字段 页面需求

立聪堂助听器29周年暨第九届助听使者活动圆满落幕

5月10日对于立聪堂来说是个特别的日子&#xff0c;这家专注于听力健康领域的公司迎来了29周年。同时&#xff0c;立聪堂第九届助听使者代表及其家人也受邀参观立聪堂南京总部&#xff0c;共庆29周年。 易被忽视的老人听力健康 大数据显示&#xff0c;我国65岁以上老人&#x…

HubSpot海外获客系统的客户生命周期管理

潜在客户阶段&#xff1a;精准识别与吸引 在潜在客户阶段&#xff0c;HubSpot的强大数据分析能力使得企业能够精准地识别出目标市场的潜在客户。通过HubSpot的跟踪和分析工具&#xff0c;企业可以深入了解潜在客户的来源、浏览行为、兴趣偏好等关键信息&#xff0c;进而定制出…

MATLAB | 最新版MATLAB绘图速查表来啦!!

之前看大佬Pjer做的MATLAB速查表 http://home.ustc.edu.cn/~pjer1316/matlabplot/ 感觉非常的实用&#xff0c;最近几次MATLAB更新围绕画图方面也有很多新东西&#xff0c;于是就有了自己做一张最新版的速查表的想法&#xff0c;这张表长这样&#xff1a; 这张表的配色基本上…

为什么跨境电商大佬都在自养号测评?看完你就懂了!

在跨境电商的激烈竞争中&#xff0c;各大平台如亚马逊、拼多多Temu、shopee、Lazada、wish、速卖通、煤炉、敦煌、独立站、雅虎、eBay、TikTok、Newegg、Allegro、乐天、美客多、阿里国际、沃尔玛、Nike、OZON、Target以及Joom等&#xff0c;纷纷成为商家们竞相角逐市场份额的焦…

Adaptive leakthrough ANC自适应通透ANC调试快速上手3

1.在MDE中通过命令控制,让耳机进入到ANC tuning状态,在ancdesigner工具中连接成功; 2.前面Mision mode的方法中得到5各录音文件,生产相应的missin model; Adaptive leakthrough ANC自适应通透ANC调试快速上手 3.在file->configration中设置FB为Filter_PEQ手动调试,可以…

C++入门——引用(2)

前言 上一节我们开始学习了C&#xff0c;并且对C有了初步的了解&#xff0c;这一节我们继续学习C的基础&#xff0c;那么废话不多说&#xff0c;我们正式进入今天的学习 C中的引用 1.1引用的概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0…

限流算法(令牌桶漏桶计数器)

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Spring⛺️稳中求进&#xff0c;晒太阳 业务重的三种情况&#xff1a;突发流量、恶意流量、业务本身需要 限流: 是为了保护自身系统和下游系统不被高并发流量冲垮&#xff0c;导致系统雪崩…

jQuery-2.鼠标焦点事件、节点操作、遍历元素、效果

鼠标事件 鼠标事件是当用户在文档上移动或单击鼠标时而产生的事件&#xff0c;常用的鼠标事件&#xff1a; 方法 描述 执行时机 click() 触发或将函数绑定到指定元素的click事件 单击鼠标时 mouseover() 触发或将函数绑定到指定元素的mouse over事件 鼠标移过时 mous…

体重秤蓝牙语音芯片方案-WT2605蓝牙音频ic在电子秤上的应用

在快节奏的现代生活中&#xff0c;健康成为了每个人关注的焦点。而体重作为健康指标之一&#xff0c;更是备受关注。如今&#xff0c;一款全新的智能体重秤蓝牙语音芯片方案正悄然改变着我们的健康管理方式&#xff0c;让健康触手可及。 性能&#xff1a; 1&#xff1a;蓝牙语…

.Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 发布到 Win7+

.Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 实测可以完整运行在 win7sp1/win10/win11. 如果用其他工具打包,还可以运行在mac/linux下, 传送门BlazorHybrid 发布为无依赖包方式 安装 WebView2Runtime 1.57 MB或136 MB 测试DEMO 发布为依赖包方式 安装 WebView2Runtime 1.…