views:

177

answers:

2

Hi All,

I just wanted to see if I could have your thoughts on the design of some work I am currently doing.

Here's the current situation - Basically:

  • I am developing a series of controls for our applications.
  • Some of these may be used in both WinForms and ASP.NET Web applications.
  • I am on a constant endeavor to improve my testing and testability of my code.

So, here is what I have done:

  • Created the core control logic in a class that has no concept of a UI. It simply raises events when things about it change. All data as stored as custom typed objects where it needs to be distinguished from others (e.g. I have a PagingControl where it has SelectedPage and PageNumber items).
  • I then created an abstract class to act as the interface for a rendering "engine". This ensures that any custom types used (and possibly added) to the core logic are handled by the engine. Following the above example, it contains an abstract method RenderSelectedPage.
  • I then created concrete implementations of the abstract rendering engine (e.g. ConsoleRenderingEngine, HtmlRenderingEngine etc.). This then handled the methods and rendered them to their respective UI's/Outputs as appropriate.

I found the following pro's and con's to this approach:

Pro's

  • It works. Quite well, its easy to implement a new rendering mechanism, all you do is subclass the abstract engine and render the output (which passes required references to you).
  • It's really seperates the UI from the core code, making it much easier to test.
  • Obviously due to the encapsulation of core/rendering logic, it's quite obvious where problems lie when they appear.

    Con's

  • It can look confusing/bloated. Even though there is not a massive amount of code in each class, there are 3x classes to get it to render to 1 output (1x core, 1x interface, 1x renderer). However, when creating the WinForms/WebForms controls it also means another classe (since one needs to sublcass Control as well as the AbstractRenderingEngine).

... OK so that's the only "con" I can really think of, and the main reason for this question ^_^

So,

What are your thoughts on this "pattern"? How would you change/improve it?


This question may get updated as more thoughts come to me, or clarity may be requested (I know it's a heavy read!).


Update

Thanks for the answers guys, funny you said MVP, I thought I had seen something like this somewhere but couldn't remember for the life of me what it was! As soon as I saw "MVP" I thought "dammit". :D

Thanks for the responses guys. I will study MVP more and see if I can improve what I have further.

+1  A: 

I might be really stupid, but that sounds very much like an MVP implementation?

Chris Canal
This made me slap myself on the forehead and think "dammit" (see update in Q). +1 :)
Rob Cooper
+2  A: 

From your description it's a bit like how I do MVP but with the events going the other way.

I usually have a very thin view that hides behind an interface and that knows nothing about the presenter. The view is the one who throws events on user actions. Usually all the view does is translate UI specific to primitives or sometimes value objects from the model (value object in a ddd sense, not .net structs) Sometimes I nest views for more complex situations and for reuse. UserControls sometimes have their own view and presenter structure. When you start doing nesting views and presenters instantiation of objects starts getting a lot of work so this is usually when I start looking for an IoC container.

The presenter knows about the view through it's interface and talks direcly to it. It reacts to view events and does most of the logic. The view and model are Di'd into the presenter so all the logic in it is testable.

Another approach I saw was where the view knew about the presenter and the presenter only knew about the view through the interface. This gets around having to raise events for view actions because the view can talk directly to the presenter. (I think this is what used to be called MVC in the smalltalk world) The presenter is still testable and this enables you to do databinding from the view to the presenter. I usually don't use databinding so for me this is not a big advantage. I to decouple stuff a bit more like in the first example.

Mendelt
Great comprehensive answer Mendelt. Thanks! :)
Rob Cooper