MVP 中的 View 逻辑放在哪里?
Where to put View logic in MVP?
所以我在 ASP.NET 网络表单中实施 MVP。
我需要能够根据某些数据的状态更改标签的颜色。
我的第一次尝试:
class Presenter
{
...
_view.IsStatusTrue = true;
}
class View
{
bool IsStatusTrue
{
set
{
if(value)
{
lbl.Text = "Status is true :)";
lbl.CssClass = "trueClass";
}
}
}
}
我的问题:这个逻辑应该在 Presenter 中吗?
class Presenter
{
...
if(status == true)
{
_view.LblCssClass = "trueClass";
_view.StatusText = "Status is true :)";
}
}
您的 post 标题确实是 self-answering,这是观点责任。我在Java开发了一个家宠MVP框架项目,框架的核心是platform-independent,我使用框架的应用也是。这让我有许多针对目标 platform/apps 视图的实现:Swing(类似于 .NET 世界的 WinForms)、GWT(Java 到 JavaScript 基础结构)、JSF(~ASP.NET MVC)、Android、JavaFX (~WPF)、Lanterna(text-mode 用户界面)和纯 CLI(command-line 界面)。将您的演示者想象成完全 platform-independent。从这个角度来看,你的第一个例子比第二个好。它给出了什么:
- 这意味着视图不会显示它将如何报告状态。这让演示者对视图的了解尽可能少。一个简单的
boolean IsSuccessful{ set; }
确实足以报告状态。如果你泄露它的组件,那么你就真的违反了封装。
- 如果您的演示者是 platform-independent,您可以在您的平台上轻松 unit-test 他们不启动目标运行时,甚至不引用目标运行时库,因此它们是纯粹的。在这种情况下,您只需要模拟您的视图。
- 您可能希望将您的一些基本代码移植到另一个运行时,不一定 ASP.NET。比方说,WinForms。引入你的第二个例子是行不通的(例如
trueClass
不能应用于 WinForms,对吧?)。只需考虑以下代码:
public sealed class CliView
: AbstractCliView, // just an example, it might containt CLI-related stuff
IStatusView {
public boolean IsSuccessful {
set {
Console.ForegroundColor = value ? ConsoleColor.Green : ConsoleColor.Red;
Console.WriteLine(value ? "success" : "FAILURE");
Console.ResetColor();
}
}
}
这是可能的,因为在第一种情况下,您封装了如何视图是如何实现的,而不是透露实现细节。如果有一天你想支持音频接口怎么办? :)
public class Presenter
{
bool _status;
IView _view;
public Presenter(IView view)
{
_view = view;
if (_status)
{
_view.LabelColorCode = "#c2d8ff";
_view.LabelText = "Status is true";
}
}
}
public interface IView
{
string LabelColorCode { set; }
string LabelText { set; }
}
所以我在 ASP.NET 网络表单中实施 MVP。
我需要能够根据某些数据的状态更改标签的颜色。
我的第一次尝试:
class Presenter
{
...
_view.IsStatusTrue = true;
}
class View
{
bool IsStatusTrue
{
set
{
if(value)
{
lbl.Text = "Status is true :)";
lbl.CssClass = "trueClass";
}
}
}
}
我的问题:这个逻辑应该在 Presenter 中吗?
class Presenter
{
...
if(status == true)
{
_view.LblCssClass = "trueClass";
_view.StatusText = "Status is true :)";
}
}
您的 post 标题确实是 self-answering,这是观点责任。我在Java开发了一个家宠MVP框架项目,框架的核心是platform-independent,我使用框架的应用也是。这让我有许多针对目标 platform/apps 视图的实现:Swing(类似于 .NET 世界的 WinForms)、GWT(Java 到 JavaScript 基础结构)、JSF(~ASP.NET MVC)、Android、JavaFX (~WPF)、Lanterna(text-mode 用户界面)和纯 CLI(command-line 界面)。将您的演示者想象成完全 platform-independent。从这个角度来看,你的第一个例子比第二个好。它给出了什么:
- 这意味着视图不会显示它将如何报告状态。这让演示者对视图的了解尽可能少。一个简单的
boolean IsSuccessful{ set; }
确实足以报告状态。如果你泄露它的组件,那么你就真的违反了封装。 - 如果您的演示者是 platform-independent,您可以在您的平台上轻松 unit-test 他们不启动目标运行时,甚至不引用目标运行时库,因此它们是纯粹的。在这种情况下,您只需要模拟您的视图。
- 您可能希望将您的一些基本代码移植到另一个运行时,不一定 ASP.NET。比方说,WinForms。引入你的第二个例子是行不通的(例如
trueClass
不能应用于 WinForms,对吧?)。只需考虑以下代码:
public sealed class CliView
: AbstractCliView, // just an example, it might containt CLI-related stuff
IStatusView {
public boolean IsSuccessful {
set {
Console.ForegroundColor = value ? ConsoleColor.Green : ConsoleColor.Red;
Console.WriteLine(value ? "success" : "FAILURE");
Console.ResetColor();
}
}
}
这是可能的,因为在第一种情况下,您封装了如何视图是如何实现的,而不是透露实现细节。如果有一天你想支持音频接口怎么办? :)
public class Presenter
{
bool _status;
IView _view;
public Presenter(IView view)
{
_view = view;
if (_status)
{
_view.LabelColorCode = "#c2d8ff";
_view.LabelText = "Status is true";
}
}
}
public interface IView
{
string LabelColorCode { set; }
string LabelText { set; }
}