C++实现简单工厂和工厂方法以及抽象工厂

news/2024/11/23 4:09:43/

工厂类型设计模式

new给封装起来,即对象的创建封装起来

一种创建型设计模式

简单工厂

假设场景:用工厂来创建不同的汽车

优点:把对象的创建封装在一个接口函数里面,通过传入不同标识来返回不同的对象。客户不用自己负责创建对象(new),不用了解创建对象的详细过程

实现代码如下:

class Car
{
public:Car(string name) :_name(name){}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;}
};enum CarType
{BMW, AUDI
};
class SimpleFactory
{
public:Car* createCar(CarType ct){switch (ct){case BMW:return new Bmw("X1");case AUDI:return new Audi("Q7");default:cerr << "传入工厂的参数不正确:" << ct << endl;break;}return nullptr;}
};int main()
{// 不好,暴露了对象的创建/*Car* p1 = new Bmw("X1");Car* p2 = new Audi("Q7");*/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;
}

缺点:所有的产品都在一个工厂创建,提供创建对象实例的接口函数不闭合,不满足开闭原则中对修改封闭

工厂方法

优点:设计一个Factory基类,提供了一个纯虚函数(创建产品),定义派生类(具体产品的工厂)负责创建对应的产品,可以做到不同产品在不同的工厂里创建,能够对现有的工厂以及产品的修改关闭。实现代码如下

// 工厂方法
class Car
{
public:Car(string name) :_name(name) {}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;}
};class Factory
{
public: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> bmwfty(new BmwFactory()); // 创建工厂unique_ptr<Factory> audifty(new AudiFactory()); // 创建工厂unique_ptr<Car> p1(bmwfty->createCar("X6"));unique_ptr<Car> p2(audifty->createCar("A6"));p1->show();p2->show();return 0;
}

工厂方法缺点:实际上,很多产品时有关联关系的,属于一个产品族,不应该放在不同的工厂中创建(如苹果手机和耳机应该在同一个工厂生产)。这样一是不符合实际产品对象的创建逻辑,二是会造成类的数量的膨胀

抽象工厂

优点:将有关联关系的属于一个产品族的所有产品创建接口函数放在一个抽象工厂类AbstractFactory中,派生类(具体产品的工厂)应该负责创建该产品族的所有产品.

即宝马工厂也生产宝马车灯和宝马座椅,奥迪工厂也生产奥迪车灯和奥迪座椅

实现代码:

class Car
{
public:Car(string name) :_name(name) {}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;}
};// 系列产品
class Light
{
public:virtual void show() = 0;
};class BmwLight : public Light
{
public:void show(){cout << "BMW light!" << endl;}
};
class AudiLight : public Light
{
public:void show(){cout << "Audi light!" << endl;}
};
class AbstractFactory
{
public:virtual Car* createCar(string name) = 0;virtual Light* createCarLight() = 0;
};class BmwFactory : public AbstractFactory
{
public:Car* createCar(string name){return new Bmw(name);}Light* createCarLight(){return new BmwLight();}
};
class AudiFactory : public AbstractFactory
{
public:Car* createCar(string name){return new Audi(name);}Light* createCarLight(){return new AudiLight();}
};int main()
{unique_ptr<AbstractFactory> bmwfty(new BmwFactory()); // 创建工厂unique_ptr<AbstractFactory> audifty(new AudiFactory()); // 创建工厂unique_ptr<Car> p1(bmwfty->createCar("X6"));unique_ptr<Car> p2(audifty->createCar("A6"));unique_ptr<Light> l1(bmwfty->createCarLight());unique_ptr<Light> l2(audifty->createCarLight());p1->show();l1->show();p2->show();l2->show();return 0;
}

http://www.ppmy.cn/news/67167.html

相关文章

【C语言】测试4 循环程序设计

若 x, i, j, k 都是 int 型变量,则计算下面表达式后, x 的值为( )。 x=( i=4 , j=16 , k=32); A. 4 B. 16 C. 32 D. 52 正确答案: C 以下能正确计算123* ⋯ 10 的程序段是( )。 A. do {i=1;s=1; s=si; i++; }while(i<=10); B. do {i=1;s=0; s=si; i++; }w…

【设计模式】模板方法模式--让你的代码更具灵活性与可扩展性

文章目录 前言模板方法模式的定义核心组成模板方法模式与其他设计模式的区别 代码实现抽象类具体类Client 经典类图spring中的例子 总结 前言 在软件开发中&#xff0c;设计模式是一种经过实践检验的、可复用的解决方案&#xff0c;它们可以帮助我们解决某一特定领域的典型问题…

PBDB Data Service:Fossil diversity over time (diagnostic) 化石多样性随时间的变化(诊断)

化石多样性随时间的变化&#xff08;诊断&#xff09; 描述用法参数需要以下参数之一以下参数指定要计数的内容以及时间分辨率以下参数选择要分析的实例 方法响应结果1&#xff1a;basic 格式术语表 描述 此操作提供了一种检查 occs/diversity 操作计数的分类群的方法。可以将…

正则化解决过拟合

本片举三个例子进行对比&#xff0c;分别是&#xff1a;不使用正则化、使用L2正则化、使用dropout正则化。 首先是前后向传播、加载数据、画图所需要的相关函数的reg_utils.py&#xff1a; # -*- coding: utf-8 -*-import numpy as np import matplotlib.pyplot as plt impor…

Linux 并发与竞争

一、并发与竞争 1、并发 Linux 系统是个多任务操作系统&#xff0c;会存在多个任务同时访问同一片内存区域&#xff0c;这些任务可 能会相互覆盖这段内存中的数据&#xff0c;造成内存数据混乱。 多线程并发访问&#xff0c; Linux 是多任务(线程)的系统&#xff0c;所以多线…

AMB300系列母线槽红外测温解决方案南沙XX养殖项目案例分享

安科瑞 耿敏花 一、 行业背景 随着当今社会的发展和用电量的急剧上升&#xff0c;现代化工程设施和装备的涌现&#xff0c;封闭式母线即母线槽因方便、节能、载流量大、机械强度高 、安装灵活、寿命长等特点&#xff0c;逐渐取代传统电缆&#xff0c;广泛应用于室内变压…

如何在VUE中使用andflow流程设计组件

andflow_js 是基于js、css、html开发的一个前端流程设计组件&#xff0c;目的是方便前端开发流程设计器。实现各种流程设计的样式风格&#xff0c;以及对设计结果的读取和显示&#xff0c;以便于与将设计结果提供给后端保存和执行。 由于VUE框架在许多实际项目中经常使用&…

2023 年第三届长三角高校数学建模 B 题 长三角新能源汽车发展与双碳关系研究

B 题 长三角新能源汽车发展与双碳关系研究 《节能与新能源汽车技术路线图 2.0》提出至 2035 年&#xff0c;新能源汽车市场占比 超过 50% &#xff0c;燃料电池汽车保有量达到 100 万辆&#xff0c;节能汽车全面实现混合动力化&#xff0c; 汽车产业实现电动化转型的明确目标。…