设计模式学习:二、策略模式

先说说个人对策略模式的理解:
策略模式:根据不同的需求做出相应的反应
话说出来的是这么简单,但是在代码里面做起来貌似就不是这么容易了。

先看读到过的一篇博客:
文章链接:https://blog.csdn.net/lmj623565791/article/details/24116745

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

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

策略模式(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,写成下面的代码:

RoleB

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("铁布衫");
	}
 
}

RoleC

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都是有可能变化的,于是我们必须把这写独立出来。再根据另一个设计原则:针对接口(超类型)编程,而不是针对实现编程,于是我们把代码改造成这样:

(这里原文是没有的,我自己的旁白,大神看这种小儿科可以忽略,这只是记录我个人心得:
讲所有变化多端的行为全部抽象成接口,作者做法也是如此。然后将对应的行为全部实现对应接口,比如:attack攻击行为有降龙十八掌和九阳神功,我们就分别实现 IAttackBehavior接口,并重写接口里面的攻击方法,这样就有了各种各样的攻击方法,同理我们还可以写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("九阳神功!");
	}
 
}
 
public class DefendTBS implements IDefendBehavior
{
 
	@Override
	public void defend()
	{
		System.out.println("铁布衫");
	}
 
}
 
public class RunJCTQ implements IRunBehavior
{
 
	@Override
	public void run()
	{
		System.out.println("金蝉脱壳");
	}
 
}
//原本作者就写了这些,可能他理解的比较透彻,觉得这些就够了,但是作为设计模式小白
//我加了如下方法

public class AttacXLSBZ implements IAttackBehavior
{
 
	@Override
	public void attack()
	{
		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();
	}
 
}

现在我们需要一个金蝉脱壳,降龙十八掌!,铁布衫,样子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类的设计完全的针对角色,和技能的实现没有关系)

全文总结:
策略模式就是抽象多变的方法(算法)成接口,根据不同需求实现对应的接口,入文中attact攻击行为,可以有九阳神功和降龙十八掌,那我们就做两份实现,逃跑run有金蝉脱壳或者龟速跑那我们就实现两个逃跑方法,使用的时候就是拼装,怎么拼?
就是在实例对象的时候,将我们所需要的行为的实现方法拼凑进去就可以了
还不够直白?
就是一只笔,公共部分就是笔壳跟笔盖,这个就不换了,也就是我们定义类的公共部分。策略:我要红油笔,那我就装红芯,黑油笔,我就装黑芯。前提是这两个颜色笔芯都实现了笔芯的接口,换句话说得跟笔杆配套。
这就是我对策略模式的理解

我写博客第一、就是为了自己学习,第二、想把自己的理解说出来,大家如果看到小弟理解哪里有偏差欢迎指正,如果对你有所帮助,或者有疑问也请留言,我们可以共同探讨,毕竟我也是个菜鸟,欢迎大家批评指正

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值