剑弑 发表于 2021-3-4 17:15:37

策略模式(StrategyPattern)

本帖最后由 剑弑 于 2021-3-5 14:52 编辑

   王者荣耀对于玩游戏的朋友都不会陌生,都知道每一个英雄跟会用到铭文及装备(局内出装);使用正确的铭文和出装将多大大的提高我们游戏内的获胜机率,所以我们在每一局开局前都会有自己的铭文和出装选择(系统推荐或自己设定)。   看到这里可能会有人觉得,我是在写游戏攻略(技术菜可不敢写{:3_55:}),毕竟策略模式(StrategyPattern)跟王者荣耀两者都没关系的;尽只会在这里水字。
   大家先不要急,因为我接下来讲的示例是以王者荣耀的铭文跟出装为示例去讲解释策略模式(StrategyPattern);接下来让我们直接进入正题吧。
   在我们开局选择英雄后系统都会帮我们默认选择一套铭文、一套出装及多套铭文、多套出装可供我们选择(当然里面有包含我们自己设定的),我们该怎么选取呢?大家是不是第一时间想到的if......else if ...... else.....去一个个判断,最后写成一大堆的if语句,而且只要更改其中的一套铭文或出装就又要改以前的代码{:3_57:}维护起来简直是恶梦,还有哪一天多加了一套铭文或出装也要改以前的代码。是不是很想摆脱这样的恶梦,解放自己的大脑,让世界多一片宁静(每天处理这样的恶梦会让人脾气暴燥)。策略模式可以帮到你,让你解放自己的大脑,在也不用处理这样的恶梦代码。
   好了废话不多说了,上代码前我们先来看看策略模式的类图

我们从类图中看到存在LiuChan类继承Hero类,Hero类中存在Inscription、OutfitAttribute两个接口,其他几个类都是这两个类的实现类。
Hero类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StrategyPattern
{
    abstract class Hero
    {
      private Inscription _inscription;
      /// <summary>
      /// 铭文
      /// </summary>
      public Inscription Inscription { get; set; }

      private OutfitAttribute _outfitAttribute;
      /// <summary>
      /// 出装特性
      /// </summary>
      public OutfitAttribute OutfitAttribute { get; set; }

      public abstract void DisPlay();

      /// <summary>
      /// 普攻
      /// </summary>
      public abstract void GeneralAttack();

      /// <summary>
      /// 技能一
      /// </summary>
      public abstract void SkillsOne();

      /// <summary>
      /// 技能二
      /// </summary>
      public abstract void SkillsTwo();

      /// <summary>
      /// 技能三
      /// </summary>
      public abstract void SkillsThree();

      /// <summary>
      /// 被动技能
      /// </summary>
      public abstract void SkillsPassivity();
    }
}

Inscription接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StrategyPattern
{
    interface Inscription
    {
      /// <summary>
      /// 铭文类型
      /// </summary>
      void InscriptionType();
    }
}

OutfitAttribute接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StrategyPattern
{
    /// <summary>
    /// 出装
    /// </summary>
    interface OutfitAttribute
    {
      void Property();
    }
}

LiuChan类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StrategyPattern
{
    class LiuChan : Hero
    {

      public LiuChan()
      {
            Inscription = new LiuChanInscription();
            OutfitAttribute = new HighDefense();
      }

      public override void DisPlay()
      {
            Console.WriteLine("我是刘禅");
            Console.WriteLine("使用铭文");
            Inscription.InscriptionType();
            Console.WriteLine("使用出装");
            OutfitAttribute.Property();
      }

      public override void GeneralAttack()
      {
            Console.WriteLine("近身释放普攻");
      }

      public override void SkillsOne()
      {
            Console.WriteLine("释放技能一");
      }

      public override void SkillsPassivity()
      {
            Console.WriteLine("触发被动技能");
      }

      public override void SkillsThree()
      {
            Console.WriteLine("释放技能三");
      }

      public override void SkillsTwo()
      {
            Console.WriteLine("释放技能二");
      }
    }
}

LiuChanInscription类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StrategyPattern
{
    /// <summary>
    /// 刘禅铭文
    /// </summary>
    class LiuChanInscriptionTwo : Inscription
    {
      public void InscriptionType()
      {
            AttackInscription();
            AttackInscription1();
            AttackInscription2();
      }

      private void AttackInscription()
      {
            Console.WriteLine("狩猎2");
      }

      private void AttackInscription1()
      {
            Console.WriteLine("虚空2");
      }

      private void AttackInscription2()
      {
            Console.WriteLine("宿命2");
      }
    }
}

LiuChanInscriptionTwo类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StrategyPattern
{
    /// <summary>
    /// 刘禅铭文
    /// </summary>
    class LiuChanInscription : Inscription
    {
      public void InscriptionType()
      {
            AttackInscription();
            AttackInscription1();
            AttackInscription2();
      }

      private void AttackInscription()
      {
            Console.WriteLine("狩猎");
      }

      private void AttackInscription1()
      {
            Console.WriteLine("虚空");
      }

      private void AttackInscription2()
      {
            Console.WriteLine("宿命");
      }
    }
}

HighDefense类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StrategyPattern
{
    class HighDefense : OutfitAttribute
    {
      public void Property()
      {
            Console.WriteLine("游走 血厚防高");
            EquipmentOne();
            EquipmentTwo();
            EquipmentThree();
            EquipmentFour();
            EquipmentFive();
            EquipmentSix();
      }

      private void EquipmentOne()
      {
            Console.WriteLine("极影");
      }

      private void EquipmentTwo()
      {
            Console.WriteLine("抵抗之鞋");
      }

      private void EquipmentThree()
      {
            Console.WriteLine("极寒风暴");
      }

      private void EquipmentFour()
      {
            Console.WriteLine("魔女斗蓬");
      }

      private void EquipmentFive()
      {
            Console.WriteLine("反伤刺甲");
      }

      private void EquipmentSix()
      {
            Console.WriteLine("不祥征兆");
      }
    }
}

代码测试
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StrategyPattern
{
    class Program
    {
      static void Main(string[] args)
      {
            Hero hero = new LiuChan();
            hero.DisPlay();
            Console.WriteLine("=======================华丽分割线================================");
            hero.Inscription = new LiuChanInscriptionTwo();
            hero.DisPlay();
            Console.ReadLine();
      }
    }
}

运行结果

策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算变化独立于使用算法的客户。
优点:
算法可以自由替换;
避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护);
扩展性良好,增加一个策略只需实现接口即可;
缺点:
策略类数量会增多,每个策略都是一个类,复用的可能性很小;
所有的策略类都需要对外暴露;

ibcadmin 发表于 2021-3-7 17:25:32

棒棒棒

剑弑 发表于 2021-3-9 14:29:12

ibcadmin 发表于 2021-3-7 17:25
棒棒棒

无业游民无聊写出来的{:2_27:}

ibcadmin 发表于 2021-3-9 20:26:27

剑弑 发表于 2021-3-9 14:29
无业游民无聊写出来的

还没去找工作吗

剑弑 发表于 2021-3-10 09:33:26

ibcadmin 发表于 2021-3-9 20:26
还没去找工作吗

在找,还没找到
页: [1]
查看完整版本: 策略模式(StrategyPattern)