玩转C科技.NET

从学会做人开始认识这个世界!http://volnet.github.io

导航

《EssentialWF》(第一章 剖析WF 1.1.1书签)补充

《EssentialWF》Note(第一章 剖析WF 1.1.1书签)

归类:Code分析

第7-8页代码

Code

 

上面四段Code的目的是通过一系列的Class来完成一个可以中断并恢复的一个类似利用一个书签来保存读书的停顿点的状态。那么该如何看这个代码将变得比实现这段代码来说显得更加地重要。

关于Code(1-5)其实并不需要我们全部地理解它,我说的理解不是要你明白该如何做才能让其Compile通过,而只需要了解它是如何通过委托来完成这样一个将事务滞后处理的一个过程,也就是能从一定地状态中恢复去完成接下来的操作。

那么看这段程序我们要理解的最核心的思想,就是保存和恢复,并在恢复后能够有一个所谓的标志告诉接下来应该要做哪些动作,而这些动作和保存之前则应该是一脉相承的。

Code(5)类似一个Main的方法体,看其第三行openSesameProgram.Start(mgr);就是去“启动”这个芝麻开门的对象,并指定它的书签管理对象为mgr,那接下来呢,很自然我们要跳转到Code(3)中从Start入手。在系统给出了key之后,按照之前控制台版本中的操作,这时候我们应该做的应该是去输入一个key(ReadLine()),再比较这个key和系统给出的key是否相等。但是我们旧有的分析表明,这个ReadLine依赖于用户的input,如果用户不input,那么结果就是这个thread将一直停滞不前并始终占用着System Resourse。现在有了书签这个模型,我们应该做的就是去将这个书签插入到这个“页”中,并在下次“翻开”的时候,根据书签进行执行。

在Start的Parameter中有BookmarkManager mgr这样的一个管理者。(暂且不考虑为什么它是外部传入的)在我们的Start中我们向“管理器”添加了一个名字叫"read"的书签,并让它在再次找到这个书签的时候我们要执行ContinuteAt的方法(因此这里我们就可以先不考虑ContinuteAt的方法究竟干了什么……)

刚才我们一直提到的书签和管理器,分别由两个类来实现,Bookmark和BookmarkManager,我们此时应该明确的是这两个类的作用。首先Bookmark的作用是作为一个记录书签的作用,而且我们希望书签是可以被持久化的,那么这里的[Serializable]则变得很好理解,即可以轻松保存进持久存储设备,如数据库等。BookmarkManager必须具备管理多个标签的能力,对于管理职责的类来说,对一个"Team"进行管理,一般会有member的Add和Remove方法,这一点应该很容易理解。Resume方法则提供了对书签进行一个Execute的一个接口。正如mgr.Resume("read",str);则利用了"read"这KEY对书签进行了Query,并根据这个KEY所提供的书签所指定的委托(ContinuteAt)进行一些操作,至于payload则可以(暂时)全当忽略不计。

因此在执行openSesameProgram.Start(mgr);的时候,我们首先是指定了一个管理器给这个对象,并让其向这个mgr书签管理器添加了这么一个名字叫"read"的书签,并希望再次看到这个"read"的时候能够执行ContinuteAt方法体。

那么又回到我们最本质的问题了,我们这个时候要做的是什么呢?就是要输入一个数对其进行比较。string str = //obtain input则完成了这一点,在这里这个问题也就是转换成将我们的输入作为一个条件传递给书签,这样书签的所谓后续动作才能够根据这个condition进行后续的判断,不然没有任何的参数,也等价于没有任何的输入与ContinuteAt进行交互那么这个程序就失去了最初要实现的含义。(比对两个string是否相同)也正是如此我们引入了payload作为条件。从当前程序来讲,这里的payload的类型可以是string,但是从设计的角度讲这里可能会是一个相对复杂的对象,因此这里将其设置为object也是为了起到抛砖引玉的作用了。

mgr.Add(new Bookmark("read",ContinueAt));ContinueAt在这里则只是一个委托实例,从C++的角度去理解也可以看成是一个函数指针,那么它里面的Bookmark的Parameter则是在Bookmark的Constructor去完成了。(public Bookmark(string name,BookmarkLocation continuteAt);)

因此这个Resume则会是这样一个类似的代码:

public void Resume(string bookmarkName,object payload)

{

Bookmark bookmark = (Bookmark)this[bookmarkName];

if(bookmark != null)

{

bookmark.SetPayload(payload); //bookmarkName = "read",payload = input key

bookmark.ContinuteAt(bookmark);

}

}

bookmark.ContinuteAt(bookmark);看起来貌似很别扭,不过由于为了提供ContinuteAt实际函数的时候能够更好地利用参数(因为毕竟不是一个member function,而只是一个delegate)。

至此,这个Code的任务算是完成了。

posted on 2007-09-29 00:44  volnet(可以叫我大V)  阅读(719)  评论(2编辑  收藏  举报

使用Live Messenger联系我
关闭