大话设计模式:策略模式

一、什么是策略模式
对算法的封装

定义了算法家族,分别封装起来,让他们之间可以互相替换,让算法的变化,不会影响到使用算法的客户.
简单点说就是我把一系列的具有同类型需求的算法按策略装进策略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:不知道这种场景是不是适用的,感觉只是为了符合设计模式而硬编的代码,刚开始的抽象类还不是这样写的,是一个武器抽象类,有一个攻击方法 ,子类实现是 苦无 和 手里剑,这种就是一个真实的对象,我感觉不太适用,万一苦无里面又有其它的攻击方式等等, 于是就改成 手里剑的抽象, 有不同的攻击方式实现,把攻击方式的算法封装。我们真实的开发过程中,大多数时候其实是先写了功能,后来发现这样写有坏味道,于是想到适用的设计模式,然后进行重构。
我们说具有相同属性和功能的独享的抽象集合才是类。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值