继续java设计模式学习之旅,
策略模式(Strategy Pattern):定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户。
可能看完之后还是很迷糊,但是有一个印象,方便阅读下面代码时候的思路理解。(本人是一名android讲师,这个也是很多学员喜欢犯的错误,不愿意看定义理论介绍,这样理解和统一思路就很难了)
话不多说,开始我们的游戏:
游戏设定角色有:Q、W、E、R和两个被动技能。
定义抽象父类Role:
package role;
public abstract class Role {
public abstract void q();
public abstract void w();
public abstract void e();
public abstract void r();
public abstract void d();
}
现在有一个角色A,q技能眩晕效果,w技能加速效果,e技能减速效果,r技能击飞效果,d是闪现
角色A代码
package role;
public class RoleA extends Role{
@Override
public void q() {
System.out.println("眩晕效果");
}
@Override
public void w() {
System.out.println("加速效果");
}
@Override
public void e() {
System.out.println("减速效果");
}
@Override
public void r() {
System.out.println("击飞效果");
}
@Override
public void d() {
System.out.println("闪现效果");
}
}
我们利用面向对象的思想设计了角色A,这个时候如果添加了新的角色呢?
RoleB:q眩晕、w伤害、e、减速、r击飞、d闪现
RoleC::q眩晕、w伤害、e、护盾、r击飞、d闪现
package role;
public class RoleB extends Role{
@Override
public void q() {
System.out.println("眩晕效果");
}
@Override
public void w() {//和A的不一样
System.out.println("伤害效果");
}
@Override
public void e() {
System.out.println("减速效果");
}
@Override
public void r() {
System.out.println("击飞效果");
}
@Override
public void d() {
System.out.println("闪现效果");
}
}
package role;
public class RoleC extends Role{
@Override
public void q() {
System.out.println("眩晕效果");
}
@Override
public void w() {
System.out.println("加速效果");
}
@Override
public void e() {//和A的不一样
System.out.println("护盾效果");
}
@Override
public void r() {
System.out.println("击飞效果");
}
@Override
public void d() {
System.out.println("闪现效果");
}
}
有创建了两个角色,但是发现很多重复的代码在里面,那么就要重新设计一下架构了,首先想到的就是使用接口,每个角色实现接口去实现不同的技能,但是接口不能实现代码复用,所以此路不同。于是你会想一下设计原则:遵循设计的原则,找出应用中可能需要变化的部分,把它们独立出来,不要和那些不需要变化的代码混在一起。这边改变的就是各种技能。再根据另一个设计原则:针对接口(超类型)编程,而不是针对实现编程,于是我们把代码改造成这样:
package skill;
public interface SkillQ {
void q();
}
package skill;
public interface SkillW {
void w();
}
package skill;
public interface SkillE {
void e();
}
package skill;
public interface SkillR {
void r();
}
package skill;
public interface SkillD {
void d();
}
定义了不同技能的接口,接下来去实现不同的技能
package bean;
import skill.SkillQ;
public class QXY implements SkillQ{
public void q() {
System.out.println("眩晕效果");
}
}
package bean;
import skill.SkillW;
public class WJiaS implements SkillW{
public void w() {
System.out.println("加速效果");
}
}
package bean;
import skill.SkillW;
public class WSS implements SkillW{
public void w() {
System.out.println("伤害效果");
}
}
不同的接口和技能实现类都写好了,需要重构Role父类
package role;
import skill.SkillD;
import skill.SkillE;
import skill.SkillQ;
import skill.SkillR;
import skill.SkillW;
public abstract class Role {
private SkillQ skillQ;
private SkillW skillW;
private SkillE skillE;
private SkillR skillR;
private SkillD skillD;
public Role setSkillQ(SkillQ skillQ) {
this.skillQ = skillQ;
return this;
}
public Role setSkillW(SkillW skillW) {
this.skillW = skillW;
return this;
}
public Role setSkillE(SkillE skillE) {
this.skillE = skillE;
return this;
}
public Role setSkillR(SkillR skillR) {
this.skillR = skillR;
return this;
}
public Role setSkillD(SkillD skillD) {
this.skillD = skillD;
return this;
}
public void q(){
skillQ.q();
}
public void w(){
skillW.w();
}
public void e(){
skillE.e();
}
public void r(){
skillR.r();
}
public void d(){
skillD.d();
}
}
重构RoleA:
package role;
public class RoleA extends Role{
}
测试类:
package test;
import role.RoleA;
import bean.DShanXian;
import bean.EJianSu;
import bean.QXY;
import bean.RJiFei;
import bean.WJiaS;
public class Test {
public static void main(String[] args) {
RoleA roleA=new RoleA();
roleA.setSkillQ(new QXY())
.setSkillW(new WJiaS())
.setSkillE(new EJianSu())
.setSkillR(new RJiFei())
.setSkillD(new DShanXian());
roleA.q();
roleA.w();
roleA.e();
roleA.r();
roleA.d();
}
}
结果:
眩晕效果
加速效果
减速效果
击飞效果
闪现效果
看着创建了很多的java文件,其实每个技能我们都去单独管理。
我们已经定义了一个算法族(各种技能),且根据需求可以进行相互替换,算法(各种技能)的实现独立于客户(角色)。现在是不是很好理解策略模式的定义了。
java的面向对象的设计思想,每种功能的独立面向接口的设计,不同功能不同实现,相互独立。
一边学习,一边记录。