23种设计模式-----行为模式

天涯浪子 提交于 2020-02-27 20:14:08

行为模式:关注系统中对象之间的相互交互,研究运行时对象之间的相互通信和协作,明确对象职责

1.模板方法模式(template method)

定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现。这样,新的子类可以在不改变一个算法结构的前提下重新定义该算法的某些特定步骤。

即:处理步骤父类中定义好,具体实现延迟到子类中定义。

开发中:数据库访问的封装、Junit单元测试、servlet中doGet/doPost方法调用、Hibernate中模板程序等等

银行案例:

 1 public abstract class BankTemplateMethod {
 2     
 3     //具体方法
 4     public void takeNumber() {
 5         System.out.println("取号排队");
 6     }
 7     
 8     //办理具体业务 、钩子方法
 9     public abstract void transact();
10     public void evaluate() {
11         System.out.println("反馈评分");
12     }
13     
14     //模板方法
15     public final void process() {
16         this.takeNumber();
17         
18         this.transact();
19         
20         this.evaluate();
21     }
22     
23 }
银行模板
 1 public class Client {
 2     public static void main(String[] args) {
 3 //        BankTemplateMethod btm = new DrawMoney();
 4 //        btm.process();
 5         
 6         //采用匿名内部类
 7         BankTemplateMethod btm2 = new BankTemplateMethod() {
 8             
 9             @Override
10             public void transact() {
11                 System.out.println("我要存钱");
12             }
13         };
14         btm2.process();
15         
16     }
17 }
18 
19 
20 
21 class DrawMoney extends BankTemplateMethod{
22     @Override
23     public void transact() {
24         System.out.println("我要取款");
25     }
26 }
测试

 

2.命令模式(command)

  • 抽象命令类Command
  • 具体命令类ConcreteCommand
  • 调用者/请求者Invoker:请求的发送者,通过命令对象来执行请求。调用者只与抽象命令类存在关联,运行时调用命令对象的execcute(),间接调用接收者的相关操作。
  • 接收者Receiver:1、接收者执行与请求相关的操作,具体实现对请求业务的处理。2、未抽象前,实际执行操作内容的对象
  • 客户类Client:需要创建调用者和具体命令类对象,在创建具体命令对象时指定对应的接收者。发送者和接收者没有直接关系,都通过命令对象间接调用

应用于:Struts2中action调用、数据库事务机制、命令的撤销和恢复。

1 public interface Command {
2     void execute();
3 }
抽象命令类
 1 public class ConcreteCommand implements Command{
 2     private Receiver receiver;//命令的真正执行者
 3     
 4     public ConcreteCommand(Receiver receiver) {
 5         super();
 6         this.receiver = receiver;
 7     }
 8 
 9     @Override
10     public void execute() {
11         //命令执行前后,可执行相关处理
12         receiver.action();
13     }
14 
15 }
具体命令类
1 public class Receiver {
2     public void action() {
3         System.out.println("出发!");
4     }
5 }
真正命令的执行者、接收者
 1 public class Invoke {
 2     private Command command;/*也可以通过容器List<Command>
 3     容纳很多命令对象,进行批处理。数据库底层的事务管理就是类似的结构!*/
 4 
 5     public Invoke(Command command) {
 6         super();
 7         this.command = command;
 8     }
 9     
10     //业务方法,用于调用命令类方法
11     public void call() {
12         command.execute();
13     }
14     
15 }
调用者、发起者
1 public class Client {
2     public static void main(String[] args) {
3         Command c = new ConcreteCommand(new Receiver());
4         Invoke i = new Invoke(c);
5         
6         i.call();
7         
8     }
9 }
客户类

 

3.迭代器模式(iterator)

  •  JDK内置迭代器(List/Set)

 

4.观察者模式(Observer)

主要用于1:N的通知。当一个对象的状态变化时,他需要及时告知一系列对象,令他们做出响应

  • 推:每次 都会把通知以广播方式发送给所有观察者 ,所有观察者只能被动接收。
  • 拉:观察者只要知道有情况即可。至于什么时候获取内容,获取什么内容都可以自主决定

开发中:聊天室,服务器发个所有客户端、网络游戏、邮件订阅、Servlet中,监听器、Android中,广播机制、商城中,群发消息。

5.中介者模式(Mediator)

本质是解耦多个同事对象之间的交互关系。每个对象都持有中介者对象的引用,只跟中介者对象打交道,通过中介者统一管理这些交互关系

应用:

MVC模式、窗口游戏程序、图形界面开发GUI

公司部门案例:

