编程语言
首页 > 编程语言> > 雍禾植发帝之java设计模式学习(一)策略模式

雍禾植发帝之java设计模式学习(一)策略模式

作者:互联网

雍禾植发帝之java设计模式学习(一)策略模式

策略模式

1. 策略模式的基本内容

2. 策略模式的“由来”

2.1“继承”局限性

场景一:
当小明设计一款冒险游戏时,有三个不同的角色(King、Queen、Knight),每个角色有一个display()会告诉玩家他们是什么角色,小明理所当然的想到Java基础中的继承来实现:
1

场景二:
第二天,游戏策划告诉小明,角色应该可以战斗,小明想这还不简单,只需要在Character抽象类中添加一个fight(),然后在每一个角色实现类中实现这个方法,那不就行了吗,说干就干,小明已经想到自己完成之后下班要去吃什么了:(注意:图中fight()在不同的角色实现中,可能是用不同的武器去战斗,在这里就不画出来了)
2

场景三:
然而too young too simple,就在小明提交了自己的想法没多久,策划就打来了电话:小明,Queen王后是不会战斗的,怎么你的王后跟着国王下战场了?!
小明:啊,还有这种情况,不过难不倒我,这很简单,只要在Queen的实现类中,让fight()什么都不做,这样王后就不会去战斗了:
3

场景四:
到了这个时候,小明突然想到,如果过两天策划突然决定添加一个生育系统giveBirth(),到时候若是在抽象类Character类添加该功能,那岂不是所有的角色(包括KingKnight)都会生小孩了,到时候要避免这种情况,岂不是又要在KingKnight的实现类中,覆盖掉giveBirth(),让它们什么都不做(类似于场景三),想到那样的工作量,小明就隐隐一阵头疼

使用继承来提供Character的行为,会导致以下的缺点

那要是接口的话呢?:

场景五:
小明将fight()提取成一个FightBehavior接口,当以后新增加的角色会战斗时,则实现该接口,若不会战斗时,就不实现该接口,如下图中的王后,这样总算可以解决刚刚的问题了吧。
4

 

其实这样又出现了新的问题:虽然解决了一部分的问题,却造成代码无法“复用”的问题(当不同的角色使用相同的方式战斗时,fight()需要在不同的实现类中实现多次。而且当这个方法发生改变时,修改起来的代码量是很多),有没有什么办法,既可以提高代码“复用”率,并且当需求改变时,可以用最小的代码量修改就达成目标呢?

2.2 “策略模式”登场

将经常需要改变的行为方法从类中抽离出来,另外形成一组类(暂时将其称为’锦囊’),当原本的类需要某个行为方法时,则从锦囊中取出对应的行为方法给它,当需要更换行为方法时,则只需要从锦囊中取出另外一个行为方法替换就可以达到目的(这样既达到复用的目的,也不让原本的类被实现绑死)

这句话的意思有点抽象,让我们代入到小明的开发场景中去:
既然fight()战斗这个行为方法常常需要改变,干脆把它从具体的类实现中抽离出来,将各种武器(Knife、Sword、Arrow,同时也有’空武器’)放入一个战斗锦囊,然后给每一个角色发放一个战斗锦囊,当角色需要某一个武器时,则从锦囊中取出相应的武器就好了
6

5

2.3 “策略模式”中的设计原则

  1. 而在“策略模式”中,我们强调将经常发生改变的行为方法从类中抽离出来,这一步就是体现了设计原则中的"封装变化"
  2. 在具体的角色类中,角色只需要知道调用行为方法的接口,而不需要管该方法的具体实现,而这体现的就是设计原则中的"接口编程"
  3. 将原本的类和封装变化而产生的类二者相结合起来使用,这就是“组合”,体现了设计原则中的"多用组合,少用继承

策略模式的介绍就到这里!

####此处粘上来代码(其中角色类和武器类分别只贴上来一个)

//Character类(抽象类)
public abstract class Character {
	
    WeaponBehavior wb; 

    public abstract void display();

    public void fight() {
        wb.userWeapon();
    }
}

//King类(继承自Character类)
public class King extends Character {
    public King() {
        wb = new SwordBehavior();   //在此处修改角色对应的战斗方式:此处让他从武器锦囊中取出 “剑”
    }

    @Override
    public void display() {
        System.out.println("我是国王");	
    }
	
}

//武器锦囊接口
public interface WeaponBehavior {
    public void userWeapon();
}

//武器:剑(实现了接口 'WeaponBehavior')
public class SwordBehavior implements WeaponBehavior{

    @Override
    public void userWeapon() {
        System.out.println("使用 剑 攻击!");
    }
}
	
//测试类
public class CharacterGame {
    public static void main(String args[]) {
        Character king = new King();
        king.display();
        king.fight();
    }
}

一个练习用的例子:人、鸡和鸭、马(吃饭和睡觉的方法都不一样,应用’策略模式’应该如何设计)

标签:小明,雍禾,java,角色,Character,fight,锦囊,设计模式,public
来源: https://www.cnblogs.com/yonghe/p/14517206.html