一、什么是策略模式
对算法的封装
定义了算法家族,分别封装起来,让他们之间可以互相替换,让算法的变化,不会影响到使用算法的客户.
简单点说就是我把一系列的具有同类型需求的算法按策略装进策略strategy里面,外界调用strategy时就知道我要用哪一种算了.
UML图
二、适用场景
当遇到在不同时间需要针对不同策略进行不同算法时,所得结果又都是同一类型时,就该想到用策略模式.
需注意一系列算法虽然实现不同,但本质是一样的,都是完成的相同工作,策略模式就能用相同的方式调用不同的算法.
三、优缺点
优点
算法的封装。客户端不接触算法类算法方法。
把算法封装成类,算法就可随意运用替换。且不影响其它算法。
满足“开-闭原则”。当增加新的具体策略时,不需要修改上下文类的代码,上下文就可以引用新的具体策略的实例。
缺点
所有的策略类都需要对外暴露。
封装具有针对性,如果外界需要整个对象,使用对象的不同属性不同方法,策略模式就不适用了。
策略类数量会增多,每个策略都是一个类,复用的可能性很小
四、大话中的例子
超市收银的需求,按正常价格,打八折, 满300反50,等不同的金额算法,运用了策略模式,将这些算法封装成类 ,大家都是一个目标,计算金额,只是计算的方式不一样,那就都继承了一个计算金额方法的父类,子类分别自己实现.在策略类中按需创建对应的算法类,策略类自己写一个计算方法,将算法类的计算金额的方法放进来,这样外界就只需要和策略类交互即可.
结合简单工厂模式策略类数量会增多,每个策略都是一个类,复用的可能性很小。
五、我的例子
把策略模式和简单工厂模式结合了。客户端避免了做判断的逻辑。
using System;
namespace StrategieMode
{
class Program
{
static void Main(string[] args)
{
int mylevel = 6;
ContextWeapon ctwep = new ContextWeapon(ShurikenAttackEnum.ShurikenCommonAttack);
Console.WriteLine(ctwep.WeaponAttack(mylevel));
ctwep = new ContextWeapon(ShurikenAttackEnum.ShurikenThumAttack);
Console.WriteLine(ctwep.WeaponAttack(mylevel));
Console.ReadKey();
}
}
public interface Shuriken//定义 武器抽象类
{
int Attack(int level);
}
public class ShurikenCommonAttack : Shuriken
{
public int Attack(int level)
{
return 10 + level;
}
}
public class ShurikenThumAttack : Shuriken
{
public int Attack(int level)
{
return level * 5;
}
}
public class ContextWeapon
{
Shuriken shuriken;
public ContextWeapon(ShurikenAttackEnum @enum)
{
switch (@enum)
{
case ShurikenAttackEnum.ShurikenCommonAttack:
shuriken = new ShurikenCommonAttack();
break;
case ShurikenAttackEnum.ShurikenThumAttack:
shuriken = new ShurikenThumAttack();
break;
default:
break;
}
}
public int WeaponAttack(int level)
{
return shuriken.Attack(level);
}
}
public enum ShurikenAttackEnum
{
ShurikenCommonAttack,//普通攻击
ShurikenThumAttack,//重击
}
}
运行结果
PS:不知道这种场景是不是适用的,感觉只是为了符合设计模式而硬编的代码,刚开始的抽象类还不是这样写的,是一个武器抽象类,有一个攻击方法 ,子类实现是 苦无 和 手里剑,这种就是一个真实的对象,我感觉不太适用,万一苦无里面又有其它的攻击方式等等, 于是就改成 手里剑的抽象, 有不同的攻击方式实现,把攻击方式的算法封装。我们真实的开发过程中,大多数时候其实是先写了功能,后来发现这样写有坏味道,于是想到适用的设计模式,然后进行重构。
我们说具有相同属性和功能的独享的抽象集合才是类。