目录
1、策略模式的提出:
2、策略模式定义:
3、策略模式总结:
4、需求描述:
5、普通实现
6、使用策略模式实现
1、策略模式的提出:
在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,会使对象变得异常的复杂,而且有时候支持不使用的类型算法也是一个性能开销(if中多个条件,switch中多个case)。
如果将算法跟对象的本身进行解耦,就可以解决上面的系统复杂和性能问题。
2、策略模式定义:
定义一系列算法,将它们一个一个都封装起来,并且使它们可互相替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定结构)而变化(扩展--->子类化)。即:使用算法的客户程序流程不会随着算法需求的变化而变化,对于算法需求的变化可以在子类中进行适配。
3、策略模式总结:
(1)策略模式提供了条件判断语句if/switch的另一种实现方法,可以实现多个算法之间的解耦。注意:如果if、switch的条件类型是固定的,不会再扩展的话(eg:if的判断只有5种情况,不会再出现其他情况),则不使用策略类型。
(2)如果策略对象没有实例变量,那么上下文可以共享一个策略对象(单例模式),从而节省对象开销。
4、需求描述:
根据不同的水果类型和重量,输出对应水果的总价格。
5、普通实现
#include <iostream>
using namespace std;
enum class GoodsType
{
EM_BANANA=0,
EM_APPLE,
EM_ORANGE,
EM_GRAPE
};
/*
* 枚举类型优点:1、降低命名空间污染,访问方法:枚举类名::变量,eg:GoodsType::EM_BANANA
* 2、避免发生隐式转换,eg:int a = GoodsType::EM_APPLE;
* 3、可以前置声明,eg:enum class GoodsGType;
*/
class MyGoods
{
public:
double GetPrice(const GoodsType& type,const double& kg)
{
double price = 0.0;
if(GoodsType::EM_BANANA == type)
{
price = kg * 3.99;
}else if(GoodsType::EM_APPLE == type)
{
price = kg * 7.99;
}
else if(GoodsType::EM_ORANGE == type)
{
price = kg * 8.99;
}
else if(GoodsType::EM_GRAPE == type)
{
price = kg * 18.99;
}
return price;
};
};
int main()
{
MyGoods obj;
double kg = 18.00;
GoodsType type = GoodsType::EM_GRAPE;
std::cout << "price is " << obj.GetPrice(type,kg) << std::endl;
}
运行结果如下:
6、使用策略模式实现
#include <iostream>
using namespace std;
enum class GoodsType
{
EM_BANANA=0,
EM_APPLE,
EM_ORANGE,
EM_GRAPE
};
class AbsProduct
{
public:
virtual double GetPrice(double& kg)=0;
virtual ~AbsProduct(){};
};
class ProdutBanana:public AbsProduct
{
public:
virtual double GetPrice(double &kg) override
{
return kg * 3.99;
};
virtual ~ProdutBanana(){};
};
class ProdutApple:public AbsProduct
{
public:
virtual double GetPrice(double &kg) override
{
return kg * 7.99;
};
virtual ~ProdutApple(){};
};
class ProdutOrange:public AbsProduct
{
public:
virtual double GetPrice(double &kg) override
{
return kg * 8.99;
};
virtual ~ProdutOrange(){};
};
class ProdutGrape:public AbsProduct
{
public:
virtual double GetPrice(double &kg) override
{
return kg * 18.99;
};
virtual ~ProdutGrape(){};
};
class StrategyFactory
{
public:
virtual AbsProduct* CreateProduct()=0;
virtual ~StrategyFactory(){};
};
class FactoryBanana:public StrategyFactory
{
public:
virtual AbsProduct * CreateProduct() override
{
return new ProdutBanana();
}
};
class FactoryApple:public StrategyFactory
{
public:
virtual AbsProduct * CreateProduct() override
{
return new ProdutApple();
}
};
class FactoryOrange:public StrategyFactory
{
public:
virtual AbsProduct * CreateProduct() override
{
return new ProdutOrange();
}
};
class FactoryGrape:public StrategyFactory
{
public:
virtual AbsProduct * CreateProduct() override
{
return new ProdutGrape();
}
};
class MyGoods
{
private:
AbsProduct* product = nullptr;
public:
void SetProductType(StrategyFactory* pThis)
{
this->product = pThis->CreateProduct(); //产品类型对象的生成使用工厂方法模式实现
}
double GetPrice(double kg)
{
return product->GetPrice(kg); //多态实现算法匹配
}
virtual ~MyGoods()
{
if(product != nullptr)
{
delete product;
product = nullptr;
}
}
};
int main()
{
double kg = 18.00;
MyGoods obj;
StrategyFactory *proGrape = new FactoryGrape();
obj.SetProductType(proGrape);
std::cout << "price is " << obj.GetPrice(kg) << std::endl;
return 0;
}
运行结果如下:
代码描述:使用策略模式,将获取的产品价格跟产品类型进行了解耦,MyGoods获取价格的实现步骤不会随着产品类型的变化而变化。
当具有新的产品类型时,只需要扩展定义新的产品和产品工厂类就可以适配新需求变化,这种代码具有可复用性和可扩展性。