sharing about .NET and technology RSS 2.0
# Monday, February 13, 2006

Building an application and/or library usually starts with an OO design. Typically from that design you will define interfaces and implement base classes, which can be used as a starting point for building your application.

Defining the signature of a base class is very important. More specific, the visibility (public, protected & private) and purpose (virtual or not) of the methods are very important. Take for example an order-entry form based application that contains several screens for adding and updating data. Every screen will need to implement a kind of save method for persisting the changes. The very basic structure of your design can be:

public interface IDataView
{
   void Save()
}

public class DataViewBase: IDataView
{
   public virtual void Save()
   {
   }
}

Here the intention is that for example every screen of your application need to inherit from DataViewBase and implement the Save method. The problem with this design, is that the interface is marked as virtual (see Virtuality) and is responsible for two jobs, namely that it is part of an interface and for specifying the implementation.

A better way is to apply the Template Method design pattern, also called the  'Hollywood principle', that is, 'Don't call us, we'll call you'. (This pattern is also used a lot throughout the .NET SDK library.)

public class DataViewBase: IDataView
{
   public void Save()
   {
      DoSave();
   }

   protected virtual void DoSave()
   { 
   }
}

This way you have complete control of the interface and you can easily add some logging before and after the save for example, extra checks, etc. If for example you need to implement whether a form-screen is dirty or not, you can easily plug it in as follow:

public class DataViewBase: IDataView
{
   public void Save()
   {
      // do some checks
      // do some logging

      if (IsDirty())
         DoSave(); 
   }

   protected virtual void DoSave()
   { 
   }

   protected virtual bool IsDirty()
   {
      return true;
   }
}

If for example you need to extend the application such that when the screen is dirty you get a dialog box asking if you want to save or not. You can simply change the Save method without affecting the derived classes

public class DataViewBase: IDataView
{
   public void Save()
   {
      // do some checks
      // do some logging

      if (IsDirty())
         if (MessageBox.Show("Do you want to save?", "Information", 
                             MessageBoxButtons.YesNo, 
                             MessageBoxIcon.Question) == DialogResult.Yes)
            DoSave(); 
   }

   protected virtual void DoSave()
   { 
   }

   protected virtual bool IsDirty()
   {
      return true;
   }
}

Due to the fact that the interface and the custom implementation is separated, we can easily extend and have control of the interface. In the other case we would have a lot of code duplication and in most cases we would violate the Liskov Substitution principle.

Monday, February 13, 2006 2:00:37 AM (Romance Standard Time, UTC+01:00) -  # -  Comments [0] -
.NET | Patterns & Practices
# Wednesday, January 25, 2006

Nowadays, is every kind of enterprise application more complex because there is the need to have much richer UI experience, integration with other systems, security, etc. Therefore it's important to have a good architecture and design of your application, so that you can better maintain and extend your application.

In every enterprise application you have a dependency to data resources. These resources can be to a database, web service, registry, file system, etc. It's a good practice to encapsulate all these dependent resources into services, such that the consumer (caller of the service) doesn't need to know the implementation details and the origin of the data.

That pattern is used a lot and is called a Service Gateway or Service Agent. There is a discussion on the difference between a Service Gateway that can be seen as consumer of a service and a Service Agent as a provider, but in the community both terms are used and mixed. The dependency between the consumer and the service is a contract which is typically a set of interfaces and business entities. In most cases, the service interface acts as a facade pattern, it encapsulates all subsystems underneath.

A typical example of a service agent is:

public interface ICustomerAgent
{
   Customer GetCustomer(int customerId);
   Order[] GetOrders(int customerId);
}

Note that the interface doesn't expose any details about the underlying system (e.g. database, xml, etc.) and communication protocol (e.g. web service, remoting, etc.).

Porgramming the UI of an application is typically the most difficult part and a challenge to achieve encapsulation and loose coupling. Thankfully there is for .NET 2.0 the Composite UI and the Smart Client Baseline Architecture Toolkit which guides you to an architecture for developing smart clients. Offcourse there is still the bible that every developer should read/know, it's the GoF book that describes a set of design patterns.

One of the drawbacks of a designer like in Visual Studio.NET, is that it is so easy to drag and drop (in dutch I call it 'drag en drol') components, change some attributes and going through wizards for making your application. For prototyping and demo's this is good enough, but for real enterprise applications it's not. If you want you can write an application that has only one class (= form), named Form1.cs that includes all UI logic, business logic, data access, security, etc but that's not what we want.

Building the UI is basically populating UI controls with data that resides in business entities. This means that for example an array of customers that must be shown in a list, means that every customer entity must be translated to a ListViewItem (if we don't use databinding). In most of the cases this logic resides in the form/usercontrol itself, but in fact it can be seen as a separated responsability for mapping a customer entity to a ListViewItem and vice versa (like in SC-BAT). This means that we can have something like:

public static class CustomerMapper
{
   public static ListViewItem ToListViewItem(Customer customer) { ... }
   public static Customer FromListViewItem(ListViewItem listViewItem) { ... }
}

And in your form/usercontrol you write:

foreach (Customer customer in customers)
   customerListView.Items.Add(CustomerMapper.ToListViewItem(customer));

In every project there are some OO concepts and patterns I always try to achieve maintainability and extensibility. Making good OO designs is in my opinion a matter of experience, creativity and making abstractions. My conclusion...

The art of OO programming is to define the set of responsabilities (= objects),
to encapsulate and to interact them in a loosely coupled way.

Wednesday, January 25, 2006 1:50:37 AM (Romance Standard Time, UTC+01:00) -  # -  Comments [1] -
.NET | Patterns & Practices
Navigation
Archive
<September 2010>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Christoph De Baene
Sign In
Statistics
Total Posts: 176
This Year: 2
This Month: 0
This Week: 0
Comments: 283
All Content © 2010, Christoph De Baene
DasBlog theme 'Business' created by Christoph De Baene