策略模式
提起强大的Java,脑海里总会蹦出几个关键字,封装,继承,多态,一处编译处处运行,代码复用等等,而设计模式在我的学习中认为是前人经验的复用,从而让Java写出来的系统更加的具有延展性,以应变后面需求的变化.今天要学习的就是策略模式.
有一个国家人员复杂,管理起来麻烦,此时他历经千辛万苦找到了你,在随从的侍卫放下两大箱的黄金之后,请求你为国家设计一个人员管理系统,但在此之前他需要考量一下你, 假设有如此需求,这是一个尚武的国家,有剑客,弓箭手,战士(使用斧头)等,此时需要你写一个小的demo来管理各自人员的战斗方式.
为了尽早拿下这个项目,于是咖啡都没有冲,你就自信的选择了继承来实现;
1,首先定义抽象父类,将fight()的方式留给子类来实现
父类Role
publicabstractclass Role {
protected String name;
protected Integer age;
protectedvoid breath(){
System.out.println("我们都呼吸空气");
}
protectedabstractvoid fight();
}
子类1,弓箭手
publicclass BowMan extends Role{
@Override
protectedvoid fight() {
System.out.println("我是弓箭手,我的武器是弓箭!");
}
}
子类2,剑客
publicclass SwordMan extends Role{
@Override
protectedvoid fight() {
System.out.println("我是剑客,我的武器是剑!");
}
}
子类3,战士
public class WarriorMan extendsRole{
@Override
protectedvoid fight() {
System.out.println("我是战士,我的武器是斧头!");
}
}
定义测试类:
public class RoleTest {
@Test
publicvoid test4RoleExtends(){
Role role1 = new BowMan();
Role role2 = new SwordMan();
Role role3 = new WarriorMan();
role1.breath();
role2.breath();
role3.breath();
role1.fight();
role2.fight();
role3.fight();
}
}
测试结果:控制台输出如下:
我们都呼吸空气
我们都呼吸空气
我们都呼吸空气
我是弓箭手,我的武器是弓箭!
我是剑客,我的武器是剑!
我是战士,我的武器是斧头!
我要参加战斗!
我要参加战斗!
我要参加战斗!
你向国外许诺,这个系统足以应付所有的问题,无论来什么样的角色,它都可以完美应对,国王很快将他推向了全民,并且Role的子类越来越多,这个系统完美地运行着,有一天国王突发奇想,没错就是突发奇想,需要选拔一些远攻role去攻克一个难关,国王希望国家里的人来报名,深感Java继承的巨大优势的你嗅到了升官发财三妻四妾的契机,大包大揽的应承了这份工作,悠闲的冲了杯咖啡,修改了Role类
publicabstractclass Role {
protected String name;
protected Integer age;
protectedvoid breath(){
System.out.println("我们都呼吸空气");
}
protectedabstractvoid fight();
//报名参加战斗
protectedvoid regiesterFight() {
System.out.println("我要参加战斗!");
}
}
选拔开始:
publicclass RoleTest {
@Test
publicvoid test4RoleExtends(){
Role role1 = new BowMan();
Role role2 = new SwordMan();
Role role3 = new WarriorMan();
role1.breath();
role2.breath();
role3.breath();
role1.fight();
role2.fight();
role3.fight();
role1.regiesterFight();
role2.regiesterFight();
role3.regiesterFight();
}
}
全民响应战斗:
于是乎,战场上一群扔了斧头和剑就没法再战斗的role,因为这场战斗需要远程投掷.毫无疑问,这场战斗,大败而归,国王大怒,责令你一周之内拿出解决方案,否则剥夺你喝咖啡的权利,没有了咖啡,你就很有可能在代码的海洋中溺死.
此时你想起了尘封了很久的武林秘籍,headfirst之设计模式,哪一个模式才能应付这样行为多变的情况呢,思考了六天,在毫无头绪中度过,第七天终于想起了那根救命稻草---策略模式.
策略模式:
定义算法族,让算法和使用算法的用户分离起来.
将战斗和报名战斗的行为委托出去分别由FightBehavior和RegFightBehavior两个接口(面向接口编程,远远胜于面向实现编程),行为的具体方式由其不同的实现类实现.
重新定义Role
publicabstractclass Role {
protected String name;
protected Integer age;
protected FightBehavior fightBehavior;
protected RegFightBehavior regFightBehavior;
protectedvoid breath(){
System.out.println("我们都呼吸空气");
}
}
定义接口FightBehavior,RegFightBehavior
public interface FightBehavior {
publicvoid fight();
}
其实现类:
public class FightByAxe implementsFightBehavior{
@Override
publicvoid fight() {
System.out.println("我用斧头!!!");
}
}
public class FightByBow implementsFightBehavior{
@Override
publicvoid fight() {
System.out.println("我用弓箭!!!");
}
}
public class FightBySword implementsFightBehavior{
@Override
publicvoid fight() {
System.out.println("我用剑!!!");
}
}
将战斗的行为分离出来,并叫交由其实现类来处理,在role中添加战斗行为属性,而不需要考虑其如何实现的.
public interface RegFightBehavior {
publicvoid regFight();
}
public class RegFightByClose implements RegFightBehavior{
@Override
publicvoid regFight() {
System.out.println("我是近战,我不能参加!!");
}
}
public class RegFightByFar implements RegFightBehavior{
@Override
publicvoid regFight() {
System.out.println("我是远攻我要参加");
}
}
是否参加战斗这一行为也是如此,为了形象的表现将行为委托出去了,将命名变为byFar byClose这种方式.
此时再在role的子类中,定义或者赋予行为类的具体委托类,也就是指定客户使用的算法
publicclass BowMan extends Role{
publicvoidfight(){
fightBehavior = newFightByBow();
fightBehavior.fight();
}
publicvoidregFight(){
regFightBehavior = newRegFightByFar();
regFightBehavior.regFight();
}
}
publicclass SwordMan extends Role{
publicvoidfight() {
fightBehavior = newFightBySword();
fightBehavior.fight();
}
publicvoidregFight(){
regFightBehavior = newRegFightByClose();
regFightBehavior.regFight();
}
}
public class WarriorMan extendsRole{
publicvoid fight() {
fightBehavior= new FightByAxe();
fightBehavior.fight();
}
publicvoid regFight(){
regFightBehavior= new RegFightByClose();
regFightBehavior.regFight();
}
}
测试类
public class RoleTest {
@Test
public voidtest4RoleExtends(){
Rolerole1 = new BowMan();
Rolerole2 = new SwordMan();
Rolerole3 = new WarriorMan();
role1.fight();
role1.regFight();
System.out.println("以上是bowman");
role2.fight();
role2.regFight();
System.out.println("以上是swordman");
role3.fight();
role3.regFight();
System.out.println("以上是warriorman");
}
}
测试结果:
我用弓箭!!!
我是远攻我要参加
以上是bowman
我用剑!!!
我是近战,我不能参加!!
以上是swordman
我用斧头!!!
我是近战,我不能参加!!
以上是warriorman