点击链接阅读原文,获取更多技术内容:
(资料图)
本文从设计原则、创建型模式、结构型模式、行为模式四个方向讲述C++的设计模式。
作者 | 恒索
来源 | 阿里开发者公众号
设计原则
单一职责原则
定义:单一职责原则[1],所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该 有且只有一个改变的原因。
bad case :IPhone类承担了协议管理(Dial、HangUp)、数据传送(Chat)。
good case:
里式替换原则
定义:里氏代换原则[2](Liskov Substitution Principle LSP),任何 基类 可以出现的地方, 子类一定可以出现。
bad case :ToyGun继承了AbstractGun,但Solider在调用KillEnemy()时会报错(ToyGun无法KillEnemy),即ToyGun无法完全行使AbstractGun的职责。
good case: AbstractToy中将声音、形状都委托给AbstractGun处理。
如果子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开父子继承关系,采用依赖、聚集、组合等关系代替。
依赖倒置原则
定义:依赖倒置原则[3](Dependence Inversion Principle)是程序要 依赖于抽象接口,不要依赖于具体实现。 简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
bad case: Driver强依赖于奔驰车。
good case:
接口隔离原则
定义: 接口隔离原则[4],客户端不应该依赖它不需要的接口。一个类对另一个类的 依赖 应该建立在 最小的接口上 。
bad case: 星探寻找美女的类图,其中IpettyGirl过于庞大,容纳过多可变的因素。
good case: 通过拆分接口,提高了灵活性、可维护性。
迪米特法则
定义:迪米特法则[5](Law of Demeter)又叫作 最少知识原则 (The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。
bad case: Teacher要求GroupLeader清点女生的数量,这里Teacher不应该依赖于Gril。
good case:
开闭原则
定义:开闭原则[6],在面向对象编程领域中,规定“软件中的对象(类,模块,函数等等)应该对于 扩展是开放 的,但是对于 修改是封闭 的”。
以一个书店售书类图为例,当在书店要增加一个打折操作时。
bad case:修改实现类,在IBook上增加一个方法GetOffPrice() good case:通过扩展实现变化,增加一个子类OffNovelBook创建型模式
工厂方法
定义一个用于创建对象的接口 Product* CreateProduct() ,让子类决定实例化哪一个类。工厂方法模式让类的实例化延迟到子类中进行,从而避免了在父类中创建对象时出现类名称紧耦合的问题,同时提高了代码的可扩展性和可维护性。(工厂方法的好处就是 解耦 ,当我们修改了具体的类,对调用方而言完全不用修改)
class Product { // 抽象产品public: virtual void Method() = 0;};class ConcreteProduct1 : public Product {public: void Method() { cout << \"ConcreteProduct1\" << endl; }};class ConcreteProduct2 : public Product {public: void Method() { cout << \"ConcreteProduct2\" << endl; }};class Factory { // 抽象工厂public: virtual Product* CreateProduct() = 0;};class ConcreteFactory1 : public Factory {public: Product* CreateProduct() {return new ConcreteProduct1(); }};class ConcreteFactory2 : public Factory {public: Product* CreateProduct() {return new ConcreteProduct2(); }};int main () { Factory *factory1 = new ConcreteFactory1(); Factory *factory2 = new ConcreteFactory2(); Product *product1 = factory1->CreateProduct(); Product *product2 = factory2->CreateProduct(); product1->Method(); product2->Method();}
抽象工厂
为创建一组相关或相互依赖的对象提供一个接口,而且无须指定他们的具体类。(工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是 多个产品等级结构 。抽象工厂模式主要用来实现生产一系列的产品。)
class AbstractProductA { public: virtual ~AbstractProductA(){}; virtual std::string FunctionA() const = 0;};class ProductA1 : public AbstractProductA { public: std::string FunctionA() const override { return \"The result of the product A1.\"; }};class ProductA2 : public AbstractProductA { std::string FunctionA() const override { return \"The result of the product A2.\"; }};class AbstractProductB { public: virtual ~AbstractProductB(){}; virtual std::string FunctionB() const = 0;};class ProductB1 : public AbstractProductB { public: std::string FunctionB() const override { return \"The result of the product B1.\"; }};class ProductB2 : public AbstractProductB { public: std::string FunctionB() const override { return \"The result of the product B2.\"; }};class AbstractFactory { public: virtual AbstractProductA *CreateProductA() const = 0; virtual AbstractProductB *CreateProductB() const = 0;};class Factory1 : public AbstractFactory { public: AbstractProductA *CreateProductA() const override { return new ProductA1(); } AbstractProductB *CreateProductB() const override { return new ProductB1(); }};class Factory2 : public AbstractFactory { public: AbstractProductA *CreateProductA() const override { return new ProductA2(); } AbstractProductB *CreateProductB() const override { return new ProductB2(); }};void Client(const AbstractFactory &factory) { const AbstractProductA *productA = factory.CreateProductA(); const AbstractProductB *productB = factory.CreateProductB(); std::cout << productA->FunctionA() << \"
\"; std::cout << productB->FunctionB() << \"
\"; delete productA; delete productB;}int main() { Factory1 *f1 = new Factory1(); Client(*f1); delete f1; Factory2 *f2 = new Factory2(); Client(*f2); delete f2; return 0;}
生成器/建造者
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。(建造者模式关注的是 零件类型 和装配工艺( 顺序 ))
class Product1{public: std::vectormParts; void ListParts()const{ std::cout << \"Product parts: \"; for (size_t i=0;imProduct->mParts.push_back(\"PartA1\"); } void ProducePartB()const override{ this->mProduct->mParts.push_back(\"PartB1\"); } void ProducePartC()const override{ this->mProduct->mParts.push_back(\"PartC1\"); } Product1* GetProduct() { Product1* result= mProduct; Reset(); return result; }};class Director { Builder* mbuilder;public: void set_builder(Builder* builder){ mbuilder = builder; } void BuildMinimalViableProduct(){ mbuilder->ProducePartA(); } void BuildFullFeaturedProduct(){ mbuilder->ProducePartA(); mbuilder->ProducePartB(); mbuilder->ProducePartC(); }};void ClientCode(Director& director){ ConcreteBuilder1* builder = new ConcreteBuilder1(); director.set_builder(builder); std::cout << \"Standard basic product:
\"; director.BuildMinimalViableProduct(); Product1* p= builder->GetProduct(); p->ListParts(); delete p; std::cout << \"Standard full featured product:
\"; director.BuildFullFeaturedProduct(); p= builder->GetProduct(); p->ListParts(); delete p; // Remember, the Builder pattern can be used without a Director class. std::cout << \"Custom product:
\"; builder->ProducePartA(); builder->ProducePartC(); p=builder->GetProduct(); p->ListParts(); delete p; delete builder;}int main(){ Director* director= new Director(); ClientCode(*director); delete director; return 0; }
原型
用原型实例指定创建对象的种类,并且通过 拷贝 这些原型创建新的对象。(原型模式实现的是一个Clone 接口,注意是接口,也就是基于 多态的 Clone 虚函数 。)
class Prototype { protected: string mPrototypeName; float mPrototypeField;public: Prototype() {} Prototype(string prototypeName) : mPrototypeName(prototypeName) { } virtual ~Prototype() {} virtual Prototype *Clone() const = 0; virtual void Function(float prototype_field) { this->mPrototypeField = prototype_field; std::cout << \"Call Function from \" << mPrototypeName << \" with field : \" << prototype_field << std::endl; }};class ConcretePrototype1 : public Prototype {private: float mConcretePrototypeField;public: ConcretePrototype1(string prototypeName, float concretePrototypeField) : Prototype(prototypeName), mConcretePrototypeField(concretePrototypeField) { } Prototype *Clone() const override { return new ConcretePrototype1(*this); }};class ConcretePrototype2 : public Prototype {private: float mConcretePrototypeField;public: ConcretePrototype2(string prototypeName, float concretePrototypeField) : Prototype(prototypeName), mConcretePrototypeField(concretePrototypeField) { } Prototype *Clone() const override { return new ConcretePrototype2(*this); }};class PrototypeFactory {private: std::unordered_map>mPrototypes;public: PrototypeFactory() { mPrototypes[Type::PROTOTYPE_1] = new ConcretePrototype1(\"PROTOTYPE_1 \", 50.f); mPrototypes[Type::PROTOTYPE_2] = new ConcretePrototype2(\"PROTOTYPE_2 \", 60.f); } ~PrototypeFactory() { delete mPrototypes[Type::PROTOTYPE_1]; delete mPrototypes[Type::PROTOTYPE_2]; } Prototype *CreatePrototype(Type type) { return mPrototypes[type]->Clone(); }};void Client(PrototypeFactory &prototypeFactory) { std::cout << \"Let"s create a Prototype 1
\"; Prototype *prototype = prototypeFactory.CreatePrototype(Type::PROTOTYPE_1); prototype->Function(90); delete prototype; std::cout << \"Let"s create a Prototype 2
\"; prototype = prototypeFactory.CreatePrototype(Type::PROTOTYPE_2); prototype->Function(10); delete prototype;}int main() { PrototypeFactory *prototypeFactory = new PrototypeFactory(); Client(*prototypeFactory); delete prototypeFactory; return 0;}
单例
单例模式是指在整个系统生命周期内,保证 一个类只能产生一个实例 ,确保该类的 唯一性 。
剩余60%,完整内容请点击下方链接查看:
阿里云开发者社区,千万开发者的选择。百万精品技术内容、千节免费系统课程、丰富的体验场景、活跃的社群活动、行业专家分享交流,尽在:
关键词:
(责任编辑:黄俊飞)推荐内容
- 一文讲透设计模式(C++版)
- 河北高考志愿填报辅助系统和志愿填报系统
- 海报|周鸿祎:大模型将成为产业数字化重
- PET铜箔产业迎质的突破 板块逆势上涨1.31%
- 当前视点!雅创电子:拟购买WE剩余86%股权
- 冯仑向左,王石向右
- 全面排查整治城镇燃气8类安全隐患
- LGD 1-2不敌GG,止步前三;GG包揽四大冠
- “走进泰拳”推广活动亮相昆明 展现泰国
- 如何修复portabledeviceconnectapi.dll丢
- 深圳通报百富兴大厦异响振动事件后续:房
- 电动汽车电池陷入二次利用困境:技术可行
- 夏天的快乐,去一趟冷饮批发店就能拥有!
- 全球消息!「光明时评」加强薄弱地区教育
- 每日热议!土地热线|保利广州长沙同日拿
- 扒窃未遂是否认定犯罪(扒窃的认定) 全
- 放送到第5话的三体动画口碑持续下滑连投
- 山东省中小学教师信息技术应用能力提升工
- 宋韶光2013年蛇年运程原装正版-全球观点
- 【天天时快讯】“拒聘川大毕业生”,冲上
- 虽然未展示,但健身依然是苹果Vision Pr
- 信息:皮肤软组织感染导致休克,大叔险送
- 中国移动社会渠道网址_河南移动社会渠道
- 环球快消息!曝微软:苹果和谷歌是游戏平
- 环球热消息:万物皆可Linux:已实现M2芯
- 二氧化碳电还原反应机理有了新认识 环球
- 疑似蔡徐坤妈妈协商堕胎语音曝光 表示愿
- 环球快消息!战争进化史手机版破解版游戏
- 6月26日基金净值:长信金利趋势混合A最新
- 马来西亚学者:海洋不应成为核污染水后院
- 贵南高铁贵州段进入运行试验阶段-最资讯
- 文学专家解读:切割泡沫板技巧与送礼建议
- 三亚文旅促消费|实施酒店入住率阶段性等
- 快看:光洋股份:6月21日公司高管程上楠
- 每日聚焦:夏令营入营注意事项_关于夏令
- 天天速看:工信部副部长王江平会见联发科
- 【独家焦点】地缘紧张局势升温 伦敦金阻
- 索尼新款耳机售价曝光:比WF-1000XM4贵出
- 全球今热点:中国燃气公布年度业绩 实现
- 环球热推荐:高温天气持续 人社部要求做
- 商丘市发展投资集团完成发行10亿元短期融
- 上海易连(600836)6月26日主力资金净卖
- 潢川江家集派出所:“主动警务”助推群众
- 快消息!昆仑万维:不存在借助市场热点操
- 今日看点:拼多多一件代发做什么类目好
- 全球热讯:上汽集团拟60亿参设基金,加快
- 网络红人陈琳的qq_网络红人ck|全球今亮点
- 速读:30年期国债期货填补品种空白 收益
- 辽宁科技大学:援非翻译向世界展示“爱和
- Faker给uzi送出祝福,希望他能回归巅峰,
- 天天热门:2023吉网高考服务大宝典 志愿
- 环球快消息!2024年高考作文预测:让“互
- 每日速递:亚太实业控股股东、实控人正筹
- 每日速读!中国信通院:5月国内市场手机出
- 世界聚焦:侨博阅览室向公众开放
- 广州南沙:夏日赏荷正当时 环球百事通
- 杭州园林最新公告:子公司拟700万元参与
- 最高法:通过国际物流寄递、陆路绕道或者
- 煎饼鏊子:一“烙”几千年|当前信息
- 恶魔的禁锢囚爱依稀 恶魔的禁锢
- 虽然未展示,但健身依然是苹果Vision Pr
- 信息:皮肤软组织感染导致休克,大叔险送
- 中国移动社会渠道网址_河南移动社会渠道
- 环球快消息!曝微软:苹果和谷歌是游戏平
- 环球热消息:万物皆可Linux:已实现M2芯
- 二氧化碳电还原反应机理有了新认识 环球
- 疑似蔡徐坤妈妈协商堕胎语音曝光 表示愿
- 环球快消息!战争进化史手机版破解版游戏
- 6月26日基金净值:长信金利趋势混合A最新
- 马来西亚学者:海洋不应成为核污染水后院
- 贵南高铁贵州段进入运行试验阶段-最资讯
- 文学专家解读:切割泡沫板技巧与送礼建议
- 三亚文旅促消费|实施酒店入住率阶段性等
- 快看:光洋股份:6月21日公司高管程上楠
- 每日聚焦:夏令营入营注意事项_关于夏令
- 天天速看:工信部副部长王江平会见联发科
- 【独家焦点】地缘紧张局势升温 伦敦金阻
- 索尼新款耳机售价曝光:比WF-1000XM4贵出
- 全球今热点:中国燃气公布年度业绩 实现
- 环球热推荐:高温天气持续 人社部要求做
- 商丘市发展投资集团完成发行10亿元短期融
- 上海易连(600836)6月26日主力资金净卖
- 潢川江家集派出所:“主动警务”助推群众
- 快消息!昆仑万维:不存在借助市场热点操
- 今日看点:拼多多一件代发做什么类目好
- 全球热讯:上汽集团拟60亿参设基金,加快
- 网络红人陈琳的qq_网络红人ck|全球今亮点
- 速读:30年期国债期货填补品种空白 收益
- 辽宁科技大学:援非翻译向世界展示“爱和
- Faker给uzi送出祝福,希望他能回归巅峰,
- 天天热门:2023吉网高考服务大宝典 志愿
- 环球快消息!2024年高考作文预测:让“互
- 每日速递:亚太实业控股股东、实控人正筹
- 每日速读!中国信通院:5月国内市场手机出
- 世界聚焦:侨博阅览室向公众开放
- 广州南沙:夏日赏荷正当时 环球百事通
- 杭州园林最新公告:子公司拟700万元参与
- 最高法:通过国际物流寄递、陆路绕道或者
- 煎饼鏊子:一“烙”几千年|当前信息
- 恶魔的禁锢囚爱依稀 恶魔的禁锢
- 2022~2023年山东养老金上调方案最新消息
- 科技感爆棚,这个沉浸式禁毒宣传教育基地
- 【环球热闻】运动也会猝死?跑步时出现这
- 【全球速看料】中信证券为CITIC Securit
- 魅族不用电源键怎么开机|天天观速讯
- 金元顺安基金董事长任开宇:秉承工匠精神
- 当前视点!陕国投A将于6月29日解禁11.5亿股
- 半导体设备快速拉涨,中科飞测涨超6%_世
- 海口解除暴雨橙色预警
- 三无充电头爆炸!千万别在这儿省钱
- 天津着力优化营商环境、提升服务水平——
- 戈壁滩上的现代农业
- 世界今日报丨吉林省召开农药包装废弃物回
- 报道:美育培元 天津四百名音美教师封闭
- 蚂蚁树枝打一成语疯狂猜成语_疯狂猜成语
- 提升“互联网+政务服务”水平!宝山区行
- 世界讯息:最高法:新型毒品犯罪上升 非
- 福晟国际:法院批准计划 环球聚焦
- 快资讯:2023年湖南益阳中考录取分数线公
- 今日精选:交易异动!*ST美谷:近3个交易