今天咱们来看策略模式【Stragety Pattern【行为型】】,这个模式仍是比较好理解的。策略怎么理解呢?通常是指:1. 能够实现目标的方案集合;2. 根据形势发展而制定的行动方针和斗争方法;3. 有斗争艺术,能注意方式方法。总的来讲呢就是针对一个目的的不一样的方法集合。这里要讲的策略模式怎么理解呢?简单的说就是对于一个类的行为或者其算法能够在运行时更改替换。算法
在软件系统中,一些对象使用的算法或者行为可能会常常变化,若是把这些变化的算法写到对象中的话,会使对象变得较为复杂、不易理解。那么咱们如何在运行时动态的修改对象的不一样的算法呢?这就使用到了策略模式。bash
定义一系列的算法,把它们一个个封装起来, 而且使它们可相互替换。优化
看上面的案例图好像和上一篇状态模式的案例图有点类似。都是包含的三个部分。具体区别咱们看后面的详细介绍。加密
环境角色:包含持有一个Strategy抽象策略的引用。spa
抽象策略:定义一个公共方法,由其具体策略去实现不一样算法。code
具体策略:实现抽象策略接口方法。cdn
这里咱们看这么一个案例,在一个超市买东西。最后结算的时候都会问是否有会员,结算机制就有如下几种。普通用户全额计算。普通会员打95折。黄金会员打9折。钻石会员打8折。咱们看下如何实现这一功能:对象
namespace Stragety_Pattern
{
class StragetyPattern
{
}
#region 抽象策略==================
/// <summary>
/// 抽象策略接口
/// </summary>
public interface IStragetyPattern
{
/// <summary>
/// 结算接口
/// </summary>
void Settlement(decimal Money);
}
#endregion
#region 具体策略=======================
/// <summary>
/// 无会员计算方式
/// </summary>
public class OrdinaryStragety : IStragetyPattern
{
public void Settlement(decimal Money)
{
Console.WriteLine($"不是会员,不进行折扣结算。应付款{Money}");
}
}
/// <summary>
/// 普通会员计算方式
/// </summary>
public class MemberStragety : IStragetyPattern
{
public void Settlement(decimal Money)
{
Console.WriteLine($"普通会员,打95折结算。应付款{Money*0.9M}");
}
}
/// <summary>
/// 黄金会员计算方式
/// </summary>
public class GoldMemberStragety : IStragetyPattern
{
public void Settlement(decimal Money)
{
Console.WriteLine($"黄金会员,打9折结算。应付款{Money*0.95M}");
}
}
/// <summary>
/// 钻石会员计算方式
/// </summary>
public class DiamondGoldMemberStragety : IStragetyPattern
{
public void Settlement(decimal Money)
{
Console.WriteLine($"钻石会员,打8折结算。应付款{Money*0.8M}");
}
}
#endregion
#region 环境角色
public class ContextStragety
{
private IStragetyPattern _stragety;
public ContextStragety(IStragetyPattern stragety)
{
_stragety = stragety;
}
/// <summary>
/// 调用结算方法
/// </summary>
/// <param name="Money"></param>
public void GetSettlement(decimal Money)
{
_stragety.Settlement( Money);
}
}
#endregion
}复制代码
namespace Stragety_Pattern
{
class Program
{
static void Main(string[] args)
{
decimal Account = 190.99M;
///会员计算
ContextStragety stragety = new ContextStragety(new MemberStragety());
stragety.GetSettlement(Account);
///普通结算
stragety = new ContextStragety(new OrdinaryStragety());
stragety.GetSettlement(Account);
}
}
}复制代码
这里咱们针对最后结算的金额进行计算的时候是能够相互替换的。由于在具体策略中,都把算法的变化封装了起来。blog
一、若是在系统中有一些类,他们之间的区别就在于其行为的话。可使用策略模式让一个对象在许多的行为中动态的选择一种行为。接口
二、一个系统中须要在多种算法中选择一种。
三、若是一个对象有许多的行为的话,能够简化其多重条件选择语句。避免难于维护的问题。
一、策略类之间能够自由切换,由于策略类中都是实现的抽象策略的一个方法。因此能够自由切换。
二、易于扩展,在咱们新增策略的时候基本上不须要修改以前的代码。
三、对多重条件选择语句进行优化简化
一、随着策略增多,策略类会随之增长。
二、客户端必须知道全部的策略类,而且自行决定使用哪种策略。
到这里策略模式就介绍完了。策略模式主要是针对的有一系列算法。并把他们都封装起来。他们之间能够自由切换。使这些算法的变化独立于客户端的变化。也就是把多种行为之间的变化分别进行封装起来。而后在咱们调用的时候能够自由的进行切换调用。
这里咱们在开篇有提到策略模式的案例图和状态模式的有点类似。这里咱们重点分析一些策略模式和状态模式之间的区别吧:
一、环境角色中的任务有所不一样,策略模式的环境角色中具备一种委托做用,负责根据传进来的策略调用其算法。可是状态模式中的环境角色不只负责这行为方法的调用,还负责有记录状态变化、与具体的状态类协做。完成状态切换以后行为的切换。
二、策略模式主要解决的问题是将内部的算法的改变对外部的影响下降。保证算法的自由切换。状态模式主要解决的是状态的改变引发行为的变化、一个对象状态改变,从外界看来就好像是行为改变。
三、策略模式是一个算法的封装。这里封装的一个算法能够是有意义的对象,也能够是没有意义的逻辑片断。例如这里封装加密算法。各类加密算法,能够自由切换。算法必须是平行的。状态模式是要求一些列的状态变化随着有着行为的变化。要求拥有状态和行为。
即便受伤了,也要抬起头微笑着说,今每天气真好。