【机房合作】——备忘录模式

          在做机房合作的时候,有两个功能可以用到备忘录模式,一个就是修改基础信息界面有一个取消修改的按钮,还有一个需求是验收的时候师傅提出的思路,就是当你的服务器坏了的时候,如何重启服务器还能继续原来的状态进行计算金额等一系列正常的工作,这个功能也可以通过备忘录模式实现。下边就来介绍一下备忘录模式到底是什么。。。

定义

备忘录(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态
个人理解:其实备忘录很容易理解,就是将当下的状态放到一个容器中,保存起来,当需要这个状态的时候,直接从容器中拿出这个状态重新赋给对象就好了。


UML图


【机房合作】——备忘录模式_第1张图片


      首先看Originator这个类,这个类里边封装了一个State的属性,还有两个方法,首先说CreateMemento,这个方法的作用就是实例化一个Memento的对象,并且把状态(state)传进去,这就需要Memento里边有一个构造函数来接收originator传入的状态。而第二个SetMomento的方法,就是恢复状态时用的,将Memento实例化出来的对象的状态重新赋给这个类的状态。在说Caretaker这个类,他其实说白了就是Memento的一个实体类,负责存放备忘录的信息。

       客户端如何调用呢?请看下边的代码

static void Main(string[] args)
{
	Originator o=new Originator(); //实例化发起人类
	o.State="on";  //开始状态为on
	o.Show();
	
	Caretaker c=new Caretaker();   //实例化备忘录实体
	c.Memento=o.CreateMemento();  //发起人类实例化备忘录对象,并通过构造函数,将状态保存在这个对象中
	
	o.State="off";   //这是状态发生改变
	o.Show();
	
	o.SetMemento(c.Memento);//调用发起人的恢复状态的额方法,参数是备忘录的对象,因为开始的状态保存在这个对象中
	o.Show();
	
	Console.Read();
}


       我们从客户端中可以发现,我们具体在备忘录中存放了哪些属性,在客户端是看不见的,这就体现了这个模式的一个良好的封装性,因为所有的属性都是封装到发起人(Originator)这个类中的,而我们有时又需要将一些属性保存到外部对象中,这就需要发起人这个类自身有读取的方法,这样才可以保证内部信息对外部来说是封闭的。


机房中的应用

         但其实在机房合作的过程中,封闭性做不到那么好,因为UI界面就相当于我们的客户端,就拿BasicData窗体举例,开始窗体从数据库获取到基础数据,并且显示到界面上,这就说明我们起始的状态就是通过界面获取的,UI层就相当于我们的发起人。所以说我们不能完全套用这个模式,但是作为练手也无妨。代码如下(修改学生信息窗体):有不合适的地方,希望大师们多多指点:


发起人类(Info)

 class Info
    {
       
        #region 需要保存的属性
        private string _department;
        private string _explain;
        private string _grade;
        private string _major;
        private string _sex;
        private string _Strclass;
        private string _studentName;
        private string _studentNo;

        public string Department
        {
            get { return _department; }
            set { _department = value; }
        }
        public string Explain
        {
            get { return _explain; }
            set { _explain = value; }
        }
        public string Grade
        {
            get { return _grade; }
            set { _grade = value; }
        }

        public string Major
        {
            get { return _major; }
            set { _major = value; }
        }

        public string Sex
        {
            get { return _sex; }
            set { _sex = value; }
        }

        public string Strclass
        {
            get { return _Strclass; }
            set { _Strclass = value; }
        }

        public string StudentName
        {
            get { return _studentName; }
            set { _studentName = value; }
        }

        public string StudentNo
        {
            get { return _studentNo; }
            set { _studentNo = value; }
        }

        #endregion

        public void GetInitState(StudentEntity studentinfo) //获得学生最开始的值,这个值UI界面传入的学生实体获得
        {
            this.Department = studentinfo.department;
            this.StudentName = studentinfo.studentName;
            this.StudentNo = studentinfo.studentNo;
            this.Sex = studentinfo.sex;
            this.Strclass = studentinfo.Strclass;
            this.Major = studentinfo.major;
            this.Explain = studentinfo.explain;
            this.Grade = studentinfo.grade;
        }

        public InfoStateMemento SaveState()//实例化备忘录,并且存入最初状态
        {
            return (new InfoStateMemento(StudentNo, StudentName, Sex, Department, Strclass, Grade, Explain ,Major));
        }

        public void RecoveryState(InfoStateMemento memento)  //恢复状态
        {
            this.StudentNo = memento.StudentNo;
            this.StudentName = memento.StudentName;
            this.Sex = memento.Sex;
            this.Department = memento.Department;
            this.Strclass = memento.Strclass;
            this.Grade = memento.Grade;
            this.Explain = memento.Explain;
            this.Major = memento.Major;
        }
    }


备忘录类

  public InfoStateMemento(string studentNo, string studentName, string sex, string department, string strclass, string grade, string explain,string major)
        {
            this.studentNo = studentNo;
            this.studentName = studentName;
            this.sex = sex;
            this.department = department;
            this.strclass = strclass;
            this.grade = grade;
            this.explain = explain;
            this.major = major; 
        }

        //因为此类不能对存入的属性进行修改,所以这里只有只读器
        public string Department
        {
            get { return department; }
        }
        public string Explain
        {
            get { return explain; }
        }
        public string Grade
        {
            get { return grade; }
        }

        public string Major
        {
            get { return major; }
        }

        public string Sex
        {
            get { return sex; }
        }

        public string Strclass
        {
            get { return strclass; }
        }

        public string StudentName
        {
            get { return studentName; }
        }

        public string StudentNo
        {
            get { return studentNo; }
        }

    }


备忘录实体

  class InfoStateCaretaker
    {
        private InfoStateMemento  memento;
        public InfoStateMemento Memento    //Memento属性
        {
            get { return memento; }
            set { memento = value; }
        }
    }


客户端调用

首先要实例化发起人和备忘录实体类(这两个要写在方法外),因为多次进行实例化的话,里边存的初始数据就没有了

 Info studentDan = new Info();
        InfoStateCaretaker stateAdmin = new InfoStateCaretaker();

    private void Cancel_Click(object sender, EventArgs e)
        {
            studentDan.RecoveryState(stateAdmin.Memento);//从状态中得到数据

            txtStudentNo.Text = studentDan.StudentNo;
            txtDepartment.Text = studentDan.Department;
            txtExplain.Text = studentDan.Explain;
            txtMajor.Text = studentDan.Major;
            txtStudentName.Text = studentDan.StudentName;
            txtClass.Text = studentDan.Strclass;
            cboSex.Text = studentDan.Sex;
            txtGrade.Text = studentDan.Grade;

        }

总结

       其实在机房中这个功能不用备忘录模式非常好实现,只要界面加载出来,将学生信息保存在学生实体中,当点击取消按钮,直接将实体中的值重新赋给窗体就行了,绕了这么大一圈就是想要了解了解备忘录模式的应用,我们在使用设计模式的时候,大多有一个感受,代码量增多,而且好处也没怎么体会到,这也许是我们用的地方不是那么的合适,或者说我们没有在继续的开发这个系统,当我们需要扩展出来一个功能的时候,就能体会到设计模式易于扩展的好处了,先学习先了解,不用考虑那么多就好了


你可能感兴趣的:(【机房合作】——备忘录模式)