大家好,我是知微。
写代码好几年,是不是还纠结于这些问题:
- 面对一堆
if-else
,代码越写越长,维护起来比攀登珠穆朗玛峰还难 - 每次只敢小心翼翼改个小功能,生怕程序突然“嘭”一声,全炸了
- 想学习大佬们的代码,却总是看得一头雾水,不知如何下手。
别急,优秀的代码设计往往有秘诀——设计模式。模仿只是表面,理解背后的设计哲学才是关键。
设计模式,何方神圣?
在编程的江湖里,设计模式就是解决问题的宝典,是前辈们在软件开发中留下的宝贵经验,帮我们写出可复用、灵活、高效的代码。
设计模式,三分天下
设计模式大致分为三类:
- 创建型模式:关注对象的诞生,如何优雅地创建和管理对象。
- 结构型模式:关注类和对象的“排列组合”,化简为繁,构建复杂系统。
- 行为型模式:关注对象之间的“互动”,定义它们如何协同工作。
“唉,又来这些概念,头都大了!”
行了行了,不卖关子了,咱们直接进入正题:简单工厂模式。
第一幕:美食街的邂逅
晚上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种经典设计模式,敬请期待!
📢你的每一次👍点赞 ⭐收藏 📝评论,都是我更新的动力,如有错误请留言指正,非常感谢!