1 public interface Mediator {
2     void register(String dname,Department d); 
3     void command(String dname);
4 }
中介者接口
1 public interface Department {
2     void selfAction();//做本职工作
3     void outAction();//向上级汇报工作
4 }
同事类(部门类)接口
 1 public class Market implements Department{
 2     
 3     private Mediator m;//持有中介者的引用
 4     
 5     public Market(Mediator m) {
 6         super();
 7         this.m = m;
 8         m.register("market",this);
 9     }
10 
11     @Override
12     public void selfAction() {
13         System.out.println("汇报工作,项目进度需要资金");
14         
15         m.command("finacial");
16     }
17 
18     @Override
19     public void outAction() {
20         System.out.println("开发市场");
21     }
22     
23 }
市场部门
 1 public class Finacial implements Department{
 2     
 3     private Mediator m;//持有中介者的引用
 4     
 5     public Finacial(Mediator m) {
 6         super();
 7         this.m = m;
 8         m.register("finacial",this);
 9     }
10 
11     @Override
12     public void selfAction() {
13         System.out.println("汇报工作,资金充裕");
14         
15     }
16 
17     @Override
18     public void outAction() {
19         System.out.println("整理资金");
20     }
21     
22 }
财务部门
 1 public class President implements Mediator{
 2     
 3     private Map<String,Department> map = new HashMap<String,Department>();
 4         
 5     @Override
 6     public void register(String dname, Department d) {
 7         map.put(dname, d);
 8     }
 9 
10     @Override
11     public void command(String dname) {
12         map.get(dname).selfAction();
13     }
14 }
总经理
 1 public class Client {
 2     public static void main(String[] args) {
 3         Mediator m = new President();
 4         
 5         Market market = new Market(m);
 6         Finacial f = new Finacial(m);
 7         
 8         market.selfAction();
 9         market.outAction();
10     }
11 }
测试

 

6.备忘录模式(memento)

 保存某个对象内部状态的拷贝,以后可以将该对象恢复到原先状态

结构:

  • 源发器类Originator
  • 备忘录类Memento
  • 负责人类CareTake 

 开发中:棋类游戏,悔棋、普通软件的撤销操作、数据库软件中的回滚操作、历史记录

 

 1 public class Emp {
 2     private String ename;
 3     private int age;
 4     
 5     //进行备忘操作,并返回备忘录对象
 6     public EmpMemento memento() {
 7         return new EmpMemento(this);
 8     }
 9     
10     //进行数据恢复,恢复成制定备忘录对象的值
11     public void recovery(EmpMemento mmt) {
12         this.ename = mmt.getEname();
13         this.age = mmt.getAge();
14     }
15     
16     public Emp(String ename, int age) {
17         super();
18         this.ename = ename;
19         this.age = age;
20     }
21 
22     public String getEname() {
23         return ename;
24     }
25 
26     public void setEname(String ename) {
27         this.ename = ename;
28     }
29 
30     public int getAge() {
31         return age;
32     }
33 
34     public void setAge(int age) {
35         this.age = age;
36     }
37     
38 }
源发器类
 1 public class EmpMemento {
 2     private String ename;
 3     private int age;
 4     
 5     public EmpMemento(Emp e) {
 6         this.ename = e.getEname();
 7         this.age = e.getAge();
 8         
 9     }
10 
11     public String getEname() {
12         return ename;
13     }
14 
15     public void setEname(String ename) {
16         this.ename = ename;
17     }
18 
19     public int getAge() {
20         return age;
21     }
22 
23     public void setAge(int age) {
24         this.age = age;
25     }
26     
27 }
备忘录类
 1 public class CareTaker {
 2     private EmpMemento memento;
 3 
 4     public EmpMemento getMemento() {
 5         return memento;
 6     }
 7 
 8     public void setMemento(EmpMemento memento) {
 9         this.memento = memento;
10     }
11     
12     
13 }
负责人类,管理备忘录对象
 1 public class Client {
 2     public static void main(String[] args) {
 3         CareTaker taker = new CareTaker();
 4         
 5         Emp emp = new Emp("张三",18);
 6         System.out.println("第一次打印:"+emp.getEname()+"---"+emp.getAge());
 7         
 8         taker.setMemento(emp.memento());//备忘一次
 9         
10         emp.setAge(28);
11         emp.setEname("李四");
12         
13         System.out.println("第二次打印:"+emp.getEname()+"---"+emp.getAge());
14         
15         //恢复到备忘存储的对象
16         emp.recovery(taker.getMemento());
17         System.out.println("第三次打印:"+emp.getEname()+"---"+emp.getAge());
18     }
19 }
测试

 

7.解释器模式(Interpreter)

开发常见:EL表达式、正则表达式、SQL语法、数学表达式

基本用不着 

 

8.状态模式(state)

用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题

结构:

  • 环境类Context:环境类中维护一个State对象,他是定义了当前的状态。
  • 抽象状态类State
  • 具体状态类ConcreteState:每一个类封装了一个状态对应的行为

开发中:银行系统中账号状态管理、OA系统公文状态管理、酒店系统房间状态管理、线程对象各状态之间的切换

酒店管理案例:

