问题描述
我很开心,试图将我的头围绕一些MVP STUF,因为它与用户控件有关.我正在使用.net winforms(或与之接近的东西)和监督控制器模式(好吧,我想我是:).
用户控件本身是MVP应用程序的一部分(其视图,具有关联的演示者等).主持人总是首先启动,然后启动模型,然后查看(s).该视图构建了其UI,其中一部分将是新的UC,这是视图.
现在(表格)主持人需要了解UC主持人,但我认为它对观点的组成一无所知.例如,演示者不知道UC是表格控件集合的一部分,也不应.
此外,设计经验不应改变; IOW视图(表单)的开发器应该能够从工具箱中选择一个用户控件并将其放在表单上.
所以,我的问题.首先,我的假设上述正确吗?有点误导?弄乱? WTF您在想吗?
其次,是否正确(足够吗?)使表单视图调用UC视图,并且表格主持人调用UC主持人并具有一些机制来告诉UC视图其演示者是什么?这打破了我的"主持人第一"规则,但我不确定该怎么做.
任何其他想法,建议,评论都很乐意接受.
- nwahmaet
推荐答案
演示者应被视为演示层中的"自治状态".这意味着它负责确保对模型状态的观点的呈现是同步的.我提出这个问题的原因是因为MVP的"模式"常常在的教条观点中丢失,应该如何分开.这似乎是马丁·福勒(Martin Fowler)决定尝试尝试澄清MVP 模式周围的术语.
我最喜欢的MVP风味是被动视图,所以我的答案是基于此的.
i经常使用被动视图模式实现复合用户控制和表单.本质上有3种不同的配置:
- 层次结构中所有用户控件的主持人.使用接口将视图弄平.
- 复合树中每个用户控件的一个主持人.每个父母主持人都负责实例化和初始化其子女演示者.用户控件是在设计时创建的,并且能够在没有演示者的情况下(没有演示行为)运行
- 复合树中每个用户控件的一个主持人.所有演示者都松散地通过更高级别的控制器类耦合.控制器类负责构造演示者,对其进行接线并协调其事件.
尽管这对我来说是最后的解决方案(由于它的复杂性),但我认为最后一个选择是您正在寻找的解决方案.
其他推荐答案
在我正在处理的应用程序中,我已经在这个确切的问题上遇到了几个月的问题.我最近得出的结论是,在许多情况下,可能不可能在窗口和用户控制级别上应用MVP模式,而不会"破坏"模式.
我对此的想法是,用户控件是视图实现的一部分,主持人不应该知道视图实现内部发生了什么,这意味着窗口级的演示者扩展不应知道用户控制者的主持人,因此他们之间不应进行沟通,包括前者对后者的实例化.可以说,用户控件的演示者是窗口视图实现的一部分,因此窗口视图可以实例化用户控制主持人.但是它不能注入演示者所需的模型类,因为视图不应该意识到它们.
我认为我要得出的结论是,所有用户控件都是特定于视图的,因此应完全包含在较大模式的视图中.因此,他们没有自己的演示者……至少没有与控制实施本身捆绑在一起.取而代之的是,它们应通过在视图接口上暴露的直通字段间接地通过父窗口的主持人进行操纵.简而言之,用户控件不是通过其自己的接口来暴露于演示者,而是通过其父视图实现的通用通行接口.称其为"部分视图接口".
您的演示者可以包含可重复使用的子总统类的实例,该类仅适用于此部分视图接口以及模型的相关片段.这将使您避免重写演示者代码,以每次需要使用该控件时从模型中转换,并防止窗口视图需要了解该模型以将信息传递到控件的演示者.
这有效做到的是,它将用户控制作为模块与数据模型进一步分开.如果您将用户控制(整体上)视为视图实现的元素,这是有道理的.作为可重复使用的单元,它是一个视图功能,并且不应与您的数据模型相关.
其他推荐答案
您的问题是可以应用各种方案的一般性.
在这种情况下,我的猜测是您应该查看观察者模式.
您有一个使用该视图的任何接口.然后,当应用程序以这些接口的集合初始化时,它将自身注册.任何需要更新该视图的命令都会穿越该集合,并通知应更新每个视图.
与典型示例不同,视图将是用户控件.您具有使任何UI元素实现该接口的灵活性,因此除了用户控件外,还可以使用对话框,完整表格等.
最终记住用户控件不是视图,而是视图的实现.无论您采用哪种方案,都可以定义您想要的深度视图,并使用户控件实现该接口.
问题描述
I'm having some fun trying to get my head around some MVP stuf, as it pertains to User Controls. I'm using .NET WinForms (or something close to it) and Supervising Controller pattern (well, I think I am :).
The User Control is itself part of an MVP application (its the View and has an associated Presenter etc). The Presenter is always started first, and it starts the Model(s) and then View(s). The View builds its UI, part of which will be to NEW the UC, which is the View.
Now the (form) Presenter needs to know about the UC Presenter, but I'm thinking that it doesn't know anything about how the View is composed. The form Presenter doesn't, for instance, know that the UC is part of the form's Controls collection, nor should it.
Furthermore, the design experience should not be changed; IOW the dev of the View (form) should just be able to select a User Control from the toolbox and drop it on a form.
So, on to my questions. Firstly, are my assumptions above correct? Somewhat misguided? Messed up? WTF are you thinking?
Secondly, is it right (enough?) to have the form View invoke the UC View, and the form Presenter invoke the UC Presenter and have some mechanism to tell the UC View what its Presenter is? This breaks my "Presenter first" rule, but I'm not sure how else to do it.
Any other thoughts, suggestions, comments gladly accepted.
-- nwahmaet
推荐答案
A presenter should be thought of as "autonomous state" in the presentation tier. This means that it is responsible for ensuring that the view's presentation of the model's state is in sync. The reason I bring this up is because the "pattern" of MVP often gets lost in the dogmatic view of how things should be separated. It seems that this is one reason Martin Fowler decided to try to clarify the terminology around the MVP pattern.
My favored flavor of MVP is the passive view, so my answer is based off of that.
I implement composite user controls and forms very often using the passive view pattern. There are essentially 3 different configurations:
- One presenter for all user controls in the hierarchy. Flatten the view using an interface.
- One presenter for each user control in the composite tree. Each parent presenter is responsible for instantiating and initializing its child presenters. The user controls are created at design time, and are able to function without a presenter (with no presentation behavior)
- One presenter for each user control in the composite tree. All of the presenters are loosely coupled through a higher level controller class. The controller class is responsible for construcing the presenter, wiring them up, and coordinating their events.
Although it is a solution of last resort for me (because of its complexity), I think that the last option is the solution that you are looking for.
其他推荐答案
I've been running up against this exact problem for several months in an application I'm working on. The conclusion that I've very recently come to is that in many cases it might be impossible to apply the MVP pattern at both the window AND user control levels, without "breaking" the pattern.
My thought on it is that the user control is part of the view implementation, and the presenter should not know what is going on inside the view implementation, which means that the window-level presenter by extension should not know about the user control's presenter, and hence there should be no communication between them, including instantiation of the latter by the former. It might be argued that the user control's presenter is part of the window view implementation, and so the window view may instantiate the user control presenter. But it cannot inject the model classes that the presenter needs, because the view isn't supposed to be aware of them.
The conclusion that I think I am arriving at is that ALL user controls are view-implementation-specific, and so should be contained completely within the view silo of the larger pattern. As such, they don't get to have their own presenters... At least not bundled up with the control implementation itself. Instead they should be manipulated indirectly by the parent window's presenter, via pass-through fields exposed on the view interface. In short, the user control is exposed to the presenter not by its own interface, but rather via a common pass-through interface implemented by its parent view. Call this a "partial view interface".
Your presenter can then contain instances of a re-usable sub-presenter class which works only with this partial view interface, and the relevant pieces of the model. This will allow you to avoid re-writing the presenter code to translate from the model every time you need to use the control, AND it prevents the window view from needing to know about the model in order to pass info through to the control's presenter.
What this effectively does is it further separates the user control, as a module, from your data model. This makes sense if you think of a user control, as a whole, as an element of the view implementation. As a re-usable unit, it is a piece of view functionality, and no part of it should be tied to your data model.
其他推荐答案
Your questions is general that a variety of schemes could apply.
In this case my guess is that you should look at Observer Pattern.
You have a interface that anything that uses that view would implement. Then it would register itself when the application initializes with a collection of those interfaces. Any command that needs to update that view would traverse the collection notifying that each view should be updated.
Unlike typical examples the views would be User Controls. You have the flexibility of making any UI element implement that interface so you could use dialogs, full forms, etc in addition to your User Control.
Finally remember the User Control is NOT the view but the implementation of the View. Whatever scheme you adopt you can define what the View as deep as you want and have the User Control implement that interface.