views:

295

answers:

3

I'm trying to understand how to use Passive View correctly. It seems to me that every examples I look at on Passive View breaks the Law of Demeter :

//In the presenter code
myview.mytextfield.text = "whatever";

So what's a better implementation of Passive View?

+1  A: 

Okay, well, yes, that does break the Law of Demeter, which basically says that the interface to an object shouldn't reveal the implementation of the object. But then, the second one gives a helluva lot of hints to the implementation too.

I think it's time to ask if you have the right interface in general. What are these text fields? Who is setting them in the view? Shouldn't the view be asking the Model for data, instead of vice-versa?

Maybe you need the Observer pattern -- the Model keeps a list of interested parties and notifies them when its internal state changes.


Ah, that Passive View. Hadn't looked at that in a long while. Basically, I see two parts: one of them is that by making the Controller (not the model) drive all the updates, for (I presume) efficiency he exposes the specific field methods to update those fields. This does violate the Law of Demeter, which is, after all, only a "law" in some metaphorical sense, like Murphy's Law. It is usually a good idea, though. In this case, I'd redo the View and use it as a facade to wrap the updates to the individual field.

You don't need the Observer pattern though, because now you've got the Controller making all updates. It adds some complexity and error proneness to the overall code, because now you hve to write the Controller to make parallel updates.

Charlie Martin
You're right about the second. I don't use that either. Also, as far as I understand passive view, the view shouldn't be coupled with the model. It's the role of the presenter to pull data from the model and push it to the view. http://www.martinfowler.com/eaaDev/PassiveScreen.html
Subb
Also, I'm trying to understand the passive view pattern. I'm not using it for anything right now. I've edited the question to make it clearer.
Subb
+1  A: 

A better implementation would be to have an API between the Presenter and the View. The Presenter would push data to its View through a single method (defined in the View's interface). The View would manage the new input according to some internal logic.

Therefore, the Presenter does not have to know anything about the View and the Law of Demeter is safe.

Mexican Seafood
+4  A: 

First, the Law of Demeter, like most rules of programming, is more of a principle or guideline and there are occasions when the principle doesn't apply. That being said, the Law of Demeter doesn't really apply to Passive View because the reason for the law isn't a problem in this case.

The Law of Demeter is trying to prevent dependency chaining such as:

objectA.objectB.objectC.DoSomething();

Obviously if objectB's implementation changes to use objectD instead then it will break objectA's dependency and cause a compilation error. If taken to an extreme you wind up doing shotgun surgery any time the chain is disturbed by an implementation change.

In the case of Passive View

  • The presenter depends on an interface so the view's implementation can change as long as the interface remains the same.
  • The view usually exposes properties as generalized data types such as system types and collections. This allows you to make changes to the UI without affecting the presenter.
  • To the presenter the view appears as nothing more than a data structure, a place to retrieve and dump data. Since the view is pretty simple, the presenter shouldn't even be able to do dependency chaining.

So the example you gave would normally be implemented:

//from presenter
view.MeaningfulName = "data";

While the view would be something like:

//from view
public string MeaninfulName
{
    get
    {
        return someControl.text;
    }
    set
    {
        someControl.text = value;
    }

Hope this clarifies things a bit.

codeelegance