创建外部数据结构更新程序UI的有效方法

时间:2015-01-11 12:21:58

标签: c# oop design-patterns

我有一个包含很多属性的类。其中一个需要编辑特殊的UI。 用户可以在UI中按此编辑到该属性,然后他进行更改并按“确定”或“取消”

e.g。

class A{
    private List<Employee> employees;

    public void EditMyEmployees(){
        EmployeeEditorForm editor = new EmployeeEditor(employees);
        if(editor.ShowDialog() == DialogResult.OK){
           employees = editor.GetEditedEmployeesList();
        }
    }
}

上一代码中的问题是编辑器具有对员工列表的引用的副本

当编辑器在List中进行任何编辑时,它将反映在原始对象中。 因此,按OK或取消将产生相同的效果(对象已更新),无需执行步骤

employees = editor.GetEditedEmployeesList();

我知道在发送给编辑器之前为employees数组制作深层副本将解决问题,但我认为这不是有效的方法

我正在寻找能够以更好的方式实现这一目标的设计模式。

2 个答案:

答案 0 :(得分:1)

您不一定需要深入复制整个集合。您只需要跟踪已更改的元素。在EmployeeEditor中,使用三个列表(List<Employee>来跟踪:

  1. 添加员工
  2. 已移除员工
  3. 变更员工
  4. 取消后,您需要删除&#34;添加&#34;项目,添加&#34;删除&#34;项目,并将更改的项目替换为其原始状态。

    请注意,更改后的员工列表需要保留对象原始状态的副本。如果Employee类具有某种唯一ID,则可以匹配该ID。否则,&#34;改变&#34; list必须是List<Tuple<Employee, Employee>>,以便您可以存储匹配的项目。

    另请注意,当员工列表中发生更改时,您还需要对这三个列表进行必要的更改。例如,如果添加了一个新员工然后将其删除,您还需要从&#34;添加&#34;名单。或者员工可能会被更改然后被删除,在这种情况下,您还需要从&#34;更改&#34;名单。

    说完这一切之后,如果我是你,我会根据预期的用例和真正的性能问题(不是预期的性能问题)做出决定。简单地深度复制您的集合很可能是最简单且最不容易出错的方式。

答案 1 :(得分:1)

此处涉及两种更改:(1)更改列表(添加/删除)和(2)更改列表中的各个元素(本例中为员工)。

现在,部分问题来自OK / Cancel的语义。如果您将这两个按钮的范围限制为第二种类型的更改(即更改列表元素),您将能够通过此特定操作的确认对话框处理删除(“删除此类等”? )。对于Addition,您不需要任何特殊内容,只需在列表中添加一个新元素即可。如果用户改变主意,他们仍然可以使用“删除”操作。

对于特定元素(第二类)的更改,您可以使用注释中提到的命令模式。更简单地说,您可以为编辑器显示的所有字段初始化临时变量。当用户修改某些值时,编辑器将更新相应的临时值。如果用户按下取消,您将忘记这些更改(或从元素重新初始化它们)。如果用户按Apply(是的,您还应该包括Apply按钮),现在将每个临时值写入相应元素的属性。如果用户点击OK,您将应用并关闭。