Linux C++ 045-设计模式之工厂模式

news/2024/7/24 11:30:15 标签: linux, c++, 设计模式

Linux C++ 045-设计模式之工厂模式

本节关键字:Linux、C++、设计模式、简单工厂模式、工厂方法模式、抽象工厂模式
相关库函数:

简单工厂模式

基本简介

设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。

简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

实现方式

简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

角色结构

工厂角色:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。

抽象产品角色:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

具体产品角色:是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。

class SimpleOperation
{
public:
    SimpleOperation() {
    	numberA = 1;
    	numberB = 1;
    }
public:
    double numberA, numberB;
    virtual double getResult() = 0;
};

class AddSimpleOperation : public SimpleOperation
{
    double getResult() {
        return numberA + numberB;
    }
};
class SubSimpleOperation : public SimpleOperation
{
    double getResult() {
        return numberA - numberB;
    }
};
class MulSimpleOperation : public SimpleOperation
{
    double getResult() {
        return numberA * numberB;
    }
};
class DivSimpleOperation : public SimpleOperation
{
    double getResult() {
        return numberA / numberB;
    }
};
class OperSimpleOperation
{
public:
    static SimpleOperation* createOperation(char c)
    {
        switch (c)
        {
        case '+':
            return new AddSimpleOperation;
            break;
        case '-':
            return new SubSimpleOperation;
            break;
        case '*':
            return new MulSimpleOperation;
            break;
        case '/':
            return new DivSimpleOperation;
            break;
        }
    }
};
int main_SimpleFactory()
{
    OperationSimple* oper = operFactorySimple::createOperation('+');
    oper->numberA = 123;
    oper->numberB = 456;
    cout << oper->getResult() << endl;
    return 0;
}

工厂方法模式

基本简介

工厂方法(FactoryMethod)模式是类的创建模式,其用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。

工厂方法模式的实质是“定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。”

在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不接触哪一个产品类被实例化这种细节。这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。

在Factory Method模式中,工厂类与产品类往往具有平行的等级结构,它们之间一一对应。

实现方式

工厂方法模式的实质是:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。

角色结构

抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。

抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。

具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。

class OperationMethod
{
public:
    OperationMethod() {

    }
    ~OperationMethod() {

    }
public:
    double numberA, numberB;
    virtual double getResult() = 0;
};
class AddOperationMethod : public OperationMethod
{
    double getResult() {
        return numberA + numberB;
    }
};
class SubOperationMethod : public OperationMethod
{
    double getResult() {
        return numberA - numberB;
    }
};
class MulOperationMethod : public OperationMethod
{
    double getResult() {
        return numberA * numberB;
    }
};
class DivOperationMethod : public OperationMethod
{
    double getResult() {
        return numberA / numberB;
    }
};
class IFactoryMethod
{
public:
    virtual OperationMethod* createOperation() = 0;
};
class AddFactoryMethod : public IFactoryMethod
{
public:
    static OperationMethod* createOperation() {
        return new AddOperationMethod();
    }
};
class SubFactoryMethod : public IFactoryMethod
{
public:
    static OperationMethod* createOperation() {
        return new SubOperationMethod();
    }
};
class MulFactoryMethod : public IFactoryMethod
{
public:
    static OperationMethod* createOperation() {
        return new MulOperationMethod();
    }
};
class DivFactoryMethod : public IFactoryMethod
{
public:
    static OperationMethod* createOperation() {
        return new DivOperationMethod();
    }
};
int main_MethodFactory()
{
    OperationMethod* oper = MulFactoryMethod::createOperation();
    oper->numberA = 666;
    oper->numberB = 999;
    cout << oper->getResult() << endl;
    return 0;
}

抽象工厂模式

基本简介

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

当每个抽象产品都有多于一个的具体子类的时候,工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产品角色都有两个具体产品。抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。

每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。

实现方式

根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

产品族

产品族是指位于不同产品等级结构中,功能相关联的产品组成的家族。一般是位于不同的等级结构中的相同位置上。显然,每一个产品族中含有产品的数目,与产品等级结构的数目是相等的,形成一个二维的坐标系,水平坐标是产品等级结构,纵坐标是产品族。叫做相图。

当有多个不同的等级结构的产品时,如果使用工厂方法模式就势必要使用多个独立的工厂等级结构来对付这些产品的等级结构。如果这些产品等级结构是平行的,会导致多个平行的工厂等级结构。

抽象工厂模式使用同一个 工厂等级结构负责这些不同产品等级结构产品对象的创建。

对于每一个产品族,都有一个具体工厂。而每一个具体工厂创建属于同一个产品族,但是分属于不同等级结构的产品。

通过引进抽象工厂模式,可以处理具有相同(或者相似)等级结构的多个产品族中的产品对象的创建问题。

由于每个具体工厂角色都需要负责两个不同等级结构的产品对象的创建,因此每个工厂角色都需要提供两个工厂方法,分别用于创建两个等级结构的产品。既然每个具体工厂角色都需要实现这两个工厂方法,所以具有一般性,不妨抽象出来,移动到抽象工厂角色中加以声明。

