关闭

设计模式 策略模式 以角色游戏为背景

标签: 设计模式策略模式
15638人阅读 评论(48) 收藏 举报
分类:

今天不想写代码,给大家带来一篇设计模式的文章,帮助大家可以把系统组织成容易了解、容易维护、具有弹性的架构。

先来看看策略模式的定义:

策略模式(Strategy Pattern):定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户。

好了,对于定义,肯定不是一眼就能看明白的,不然这篇文章就收尾了,对于定于大家简单扫一眼,知道个大概,然后继续读下面的文章,读完以后再来回味,效果嘎嘣脆。大家应该都玩过武侠角色游戏,下面我就以角色游戏为背景,为大家介绍:假设公司需要做一款武侠游戏,我们就是负责游戏的角色模块,需求是这样的:每个角色对应一个名字,每类角色对应一种样子,每个角色拥有一个逃跑、攻击、防御的技能。

初步的代码:

package com.zhy.bean;

/**
 * 游戏的角色超类
 * 
 * @author zhy
 * 
 */
public abstract class Role
{
	protected String name;

	protected abstract void display();

	protected abstract void run();

	protected abstract void attack();

	protected abstract void defend();

}
package com.zhy.bean;

public class RoleA extends Role
{
	public RoleA(String name)
	{
		this.name = name;
	}

	@Override
	protected void display()
	{
		System.out.println("样子1");
	}

	@Override
	protected void run()
	{
		System.out.println("金蝉脱壳");
	}

	@Override
	protected void attack()
	{
		System.out.println("降龙十八掌");
	}

	@Override
	protected void defend()
	{
		System.out.println("铁头功");
	}

}

没几分钟,你写好了上面的代码,觉得已经充分发挥了OO的思想,正在窃喜,这时候项目经理说,再添加两个角色

RoleB(样子2 ,降龙十八掌,铁布衫,金蝉脱壳)。

RoleC(样子1,拥有九阳神功,铁布衫,烟雾弹)。

于是你觉得没问题,开始写代码,继续集成Role,写成下面的代码:

package com.zhy.bean;

public class RoleB extends Role
{
	public RoleB(String name)
	{
		this.name = name;
	}

	@Override
	protected void display()
	{
		System.out.println("样子2");
	}

	@Override
	protected void run()
	{
		System.out.println("金蝉脱壳");//从RoleA中拷贝
	}

	@Override
	protected void attack()
	{
		System.out.println("降龙十八掌");//从RoleA中拷贝
	}

	@Override
	protected void defend()
	{
		System.out.println("铁布衫");
	}

}

package com.zhy.bean;

public class RoleC extends Role
{
	public RoleC(String name)
	{
		this.name = name;
	}

	@Override
	protected void display()
	{
		System.out.println("样子1");//从RoleA中拷贝
	}

	@Override
	protected void run()
	{
		System.out.println("烟雾弹");
	}

	@Override
	protected void attack()
	{
		System.out.println("九阳神功");
	}

	@Override
	protected void defend()
	{
		System.out.println("铁布衫");//从B中拷贝
	}

}

写完之后,你自己似乎没有当初那么自信了,你发现代码中已经存在相当多重复的代码,需要考虑重新设计架构了。于是你想,要不把每个技能都写成接口,有什么技能的角色实现什么接口,简单一想,觉得这想法高大尚啊,但是实现起来会发现,接口并不能实现代码的复用,每个实现接口的类,还是必须写自己写实现。于是,we need change ! 遵循设计的原则,找出应用中可能需要变化的部分,把它们独立出来,不要和那些不需要变化的代码混在一起。我们发现,对于每个角色的display,attack,defend,run都是有可能变化的,于是我们必须把这写独立出来。再根据另一个设计原则:针对接口(超类型)编程,而不是针对实现编程,于是我们把代码改造成这样:

package com.zhy.bean;

public interface IAttackBehavior
{
	void attack();
}

package com.zhy.bean;

public interface IDefendBehavior
{
	void defend();
}

package com.zhy.bean;

public interface IDisplayBehavior
{
	void display();
}

package com.zhy.bean;

public class AttackJY implements IAttackBehavior
{

	@Override
	public void attack()
	{
		System.out.println("九阳神功!");
	}

}
package com.zhy.bean;

public class DefendTBS implements IDefendBehavior
{

	@Override
	public void defend()
	{
		System.out.println("铁布衫");
	}

}

package com.zhy.bean;

public class RunJCTQ implements IRunBehavior
{

	@Override
	public void run()
	{
		System.out.println("金蝉脱壳");
	}

}

这时候需要对Role的代码做出改变:

package com.zhy.bean;

/**
 * 游戏的角色超类
 * 
 * @author zhy
 * 
 */
public abstract class Role
{
	protected String name;

	protected IDefendBehavior defendBehavior;
	protected IDisplayBehavior displayBehavior;
	protected IRunBehavior runBehavior;
	protected IAttackBehavior attackBehavior;

	public Role setDefendBehavior(IDefendBehavior defendBehavior)
	{
		this.defendBehavior = defendBehavior;
		return this;
	}

	public Role setDisplayBehavior(IDisplayBehavior displayBehavior)
	{
		this.displayBehavior = displayBehavior;
		return this;
	}

	public Role setRunBehavior(IRunBehavior runBehavior)
	{
		this.runBehavior = runBehavior;
		return this;
	}

	public Role setAttackBehavior(IAttackBehavior attackBehavior)
	{
		this.attackBehavior = attackBehavior;
		return this;
	}

