设计模式之策略模式
策略模式定义了算法类,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
策略模式是对算法的包装,是把使用的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。
策略模式涉及到三个角色:
环境(Context)角色:持有一个Strategy的引用,也称策略上下文。
抽象策略(Strategy)角色:这是一个抽象角色,通常使用抽象类或者接口来实现。此角色给出所有的具体策略类所需要的接口。
具体策略(ConcreteStrategy)角色:此角色包装了所有的算法和行为。
Eg:商场搞促销,促销方式有打折、满100减50等。
在本例中,抽象策略角色用一个结果实现,接口中有一个计算价格的方法。接口实现如下:
namespace Strategy_Pattern
{
/// <summary>
/// 策略接口
/// </summary>
interface IPromotion
{
/// <summary>
/// 根据原价和策略计算新价格
/// </summary>
/// <param name="originalPrice">原价</param>
/// <returns></returns>
double GetPrice(double originalPrice);
}
}
具体策略角色有两个,分别表示打折类和满100减50,都实现策略接口。
打折类实现如下:
using System;
namespace Strategy_Pattern
{
/// <summary>
/// 打折策略类
/// </summary>
class Discount : IPromotion
{
#region Public Methods
public double GetPrice(double originalPrice)
{
Console.WriteLine("打八折");
return originalPrice * 0.8;
}
#endregion
}
}
满100减50类实现如下:
/// <summary>
/// 返现策略类:满100返50
/// </summary>
class MoneyBack : IPromotion
{
#region Public Methods
public double GetPrice(double originalPrice)
{
Console.WriteLine("满100返50");
return originalPrice - (int)originalPrice / 100 - 50;
}
#endregion
}
环境(Context)角色类如下:
/// <summary>
/// 策略上下文类
/// </summary>
class PromotionContext
{
#region Fields
private IPromotion m_promotion = null;
#endregion
#region Constructors
public PromotionContext(IPromotion iPromotion)
{
this.m_promotion = iPromotion;
}
#endregion
#region Public Methods
/// <summary>
/// 默认策略方法
/// </summary>
/// <param name="originalPrice"></param>
/// <returns></returns>
public double GetPrice(double originalPrice)
{
if (this.m_promotion == null)
{
this.m_promotion = new Discount();
}
return this.m_promotion.GetPrice(originalPrice);
}
/// <summary>
/// 更改策略的方法
/// </summary>
/// <param name="iPromotion"></param>
public void ChangePromotion(IPromotion iPromotion)
{
this.m_promotion = iPromotion;
}
#endregion
}
然后再主类中调用相应的策略,主类实现如下:
class Program
{
static void Main(string[] args)
{
//默认策略:打八折的策略
PromotionContext promotionContext=new PromotionContext(null);
Console.WriteLine(promotionContext.GetPrice(300));
//更改策略:满100减50的策略
promotionContext.ChangePromotion(new MoneyBack());
Console.WriteLine(promotionContext.GetPrice(100));
Console.ReadLine();
}
}