class IUser
{
public:
    virtual void getUser() = 0;
    virtual void setUser() = 0;
};
class SqlUser : public IUser
{
public:
    void getUser() {
        cout << "在sql中返回user" << endl;
    }
    void setUser() {
        cout << "在sql中设置user" << endl;
    }
};
class AccessUser : public IUser
{
public:
    void getUser() {
        cout << "在Access中返回user" << endl;
    }
    void setUser() {
        cout << "在Access中设置user" << endl;
    }
};
class IDepartment
{
public:
    virtual void getDepartment() = 0;
    virtual void setDepartment() = 0;
};
class SqlDepartment : public IDepartment
{
public:
    void getDepartment() {
        cout << "在sql中返回Department" << endl;
    }
    void setDepartment() {
        cout << "在sql中设置Department" << endl;
    }
};
class AccessDepartment : public IDepartment
{
public:
    void getDepartment() {
        cout << "在Access中返回Department" << endl;
    }
    void setDepartment() {
        cout << "在Access中设置Department" << endl;
    }
};
class IFactory
{
public:
    virtual IUser* createUser() = 0;
    virtual IDepartment* createDepartment() = 0;
};
class SqlFactory : public IFactory
{
public:
    IUser* createUser() {
        return new SqlUser();
    }
    IDepartment* createDepartment() {
        return new SqlDepartment();
    }
};
class AccessFactory :public IFactory
{
public:
    IUser* createUser() {
        return new AccessUser();
    }
    IDepartment* createDepartment() {
        return new AccessDepartment();
    }
};
class DataAccess // 简单工厂类
{
private:
    static string db;
public:
    static IUser* createUser() {
        if (db == "access") {
            return new AccessUser();
        }
        else if (db == "sql") {
            return new SqlUser();
        }
    }
    static IDepartment* createDeparment() {
        if (db == "access") {
            return new AccessDepartment();
        }
        else if (db == "sql") {
            return new SqlDepartment();
        }
    }
};
string DataAccess::db = "sql";

int main_AbstractFactory()
{
    // IFactory* factory = new SqlFactory();
    IFactory* factory;
    IUser* user;
    IDepartment* department;

    factory = new AccessFactory();
    user = factory->createUser();
    department = factory->createDepartment();

    user->getUser();
    user->setUser();
    department->getDepartment();
    department->setDepartment();

    // 简单工厂类的调用
    user = DataAccess::createUser();
    department = DataAccess::createDeparment();

    user->getUser();
    user->setUser();
    department->getDepartment();
    department->setDepartment();
    return 0;
}

http://www.niftyadmin.cn/n/5547016.html

相关文章

接口测试(1)

什么是接口测试 路线&#xff1a; 项目介绍 URL&#xff1a;统一资源定位符 HTTP协议 请求URL 请求行 请求方法 post/put 请求行 请求数据类型 content-type json 请求数据 请求体 响应状态码 响应行 响应数据类型 content-type json 响应数据 请响应体 用户名&#xf…

[激光原理与应用-98]:南京科耐激光-激光焊接-焊中检测-智能制程监测系统IPM介绍 - 2 - 什么是激光器焊接? 常见的激光焊接技术详解

目录 一、什么是激光焊接 1.1 概述 1.2 激光焊接的优点 二、激光焊接的应用 2.1 哪些场合必须使用激光焊接 1. 汽车制造业 2. 航空航天领域 3. 电子行业&#xff1a;消费类电子3C 4. 医疗器械制造 5. 新能源锂电池行业 6. 其他领域 三、激光焊接的分类 3.1 按焊接…

【高校科研前沿】中国农业大学姚晓闯老师等人在农林科学Top期刊发表长篇综述:深度学习在农田识别中的应用

文章简介 论文名称&#xff1a;Deep learning in cropland field identification: A review&#xff08;深度学习在农田识别中的应用&#xff1a;综述&#xff09; 第一作者及单位&#xff1a;Fan Xu&#xff08;中国农业大学土地科学与技术学院&#xff09; 通讯作者及单位&…

SpringBoot 实现视频分段播放(通过进度条来加载视频)

需求&#xff1a;现在我本地电脑中有一个文件夹&#xff0c;文件夹中都是视频&#xff0c;需要实现视频播放的功能。 问题&#xff1a;如果通过类似 SpringBoot static 文件夹的方式来实现&#xff0c;客户端要下载好完整的视频之后才可以播放&#xff0c;并且服务端也会占用大…

论文《Generalizable Adversarial Attacks Using Generative Models》笔记

【DAGAER】传统的攻击方法依赖于约束优化范式&#xff0c;具有局限性&#xff0c;例如经典的Nettack攻击方法。本文提出了一个统一的白盒对抗攻击生成框架&#xff0c;该方法学习了目标域的深度生成模型&#xff0c;不是在原始输入空间中生成对抗性例子&#xff0c;而是学习在一…

印尼网络安全治理能力观察

在全国国际机场的移民服务完全瘫痪 100 多个小时后&#xff0c;印尼政府承认其新成立的国家数据中心 (PDN) 遭受了网络攻击。 恶意 Lockbit 3.0 勒索软件加密了存储在中心的重要数据&#xff0c;其背后的黑客组织要求支付 800 万美元的赎金。 不幸的是&#xff0c;大多数数据…

华为od 100问 持续分享-2

我是一名软件开发培训机构老师&#xff0c;我的学生已经有上百人通过了华为OD机试&#xff0c;学生们每次考完试&#xff0c;会把题目拿出来一起交流分享。 重要&#xff1a;2024年5月份开始&#xff0c;考的都是OD统一考试&#xff08;D卷&#xff09;&#xff0c;题库已经整…

Redis-Jedis连接池\RedisTemplate\StringRedisTemplate

Redis-Jedis连接池\RedisTemplate\StringRedisTemplate 1. Jedis连接池1.1 通过工具类1.1.1 连接池&#xff1a;JedisConnectionFactory&#xff1a;1.1.2 test&#xff1a;&#xff08;代码其实只有连接池那里改变了&#xff09; 2. SpringDataRedis&#xff08;lettuce&#…