Interface 模型视图演示器-如何在IView交互中实现复杂属性

Interface 模型视图演示器-如何在IView交互中实现复杂属性,interface,view,mvp,presenter,Interface,View,Mvp,Presenter,我发现很难理解如何最好地实现非简单类型的“IView”接口属性,我想知道其他人是如何在模型视图演示器应用程序中实现这一点的 我读过的文章都很好,但没有一篇文章能够处理更复杂的视图,其中的列表属性属于接口类型,表示域模型中的类,例如IPerson或IName等 我将尽可能简要地概述一个情景 假设我需要一个视图来最终保存一个名称列表,每个名称列表包含3个属性“Forename”、“姓氏”和“Title” 通常我会有一个域模型,它的类名为'Name',具有3个属性。此域模型将实现一个名为“IName”

我发现很难理解如何最好地实现非简单类型的“IView”接口属性,我想知道其他人是如何在模型视图演示器应用程序中实现这一点的

我读过的文章都很好,但没有一篇文章能够处理更复杂的视图,其中的列表属性属于接口类型,表示域模型中的类,例如IPerson或IName等

我将尽可能简要地概述一个情景

假设我需要一个视图来最终保存一个名称列表,每个名称列表包含3个属性“Forename”、“姓氏”和“Title”

通常我会有一个域模型,它的类名为'Name',具有3个属性。此域模型将实现一个名为“IName”的接口(在单独的“接口”类库中)

现在,在我的“Interaces”库中的“Views”命名空间中,我有一个名为“IViewNames”的接口。这是任何希望最终持久化名称列表的视图都将实现的视图接口

如何定义这个“IViewNames”接口让我感到困惑。如果我给它一个这样的属性:

public List<IName> Names {get;set;}
公共列表名称{get;set;}
然后,我实现的具体视图最终将有一个复杂的属性“Names”,它需要一个“getter”,在视图上的字段中循环,以某种方式实例化“IName”的实例,设置其属性,在返回列表之前添加到列表中。“setter”将同样复杂,接收一个“INames”列表,并在视图上迭代设置字段

我觉得这打破了MVP方法的主要目标之一,MVP方法能够在没有任何具体视图实现的情况下彻底测试应用程序代码。毕竟,我可以轻松编写一个presenter,查看“View.Names”属性并将其发送到服务层,或者在从服务层接收“Name”对象列表时设置“View.Names”属性。我可以很容易地编写很多测试来确保一切正常,除了视图中的复杂属性

所以我的问题是,其他人如何处理IView属性,这些属性不是简单的类型,但实际上是域模型的类型?(很好,代表您的域模型的接口类型,因为我显然不希望从我的表示层引用到我的域模型层)

我非常确定有一种已知的技术可以优雅地实现这一点,它比我的示例方法更符合模型视图演示者的目标


提前感谢所有帮助过我的人。

我已经从我在网站上写的一篇文章中删除了这个解释

演示者查看通信 有两种样式用于使用我使用的演示者和模型中的数据填充视图。它们之间的唯一区别在于,您的视图与模型的耦合程度有多紧密。对于该示例,我们将以下内容作为我们的模型:

public class Person
{
    public int ID { get; private set; }
    public int Age { get; set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
    Public Genders Gender { get; set; }
}
方法1:使用模型 现在我们的视图代码:

public interface IEmployeesView
{
    void ClearList();
    void PopulateList(IEnumerable<Person> people);
}
public interface IEmployeesView
{
    void ClearList();
    void PopulateList(IEnumerable<Tuple<int, String> names);
}
这种填充方法在模型和视图之间产生了链接;在
PopulateList
中用作参数的Person对象

这样做的好处是IEEmployeesView的具体实现可以决定在其人员列表中显示什么,从
人员
上的任何或所有属性中进行选择

这种方法有两个缺点。首先,没有任何东西可以阻止视图调用
上的方法,这使得懒惰的代码很容易溜进。第二,如果模型从
列表
更改为
列表
,那么不仅模型和演示者需要更改,视图也需要更改

方法2:使用泛型类型 另一种方法填充依赖于使用
Tuple
KeyValuePair
和自定义类和结构:

现在我们的视图代码:

public interface IEmployeesView
{
    void ClearList();
    void PopulateList(IEnumerable<Person> people);
}
public interface IEmployeesView
{
    void ClearList();
    void PopulateList(IEnumerable<Tuple<int, String> names);
}
公共接口IEmployeesView
{
void ClearList();
void PopulateList(IEnumerable新元组(x.ID,x.FirstName+“”+x.LastName));
_view.ClearList();
_视图。大众列表(名称);
}
}
这种填充方法的优点是,模型可以自由更改,而无需更新视图,并且视图不需要决定显示什么。它还防止视图调用
人员
上的任何额外方法,因为它没有对它的引用


这种方法的缺点是缺乏强类型性和可发现性—很明显,
人是什么,
元组是什么,
不太明显。

我对MVP设计模式没有太多研究,但肯定会尝试一下

方法1:数据绑定

在这种情况下,还可以在IView中创建单个特性,并将presenter中的这些特性绑定到模型特性。这样,您的视图就不会变得复杂。由于UI中的值可以直接在模型中使用,所以体验是快速和无缝的。更改模型中的属性值将立即反映在UI中。对此,您可能必须使用NotifyPropertyChange事件

方法2:复杂类型

您可以尝试创建列表或元组来存储这些值,并在presenter中使用这些值。您可能必须使用事件或操作来反映模型到视图的值,反之亦然

如果对你有帮助,请告诉我。谢谢