1

为什么说 Memento 在不违反封装的情况下完成了它的工作,而我可以实现简单的方法但又不违反封装?备忘录有什么用?我有一个示例程序,它将在用户按下保存按钮时保存学生详细信息,并在用户按下然后撤消按钮时撤消操作。
下面的示例代码是不使用 Memento 模式的实现:
Student.java

public class Student
{
    private String name;
    private String gender;
    private int age;
    private Contact contact;

    public Student(String name, String gender, int age, Contact contact)
    {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.contact = contact;
    }
    //getter and setter
}

主.java

public class Main extends javax.swing.JFrame implements DocumentListener
{
    private Student sCopy, student;

    private void btnUndoActionPerformed(java.awt.event.ActionEvent evt)                                        
    {                                            
        txtName.setText(sCopy.getName());
        txtGender.setText(sCopy.getGender());
        txtAge.setText(sCopy.getAge() + "");
        txtPhone.setText(sCopy.getContact().getPhoneNo());
        txtEmail.setText(sCopy.getContact().getEmail());
        txtAddress.setText(sCopy.getContact().getAddress());
        student = sCopy;
    }                                       

    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt)                                        
    {                                            
        sCopy = student;
        Contact c = new Contact(txtPhone.getText(), txtEmail.getText(), txtAddress.getText());
        student = new Student(txtName.getText(), txtGender.getText(), Integer.parseInt(txtAge.getText()), c);
    }    

上面的示例代码完美运行,但为什么我们需要 memento 而它可以如此轻松地完成呢?我没有看到上面的实现在哪里破坏了封装......

总结
上面的方法是否违反了封装?如果不是,那么 Memento 的目的是什么?允许多次撤消?虽然上面的实现不允许多次撤消,但也可以在不应用备忘录的情况下完成。

4

2 回答 2

1

在您的方法中,引用的实例sCopy公开了所有可用的设置器。如果它们用于更改值,撤消将无法正常工作。这违反了封装,因为撤消的正确性取决于类的客户端。

memento 对象不会公开任何(变异)方法,并且始终可以安全地用于准确恢复对象的状态。

于 2017-06-21T17:11:21.457 回答
0

上述方法是否违反封装?

大概。我们会看到。

首先,选择一些违反封装的定义:

拥有 getter 和 setter 本身并不会破坏封装。打破封装的原因是每个数据成员(每个字段,用 java 术语)都有一个 getter 和一个 setter。这距离公开所有数据成员仅一步之遥。

是你的情况吗?您在 Student 中有一些 getter 和 setter,可能会暴露一些在您的应用程序中不需要的方法,例如genderor name。即使它们是必要的,将来可能会在 Student 中出现新的字段,并且您的解决方案在不违反封装的情况下将无法工作。

允许多次撤消?

这是优点之一。

虽然上面的实现不允许多次撤消,但也可以在不应用备忘录的情况下完成。

是的,但可能违反封装。

于 2017-06-21T23:47:06.487 回答