【Java】策略模式

策略模式Strategt Pattern定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

说白了,就是在主函数新建一个类之后,调用相同的方法,得到的实现的结果是不同的,即使这些类是继承同一个抽象。

具体直接看一道2010年上半年的软件设计师的软考题来说明这个问题:

某软件公司先欲开发一款飞机飞行模拟系统,该系统主要模拟不同种类飞机的飞行特征与起飞特征,需要模拟的飞机种类机器特征如下所示:

直升机Helicopter:垂直起飞VerticalTakeOff、亚音速飞行SubSonicFly

客机AirPlan:长距离飞行LongDistanceTakeOff、亚音速飞行SubSonicFly

歼击机Fighter:长距离飞行LongDistanceTakeOff、超音速飞行SuperSonicFly

鹞式战斗机Harrier:垂直起飞VerticalTakeOff、超音速飞行SuperSonicFly

为支持将来模拟更多种类的飞机,采用策略设计模式Strategt Pattern,设计如下类图:


图6-1中,AirCraft为抽象类,描述了抽象的飞机,而类Helicopter、AirPlane、Fighter、Harrier分别描述具体的飞机种类,方法fly()和takeOff()分别表示不同飞机都具有飞行特征和起飞特征:类FlyBehavior与TakeOffBehavior为抽象类,分别用于表示抽象的飞机行为与起飞行为,类SubSonicFly与SuperSonicFly分别描述亚音速废弃和超音速起飞的行为,类VerticalTakeOff与LongDistanceTakeOff分别描述垂直起飞与长距离起飞的行为。

在写代码解答此题之前,我们先来看一下这个类图,也就是所谓的UML,AirCraft依赖于FlyBehavior与TakeOffBehavior,注定会在自己的类成员有这两个对象所对应的实体。之后类SubSonicFly与SuperSonicFly继承于FlyBehavior,VerticalTakeOff与LongDistanceTakeOff继承于TakeOffBehavior,Helicopter、AirPlane、Fighter、Harrier继承于AirCraft。子类注定是父类接口的实现。在FlyBehavior、TakeOffBehavior、AirCraft中,+表示该类存在的方法,-号表示该类存在的类成员,因此顺利成章地能够得到如下的代码:

//一、飞行方式
//1.接口
interface FlyBehavior {
	public void fly();
};
//2.实现
class SubSonicFly implements FlyBehavior {
	public void fly() {
		System.out.println("亚音速飞行!");
	}
};

class SuperSonicFly implements FlyBehavior {
	public void fly() {
		System.out.println("超音速飞行!");
	}
};
//二、起飞方式
//1.接口
interface TakeOffBehavior {
	public void takeOff();
};
//2.实现
class VerticalTakeOff implements TakeOffBehavior {
	public void takeOff() {
		System.out.println("垂直起飞!");
	}
};

class LongDistanceTakeOff implements TakeOffBehavior {
	public void takeOff() {
		System.out.println("长距离起飞!");
	}
};
//三、飞机
//1.飞机的抽象
abstract class AirCraft {
	protected FlyBehavior flyBehavior;
	protected TakeOffBehavior takeOffBehavior;

	public void fly() {
		flyBehavior.fly();
	}

	public void takeOff() {
		takeOffBehavior.takeOff();
	};
};
//2.飞机的实现
class Helicopter extends AirCraft {
	public Helicopter() {
		flyBehavior = new SubSonicFly();
		takeOffBehavior = new VerticalTakeOff();
	}
}
class AirPlane extends AirCraft {
	public AirPlane() {
		flyBehavior = new SubSonicFly();
		takeOffBehavior = new LongDistanceTakeOff();
	}
}
class Fighter extends AirCraft {
	public Fighter() {
		flyBehavior = new SuperSonicFly();
		takeOffBehavior = new LongDistanceTakeOff();
	}
}
class Harrier extends AirCraft {
	public Harrier() {
		flyBehavior = new SuperSonicFly();
		takeOffBehavior = new VerticalTakeOff();
	}
}

//测试主函数
public class StrategyTest {

	public static void main(String[] args) {
		Helicopter helicopter=new Helicopter();		
		helicopter.takeOff();
		helicopter.fly();
		AirPlane airPlane=new AirPlane();
		airPlane.takeOff();
		airPlane.fly();
	}

}

运行结果如下:


很显然的是,在主函数中,虽然Helicopter与AirPlane使用的是同一个方法,但是其得到的结果,也就是输出是不同的。

同时在于AirCraft,如果以后各个飞机要扩展不同的功能,可以直接在里面加,在不同的飞机实现补上不同的实现就得到不同的同名类实现方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值