模板方法

行为型模式和结构型模式一样,也分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。

行为型-模板方法&策略&状态 - 图1

行为型-模板方法&策略&状态 - 图2

  1. /**
  2. * 1、定义模板
  3. */
  4. public abstract class CookTemplate {
  5. /**
  6. * 定义算法: 定义好了模板
  7. * 父类可以实现某些步骤
  8. * 留关键给子类
  9. */
  10. public void cook(){
  11. //定义算法步骤
  12. heating(); //v
  13. addfood();
  14. addsalt();
  15. stirfry(); //v
  16. end(); //v
  17. }
  18. //加热方法
  19. public void heating(){
  20. System.out.println("开火...");
  21. };
  22. //添加食物
  23. public abstract void addfood();
  24. //加盐
  25. public abstract void addsalt();
  26. //翻炒
  27. public void stirfry(){
  28. System.out.println("翻炒中...");
  29. };
  30. //出锅
  31. public void end(){
  32. System.out.println("出锅....");
  33. };
  34. }
  1. /*
  2. * 继承模板,实现方法
  3. */
  4. public class AutoCookMachine extends CookTemplate{
  5. @Override
  6. public void addfood() {
  7. System.out.println("放了三个小白菜");
  8. }
  9. @Override
  10. public void addsalt() {
  11. System.out.println("放了三勺盐");
  12. }
  13. }
  1. public static void main(String[] args) {
  2. AutoCookMachine cookMachine = new AutoCookMachine();
  3. //实际调用的是父类的方法,但是细节都是子类所实现的
  4. cookMachine.cook();
  5. }

使用场景

什么场景用到?
Spring的整个继承体系都基本用到模板方法;
BeanFactory.getBean(1,2,3,4)—A1—-A2—-A3—-A4(全部被完成)
JdbcTemplate、RedisTemplate都允许我们再扩展…..
我们自己的系统也应该使用模板方法组织类结构
……

策略模式

策略(Strategy)模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。属于对象行为模式。

行为型-模板方法&策略&状态 - 图3

实例:游戏策略

  1. public interface GameStrategy {
  2. //战斗策略
  3. void warStrategy();
  4. }
  1. /**
  2. * 稳健运营策略(具体策略)
  3. */
  4. public class SteadyStrategy implements GameStrategy {
  5. @Override
  6. public void warStrategy() {
  7. System.out.println("各路小心...及时支援...");
  8. }
  9. }
  1. /**
  2. * 冲锋向前策略(具体策略)
  3. */
  4. public class UziStrategy implements GameStrategy{
  5. @Override
  6. public void warStrategy() {
  7. System.out.println("uzi.....");
  8. }
  9. }
  1. /**
  2. * 环境类
  3. */
  4. public class TeamGNR {
  5. //抽取游戏策略算法,并进行引用
  6. private GameStrategy gameStrategy;
  7. public void setGameStrategy(GameStrategy gameStrategy) {
  8. this.gameStrategy = gameStrategy;
  9. }
  10. public void startGame(){
  11. System.out.println("游戏开始.....");
  12. //游戏策略
  13. //
  14. gameStrategy.warStrategy();
  15. System.out.println("win......");
  16. }
  17. }
  1. public class MainTest {
  2. public static void main(String[] args) {
  3. TeamGNR gnr = new TeamGNR();
  4. gnr.setGameStrategy(new RandomStrategy()); //设置相应的策略
  5. gnr.startGame();
  6. }
  7. }

当我们要扩展一个策略时,只需要new一个类实现接口就可以

  1. //添加新的策略
  2. public class RandomStrategy implements GameStrategy{
  3. @Override
  4. public void warStrategy() {
  5. System.out.println("大乱斗...");
  6. }
  7. }

使用场景

什么场景用到?
使用策略模式可以避免使用多重条件语句,如 if…else 语句、switch…case 语句
什么是Spring的 InstantiationStrategy
线程池拒绝策略

……

状态模式

状态模式和策略模式非常像,不过状态模式在策略的基础上添加了状态,会有状态之间的流转

行为型-模板方法&策略&状态 - 图4

  1. /**
  2. * 抽象状态
  3. */
  4. public interface TeamState {
  5. //玩游戏
  6. void playGame();
  7. //切换到下一个状态
  8. TeamState next();
  9. }
  1. /**
  2. * 竞赛状态
  3. */
  4. public class MatchState implements TeamState{
  5. @Override
  6. public void playGame() {
  7. System.out.println("全力以赴打比赛....");
  8. }
  9. //状态模式的核心
  10. @Override
  11. public TeamState next() {
  12. return new VocationState();
  13. }
  14. }
  1. /**
  2. * 吃牛肉面状态
  3. */
  4. public class BeafNodleState implements TeamState {
  5. @Override
  6. public void playGame() {
  7. System.out.println("饱饱的一顿牛肉面......中了诅咒,输了");
  8. }
  9. @Override
  10. public TeamState next() {
  11. return new MatchState();
  12. }
  13. }
  1. /**
  2. * 休假状态
  3. */
  4. public class VocationState implements TeamState {
  5. @Override
  6. public void playGame() {
  7. System.out.println("三亚旅游真舒服....饿了...不玩游戏");
  8. //状态流转
  9. }
  10. @Override
  11. public TeamState next() { //下一个状态
  12. return new BeafNodleState();
  13. }
  14. }
  1. /**
  2. * 环境类:
  3. */
  4. public class SKTTeam {
  5. private TeamState teamState; //状态
  6. public void setTeamState(TeamState teamState) {
  7. this.teamState = teamState;
  8. }
  9. //开始游戏
  10. public void startGame(){
  11. //状态不同会导致不同的游戏结果
  12. teamState.playGame();
  13. }
  14. //下一个状态
  15. void nextState(){
  16. teamState = teamState.next();
  17. }
  18. }
  1. /**
  2. * 状态切换
  3. */
  4. public class MainTest {
  5. public static void main(String[] args) {
  6. SKTTeam sktTeam = new SKTTeam();
  7. TeamState state = new VocationState();
  8. sktTeam.setTeamState(state);
  9. sktTeam.startGame();
  10. // sktTeam.startGame();
  11. //
  12. // sktTeam.nextState();
  13. // sktTeam.startGame();
  14. //
  15. // sktTeam.nextState();
  16. // sktTeam.startGame();
  17. state = state.next();
  18. sktTeam.setTeamState(state);
  19. sktTeam.startGame();
  20. }
  21. }

使用场景

什么场景用到?
策略模式和状态模式是一样的?
状态模式核心需要具体状态类能在必要的时候切换状态
流程框架与状态机
……