设计模式 -- 策略模式

131 阅读2分钟

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

含义: 对一系列算法进行封装, 并且使它们可相互替换;能够使得算法的变化独立出来。

接下来我们就拿最近比较火热的游戏永劫无间来举例子吧,每个人物都有名字,每个角色都有一个 F 技能和一个 V 技能。

本来我们实现这些人物的类,可以这样写

1.角色的超类

 public abstract class GameRoles{
     private String name;
     private abstract void SkillsF();
     private abstract void SkillsV();
 }

2.人物具体介绍

 public class NingHongye extends GameRoles{
     public NingHongye(String name){
         this.name = name;
     }
     
     @Override
     private void SkillsF(){
         System.out.println("昆仑决");
     }
     
     @Override
     private void SkillsV(){
         System.out.println("赤练无明");
     }
 }
 ​
 public class TeMuer extends GameRoles{
     public TeMuer(String name){
         this.name = name;
     }
     
     @Override
     private void SkillsF(){
         System.out.println("风之精灵");
     }
     
     @Override
     private void SkillsV(){
         System.out.println("风之牢笼");
     }
 }

像这样,如果人物多的话,就需要写大量重复的代码,这样当然也是可以的,但是确实很丑。我们可以针对接口编程,而不是及具体的实现。

1.每个技能的接口

 public interface ISkillsF{
     void SkillsF();
 }
 public interface ISkillsV{
     void SkillsV();
 }

2.具体的技能,这里就是具体的策略类

 public class KLJSkills implements ISkillsF{
     @Override
     public void SkillsF(){
         System.out.println("昆仑决");
     }
 }
 ​
 public class CLWMSkills implements ISkillsF{
     @Override
     public void SkillsV(){
         System.out.println("赤练无明");
     }
 }

3.修改人物的超类

 public abstract class GameRoles
 {
     protected String name;
  
     protected ISkillsF skillsf;
     protected ISkillsV skillsv;
  
     public GameRoles setISkillsF(ISkillsF skillsf)
     {
         this.skillsf = skillsf;
         return this;
     }
  
     public GameRoles setISkillsV(ISkillsV skillsv)
     {
         this.skillsv = skillsv;
         return this;
     }
  
     protected void SkillsF()
     {
         skillsf.SkillsF();
     }
  
     protected void SkillsV()
     {
         skillsv.ISkillsV();
     }
 }

4.只需定义角色的名字

 public class NingHongye extends GameRoles{
     public NingHongye(String name){
         this.name = name;
     }
 }

5.具体输出

 public class Test
 {
     public static void main(String[] args)
     {
         GameRoles ningHongye = new NingHongye("宁红夜");
  
         ningHongye.setISkillsF(new KLJSkills())
                 .setISkillsV(new CLWMSkills())
         System.out.println(ningHongye.name + ":");
         ningHongye.SkillsF();
         ningHongye.SkillsV();
     }
 }

优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。

缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。

使用场景: 1、如果在一个系统里面有许多仅仅是行为有区别的类,策略模式可以动态地让一个对象在定义的行为中自由的选择需要的行为。 2、动态选择几种算法中的一种。

注意事项: 如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

\