	protected void display()
	{
		displayBehavior.display();
	}

	protected void run()
	{
		runBehavior.run();
	}

	protected void attack()
	{
		attackBehavior.attack();
	}

	protected void defend()
	{
		defendBehavior.defend();
	}

}

每个角色现在只需要一个name了:

package com.zhy.bean;

public class RoleA extends Role
{
	public RoleA(String name)
	{
		this.name = name;
	}

}

现在我们需要一个金蝉脱壳,降龙十八掌!,铁布衫,样子1的角色A只需要这样:

package com.zhy.bean;

public class Test
{
	public static void main(String[] args)
	{

		Role roleA = new RoleA("A");

		roleA.setAttackBehavior(new AttackXL())//
				.setDefendBehavior(new DefendTBS())//
				.setDisplayBehavior(new DisplayA())//
				.setRunBehavior(new RunJCTQ());
		System.out.println(roleA.name + ":");
		roleA.run();
		roleA.attack();
		roleA.defend();
		roleA.display();
	}
}

经过我们的修改,现在所有的技能的实现做到了100%的复用,并且随便项目经理需要什么样的角色,对于我们来说只需要动态设置一下技能和展示方式,是不是很完美。恭喜你,现在你已经学会了策略模式,现在我们回到定义,定义上的算法族:其实就是上述例子的技能;定义上的客户:其实就是RoleA,RoleB...;我们已经定义了一个算法族(各种技能),且根据需求可以进行相互替换,算法(各种技能)的实现独立于客户(角色)。现在是不是很好理解策略模式的定义了。

附上一张UML图,方便大家理解:


最后总结一下OO的原则:

1、封装变化(把可能变化的代码封装起来)

2、多用组合,少用继承(我们使用组合的方式,为客户设置了算法)

3、针对接口编程,不针对实现(对于Role类的设计完全的针对角色,和技能的实现没有关系)



点击此处下载源码







61
4
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

设计模式 策略模式 以角色游戏为背景

今天不想写代码,给大家带来一篇设计模式的文章,帮助大家可以把系统组织成容易了解、容易维护、具有弹性的架构。 先来看看策略模式的定义: 策略模式(Strategy Pattern):定义了算法族,分别封...
  • lmj623565791
  • lmj623565791
  • 2014-04-19 17:03
  • 15638

Java设计模式之策略模式

本文属于23种设计模式系列。 介绍的是策略模式。
  • jason0539
  • jason0539
  • 2015-04-13 07:20
  • 33383

java设计模式之策略模式及项目中的应用

今天开始,我们LazyCoder准备着手开发一款模拟人生游戏,首先从设计人物开始,我们设想我们设计的人物可以讲话,吃东西,睡觉,他们的样子也都不一样。我们想到了继承,于是有了第一个类Person,之后...
  • zcm101
  • zcm101
  • 2013-07-17 17:00
  • 2330

设计模式 策略模式 以角色游戏为背景

先来看看策略模式的定义: 策略模式(Strategy Pattern):定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户。 好了,对于定义,肯定不是...
  • dzc372787439
  • dzc372787439
  • 2015-03-09 10:56
  • 418

设计模式 策略模式 以角色游戏为背景

设计模式 策略模式 以角色游戏为背景
  • u013651026
  • u013651026
  • 2017-12-15 15:41
  • 216

设计模式 策略模式 以角色游戏为背景

给大家带来一篇设计模式的文章,帮助大家可以把系统组织成容易了解、容易维护、具有弹性的架构。 先来看看策略模式的定义: 策略模式(Strategy Pattern):定义了算法族,分别封装起来,让它...
  • hahashui123
  • hahashui123
  • 2014-07-07 15:37
  • 407

设计模式 策略模式 以角色游戏为背景

今天不想写代码,给大家带来一篇设计模式的文章,帮助大家可以把系统组织成容易了解、容易维护、具有弹性的架构。 先来看看策略模式的定义: 策略模式(Strategy Pattern):定义了算法族,分...
  • wy819
  • wy819
  • 2016-05-09 16:18
  • 121

设计模式 策略模式 以角色游戏为背景

今天不想写代码,给大家带来一篇设计模式的文章,帮助大家可以把系统组织成容易了解、容易维护、具有弹性的架构。 先来看看策略模式的定义: 策略模式(Strategy Pattern):定义了算...
  • qq_32523587
  • qq_32523587
  • 2017-05-02 22:20
  • 297

设计模式 策略模式 以角色游戏为背景

今天不想写代码,给大家带来一篇设计模式的文章,帮助大家可以把系统组织成容易了解、容易维护、具有弹性的架构。先来看看策略模式的定义:策略模式(Strategy Pattern):定义了算法族,分别封装起...
  • m0_37651226
  • m0_37651226
  • 2017-06-22 16:49
  • 160

设计模式 策略模式 以角色游戏为背景

今天不想写代码,给大家带来一篇设计模式的文章,帮助大家可以把系统组织成容易了解、容易维护、具有弹性的架构。 先来看看策略模式的定义: 策略模式(Strategy Pattern):定义了算...
  • walid1992
  • walid1992
  • 2016-05-22 09:00
  • 993
    个人资料
    • 访问:17922300次
    • 积分:51373
    • 等级:
    • 排名:第66名
    • 原创:205篇
    • 转载:0篇
    • 译文:6篇
    • 评论:15630条
    我的微信公众号
    联系方式


    QQ群:
    • 55032675
    • 423372824
    • 497438697
    • 请勿重复加群,Thx
    博客专栏
    统计