简单工厂模式----收银台程序

使用简单工厂模式实现的收银台程序

需求:写一个收银台程序,可以实现,输入商品单价后可以按一定的规则计算出失守金额,例如该商品搞活动,打七折出售,或者店家高活动全场满五百减一百等等活动时,需要计算出实际价格。
以前的我肯定会觉得很简单,分情况讨论一下即可,例如写一个 switch 语句即可,但是在学习完简单工厂模式后觉得,这样的做法太不合理。如商家活动策咯增多时,你需要不断的重复写很多代码,所以利用工厂模式来重构了代码,写完以后,受益颇多。

工厂模式

现实中工厂是用来生产物件的,那这里的工厂肯定是生产一些对象的,那么这些对象是什么呢?

  • 首先,我们思考一下,对于商品的促销活动,无非就那么集中,一般分为打折和满减两大类。
  • 在打折中,会有打六折、打八折等情况;在满减时,会有满三百减五十、满四百减一百等等。我们可以发现这里只需要两个类,就可以完成所有的打折和满减活动策咯。
    • 打折类:根据输出参数的不同,返回相应的折扣后价格
    • 满减类:根据不同的满减规则,返回相应的金额。
  • 这样,我们就有了俩个类,类是抽象的,只有对象才是实际存在,工厂适用于生产对象的,那么在这里它所生产的对象一目了然,就是这两个类根据不同的促销规则,输入相应的参数所创建的不同的对象,例如有:打八折的一个对象、满三百减一百的对象等等,此时我们的工厂类只需要负责创建这些对象即可。如现在只有打八折的一个对象、满三百减一百的对象,但是我现在需要打九折的对象,只需要在使用工厂类创建一个打九折的对象即可完成,不需要去重复写过多的代码,看到这,你是不是也豁然开朗,觉得工厂模式确实是个不错的方式。

所以简单工厂模式实现的基本思路是:
1. 编写俩个或者更多关于促销的类,这些类都继承于一个基类,即收款金额的类
2. 编写一个创建收款方式对象的类,即收费方式对象生产的工厂

具体代码实现如下:

//简单工厂模式
//收银台程序
//现金收费基类
class CashSuper
{
public:
    virtual double acceptCash(double money)= 0;     //定义为纯虚函数,用来定义一个统一的接口,使其称为抽象类
};

double CashSuper:: acceptCash(double money)
{
    return money;
}


//正常收费子类
class CashNormal :public CashSuper
{
public:
    double acceptCash(double money)
    {
        return money;
    }
};

//打折收费子类
class CashRebate : public CashSuper
{
public:
    CashRebate(double moneyRebate) :m_moneyRebate(moneyRebate){}
    double acceptCash(double money){ return money*m_moneyRebate; }
private:
    double m_moneyRebate;
};

//返利收费子类
class CashReturn :public CashSuper
{
public:
    CashReturn(int momeyCondtion, int moneyReturn):m_moneyCondition(momeyCondtion), m_moneyReturn(moneyReturn){}
    double acceptCash(double money)
    {
        double result = money;
        if (money >= m_moneyCondition)
            result = money - (money / m_moneyCondition * m_moneyReturn);

        return result;
    }
private:
    double m_moneyCondition;
    double m_moneyReturn;
};

//现金收费工厂类
//用于创建不同的对象,如:正常收费类的对象、折扣收费类的对象及满减收费类的对象。
class CashFactory
{
public:
    static CashSuper* createCashAccept(size_t type);
    //这里使用 static 修饰,可以通过类的对象以及作用域来调用此函数
};

CashSuper* CashFactory:: createCashAccept(size_t type)
{
    CashSuper* cs = nullptr;  //这里需要使用指针
    switch (type)
    {
        //正常收费
        case 0:
            cs =  new CashNormal();  
            //这里需要动态申请对象的空间,因为在函数调用完以后,此对象要一直存在至程序结束,或不在需要该类收费对象。
            break;
        //打八折
        case 1:
            cs = new CashRebate(0.8);
            break;
        //满三百减一百
        case 2:
            cs = new CashReturn(300, 100);
            break;
        default:
            break;
        //在需要其他收费规则时,只需要在这里添加创建对象的方法,若过需要创建的对象是上面写的三个类之外的对象,可以先写一个新方法的类,然后在这里创建新的对象
    }
    return cs;  //将动态创建的收费对象的地址返回
}

测试程序:

int main()
{
    //分别对于1000 元的商品,根据工厂创建的对象的不同,可以输出相应的优惠后的金额
    cout << "打八折:" ;
    CashSuper *Cashsuper = CashFactory::createCashAccept(1);
    cout << Cashsuper->acceptCash(1000) << endl;

    cout << "满三百减一百:";
    CashSuper *Cashsuper1 = CashFactory::createCashAccept(2);
    cout << Cashsuper1->acceptCash(1000) << endl;
    system("pause");
}

运行结果:
简单工厂模式----收银台程序_第1张图片
注,测试程序只是为了展示她可以实现多态,以及工厂模式的功能和特点,并没有像实际开发那样写业务逻辑。

当然这个模式只是解决了对象的创建问题,但是商场可以经常改变七促销释放,每一次更改打折和返利的规则,都需要改动一下工厂,以致代码需要重新编译,所以这个模式也会有一些缺点。

你可能感兴趣的:(设计模式)