Showing posts with label architectural patterns. Show all posts
Showing posts with label architectural patterns. Show all posts

Thursday, April 30, 2009

Tom's Patterns Cheat Sheet , Part 6 - The Decorator Pattern

This post is based mainly off of the GoF Patterns Bible, Design Patterns: Elements of Reusable Object-Oriented Software. The basic Decorator Pattern is this:



Basic Decorator Pattern
(Click on the diagram to open in a separate window)

The name of the pattern is very descriptive. It involves a main class that does most of the work, represented by the ConcreteComponent class above, and one or more Decorator classes that inherits from the same base class as ConcreteComponent (the abstract Component class in the diagram above), and also holds onto a reference to a Component class.

The Decorator classes delegate most of the real work to their Component class instance, but "decorate" its functionality by tacking on their own behavior.

Note that in the diagram above the abstract DecoratorComponent doesn't add a lot of value - it defines a way to pass the reference to the Component class to the decorators, and nothing else. When there's only a single Decorator you can simplify the diagram like so:



Simplified Decorator Pattern

In fact even when there are multiple Decorator classes the base Decorator class is often omitted, as is the case in the CryptoStream example from the .NET Framework, which is shown below.

The GoF book says that another name for this pattern is the Wrapper Pattern, but in my opionion "wrapper" is a loose term that applies to a number of patterns in which one object delegates most of its behavior to another, "contained" object. In particular, I'd say "wrapper" applies to the Decorator, Fascade and Adapter patterns, but not to the Proxy pattern because in that case the object you are delegating to is not conceived of as being "contained in" the proxy.

It's not terribly easy to find real-life examples of the Decorator Pattern. One of the examples given by the GoF is also the example given in this MSDN article that describes the Decorator Pattern, which is the Stream family of classes:



Decorator Pattern Example: A CryptoStream

In this example the CryptoStream class inherits from the abstract Stream class and is also given a Stream object reference, overrides the Write method, encrypts the bytes and then calls the Write method on the contained stream to write the encrypted bytes. In fact, if you use Reflector on the .NET Framework CryptoStream class you can see that it has actually been implemented using this pattern. The CryptoStream constructor takes a Stream reference:

public CryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode)
{
this._stream = stream;
...
}

And the Write method encrypts the buffer before writing it to the stream:

public override void Write(byte[] buffer, int offset, int count)
{
// Bunch of encryption goo...
this._stream.Write(this._OutputBuffer, 0, num3);
}

The Decorator Pattern can provide a very elegant means of composing the behaviors of objects at run time. In the example above, because CryptoStream is passed an abstract Stream object base class reference, it can operate on any type of stream: a FileStream, MemoryStream or any type of stream that you may create in the future. And because CryptoStream itself derives from Stream, it can be passed to other decorators. So if in the future a CompressionStream class were created, you could compose a FileStream that is encrypted and compressed, or a MemoryStream that is compressed by not encrypted. All this can be done dynamically, at runtime, rather than at compile time, as would be the case if you were to attempt this via inheritance.

Pros and Cons of the Decorator Pattern, according to the GoF:

Pros:
  • Allows for more flexible composition of behaviors than static inheritance.
  • Allows you to break object behaviors into small components (as opposed, for example, to creating a CryptoCompressionStream class that inherits from CryptoStream)
Cons:
  • Can lead to an explosion of small component classes are are difficult to understand.
  • Can't rely on object identity remaining unchanged because a client's initial Concrete object may be wrapped in a Decorator at any time.
And I think I should add that creating a Component base class definition that is amenable to this kind of infinitely forward-compatible extensibility is more difficult than it looks, because the Decorator classes have no ability to change the internal behavior of the Component, as they would with inheritance. This is probably why the Decorator Pattern isn't used more often in practice.

Tuesday, March 17, 2009

A First Look at Model-View-ViewModel

Model-View-ViewModel (MVVM) is a pattern used extensively by WPF developers. It was first introduced in October 2005 on WPF-and-Silverlight architect John Grossman's blog, where it was billed as a variation of MVC. According to Grossman, Expression Blend was written entirely using the MVVM pattern, and it is now, as far as I can tell, far and away the most common pattern used by WPF programmers.

I'm new to WPF and to MVVM, so I'm not going to claim to be able to make any definitive pronouncements about it. Most of what I've learned about it has come from reading this MSDN article, which was written by Infragistics engineer Josh Smith, and which Grossman himself recommends, as well as from reading various blog posts and newsgroup threads. But I will attempt to give some initial impressions, which I will hopefully refine and correct over time.


What is MVVM?

First of all, even though Grossman and others refer to it as a variant of MVC, it appears to me that MVVM is exactly Presentation Model, which is why my last post was a recap of Presentation Model. So far as I can tell, there is no structural or conceptual difference between MVVM and Presentation Model that could be used to classify it as a separate pattern. It is simply the application of the simpler form of Presentation Model to WPF applications. Smith agrees with this, saying "I consider MVVM to be a specialization of the more general PM pattern, tailor-made for the WPF and Silverlight platforms."


MVVM as an Adaptation of Presentation Model

You may recall that the simpler form of Presentation Model that I discussed in my last post was this one:



Presentation Model pattern in which the View references the Presentation Model

