设计模式之工厂模式

代码

这个工厂模式算是简单工厂的升级版,姑且叫它工厂2.0吧,后续还有工厂3.0(抽象工厂更加复杂)。还是采用例子来讲解,例子和前面的简单工厂是一样的,就是加减乘除四个不同算法类,相对比简单工厂,这个设计模式有四个部分,且听我娓娓道来:

  1. 工厂类基类,是不同算法类工厂的基类,对应下面代码的 i F a c t o r y iFactory iFactory
  2. 具体的工厂类,对应加减乘除不同算法的具体工厂,对应于下面代码中继承于 i F a c t o r y iFactory iFactory的类
  3. 算法类的抽象,不同算法的基类,对应下面的 O p e r a t i o n Operation Operation
  4. 具体的算法类,算法的具体类,对应于下面代码中继承于 O p e r a t i o n Operation Operation的类

看过前面的简单工厂之后,就可以很容易的发现,这里的变化,就是此工厂类不再生产所有的具体算法类了,工厂类也有抽象了,每个不同的具体工厂来生产具体的算法,为何要这样呢,这样代码不就变多了吗。不急不急,后面我会狡辩。咱继续看。

#include <iostream>
#include <string>
using std::string;

class Operation
{
    protected:
        double numberA;
        double numberB;
    public:
        Operation():numberA(0),numberB(0){};
        Operation(double A,double B):numberA(A),numberB(B){};
        void setA(double A){numberA = A;};
        void setB(double B){numberB = B;};
        virtual double getResult() = 0;
};

class OperationAdd : public Operation
{
    public:
        virtual double getResult(){return numberA + numberB;};
};

class OperationSub : public Operation
{
    public:
        virtual double getResult(){return numberA - numberB;};
};

class OperationMul : public Operation
{
    public:
        virtual double getResult(){return numberA * numberB;};
};

class OperationDiv : public Operation
{
    public:
        virtual double getResult(){return numberA / numberB;};
};

class iFactory
{
    public:
        virtual Operation * createOperation() = 0;
};

class addFactory : public iFactory
{
    public:
        virtual Operation * createOperation(){return new OperationAdd();};
};
class subFactory : public iFactory
{
    public:
        virtual Operation * createOperation(){return new OperationSub();};
};
class mulFactory : public iFactory
{
    public:
        virtual Operation * createOperation(){return new OperationMul();};
};
class divFactory : public iFactory
{
    public:
        virtual Operation * createOperation(){return new OperationDiv();};
};

int main()
{
    iFactory *operFactory = new addFactory();
    Operation *oper = operFactory->createOperation();
    oper->setA(1);
    oper->setB(2);
    std::cout<<oper->getResult()<<"\n";
    return 0;
}

详细表述

这里这里算法类和简单工厂是一样的,基类抽象获得具体算法类的值,调用同一个抽象基类的指针,实现不同的算法。我就不多bb了,直接说一下这个工厂类,这里你可以把基类指针(基类引用)和抽象当作同一个概念,可以的,可以的。

  1. 首先是工厂基类,是一个抽象基类,有一个纯虚函数,因此不能有具体对象,它是用来抽象具体的工厂类的,工厂抽象获得具体工厂类的值,来实现抽象
  2. 每个不同的算法类,拥有一个不同的工厂,然后算法抽象通过调用工厂抽象的 c r e a t e O p e r a t i o n createOperation createOperation方法(虽然是调用的基类指针,但是c++的运行时判断使得调用了具体工厂类的方法)得到不同的算法类,实现多态
  3. 然后我们使用的时候直接使用算法基类指针进行调用,采用运行时判断使得不同的类调用不同的虚函数 g e t R e s u l t getResult getResult实现多态

狡辩

ok,下面该我来狡辩前面的坑了,为啥工厂也要实现抽象,每个算法对应特定的工厂呢,假如嗷,我说假如,万一你使用简单工厂模式遇见了需要多个重复算法类的场景,你就的写出下面的代码,对吧(不让用循环嗷)!

Operation *oper1 = nullptr;
oper1 = OperationFactory::creatOperation('/');
Operation *oper2 = nullptr;
oper2 = OperationFactory::creatOperation('/');
Operation *oper3 = nullptr;
oper3 = OperationFactory::creatOperation('/');

现在我遇见一个问题,我不想使用除算法类了想用乘,那你就得改上面的代码,把’/‘改为’*',改三个地方,记住3嗷,下面给你看看使用工厂模式的代码

iFactory *operFactory = new addFactory();
Operation *oper = operFactory->createOperation();
Operation *oper1 = operFactory->createOperation();
Operation *oper2 = operFactory->createOperation();
Operation *oper3 = operFactory->createOperation();

这里我改动的话,只需要把具体的工厂类改了就完事了,就改一处就行了,感受到工厂模式的好处了吧。

例子已经说明好处了,我们再说点专业的话语嗷。那就是设计模式中有大约七个原则吧

  1. 单一职责原则 (Single Responsibility Principle)
  2. 开放-关闭原则 (Open-Closed Principle)
  3. 里氏替换原则 (Liskov Substitution Principle)
  4. 依赖倒转原则 (Dependence Inversion Principle)
  5. 接口隔离原则 (Interface Segregation Principle)
  6. 迪米特法则(Law Of Demeter)
  7. 组合/聚合复用原则 (Composite/Aggregate Reuse Principle)

我们看看工厂模式比简单工厂模式多满足了啥原则

  1. 首先单一职责,这个很明显吧,工厂每个具体工厂类只负责一个算法类的生成,而简单工厂负责所有的算法类生成

  2. 开放-关闭原则,这个有点抽象是吧,没听过这个原则,不好理解吧,hhh,没事,我给你们解释,通俗易懂就是对允许增加代码,但是不允许更改已有代码。我们看看工厂模式怎么符合的,我们上面有四个算法类,加减乘除,现在我要加一个算法类,取模算法类,那么简单工厂要怎么加呢,看下面代码

    class OperationFactory
    {
        public:
            static Operation * creatOperation(int operation)
            {
                Operation *result = nullptr;
                switch(operation)
                {
                    /*...
                    和前面的简单工厂一样*/
                    case '%'://here here
                        result = new OperationDiv();
                        break;
                }
                return result;
            }
    };
    

    O p e r a t i o n F a c t o r y OperationFactory OperationFactory需要改变,增加一个case,ok开放-关于原则它已破坏,那工厂模式怎么添加代码呢,看下面代码

    class OperationMod : public Operation
    {
        public:
            virtual double getResult(){return numberA % numberB;};
    };
    
    

    这里直接新添加一个子类就ok了,不要修改代码,就完成功能了,完美符合开放-关闭原则。

先说者两个吧,应该还有其他的原则,但是我不行了,我找不出来了,有知道的小朋友评论区@我一下嗷。

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值