策略模式
策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
具体代码表示策略模式:
/// <summary>
/// 抽象策略
/// </summary>
interface IStrategy
{
/// <summary>
/// 策略方法
/// </summary>
void DoSomething\(\);
}
/// <summary>
/// 具体策略类A
/// </summary>
class StrategyA : IStrategy
{
public void DoSomething\(\)
{
Console.WriteLine("A do something");
}
}
/// <summary>
/// 具体策略类B
/// </summary>
class StrategyB : IStrategy
{
public void DoSomething\(\)
{
Console.WriteLine("B do something");
}
}
/// <summary>
/// 调用者
/// </summary>
class Client
{
private IStrategy strategy;
public Client(IStrategy s)
{
this.strategy = s;
}
public void SomeThing\(\)
{
strategy.DoSomething\(\);
}
}
1 |
|
static void Main(string[] args)
{
Client c1 = new Client(new StrategyA());
c1.SomeThing();//A do something
Client c2 = new Client(new StrategyB());
c2.SomeThing();//B do something
Console.ReadLine();
}
1 |
|
public class PostController : Controller
{
private PostServer server = new PostServer();
// GET: Post
public ActionResult Index()
{
var models = server.GetList();
return View(models);
}
}
public class PostServer
{
public IEnumerable<Article> GetList\(\)
{
throw new NotImplementedException\(\);
}
}
1 |
|
public class PostController : Controller
{
private IPostServer server;
public PostController\(\)
{
server = new PostServer\(\);
}
public PostController(IPostServer postServer)
{
this.server = postServer;
}
// GET: Post
public ActionResult Index\(\)
{
var models = server.GetList\(\);
return View(models);
}
}
public interface IPostServer
{
IEnumerable<Article> GetList\(\);
}
public class PostServer : IPostServer
{
public IEnumerable<Article> GetList\(\)
{
throw new NotImplementedException\(\);
}
}
上述代码中我们获取数据的策略在控制器中是不管的.也不强依赖于具体的类,只依赖了一个IPostServer
的接口,只要有实现了IPostServer
接口的类就可以使用该控制器.
这样我们在编写单元测试的时候就可以很方便的使用Mock工具来模拟实现IPostServer
接口而不用具体真实的去访问数据库或者网络从而真正的做到单元测试只测试单元.
重新回顾认识策略模式
策略模式的重心
策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
算法的平等性
策略模式一个很大的特点就是各个策略算法的平等性。对于一系列具体的策略算法,大家的地位是完全一样的,正因为这个平等性,才能实现算法之间可以相互替换。所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。
所以可以这样描述这一系列策略算法:策略算法是相同行为的不同实现。
运行时策略的唯一性
运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象,虽然可以动态地在不同的策略实现中切换,但是同时只能使用一个。
公有的行为
经常见到的是,所有的具体策略类都有一些公有的行为。这时候,就应当把这些公有的行为放到共同的抽象策略角色Strategy类里面。当然这时候抽象策略角色必须要用抽象类实现,而不能使用接口。
这其实也是典型的将代码向继承等级结构的上方集中的标准做法。