The conception, birth, and first steps of an application named Charlie

Subscribe: Atom or RSS

The Presenter Object

by Alister Jones (SomeNewKid)

In the last weblog entry, I said that I would describe how an entity such as an Article gets onto the page. I spent time describing the business objects involved in the process, but I did not really describe how the Container object gets and presents an entity. I’ll do that in this weblog entry.

In the first instance of Charlie, I created a class named an Applet. This class inherited from ASP.NET’s UserControl class, and exposed an EntityId property. Charlie’s equivalent of the PageEngine would “ask” the Container to give it an Applet. The Container object then set the Applet’s EntityId property, thereby telling the Applet which entity it is to display. For example, an ArticleApplet would be a UserControl that includes a Title Label, a Summary Label, and a Content Label. The ArticleApplet looks at its EntityId property, which was set by its Container, to learn which Article entity to load up. After it has obtained the corresponding Article, it uses the article’s Title, Summary, and Content properties to populate the corresponding Label controls.

Since an Applet inherited from the UserControl class, the PageEngine simply dropped it onto the page, allowing the ASP.NET process to do its thing. This Applet approach proved to be a very simple way of displaying entities such as an Article. If it was simple, and if it worked, why did I change it?

For a simple item of content such as an Article, the above approach was adequate. However, for more complex content, such as a collection of blog entries which exposes Atom or RSS feeds, and accepts and presents comments from visitors, the approach was too simple. The UserControl would become very complex, accepting far too many responsibilities for an interface element. What was missing was the Controller part of the Model-View-Controller pattern.

I still liked the simplicity of the Applet approach, but I wanted to introduce the flexibility provided by the MVC pattern.

I started by renaming the Applet class as the View class. This was a simple change that formalised the part played by the UserControl-based object in the MVC pattern. Whereas the earlier ArticleApplet object had many responsibilities, including presenting an article and controlling actions such as a visitor adding a comment to the article, the new ArticleView object was responsible only for presenting the article.

The next step was to introduce the Controller object. The responsibility of the Controller object is act as the middle-man between the View (in the Presentation Layer) and the Managers (in the Business Layer). Without the Controller, the View needs to talk directly to any number of different Managers (to present an Article might require the View to talk to an ArticleManager, a CommentManager, and an AuthorManager). With the Controller in place, the View is allowed to stick to its two main responsibilities: to present the Model to the user, and to interpret actions from the user.

Is this a “true” implementation of the Model-View-Controller pattern? Hell, no; it’s not even close. However, this simplified implementation does what I wanted: the UserControl-based View object is freed from knowing about which Managers may need to become involved. All the View knows about is the Model it is to present, and the Controller it is to tell about any user actions.

Only two questions remained to be answered. First, which object would be responsible for creating this trinity of a Model object, a View object, and a Controller object? Second, how would these three objects be “packaged”?

Now, which object would be responsible for creating the package of a Model, View, and Controller? The first option would be to make the Container responsible, since this is the object that the PageEngine talks to when it comes time to place the UserControl-based View objects onto the page. However, this would give the Container a whole different set of responsibilities, which adversely affects its cohesion. To avoid complicating the Container object, I decided to introduce a new little factory class, and make the factory responsible for packaging up a Model, a View, and a Controller. My initial instinct was to call this class an MvcFactory. But, not only was this clumsy, it would become inaccurate if later developments to Charlie meant that the MVC pattern was replaced by some other approach. So, I scribbed down some alternative names and settled upon calling this class a Presenter. To my mind, having an ArticlePresenter and a WeblogPresenter would nicely balance the existing ArticleManager and WeblogManager.

The other question was how the Model, the View, and the Controller would be “packaged” and returned to the PageEngine. The Presenter could return the three objects separately, and leave it to the PageEngine to tie them together. That was a viable option, but it was more complex than the existing solution where the Container returned a single UserControl-based object that the PageEngine could drop on the page. So, yet again following the guideline that simple is better than complicated, I decided that the UserControl-based View object would comprise its Model and its Controller, so that the PageEngine only ever sees an incoming View, and never needs to know that the View represents an MVC “package”. Even better, it supports the possibility that sometimes the View will be a dirt-simple UserControl, with no Model and no Controller. So not only was this approach simpler, it was more flexible, too.

So there you have the description of how a little more of Charlie’s architecture has been designed:

by Alister Jones | Next up: The Craft of Web Design

0 comments

----