我正在开发一个采用 MVP 模式的应用程序。它仍处于开发初期,所以我仍然有机会批判性地反射(reflection)不同的设计选择。
模型 由一些结构和一些对它们进行操作的 API 函数组成,为了清楚起见,假设这是模型:
struct ComplexNumber {
double real;
double imag;
};
Complex_Add(ComplexNumber x, ComplexNumber y);
Complex_Mul(ComplexNumber x, ComplexNumber y);
然后是 View 。我在这里只使用原始类型。
class IComplexView {
public:
virtual double GetReal1() = 0;
virtual double GetImag1() = 0;
virtual double GetReal2() = 0;
virtual double GetImag2() = 0;
// Setters snipped
};
现在在 Presenter 中,据我所知,我有一些用于 View 到模型和模型到 View 数据转换的方法。我通常有一个 ReadView() 和一个 UpdateView() 方法。所以演示者的那部分看起来非常接近于此:
class ComplexPresenter {
ICopmlexView view;
ComplexNumber x;
ComplexNumber y;
// ...
static void ReadView() {
x.real = view.GetReal1();
x.imag = view.GetImag1();
y.real = view.GetReal2();
y.imag = view.GetImag2();
}
}
UpdateView()
将是相反的方式,以便从模型填充 View 。
有了这个设置,问题是: 除了上面的直接方法之外,是否有一些“聪明”的方法可以将 View 中的变量/属性绑定(bind)到模型中的变量/属性?
我看到的问题是为移动数据而添加的代码量相对较大。首先我们在 IView 中有访问器,然后是 ReadView() 和 UpdateView() 方法。我认为脚本可以连接到构建事件并自动生成所有这些代码,但我希望有其他我没有注意到的替代方案。
另一种方法是完全放弃 MVP,或者更具体地说,放弃 Presenter,只进行 UI<->Logic 分离,仅此而已。明显的缺点是更强的耦合,但另一方面,它可能会产生明显更少的代码量。
最佳答案
您描述的 MVP 变体可能被称为 Passive View
- 查看 Martin Fowler's entry about it here .它的缺点确实是有很多样板代码来同步模型和 View 。使用一些数据绑定(bind)
机制的替代方案是Supervising Controller
或 Presentation Model
(aka View Model
) .
drop the presenter, and just have a UI<->Logic separation and that's it
这里的一个危险是绑定(bind)机制可能无法处理复杂的情况
一般来说,考虑这两种解决方案:
Presentation Model
可以使用两层绑定(bind):view-to-presentation-model 和 presentation-model-to-domain-model 绑定(bind)。它保持较低的耦合度,但实现这两种机制本身可能很乏味。Supervising Controller
使用 view-to-domain-model 绑定(bind),它本身只处理绑定(bind)机制无法处理的复杂情况,因此您可以充分利用两个世界。
关于c++ - 在 MVP 中各层移动数据的众所周知的方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15523780/