策略模式

策略模式

策略是指根据不同的情况,选择不同的策略。要求策略根据情况的不同进行动态的改变(有点诸葛亮的锦囊妙计一样的感觉)。

以OO(面向对象)的思维来看,我们可以把不同的情况视为不同的子类,不同的策略看做类的不同行为或算法。其实策略模式就是实现的这一思想,在接下来的类设计中就可以清楚的看到。

1 概念

策略模式可以使得一个类的行为或其算法可以在运行时更改。

2 动机

在有多种算法相似的情况下,使用if…else所带来的复杂和难以维护。

3 结构

根据文章开始对策略的描述“策略是指根据不同的情况,选择不同的策略”,就可以发现有两大实体,一个是情况,二是策略。所以可以大体认为结构是由**“情况”**与“**策略”**这两个部分构成。

4 参与者

我们通常将“策略”写成一个接口,具体的策略(即算法)便是接口的实现。(面向接口编程)

在《设计模式:可服用面向对象软件的基础》一书中,“情况”对应的便是Context(上下文)。而Context持有对接口的引用便可动态的选择策略的多个实现。

所以我们可以得到三个参与者。

  • Strategy(策略)
    • 定义所有支持的算法的公共接口。Context使用这个接口来调用某一个ConcreteStrategy定义的算法。
  • ConcreteStrategy(具体策略)
    • 以Strategy接口实现具体算法。
  • Context(上下文)
    • 持有对Strategy引用。

5 实例

游戏里的角色(国王、女王、骑士)可以选择不同的武器(剑、匕首、弓箭)进行战斗。

使用策略模式来表达,UML图则如下:

在这里插入图片描述

使用武器攻击,对于角色来说是一个共同的行为,但又需要具备灵活性。所以不能写死在每个角色具体的实现类中,需要将其抽取出来作为接口(WeaponBehavior),并将算法封装到不同的接口实现类的方法中去。

创建一个Character(角色)类作为三种角色的基类,在基类中对策略接口进行引用。

可在子类的构造方法中初始化weapon对象引用的具体子类,或通过set方法(即setWeapon()方法)进行改变。

6 代码

对应以上UML图的设计,贴部分关键代码:Character类、一个Character子类、策略接口、一个策略接口实现类、main函数

【Character类】

public abstract class Character {
    //引用接口
    //因为要被子类继承,所以使用protected
	protected WeaponBehavior weapon;	

	public void fight() {
        //调用接口方法
		weapon.userWeapon();
	}
	
	public void setWeapon(WeaponBehavior weapon) {
		this.weapon = weapon;
	}
	
	public abstract void say();
}

【Character子类——King类】

public class King extends Character{

	public King(){
        //构造函数中配置接口实现类
		this.weapon = new Sword();
	}
	
	@Override
	public void say() {
		System.out.println("我是国王!");
	}
}

【策略接口】

public interface WeaponBehavior {
	public void userWeapon();
}

【策略接口实现类】

public class Sword implements WeaponBehavior {

	@Override
	public void userWeapon() {
		System.out.println("使用宝剑挥砍!");
	}
}

【main函数】

public class TestMain {
	public static void main(String[] args) {
		Character king = new King();
		king.say();
		king.fight();
		king.setWeapon(new Knife());
		king.fight();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值