当前位置: 首页 > news >正文

C++|设计模式(二)|简单工厂和工厂方法模式

本文探讨两种广泛使用的创建型模式——简单工厂模式和工厂方法模式,解释他们的实现细节、优势以及应用场景。

在下一篇文章中,我会补充抽象工厂模式,其实工厂模式主要就是为了封装对象的创建过程,如果我们不进行封装,如果对象较多,创建过程就需要我们自己new来new去,并且还要记住具体类的初始化方法,还是太麻烦了。

也就是说如果我们需要什么样的对象,就直接去找工厂申请,让它来代工,工厂提供了一个统一的接口。

工厂模式使用的前提,一般就是我们要创建的类比较多的时候来使用,可以大大简化程序猿的工作量。

文章目录

  • 简单工厂模式
    • 实现示例
    • 优点和适用场景
    • 缺点
  • 工厂方法模式
    • 实现示例
    • 局限性

简单工厂模式

实现示例

假设我们需要一个基于车辆类型创建车辆对象的应用:

class Car {
public:Car(string name) : name_(name) { }virtual ~Car(){}virtual void show() = 0;
protected:string name_;
};class Bmw : public Car {
public:Bmw(string name) : Car(name) { }void show() { cout << "获得一辆宝马汽车 " << name_ <<endl; }
};class Audi : public Car {
public:Audi(string name) : Car(name) { }void show() { cout << "获得一辆奥迪汽车 " << name_ << endl; }
};

我们现在创建具体的Bmw和Audi对象:

int main () {Car *p1 = new BMW("X1");Car *p2 = new Audi("A6");return 0;
}

如果我们需要创建的类比较多,并且对象的初始化方法比较复杂,那么这样的类实例化就不太符合一个良好的设计要求,所以现在我们对类进行封装:

enum CarType {BMW, AUDI
};
class SimpleFactory {
public:Car* createCar(CarType ct) {switch (ct){case BMW:return new Bmw("X1");case AUDI:return new Audi("A6");default:cout << "传入工厂的参数不正确" << ct << endl;break;}return nullptr;}
};

我们创建了一个美剧类,并且设计一个简单工厂类,之后,我们需要创建对象只要调用该类即可:

int main () {unique_ptr<SimpleFactory> factory(new SimpleFactory());unique_ptr<Car> p1(factory->createCar(BMW));unique_ptr<Car> p2(factory->createCar(AUDI));p1->show();p2->show();return 0;
}

很明显,简单且直观。

优点和适用场景

简单工厂模式的主要优点是减少系统中的代码重复,并且封装了对象创建的细节,使得代码库更简洁、更易于维护。

缺点

但是简单工厂也有不好的地方:从逻辑上来讲,同一个工厂不应该啥都建啊,又是宝马奥迪、以后说不定还有手机啥的,不符合逻辑。

并且,我们的这个简单工厂不符合“开闭原则”,如果我们有新增的对象、或者想删除某个对象,都必须修改整个接口,这个接口就会变来变去永远不封闭。

  • 第一,一个工厂负责各种对象的创建不太符合逻辑;
  • 第二,简单工厂的接口设计根本就不封闭,不符合开闭原则

所以我们的工厂方法应运而生。

工厂方法模式

工厂方法模式是简单工厂的一种扩展,每个具体产品都有一个相应的工厂,这样也符合我们真是生产中的逻辑。

当然最重要的是,工厂方法模式符合我们的“开闭原则”(对扩展开放,对修改封闭)

实现示例

我们还是使用上述的例子,我们再定义一个工厂方法的抽象类,然后为每一个产品都设计一个工厂类:

//工厂方法
class Factory {
public:virtual ~Factory() {}virtual Car* createCar(string name) = 0; //工厂方法
};//宝马工厂
class BMWFactory : public Factory {
public:Car* createCar(string name) { return new Bmw(name); }
};
//奥迪工厂
class AudiFactory : public Factory {
public:Car* createCar(string name) { return new Audi(name); }
};

调用过程:

int main () {unique_ptr<Factory> bmwFactory(new BMWFactory());unique_ptr<Factory> audiFactory(new AudiFactory());unique_ptr<Car> p1(bmwFactory->createCar("X6"));unique_ptr<Car> p2(audiFactory->createCar("A8"));p1->show();p2->show();return 0;
}

使用工厂方法后,很明显,我们如果想生产新的产品,直接写一个专属的工厂就可以了,而不需要改变我们原有的宝马工厂或者奥迪工厂。所以,该设计符合我们的开闭原则。

局限性

工厂方法模式最大的一个问题就在于:

假如我们现在考虑一类产品,也就是所谓的产品族(有关联关系的系列产品)

比如说“华为工厂”,我们就可以生产华为手机、耳机、充电线等等,我们不可能也不应该为每一种产品都专门设计一个工厂,如果这样设计工厂,那我们的产品类就太多太多了。

那么如何解决呢,我们可以引入抽象工厂模式。

具体请看本文:【C++|设计模式(二)|抽象工厂模式】

http://www.lryc.cn/news/355621.html

相关文章:

  • C语言从头学12——流程控制(一)
  • 10大领域应该怎么记?
  • 通过Ubuntu虚拟机+Linux移植LVGL并通过linux Frame buffer显示
  • M功能-支付平台(三)
  • 5G工厂长啥样
  • 使用Python操作Jenkins
  • 网络协议测试仪设计方案:474-便携式手提万兆网络协议测试仪
  • 使用numpy手写一个神经网络
  • 使用Spring AOP实现接口参数变更前后对比和日志记录
  • 免费无限换脸,火了,图片/视频/直播都行!
  • 无线领夹麦克风哪个品牌好?本期文章揭秘无线麦克风哪个品牌好用
  • 操作系统实验--终极逃课方法
  • C语言实现正弦信号扫频
  • 实用篇| huggingface网络不通
  • NLP与训练模型-GPT-3:探索人工智能语言生成的新纪元
  • iOS内购欺诈漏洞
  • 【网络服务】正向代理和反向代理到底是什么意思
  • 【算法】记忆化搜索
  • 博客系统多模块开发
  • pdf阅读器哪个好用?五款PDF阅读器大比拼
  • C#实现Queue的加锁和解锁
  • 北京邮电大学人工智能考数据结构,均分370!北京邮电大学计算机考研考情分析!
  • 1. lambda初体验
  • C#之显示转换
  • 汇编原理(三)编程
  • [MySQL数据库] Java的JDBC编程(MySQL数据库基础操作完结)
  • 绿色瓶装水“暗战”竞争越发激烈,华润饮料谋上市同时多地扩产能
  • C语言之指针详解(4)
  • 0基础学习小红书博主IP特训营,37天 教你从小白到KOL(13节)
  • 【openlayers系统学习】3.1-3.2彩色GeoTIFF图像渲染