天天看点

大话设计模式:策略模式

一、什么是策略模式

对算法的封装
           

定义了算法家族,分别封装起来,让他们之间可以互相替换,让算法的变化,不会影响到使用算法的客户.

简单点说就是我把一系列的具有同类型需求的算法按策略装进策略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:不知道这种场景是不是适用的,感觉只是为了符合设计模式而硬编的代码,刚开始的抽象类还不是这样写的,是一个武器抽象类,有一个攻击方法 ,子类实现是 苦无 和 手里剑,这种就是一个真实的对象,我感觉不太适用,万一苦无里面又有其它的攻击方式等等, 于是就改成 手里剑的抽象, 有不同的攻击方式实现,把攻击方式的算法封装。我们真实的开发过程中,大多数时候其实是先写了功能,后来发现这样写有坏味道,于是想到适用的设计模式,然后进行重构。

我们说具有相同属性和功能的独享的抽象集合才是类。