1.01k likes | 1.2k Views
行为模式. 1 不变模式. 一个对象的状态在创建后就不再允许变化,称为不变模式 例如 :java.lang.String, java.lang.Integer. 1.2 如何保证对象是线程安全的?. 一个线程不安全的例子: public class JpgProcessor(){ private byte[] data; public void setData(byte[] data){ this.data=data; } public byte[] resize(){ .... } }. 1.3 不变模式肯定可以实现线程安全.
E N D
1 不变模式 • 一个对象的状态在创建后就不再允许变化,称为不变模式 • 例如:java.lang.String, java.lang.Integer
1.2如何保证对象是线程安全的? 一个线程不安全的例子: public class JpgProcessor(){ private byte[] data; public void setData(byte[] data){ this.data=data; } public byte[] resize(){ .... } }
1.4 不变模式同享元模式的区别联系 • 享元模式中并不要求对象一定是不变的 • 但是享元模式中大多数对象是不变的。
1.5 不变模式优、缺点 • 优点:容易维护,线程安全。 • 缺点:如果频繁创建,浪费内存。
1.6 String类一个可变模式实现是什么? StringBuffer; StringBuffer.append(“xx”) 和 String1=String1+”xxx”效率上有巨大差别。
2 策略模式 • 定义一系列的算法,将每个算法封装起来,使其可以互相替换。
2.3 问题 不同算法替代问题 • 系统如何支持不同的排序算法?
2.5 多种排序算法的策略模式实现 public class Context{ private Sort mySort; public void setSort(Sort sort){ this.mySort=sort; } public void doSort(){ mySort.sort(); } }
2.7 关于策略模式的其它应用场合。 • 如何实现对数据的不同压缩算法? • PhotoShop中,对于同一个操作,有不同的实现方法,如何实现? • 如何实现商品的不同打折方式计算? • 你自己构建的系统,如何实现用户扩展?
3 模板方法 • 在父抽象类中定义一个算法中的骨架,将这些步骤延迟到子类中执行。
3.3 模板方法示例-定积分的例子 public abstract class Integral{ public double calc(start,end,step){ double sum=0; for(x=start;x<end;x=x+step){ sum=sum+getFuncValue(x); } return sum; } public abstract double getFuncValue(x); }
3.6 问题 关于控件问题 • 很多开发工具有各种控件,为什么用同样的控件可以开发出表现样子和行为不同的程序?
4 观察者模式 • 对象之间建立一种关系,使得当每个对象改变状态的时候,其依赖的对象得到通知并被自动更新。
4.3 观察者模式 部分代码 public class ConcreteSubject{ public void notifyServer(Object obj){ for(observer in observers){ observer.update(obj); } } }
4.4 观察者模式的应用 • 一个对象的变化需要通知到其他对象:例如订阅关系、缓存的刷新等等。
4.7 Timer类部分伪代码 public class Timer{ private List timerTasks; public void onTimer(){ for(timerTask in timerTasks){ if( it is time for timerTask run){ timerTask.start(); } } } }
5 迭代模式 • 提供一种可以访问聚合对象的方法(通常返回一个Iterator的实例),而不暴露这个对象内部的表示。
5.3 问题 如何实现聚集类内部元素的遍历? • List、Set其数据存放方式不尽相同,如何用同样的方法访问其数据?
6 责任链模式 • 避免请求发送者和接受者耦合到一起,让多个对象都有可能收到请求,将这些对象连接为一条链,并沿着这条链请求,直到有对象处理为止。
6.3 WebServer重定向(Servlet)的实现? <filter-name>showHtml</filter-name> <filter-class>cn.tju.edu.ShowHtml</filter-class> </filter> <filter-mapping> <filter-name>news/*.html</filter-name> <url-pattern>showHtml</url-pattern> </filter-mapping> <filter-mapping> 实际上,可以认为采用了责任链
7 命令模式 • 将一个请求封装成一个对象,因此可以参数化多个客户的不同请求,将请求排队,记录请求日志,并且支持撤销操作。
7.3 命令模式 部分代码 public class Invoker{ private Command command; public Invoker(Command command){ this.command=command} public void action(){ command.execute(); } }
7.4 命令模式 部分代码 public class ConcreteCommand implements command{ private Receiver receiver; public ConcreateCommand(Receiver receiver){ this.receiver=receiver; } public void execute() { receiver.execute() } }
7.5 调用命令模式 Receiver receiver=new Receiver(); Command command=new ConcreteCommand(receiver); Invoker invoker=new Invoker(command); invoker.action();
Receiver 孙悟空=new Receiver() ; Command 圣旨 =new Command(孙悟空); Invoker 太上老君=new Invoker (圣旨); 太上老君.执行命令(); Invoker类中部分代码: public void 执行命令(){ this.圣旨.execute(); } Command类中部分代码: public void execute(){ 孙悟空.上天(); }
7.7 如何执行一批命令? • 用户频繁写一个邮件,发送,然后再写一个再发送。如何减少用户等待发送邮件的时间?
7.8 执行一批命令代码 采用命令模式 Receiver receiver=new Receiver(); Command command=new ConcreteCommand(receiver); Invoker incoker=new Invoker(); invoker.addCommand(command); command=new ConcreteCommandB(receiver); invoker.addCommand(command); ... invoker.action();
7.9 命令模式的作用 • 便于对命令记录日志 • 便于对命令批量执行 • 便于redo,undo • 执行命令和发送命令分离
8 备忘录模式 • 在不破坏封装的前提下,捕获并且保存一个对象的内部状态。
8.3 示例代码 Originator org= new Originator(); Caretaker taker=new CareTaker(); org.setState(“on”); taker.saveMemento(org.createMemento()); org.setState(“new”); taker.restoreMemento(taker.retrieveMemento());
8.4 状态模式 • 当一个对象改变状态的时候,其行为发生改变,从外表看起来好像改变了其类一样。