第139章
小a:“备忘录模式要怎么去实现?”
大b:“我详细给你说。”
1、备忘录模式中的角色
发起人:创建含有内部状态的备忘录对象,并使用备忘录对象存储状态。
负责人:负责人保存备忘录对象,但不检查备忘录对象的内容。
备忘录:备忘录对象将发起人对象的内部状态存起来,并保证其内容不被发起人对象之外的对象像读龋
注意:在备忘录的角色中,定义了他必须对不同的人提供不同的接口,对发起人提供宽接口,对其它任何人提供窄。
接口:也许你说我都提供宽接口了。这也是备忘录的一种实现,叫做白箱备忘录,不过这种方法的封装没有设计。好,安全性不够好。
2、白箱备忘录的实现:
publicclassoriginator{
privatestringstate;
publicmementocreatememento(){
returnnewmemento(state);
}
publicvoidrestorememento(mementomemento){
this.state=memento.getstate();
}
publicstringgetstate(){
returnthis.state;
}
publicvoidsetstate(stringstate){
this.state=state;
system.out.println(“currentstate=”+this.state);
}
}
publicclassmemento{
privatestringstate;
publicmemento(stringstate){
this.state=state;
}
publicstringgetstate(){
returnthis.state;
}
publicvoidsetstate(){
this.state=state;
}
}
publicclasscaretaker{
privatemementomemento;
publicmementoretrievememento(){
returnthis.memento;
}
publicvoidsavememento(mementomemento){
this.memento=memento;
}
}
publicclassclient{
privatestaticoriginatoro=neworiginator();
privatestaticcaretakerc=newcaretaker();
publicstaticvoidmain(sting[]args){
o.setstate(“on”);
c.savememento(o.creatememento());
o.setstate(“off”);
o.restorememento(c.retrievememento());
}
}
白箱的优点:实现简单。
白箱的缺点:上边说了,破坏了封装,安全性有些问题。
说明:这里白箱的实现只保存了一个状态,其实是可以保存多个状态的。
3、双接口的实现,宽窄接口(黑箱)
如何实现宽窄接口呢?内部类也许是个好方法。我们把备忘录类设计“成发起人”的内部类,但这样还有的问题是同一package中的其它类也能访问到,为了解决这个问题,我们可以把“备忘录”的方法设计成私有的方法,这样就可以保证封装,又保证发起人能访问到。实现如下:
定义窄接口。
publicinterfacenarrowmemento{
publicvoidnarrowmethod();
}
classoriginator{
private
stringstate;
privatenarrowmementomemento;
publicoriginator(){
}
publicnarrowmementocreatememento(){
memento=newmemento(this.state);
returnmemento;
}
publicvoidrestorememento(narrowmementomemento){
mementoamemento=(memento)memento;
this.setstate(amemento.getstate());
}
publicstringgetstate(){
returnthis.state;
}
publicvoidsetstate(stringstate){
this.state=state;
}
//内部类
protectedclassmementoimplementsnarrowmemento{
privatestringsavedstate;
privatememento(stringsomestate){
savestate=somestate;
}
privatevoidsetstate(stringsomestate){
savestate=somestate;
}
privatestringgetstate()
{
returnsavestate;
}
publicvoidnarrowmethod(){
system.out.println(“thisisnarrowmethod”);
}
}
publicnarrowmementogetnarrowmemento(){
returnmemento;
}
}
publicclasscaretaker{
privatenarrowmementomemento;
publicnarrowmementoretrievememento(){
returnthis.memento;
}
publicvoidsavememento(narrowmementomemento){
this.memento=memento;
}
}
publicclassclient{
privatestaticoriginatoro=neworiginator();
privatestaticcaretakerc=newcaretaker();
publicstaticvoidmain(string[]args){
//usewideinterface
o.setstate(“on”);
c.savememento(o.creatememento());
o.setstate(“off”);
o.restorememento(c.retrievememento());
//usenarrowinterface
narrowmementomemento=o.getnarrowmemento();
memento.narrowmethod();
}
}
大b:“还要注意的是:1、前边两个例子都是记录了单个状态(单check点),要实现多个状态点很容易,只须要把记录state的字符串换成一个list,然后添加,取得。如果须要随机须得状态点,也可以用map来存放。这样多个check点就实现了。2、一般情况下可以扩展负责人的功能,让负责人的功能更强大,从而让客户端的操做更少些。解放客户端。3、自述历史模式,这个就是把发起人,负责人写在一个类中,平时的应用中这种方法比较常见。”