设计模式之策略模式

定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

这段时间准备学习一下设计模式,从这篇文章开始我会将我对每个设计模式的理解和自己设计的需求实现写出来,一来是为了更好的总结,二来也是为了方便大家。

定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

我重新理解一下这句话,就是讲行为抽象,创建行为的多重实现,在具体对象中包含抽象行为的引用,并在对象创建时赋予默认的行为实现,或添加更改具体行为实现的方法。简单点说就是将变化的提取出来,利用接口进行约定。下面举个简单的例子

需求

在游戏中有角色和装备两种事物。
角色:默认的攻击力(10),防御值(100)。有更换装备、伤害计算、防御计算方法
装备:
1.防御性:盾牌(+100防御)、铁布衫(+200防御)
2.攻击性:刀(+20攻击)、枪(+50攻击)
规则:一个角色可以同时持有两种装备,一件防御性一件攻击性。
玩法:创建一个角色,默认无装备,计算伤害和防御值,添加装备 重新计算伤害和防御值

分析

我们用面向对象设计原则来看这个问题,角色和装备两种事物下面会分别派生出很多同种其他事物,比如角色可以派生出士兵、战士、将军等,装备可以派生出攻击性和防御性两种装备,而这两种又分别派生出刀、抢、盾牌和铁布衫等。

首先我们可以想到创建角色和装备类,角色类中有装备类对象的引用,角色类中添加更换装备、伤害计算和防御计算方法,最后分别创建角色和装备的子类。从我们的分析可以看到,我们的代码用到大量的继承。设计模式原则中提出“有一个”比”是一个“更适用,即使用组合更优于继承。继承的弊端有不利于扩展,高度依赖差等等,就不一一列举了。我们基于面向对象设计原则到此就已经出现瓶颈了,那么该如何处理呢?

突然想到设计模式另一个原则

面向接口编程,而不是面向实现编程。

不错,我们不依赖于具体实现,而是通过接口定义我们的“游戏规则”,这就变得好玩了。我们约定好接口,只要是该接口的实现,我管你本质上是谁都无关紧要。在现实中最经典的例子就是电脑,电脑中有无数的接口,usb接口,hdmi接口,显卡接口,电源接口等,这么多接口的意义何在?其实就是为了解决不兼容的问题,也就是说我不管你是AMD还是蓝宝石,只要我定义好了显卡接口,各个针脚干啥的干啥的,你们各个显卡厂商回去按照这个标准做,拿回来的东西就能在我机器上用。这就是我面向接口而不面向具体实现。

回过头来,再看这个问题。系统中两大派系,角色和装备,任何一个角色身上都可以带两种装备,一个攻击性一个防御性,也就是说只要是装备,并且是攻击性和防御性的一种,甭管是石头还是锤子 给我我就能带,并且还能给你玩出花来。剩下就是具体的角色和武器了。

具体实现我扔到git,地址在本文最下方。

总结

从策略模式的学习中,我对设计模式的“分离变化”、“多用组合少用继承”和“针对接口编程而不针对实现编程”原则有了更深的认识。在策略模式中,主要是封装算法,利用接口组合算法族,使得算法族的更换更灵活,降低代码耦合度,使代码编写上更松弛。策略模式可能日后会更多的应用于自己工具类的编写当中。