This is the simpler form because the view references the presentation model, and not vice versa, so the presentation model can be written without any entanglement with the view whatsoever. Also I mentioned in my last post that where data binding is present this pattern is especially simple, which is the case in MVVM. So here is the pattern as applied to WPF applications (from here on out I'll switch to the MVVM terminology and call the presentation model a "view model"):



MVVM Pattern

WPF Elements in MVVM

The diagram above is clear, but not very interesting. Here is a diagram that shows where the WPF pieces fall into the MVVM pattern (click on the image to see a larger version):


WPF Elements in the MVVM Pattern

I'll be the first to admit that I may be focusing myopically on the sample program that Smith provides with his article. I'll update this as I learn more, but meanwhile, based on that example and on a smattering of reading, this is what I see:

View: Consists of all of the XAML in the application, including the XAML for the main Application, for the Windows and for any UserControls, plus any Styles and DataTemplates. WPF data binding is used to bind controls to view model classes, and DataTemplates map view models to WPF controls for presentation.

Once the developer puts the basic view in place, they would ship it off to a UI designer in accordance with Microsoft's strategy of separating those two roles, so the view model needs to be well separated from the view.

View Model: Application, Window and UserControl XAML code-behind falls into the View Model layer, but it is strongly recommended that code-behind code be minimized, and that View Model code be placed in separate classes to the extent possible. Those classes are the view model classes shown above.

View model classes are data-bound to the view, so they need to implement INotifyPropertyChanged in order to notify the view when it needs to be updated.

They may optionally expose Command properties, which are classes that implement the ICommand interface. WPF provides built-in support for a command pattern that allows you to easily associate a single handler with a menu item, toolbar button, context menu, short cut key, etc. E.g. you can associate a single "Copy" command handler with the "Copy" menu item, toolbar button, context menu and "Ctrl-C" shortcut key. Commands therefore provide a way to encapsulate some of the behavior of the WPF application in the view model classes.

Granularity of view models appears to be roughly one per Application, Window and UserControl, but that isn't set in stone.

Domain Model: Happily, our domain model never changes as we move from pattern to pattern. That's one of the best things about these patterns. Our efforts to create controllers that can be reused from one UI technology to another only rarely prove fruitful (what are we supposed to do with all those Windows Forms MVP presenters now that we're told we should use data binding in WPF applications?) But the domain models just keep chugging right along, oblivious to the world's UI churn. They are the only (mostly) completely reusable parts of the system we have.

Anyway that's it for my first look at MVVM. I will (hopefully) try to update this as I continue to learn about WPF.



Wednesday, February 18, 2009

Tom’s Patterns Cheat Sheet, Part 3 – Model View Presenter

Considered a descendant of Model View Controller, MVP comes in two main forms, which patterns god Martin Fowler calls Supervising Controller and Passive View. A significant variant of Passive View is the Humble View, which is epitomized by Michael Feathers' classic article The Humble Dialog Box, and a very significant variation of that is Presenter First.

Most discussions of MVP begin with MVC and proceed in chronological order, but I find this ordering illogical. From a practical standpoint, the primary reason to choose MVP is to increase testability of your UIs, so the logical starting point is the Humble View form of Passive View.

Passive View MVP

Passive View MVP

Dotted lines represent communication by events while solid lines are direct object messages. The roles of the components are as follows.

View: In this architecture the view is kept as "humble" (that is, as free of code and logic) as possible. UI technology is often difficult to unit test (though as Fowler says, this point is often over-stated) so the goal of Humble View is to remove anything from the view that might be worth testing. The view will generally not be covered by unit tests at all in this architecture.

Presenter: The view simply passes notification of user stimulus to the presenter, whose role is similar to a controller in MVC. The presenter accesses the view only through a UI-agnostic interface so that it can be easily mocked in unit tests. The presenter updates the model appropriately and can receive events from the model when its state changes. The presenter is entirely responsible for updating the view; the view has no direct knowledge of or interaction with the model. The reason for this is to simplify the logic and make the code more readable and maintainable by putting all UI manipulation code in a single place.

A presenter differs from a controller primarily in its granularity: presenters are created at the form/page/complex widget level, and not at the widget/window level as are controllers. Also in Passive View MVP presenters are responsible for updating the view as well as for responding to user interaction, while controllers are only responsible for the latter.

Model: As with MVC, the model has no knowledge of the presenter or the view.

Some other variations on Passive View:

Passive View MVP with a Presenter-Model Observer

By removing the View's direct knowledge of the presenter you can decouple the view from the presenter and allow the same view to be used with different presenters. There is however a penalty to be paid in loss of readability whenever the Observer pattern is used, and this can sometimes be significant.

Passive View MVP with a Model Interface

By adding an interface for the model you can improve testability of the presenter yet again. This can be used with or without the Presenter-View Observer. In fact I would encourage use of a model interface for all but the most trivial of models. At this point we've arrived at the MVP variant used by Presenter First, though Presenter First is really a variation of TDD, and so is as much a design/development process as an architecture.

It should be noted that Fowler considers the View interface optional, but from a practical standpoint we can assume its existence.

Supervising Controller

Historically, Supervising Controller was developed before Passive View, but logically it's the pattern you revert to in order to take advantage of data binding:

Supervising Controller MVP

With this pattern you would allow data binding of the model to the view to handle the "easy" synchronization work, and would reserve the presenter for handling any complex logic. Although this is structurally more complex than Passive View, in practice where data binding is strong it can result in far simpler code. The Presenter-Model Observer has been removed from the diagram above, but there's no reason it couldn't be added back if that were appropriate for the situation.

For additional variations on MVP, I found this to be an interesting post. I will reserve creation of MVP code samples for a future post.



Followers