工厂方法模式(大话设计模式)C/C++版本

2024-06-15 13:44

本文主要是介绍工厂方法模式(大话设计模式)C/C++版本,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

工厂方法模式

C++

参考:https://www.cnblogs.com/Galesaur-wcy/p/15926711.html

#include <iostream>
#include <memory>
using namespace std;// 运算类
class Operation
{
private:double _NumA;double _NumB;public:void SetNumA(){cout << "Enter a double number: ";if (!(cin >> _NumA))throw "It must be a number";}double GetNumA(){return _NumA;}void SetNumB(){cout << "Enter a double number: ";if (!(cin >> _NumB))throw "It must be a number";}double GetNumB(){return _NumB;}virtual double GetResult(){int result = 0;return result;}
};class OperationAdd : public Operation
{
public:double GetResult(){double result = GetNumA() + GetNumB();return result;}
};class OperationSub : public Operation
{
public:double GetResult(){double result = GetNumA() - GetNumB();return result;}
};class OperationMul : public Operation
{
public:double GetResult(){double result = GetNumA() * GetNumB();return result;}
};class OperationDiv : public Operation
{
public:double GetResult(){if (GetNumB() == 0){throw "The divisor cannot be 0";}double result = GetNumA() / GetNumB();return result;}
};class Factory
{
public:virtual Operation *CreatOperation() = 0;
};class AddFactory : public Factory
{
public:Operation *CreatOperation(){return new OperationAdd();}
};class SubFactory : public Factory
{
public:Operation *CreatOperation(){return new OperationSub();}
};class MulFactory : public Factory
{
public:Operation *CreatOperation(){return new OperationMul();}
};class DivFactory : public Factory
{
public:Operation *CreatOperation(){return new OperationDiv();}
};/* 封装一下用户选择工厂创建的过程(属于客户端代码) */
Factory * CreatFactory(char operator_type)
{switch (operator_type){case '+':return new AddFactory;break;case '-':return new SubFactory;break;case '*':return new MulFactory;break;case '/':return new DivFactory;break;default:throw "Error input operator!";break;}return nullptr;
}int main()
{cout << "Choose an operation:";char operator_char;cin >> operator_char;try{//unique_ptr<Factory> fac = unique_ptr<Factory>(CreatFactory(operator_char));//智能指针更安全Factory* fac = CreatFactory(operator_char);//unique_ptr<Operation> oper = unique_ptr<Operation>(fac->CreatOperation());Operation* oper = fac->CreatOperation();oper->SetNumA();oper->SetNumB();cout << "result is: " << oper->GetResult() << endl;}catch (const char *err){cerr << err << endl;return -1;}return 0;
}

C

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>typedef struct Operation
{double NumA;double NumB;double (*GetResult)(struct Operation *);void (*SetNumA)(struct Operation *);void (*SetNumB)(struct Operation *);
} Operation;typedef struct OperationAdd
{Operation base; // 设置为第一个成员属性,模拟继承
} OperationAdd;typedef struct OperationSub
{Operation base;
} OperationSub;typedef struct OperationMul
{Operation base;
} OperationMul;typedef struct OperationDiv
{Operation base;
} OperationDiv;double OperationAddGetResult(struct Operation *op)
{OperationAdd *add = (OperationAdd *)op;return add->base.NumA + add->base.NumB;
}double OperationSubGetResult(struct Operation *op)
{OperationSub *sub = (OperationSub *)op;return sub->base.NumA - sub->base.NumB;
}double OperationMulGetResult(struct Operation *op)
{OperationMul *mul = (OperationMul *)op;return mul->base.NumA * mul->base.NumB;
}double OperationDivGetResult(struct Operation *op)
{OperationDiv *div = (OperationDiv *)op;if (div->base.NumB == 0){fputs("The divisor cannot be 0\n", stderr);exit(EXIT_FAILURE);}return div->base.NumA / div->base.NumB;
}typedef struct Factory
{Operation* (*CreatOperation)();
}Factory;typedef struct FactoryAdd
{Factory base;
} FactoryAdd;typedef struct FactorySub
{Factory base;
} FactorySub;typedef struct FactoryMul
{Factory base;
} FactoryMul;typedef struct FactoryDiv
{Factory base;
} FactoryDiv;void SetNumA(Operation *ope)
{printf("Enter a double number: ");if (scanf("%lf", &ope->NumA) != 1){fputs("It must be a number\n", stderr);exit(EXIT_FAILURE);}
}void SetNumB(Operation *ope)
{printf("Enter a double number: ");if (scanf("%lf", &ope->NumB) != 1){fputs("It must be a number\n", stderr);exit(EXIT_FAILURE);}
}Operation *CreatOperationAdd()
{Operation *op = malloc(sizeof(Operation));op->GetResult = OperationAddGetResult;op->SetNumA = SetNumA;op->SetNumB = SetNumB;return op;
}Operation *CreatOperationSub()
{Operation *op = malloc(sizeof(Operation));op->GetResult = OperationSubGetResult;op->SetNumA = SetNumA;op->SetNumB = SetNumB;return op;
}Operation *CreatOperationMul()
{Operation *op = malloc(sizeof(Operation));op->GetResult = OperationMulGetResult;op->SetNumA = SetNumA;op->SetNumB = SetNumB;return op;
}Operation *CreatOperationDiv()
{Operation *op = malloc(sizeof(Operation));op->GetResult = OperationDivGetResult;op->SetNumA = SetNumA;op->SetNumB = SetNumB;return op;
}Factory *CreateFactory(char op)
{Factory *fac = NULL;switch (op){case '+':fac = malloc(sizeof(FactoryAdd));fac->CreatOperation = CreatOperationAdd;break;case '-':fac = malloc(sizeof(FactorySub));fac->CreatOperation = CreatOperationSub;break;case '*':fac = malloc(sizeof(FactoryMul));fac->CreatOperation = CreatOperationMul;break;case '/':fac = malloc(sizeof(FactoryDiv));fac->CreatOperation = CreatOperationDiv;break;default:fputs("Error input operator!\n", stderr);return NULL;}return fac;
}int main()
{printf("Choose an operation: ");char operator_char = getchar();Factory* fac = CreateFactory(operator_char);Operation *oper = fac->CreatOperation();if (!oper)return EXIT_FAILURE;oper->SetNumA(oper);oper->SetNumB(oper);printf("Result is: %f\n", oper->GetResult(oper));free(oper);return 0;
}

对比简单工厂模式

简单工厂模式例子

  1. 给四种运算新建了四个具体工厂类
  2. 将简单工厂类模式中的工厂创建逻辑判断,移到了客户端代码中

工厂方法模式这样做的目的就是:对创建工厂类的修改关闭,对具体工厂类的扩展开放。

思维思路:

  1. 简单工厂类中的创建工厂类中直接与具体的运算符号产生了依赖,不易于扩展(后期增加运算符,得直接修改工厂类)。
  2. 为了降低耦合,根据依赖倒置的原则(细节依赖抽象),将创建工厂类的分支判断直接改成对应的具体工厂类。

这篇关于工厂方法模式(大话设计模式)C/C++版本的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1063618

相关文章

MySQL查看表的历史SQL的几种实现方法

《MySQL查看表的历史SQL的几种实现方法》:本文主要介绍多种查看MySQL表历史SQL的方法,包括通用查询日志、慢查询日志、performance_schema、binlog、第三方工具等,并... 目录mysql 查看某张表的历史SQL1.查看MySQL通用查询日志(需提前开启)2.查看慢查询日志3.

MySQL底层文件的查看和修改方法

《MySQL底层文件的查看和修改方法》MySQL底层文件分为文本类(可安全查看/修改)和二进制类(禁止手动操作),以下按「查看方法、修改方法、风险管控三部分详细说明,所有操作均以Linux环境为例,需... 目录引言一、mysql 底层文件的查看方法1. 先定位核心文件路径(基础前提)2. 文本类文件(可直

Java实现字符串大小写转换的常用方法

《Java实现字符串大小写转换的常用方法》在Java中,字符串大小写转换是文本处理的核心操作之一,Java提供了多种灵活的方式来实现大小写转换,适用于不同场景和需求,本文将全面解析大小写转换的各种方法... 目录前言核心转换方法1.String类的基础方法2. 考虑区域设置的转换3. 字符级别的转换高级转换

使用Python实现局域网远程监控电脑屏幕的方法

《使用Python实现局域网远程监控电脑屏幕的方法》文章介绍了两种使用Python在局域网内实现远程监控电脑屏幕的方法,方法一使用mss和socket,方法二使用PyAutoGUI和Flask,每种方... 目录方法一:使用mss和socket实现屏幕共享服务端(被监控端)客户端(监控端)方法二:使用PyA

检查 Nginx 是否启动的几种方法

《检查Nginx是否启动的几种方法》本文主要介绍了检查Nginx是否启动的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1. 使用 systemctl 命令(推荐)2. 使用 service 命令3. 检查进程是否存在4

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

Java方法重载与重写之同名方法的双面魔法(最新整理)

《Java方法重载与重写之同名方法的双面魔法(最新整理)》文章介绍了Java中的方法重载Overloading和方法重写Overriding的区别联系,方法重载是指在同一个类中,允许存在多个方法名相同... 目录Java方法重载与重写:同名方法的双面魔法方法重载(Overloading):同门师兄弟的不同绝

MySQL字符串转数值的方法全解析

《MySQL字符串转数值的方法全解析》在MySQL开发中,字符串与数值的转换是高频操作,本文从隐式转换原理、显式转换方法、典型场景案例、风险防控四个维度系统梳理,助您精准掌握这一核心技能,需要的朋友可... 目录一、隐式转换:自动但需警惕的&ld编程quo;双刃剑”二、显式转换:三大核心方法详解三、典型场景

MySQL快速复制一张表的四种核心方法(包括表结构和数据)

《MySQL快速复制一张表的四种核心方法(包括表结构和数据)》本文详细介绍了四种复制MySQL表(结构+数据)的方法,并对每种方法进行了对比分析,适用于不同场景和数据量的复制需求,特别是针对超大表(1... 目录一、mysql 复制表(结构+数据)的 4 种核心方法(面试结构化回答)方法 1:CREATE

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra