目录

小故事: 一起打怪兽

模板&策略模式

常规方式

模板模式

策略模式

相似:

差异:


小故事: 一起打怪兽

有个记者去光之国采访一群奥特曼,他问迪迦奥特曼:“你每天都干什么?”
迪迦奥特曼说:“训练,飞翔,用光线打怪兽!”
接着又问戴拿奥特曼,戴拿奥特曼说:“训练,飞翔,用体术打怪兽!”
记者带着困惑问其他的奥特曼,答案都一样,就这样一直问了 99 个奥特曼。
当走到第 100 个奥特曼旁边时,记者走过去问他:每天都做些什么啊?
第100个奥特曼回答:"训练,飞翔";
记者惊奇的又问:"那你怎么不打怪兽";
那名奥特曼撇着嘴巴,瞪了记者一眼说:我就是怪兽,我的名字就是怪兽;
 啊,"原来是怪兽奥特曼"

模板&策略模式

实现姿势
我们会从简单到复杂,讲解代码正确的实现姿势,分别为最 Low 方式、常规方式、模板模式和策略模式。
最 Low 方式
假如现在有 3 个奥特曼,都喜欢 “训练,飞翔,打怪兽”

public class OldTiga {public void everyDay() {System.out.println("迪迦==>飞翔");System.out.println("迪迦==>训练");System.out.println("迪迦==>光线打怪兽");}
}public class OldDeNa {public void everyDay() {System.out.println("戴拿==>训练");System.out.println("戴拿==>飞翔");System.out.println("戴拿==>体术打怪兽");}
}public class OldMonsters {public void everyDay() {System.out.println("怪兽==>飞翔");System.out.println("怪兽==>训练");System.out.println("怪兽==>我**就是怪兽,谁敢打我");}}public class OldLandLight {public static void main(String[] args) {OldTiga oldTiga = new OldTiga();oldTiga.everyDay();OldDeNa oldDeNa = new OldDeNa();oldDeNa.everyDay();OldMonsters oldMonsters = new OldMonsters();oldMonsters.everyDay();}
}

测试:

这种方式是大家写代码时,最容易使用的方式,上手简单,也容易理解,目前看项目中陈旧的代码,经常能找到它们的影子,下面我们看怎么一步步将其进行重构。

常规方式

“训练,飞翔,打怪兽” 其实都是独立的行为,为了不相互影响,我们可以通过函数简单进行封装:

public class RTiga {public void fly(){System.out.println("迪迦==>飞翔");}public void training(){System.out.println("迪迦==>训练");}public void fightMonsters(){System.out.println("迪迦==>光线打怪兽");}
}public class RDeNa {public void fly(){System.out.println("戴拿==>飞翔");}public void training(){System.out.println("戴拿==>训练");}public void fightMonsters(){System.out.println("戴拿==>光线打怪兽");}
}public class RMonsters {public void fly(){System.out.println("怪兽==>飞翔");}public void training(){System.out.println("怪兽==>训练");}public void fightMonsters(){System.out.println("怪兽==>我**就是怪兽,谁敢打我");}
}public class RLandLight {public static void main(String[] args) {RTiga rTiga = new RTiga();rTiga.fly();rTiga.training();rTiga.fightMonsters();RDeNa rDeNa = new RDeNa();rDeNa.fly();rDeNa.training();rDeNa.fightMonsters();RMonsters rMonsters = new RMonsters();rMonsters.fly();rMonsters.training();rMonsters.fightMonsters();}
}

测试结果:

模板模式

定义:一个抽象类公开定义了执行它的方法的方式/模板,它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行,属于行为型模式。

这 3 个奥特曼,因为 “训练,飞翔” 都一样,所以我们可以直接实现出来,但是他们 “打怪兽” 的方式不同,所以封装成抽象方法,需要每个奥特曼单独去实现 “打怪兽” 的方式。

最后再新增一个方法 everyDo(),固定每天的执行流程:

定义抽象奥特曼类

public abstract class Ultraman {public void fly(String name){System.out.println(name+"==>飞翔");}public void training(String name){System.out.println(name+"==>训练");}abstract void fightMonsters(String name);public void everyDo(String name){this.fly(name);this.training(name);this.fightMonsters(name);}
}

每个不同的奥特曼实现自己的打怪兽方法

@Data
@Accessors(chain = true)
public class Tiga extends Ultraman {private String name;@Overridevoid fightMonsters(String name) {System.out.println(name+"==>光线打怪兽");}
}@Data
@Accessors(chain = true)
public class DeNa extends Ultraman {private String name;@Overridevoid fightMonsters(String name) {System.out.println(name+"==>体术打怪兽");}
}@Data
@AllArgsConstructor
@NoArgsConstructor
public class Monsters extends Ultraman {private String name;@Overridevoid fightMonsters(String name) {System.out.println(name+"==>我**就是怪兽,谁敢打我");}
}

在光之国调用

public class LandLight {public static void main(String[] args) {Tiga tiga = new Tiga().setName("迪迦");tiga.everyDo(tiga.getName());DeNa deNa = new DeNa().setName("戴拿");deNa.everyDo(deNa.getName());Monsters monsters = new Monsters("怪兽");monsters.everyDo(monsters.getName());}
}

测试结果:

策略模式

定义:一个类的行为或其算法可以在运行时更改,即我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象,策略对象改变 context 对象的执行算法,属于行为型模式。还是先定义奥特曼抽象类

public abstract class SUltraman {public void fly(String name){System.out.println(name+"==>飞翔");}public void training(String name){System.out.println(name+"==>训练");}abstract void fightMonsters(String name);
}

每个奥特曼实现自己的打怪兽方法

@Data
@Accessors(chain = true)
public class STiga extends SUltraman {@Overridevoid fightMonsters(String name) {System.out.println(name+"==>光线打怪兽");}
}@Data
@Accessors(chain = true)
public class SDeNa extends SUltraman {@Overridevoid fightMonsters(String name) {System.out.println(name+"==>体术打怪兽");}
}@Data
public class SMonsters extends SUltraman {@Overridevoid fightMonsters(String name) {System.out.println(name+"==>我**就是怪兽,谁敢打我");}
}

这里就是策略模式的重点,我们再看一下策略模式的定义 “我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象”,这里只需要关注策略的执行行为,而不需要关注是谁来执行的,只重视行为本身,而不去重视执行行为的操作者,那么该 contex 对象如下:

public class BeHaviorContext {private SUltraman ultraman;private String name;public BeHaviorContext(SUltraman newUltraman,String newName){name = newName;ultraman = newUltraman;}public void setUltraman(SUltraman newUltraman,String newName){name = newName;ultraman = newUltraman;}public void everyDo(){ultraman.fly(this.name);ultraman.training(this.name);ultraman.fightMonsters(this.name);}
}

光之国的执行测试:

public class SLandLight {public static void main(String[] args) {BeHaviorContext beHaviorContext = new BeHaviorContext(new STiga(),"迪迦");beHaviorContext.everyDo();//重新设置新的策略对象beHaviorContext.setUltraman(new SDeNa(),"戴拿");beHaviorContext.everyDo();beHaviorContext.setUltraman(new SMonsters(),"怪兽");beHaviorContext.everyDo();}
}

执行结果:

我们可以通过给 behaviorContext 传递不同的策略对象,然后来约定 everyDo() 的调用方式。

其实这个示例,有点把策略模式讲复杂了,因为纯粹的策略模式,3 个奥特曼只有 fightMonsteres() 方法不同,所以可以把 fightMonsteres() 理解为不同的算法即可。
之所以引入 everyDo(),是因为实际的项目场景中,会经常这么使用,也就是把这个变化的算法 fightMonsteres(),包装到具体的执行流程里面,所以策略模式就看起来没有那么直观,但是核心思想是一样的。

相似:

策略和模板方法模式都可以用来满足开闭原则,使得软件模块在不改变代码的情况下易于扩展;

两种模式都表示通用 function 与该 function 的详细实现的分离,不过它们所提供的粒度有一些差异。

差异:

策略模式:

它基于接口;

客户和策略之间的耦合更加松散;

定义不能被子类改变的 algorithm 的骨架,只有某些操作可以在子类中重写;

父类完全控制 algorithm ,仅将具体的步骤与具体的类进行区分;

绑定是在编译时完成的。

模板模式:

它基于框架或抽象类,甚至可以有一个具有默认实现的具体类。

模块耦合得更紧密;

它通过修改方法的行为来改变对象的内容;

它用于在 algorithm 族之间切换;

它在运行时通过其他 algorithm 完全 replace 一个algorithm 来改变对象的行为;

绑定在运行时完成

java模板/策略模式打怪兽相关推荐

  1. Java使用策略模式替换掉 if else

    Java使用策略模式替换掉 if else 我们的代码中常常大量的使用 if else ,如果条件在不断的增加,我们就需要继续在后面增加if else,代码就会越来越臃肿,可读性差,后期非常不好维护, ...

  2. Java设计模式-策略模式作业

    Java设计模式-策略模式作业,所有类和接口均在一个package内 文章目录 前言 一.作业内容 二.具体实现 1.类图 2.Strategy接口 3.PreCopyStrategy类 4.Post ...

  3. java计数器策略模式_策略模式与外观模式 | 学步园

    1.策略 :定义不同的 2. 例子:随机生成宠物,并统计各种宠物生成数量. a) 抽象类:PetCreator,用于随机生成宠物. package context; import java.util. ...

  4. java设计模式---策略模式

    1,什么是策略模式? 策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 2,策略模式有什么好处? 策略模式的好处在于你可以动态的改变对象 ...

  5. Java练习之奥特曼打怪兽(回合制)

    Java练习 1.整体要求 奥特曼打怪兽,奥特曼有名字.攻击力.血量等属性,有技能:飞行.光线攻击: 怪兽有名字.攻击力和血量属性,有技能:奔跑.蛮力攻击. 创建奥特曼和怪兽对象,然后调用他们的属性和 ...

  6. JAVA设计模式-策略模式

    1.1 需求背景 Background:M公司为某电影院开发了一套影院售票系统,在该系统中需要为不同类型的用户提供不同的电影票打折方式,具体打折方案如下: (1)学生凭学生证可享受票价8折优惠: (2 ...

  7. Java设计模式----策略模式(Strategy)

    1.  策略模式: 策略模式,也称为政策模式,定义如下: 定义一组算法,将每个算法都封装起来,使他们可以相互转化 2.  策略模式的原理是面向对象的继承和多态.策略模式的3个角色 a. Strateg ...

  8. java计数器策略模式_java设计模式(二十一)--策略模式

    对于策略模式,我在很多面试题上看到过考察这一类的问题,这种模式也的确比较好用. 我感觉这种模式就是将不同实现的方法放到一个接口中,然后通过实现这个接口来实现不同的运行结果,这种模式有三部分构成: 策略 ...

  9. Java设计模式--策略模式

    策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合 策略模式就是用来封装算法的, ...

最新文章

  1. Ubuntu 常见报错处理
  2. mysql 上级组织参数值_MySQL参数group_replication_consistency说明
  3. react实现路由跳转_react实现hash路由
  4. 卸掉IE8,降级使用
  5. set python用法_Python set()用法及代码示例
  6. Windows 2000命令行如何查看进程PID和杀进程
  7. python super详解_python中super()详解
  8. # 再次尝试 连接失败_新一代高效连接池HikariCP设计简要分析
  9. 【TWVRP】基于matlab遗传和粒子群算法求解带时间窗的车辆路径规划问题【含Matlab源码 1037期】
  10. 聚类模型ari_7.9 聚类模型评估
  11. UNIX网络编程卷一 学习笔记 第一章 简介
  12. jsonrpc(jsonrpc4j)demo
  13. 如何使用 OpManager 进行磁盘空间监控?
  14. OPICS 节假日维护
  15. PE文件格式偏移参考
  16. 公有云NAT 网关比较
  17. 阿里p9 Python工程师,进阶书籍推荐
  18. Mysql数据库操作语句总结(一)
  19. php视频直播系统源码Android 修改状态栏颜色 白色、透明色
  20. python天勤金叉编程代码大全_这些Python编程黑科技,装逼指南,高逼格代码,让你惊叹不已...

热门文章

  1. 硕士论文格式排版要点
  2. 解决 Spring boot Java下载Excel,office提示内容有问题
  3. 百度PC关键词排名查询API接口-(api_submit- 百度PC关键词排名查询API接口)
  4. 如何从ted上下载字幕
  5. OpenCV之稠密光流
  6. 什么是算法算法有些什么特性_反正是什么算法
  7. C语言的本质——C标准库之字符串操作
  8. 激光雷达传感器以及运动畸变去除
  9. 最大股票收益问题(数组最大差问题)
  10. 贵州移动IDC云管理平台--云宏