致我们工作中的设计模式之备忘录模式
《大话设计模式》中是以打游戏,打怪没过关又从一个特定的节点开始重新打怪引入记录状态这个话题的,相信打过游戏的同学都不陌生,哪怕是玩连连看,找茬,和手游塔防游戏的同学都会遇到这个问题,我们打怪死掉了,并没有从头开始来,而是从中间某一个点开始重新再来,这个就需要游戏的程序来记录游戏的当前状态,以便从这个状态再重新开始。
其实这个话题对谁来说都不陌生,从大的方面来说,电商的购物车就是一个状态记录机制,它记录了当前这个会员或者使用者,在这个平台的购物情况,一般电商在登录后向购物车放入几件商品后,退出或者几天后登录,我想购物车中的商品还是存在的,也就是说你的这次购物旅程可以接着上次再来。对于做手机应用的同学可能更有感触了,操作系统本身就引入了一个里程碑的概念,我不知道windows phone 8 现在是怎么设计的,wp7在最小化一个任务的时候,就是采用墓碑机制,将当前任务在内存的情况记录下来,在下次再重启这个任务的时候,再将这个任务加载到内存,形成原有断点前的状态。
流程机制如下:
在做流程开发控制的时候,我们会经常遇到任务的状态记录机制,说到流程控制,我的脑海中第一闪现出来的就是OA系统开发,OA的核心个人认为就是流程控制和流程的自定义化,解决了这个问题我认为就能开发一个优秀的OA系统出来。微软针对流程控制专门推出了WF,图形化进行流程的控制,做OA开发的同学建议去看看了解。
说个我工作中的实例,我三年前给某个某个政府机关开发内部使用的OA系统的时候,遇到这样一个需求,当前的文件在进入某个节点后,可能会进行会签,也有可能不会进行会签,这个文件的下步流程是未知的,需要在另一个文件处理完成之后才能确定,而这个决定的节点什么时候会发生不知道。我想在这里使用设计模式的备忘录模式是最好不过的了,当然这里如果是实际的项目肯定需要建一张或者几张表来解决。我们在这里,设计一个记录公文的储存的类做实例。
首先假设有一个File公文类
代码实现如下:
public class File { public string FileID { get; set; } public string FileName { get; set; } public DateTime FileDatetime { get; set; } public string FileContent { get; set; } public FileStatus SaveFile() { FileStatus fs = new FileStatus(); fs.FileID = this.FileID; fs.FileContent = this.FileContent; return fs; } }
再次假设有一个状态类:
代码实现如下:
public class FileStatus { public string FileID { get; set; } public string FileContent { get; set; } }
代码实现如下:
最后假设有一个状态操作类:
代码实现如下:
public class FileOperator { public FileStatus File { get; set; } }
三者如何实现备忘录模式呢,看运行实例代码:
class Program { static void Main(string[] args) { File file = new File(); file.FileID = Guid.NewGuid().ToString(); file.FileName = "name"; file.FileContent = "XXXX"; file.FileDatetime = DateTime.Now; FileOperator foperator = new FileOperator(); //记录状态 foperator.File = file.SaveFile(); //继续File类的操作 file.FileContent = "change FileContent"; Console.WriteLine(file.FileContent); //恢复File类的状态 file.FileContent = foperator.File.FileContent; Console.WriteLine(file.FileContent); } }
运行结果:
最后,说点题外话,如果这里没有FileStatus类,或者只是直接记录一个File类,在保持状态的时候直接将当前File类的对象保存到状态类中,状态类中一个File属性储存,然后File继续操作,再从状态类读取File类对象,可不可以实现呢,如下代码:
//错误代码 foperator.SFile = file;
这样处理的话肯定是实现不了的,这个涉及到C#面向对象语言基础的只是,就是对象引用,File类对象和状态类的引用了同一个对象,是堆栈上来说,是同一个托管堆。
最后附上我的源代码:https://files.cnblogs.com/aspnetdream/ModelPro_Memento.rar