工厂方法模式(大话设计模式)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. 为了降低耦合,根据依赖倒置的原则(细节依赖抽象),将创建工厂类的分支判断直接改成对应的具体工厂类。
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值