为什么在Silverlight应用程序中应该使用MVVM模式?

9
我想知道为什么我们应该使用MVVM来实现Silverlight应用程序。它有哪些优点?
除了单元测试ViewModel之外,我们还有其他原因。
以下是我对人们通常提到的一些优点的问题:
1.松耦合:当我们使用MVVM时,视图依赖于ViewModel而不是视图,为什么它是松耦合的?
2.如果我在代码后台提供公共方法,它们也可以提供可重用性。

如果您在代码后台提供属性和命令,并使用“this.DataContext = this;”进行绑定,则它也是一个视图模型。只是不要使用类似“this.firstNameTextBlock.Text = this.CurrentItem.FirstName;”的代码。 - vortexwolf
8个回答

4
好的,视图模型的单元测试能力是一个显著的优势,所以你会错过这个好处。至于其他两个方面:
松耦合
是的,视图确实依赖于视图模型。它们必须以某种方式连接才能完成应用程序的功能。因此,它们不能解耦。唯一的选择是紧密耦合、松散耦合或介于两者之间。使用MVVM,你的视图模型与你的视图的交互非常有限:基本上只有对象、属性和命令。将此与在代码后台中执行所有操作进行比较,在那里视图及其控件基本上是不可分离的。
重复使用
如果你的代码后台中的任何代码足够可重用,值得成为公共部分,那么可以将其从代码后台中取出并放入通用类中。问题是,在此之后剩下的部分就无法重用了。
如果你不想深入研究MVVM,那么你可以通过专注于数据绑定来获得一些MVVM的好处。在学习数据绑定的好处之后,你可以重新考虑MVVM的其他好处。

4
我们不会为ViewModel进行单元测试。
在MVVM中,不仅仅是要对ViewModel进行单元测试。理想情况下,您的VM应该非常薄,并且只有视图需要的属性。因此,实际上并不需要对VM进行测试。
但是,如果没有VM,如何跨层执行功能/功能测试呢?在Silverlight中,为了方便测试,您应该使用命令,而不是在代码后台文件中编写代码。这样,您可以在单元测试时模拟按钮点击和其他GUI事件。使用MVVM模式以及命令,您可以测试所有C#代码(而不是xaml),直到UI(转换器、VM等)。
如果我在代码后台提供公共方法,它们也可以提供可重用性。
不去详细解释为什么这是一种糟糕的设计,我想问你,这如何提供可重用性?如果您创建一个用户控件,则代码后台类是控件?您想创建控件的实例并使用它们吗?这就好像在说为什么我们需要成员方法,我们可以只创建公共静态方法并访问它们。我坚信,如果我们不想使用WPF/Silverlight提供的自动绑定,那么最好不要使用这些技术。为了充分利用绑定的所有能力,MVVM至关重要。
为什么它是松散耦合?
VM在很大程度上是视图的一部分。它与视图并不解耦。正如我所说,您的VM应该尽可能薄,并且只有视图需要的公共属性。您的业务逻辑将与您的视图(和VM)解耦。

1

我可以回答如何使用MVVM模式。

MVVM在以下情况下更好:

1. 如果多个控件与单个属性绑定。

MVVM:

<TextBlock x:Name="text1" Visibility="{Binding IsSomePropertyTrue, Converter={StaticResource VisibilityConverter}"/>
<TextBlock x:Name="text2" Visibility="{Binding IsSomePropertyTrue, Converter={StaticResource VisibilityConverter}"/>

我可以快速添加类似的控件或删除现有的控件。

与代码后台相比:

public string IsSomePropertyTrue
{
    set
    {
        //...
        text1.Visibility = value;
        text2.Visibility = value; 
    }
}

使用单一转换器代替多个转换器

public Brush StateColor { get { if (this.State == State.Edited && this.IsPriority) return new SolidColorBrush(Color.FromArgb(255, 0, 255, 0)); //... } }  

<sdk:DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <TextBlock Background="{Binding StateColor}" Text="{Binding State}"/>
    </DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>

3 作为 ListBox 或 DataGrid 等控件中的项模型。例如,如果我想创建一个带有每个项旁边的删除按钮的项目列表,我将创建一个 ItemView 控件和一个 ItemViewModel 类。

<ItemsControl ItemsSource="{Binding SomeItems}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <view:ItemView DataContext="{Binding}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

将数据从一个视图复制到另一个视图:

public JournalEntryViewModel(SalesOrderViewModel vm) {}

5个ViewModel可以继承CLR类并实现接口(INotifyPropertyChanged或INotifyDataErrorInfo)。

此外,我使用MVVM来用命令或属性替换事件。使用ViewModels强制按照易懂的名称调用属性。


1

1

我是WPF的早期采用者,我可以告诉你我为什么选择了MVVM(这也更或多或少适用于Silverlight)。对于我正在工作的项目,我必须创建一个屏幕,允许用户订阅系统内的通知。这是一个3步骤的过程:

  1. 用户必须搜索他们想要收到通知的项目
  2. 他们必须选择该项目并填写有关订阅的其他选项
  3. 系统必须提供摘要并允许用户确认或编辑订阅。

在第一次实现功能后(没有使用MVVM),我被告知我们需要从搜索中排除用户已经订阅的项目。

在进行修复后,我被告知我们需要根据选项为用户提供订阅的实时预览。

那时候,我开始注意到如果我不必处理UI而改变逻辑,一些这些更改可以被提取出来并变得更容易。我从未有意地遵循MVVM,但我意识到我所做的抽象与MVVM模式非常相似。

这就是为什么我推荐使用这种模式。它通过将 UI 逻辑与 UI 本身分离,简化了更改驱动 UI 的逻辑的任务。我还建议您在需要时再实施它。使用 MVVM 是有成本的,但这个成本可以摊销到更改 UI 逻辑的成本中。


1

没有MVVM,你的Silverlight应用程序代码很快就会变成难以管理的混乱


0

MVVM 中也有动态自动绑定十分有趣。

想象一下,您的视图模型具有以下属性:bool IsFirstNameVisible、bool IsFirstNameEnabled、string FirstName、double FirstNameWidth等。

在 XAML 文件中,您定义了 x:Name="FirstName" 的 TextBox,并调用您的动态 MVVM 绑定器。它通过反射检查您的视图模型类,查看您定义了哪些属性,并动态地将它们绑定到具有相同名称的控件的类似属性上,如果需要,应用值转换器。

在这种情况下,您可以获得非常干净的 XAML,而不需要使用长达一公里的数据绑定表达式和转换器。

这就是我的 MVVM 库所做的。


0

关注关注点。分离关注点。

忘记单元测试(我喜欢它;但这不是重点)。忘记可重用性(你真的会重复使用视图模型吗?不,让我们现实一点)。

这是关于分离关注点并将代码和逻辑放在它们应该在的地方。整个想法是可维护性;能够随着时间的推移对代码进行更改,而不会破坏其他东西,也不会使整个代码变成一堆混乱的代码。

MVVM,如果做得正确,可以将您的代码分成有意义的逻辑部分,并允许轻松重构和更改应用程序的要求。当您需要进行更改时,更容易找到何处。尝试编写任何半复杂的应用程序,然后将其保持不变一个月,然后回来尝试进行重大更改。经过合理结构化的应用程序并巧妙地使用MVVM后,即使在停工期后,也更容易理解,并且更容易进行更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接