1 public interface State {
2     void handle();
3 }
抽象类/抽象状态类
1 public class FreeState implements State{
2     @Override
3     public void handle() {
4         System.out.println("房间空闲");
5     }
6 }
酒店房间-空闲状态/具体状态类
1 public class CheckedInState implements State{
2     @Override
3     public void handle() {
4         System.out.println("房间已入住");
5     }
6 }
酒店房间--已入住/具体状态类
1 public class BookedState implements State{
2     @Override
3     public void handle() {
4         System.out.println("房间已预订");
5     }
6 }
酒店房间---已预订/具体状态类
 1 public class Context {
 2     private State state;
 3     
 4     //重点!
 5     public void setState(State s) {
 6         System.out.println("切换状态");
 7         state = s;
 8         state.handle();
 9     }
10     
11 }
房间对象/环境类
1 public class Client {
2     public static void main(String[] args) {
3         Context c = new Context();
4         
5         c.setState(new FreeState());
6         c.setState(new CheckedInState());
7         c.setState(new BookedState());
8     }
9 }
测试

 

9.策略模式(Strategy)

对应于解决某个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或新增算法。并且由客户端决定调用哪个算法。

开发中:GUI中布局管理、Spring框架中,Resource接口、资源访问策略

会员案例:

1 public interface Strategy {
2     public double getPrice(double standardPrice);
3 }
接口类
1 public class New implements Strategy{
2     @Override
3     public double getPrice(double standardPrice) {
4         System.out.println("不打折,原价");
5         return standardPrice;
6     }
7 }
新客户
1 public class Old implements Strategy{
2     @Override
3     public double getPrice(double standardPrice) {
4         System.out.println("打八折");
5         return standardPrice*0.8;
6     }
7 }
老客户
 1 public class Context {
 2     private Strategy strategy;//当前采用的算法对象
 3     
 4     //可以通过构造器来注入
 5     public Context(Strategy strategy) {
 6         super();
 7         this.strategy = strategy;
 8     }
 9 
10     //可以通过set方法注入
11     public void setStrategy(Strategy strategy) {
12         this.strategy = strategy;
13     }
14     
15     //自身方法
16     public void pringPrice(double s) {
17         System.out.println("报价:"+strategy.getPrice(s));
18     }
19 }
交互类(和具体的策略类交互)
1 public class Cilent {
2     public static void main(String[] args) {
3         
4         Strategy s1 = new Old();
5         Context ctx = new Context(s1);
6         
7         ctx.pringPrice(100);
8     }
9 }
测试类

 

10.职责链模式(chain of responsibility)

应用于公文审批流程、经过流程、供应链管理 

Javascript事件冒泡和捕获机制、Servlet过滤器链式处理、Struts2拦截器调用

请假流程测试:

 1 public class LeaveRequest {
 2     private String empname;
 3     private int leaveDays;
 4     public LeaveRequest(String empname, int leaveDays) {
 5         super();
 6         this.empname = empname;
 7         this.leaveDays = leaveDays;
 8     }
 9     public String getEmpname() {
10         return empname;
11     }
12     public void setEmpname(String empname) {
13         this.empname = empname;
14     }
15     public int getLeaveDays() {
16         return leaveDays;
17     }
18     public void setLeaveDays(int leaveDays) {
19         this.leaveDays = leaveDays;
20     }
21     
22 }
封装请假的基本信息
 1 public abstract class Leader {
 2     protected String name;
 3     protected Leader nextLeader;//责任链的后继对象
 4     public Leader(String name) {
 5         super();
 6         this.name = name;
 7     }
 8     //设定责任链上的后继对象
 9     public void setNextLeader(Leader nextLeader) {
10         this.nextLeader = nextLeader;
11     }
12     //处理请求的核心业务方法
13     public abstract void handleRequest(LeaveRequest request);
14 }
抽象类
 1 public class Director extends Leader{
 2 
 3     public Director(String name) {
 4         super(name);
 5     }
 6 
 7     @Override
 8     public void handleRequest(LeaveRequest request) {
 9         if(request.getLeaveDays()<7) {
10             System.out.println("主任:请假通过");
11         }else {
12             if(this.nextLeader!=null) {
13                 this.nextLeader.handleRequest(request);
14             }
15         }
16     }
17 }
主任
 1 public class Manager extends Leader{
 2     public Manager(String name) {
 3         super(name);
 4     }
 5 
 6     @Override
 7     public void handleRequest(LeaveRequest request) {
 8         if(request.getLeaveDays()<20) {
 9             System.out.println("经理:请假通过");
10         }else {
11             if(this.nextLeader!=null) {
12                 this.nextLeader.handleRequest(request);
13             }
14         }
15     }
16 }
经理
 1 public class Client {
 2     public static void main(String[] args) {
 3         Leader a = new Director("张三");
 4         Leader b = new Manager("李四");
 5         //组织责任链对象关系
 6         a.setNextLeader(b);
 7         
 8         //请假操作
 9         LeaveRequest req = new LeaveRequest("TOM", 2);
10         a.handleRequest(req);
11     }
12 }
测试

 

11.访问者模式(Visitor)

应用范围非常窄,了解即可

开发中:XML文档解析器设计、编译器的设计、复杂集合对象的处理

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!