MVP vs. MVC Patterns

I recently read an article that mentioned the Model View Presenter MVP pattern.  This was the first time I’ve seen a reference to this pattern and was curious how it was different than the Model View Controller MVC pattern.  The article below offers a great explanation of the two as well as the differences.

http://blogs.infragistics.com/blogs/todd_snyder/archive/2007/10/17/mvc-or-mvp-pattern-whats-the-difference.aspx

Here’s the MVP pattern:

And the MVC Pattern:

Key Differences

So what really are the differences between the MVC and MVP pattern. Actually there are not a whole lot of differences between them. Both patterns focus on separating responsibility across multi components and promote loosely coupling the UI (View) from the business layer (Model).  The major differences are how the pattern is implemented and in some advanced scenarios you need both presenters and controllers.

Here are the key differences between the patterns:

  • MVP Pattern
    • View is more loosely coupled to the model. The presenter is responsible for binding the model to the view.
    • Easier to unit test because interaction with the view is through an interface
    • Usually view to presenter map one to one. Complex views may have multi presenters.
  • MVC Pattern
    • Controller are based on behaviors and can be shared across views
    • Can be responsible for determining which view to display (Front Controller Pattern)

Hopefully you found this post interesting and it helped clarify the differences between the MVC and MVP pattern. If not, do not be discouraged patterns are powerful tools that can be hard to use sometimes. One thing to remember is that a pattern is a blue print and not an out of the box solutions. Developers should use them as a guide and modify the implementation according to their problem domain.

Abstract Factory Pattern

The abstract factory pattern is a software design pattern that provides a way to encapsulate a group of individual factories that have a common theme. In normal usage, the client software creates a concrete implementation of the abstract factory and then uses the generic interfaces to create the concrete objects that are part of the theme. The client does not know (or care) which concrete objects it gets from each of these internal factories since it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from their general usage.

The UML below represents how to implement the AbstractFactory pattern.

Abstract Factory Pattern

Let’s consider an example. We need a factory class that will return different brands of cars that include Ford, Chevrolet, and Dodge. Let’s first start by creating an enumeration for the different brands our factory will support.

    public enum AutomobileBrands
    {
        Ford,
        Chevrolet,
        Dodge
    }

Next, let’s define interfaces for our automobile factories as well as the automobiles themselves. We could add more methods for the auto’s, but for now, only two methods for “Start” and “Stop” will be part of the interface.

    public interface IAutomobileFactory
    {
        Automobile CreateAutomobile();
    }

    public interface IAutomobile
    {
        void Start();

        void Stop();
    }

The factory will return an abstract class that defines the common methods and properties for all automobiles. Let’s define this next. The class will have the ToString method overriden so we can display the brand of the automobile as output later on.

    public abstract class Automobile : IAutomobile
    {
        protected AutomobileBrands BrandName { get; set; }

        public virtual void Start()
        {
            Console.WriteLine(String.Format("The {0} has started.", BrandName));
        }

        public virtual void Stop()
        {
            Console.WriteLine(String.Format("The {0} has stopped.", BrandName));
        }

        public override string ToString()
        {
            return String.Format("This is a {0} automobile.", BrandName);
        }
    }

The BrandName property is defined as protected since it will only be defined in the concrete classes. Now let’s define three concrete classes for each of the brands our factory will support creating. Each will implement the IAutomobile interface defined above. I’ve overridden the Start method on a the Chevrolet and Dodge classes to show specific behavior of those brands of automobiles. There’s a lot more differences, but for now let’s keep it simple by showing only a difference with how they start.

    class Ford : Automobile
    {
        public Ford()
        {
            BrandName = AutomobileBrands.Ford;
        }
    }

    class Chevrolet : Automobile
    {
        public Chevrolet()
        {
            BrandName = AutomobileBrands.Chevrolet;
        }

        public override void Start()
        {
            Console.WriteLine(String.Format("The {0} starts Fast.", BrandName));
        }
    }

    class Dodge : Automobile
    {
        public Dodge()
        {
            BrandName = AutomobileBrands.Dodge;
        }

        public override void Start()
        {
            Console.WriteLine(String.Format("The {0} is slowly starting up.", BrandName));
        }
    }

Now let’s create the factories for each brand. Each factory must implement the IAutomobileFactory interface so the main factory class (see below) can call the CreateAutomobile method. Each factory is marked as internal since we only want the main factory class to interact with these classes.

    internal class FordFactory : IAutomobileFactory
    {
        public  Automobile CreateAutomobile()
        {
            return new Ford();
        }
    }

    internal class ChevroletFactory : IAutomobileFactory
    {
        public Automobile CreateAutomobile()
        {
            return new Chevrolet();
        }
    }

    internal class DodgeFactory : IAutomobileFactory
    {
        public Automobile CreateAutomobile()
        {
            return new Dodge();
        }
    }

Now that we’ve defined a factory for each brand, let’s create a static factory class that will be used for creating all types of automobiles. This class will act as the facade for all automobile factories.

    public static class AutomobileFactory
    {
        public static Automobile CreateAutomobileByBrand(AutomobileBrands brand)
        {
            IAutomobileFactory factory;
            switch (brand)
            {
                case AutomobileBrands.Ford:
                    factory = new FordFactory();
                    break;
                case AutomobileBrands.Chevrolet:
                    factory = new ChevroletFactory();
                    break;
                case AutomobileBrands.Dodge:
                    factory = new DodgeFactory();
                    break;
                default:
                    throw new ArgumentOutOfRangeException(brand.ToString(), brand, "Brand is not a valid automobile brand.");
            }

            return factory.CreateAutomobile();
        }
    }

The factory class above only requires one argument which is used to determine what kind of automobile class to create. Now let’s put all this to test by writing some test code in the Main method of the application.

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Ford));
            Console.WriteLine(AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Chevrolet));
            Console.WriteLine(AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Dodge));

            IAutomobile ford = AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Ford);
            ford.Start();
            ford.Stop();

            IAutomobile chevy = AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Chevrolet);
            chevy.Start();
            chevy.Stop();

            IAutomobile dodge = AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Dodge);
            dodge.Start();
            dodge.Stop();

            Console.ReadLine();
        }
    }

When the program runs, the output displayed in the console is:

This is a Ford automobile.
This is a Chevrolet automobile.
This is a Dodge automobile.
The Ford has started.
The Ford has stopped.
The Chevrolet starts fast.
The Chevrolet has stopped.
The Dodge is slowly starting up.
The Dodge has stopped.

Here’s all of it put together:


using System;

namespace AbstractFactoryExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Ford));
            Console.WriteLine(AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Chevrolet));
            Console.WriteLine(AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Dodge));

            IAutomobile ford = AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Ford);
            ford.Start();
            ford.Stop();

            IAutomobile chevy = AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Chevrolet);
            chevy.Start();
            chevy.Stop();

            IAutomobile dodge = AutomobileFactory.CreateAutomobileByBrand(AutomobileBrands.Dodge);
            dodge.Start();
            dodge.Stop();

            Console.ReadLine();
        }
    }

    public static class AutomobileFactory
    {
        public static Automobile CreateAutomobileByBrand(AutomobileBrands brand)
        {
            IAutomobileFactory factory;
            switch (brand)
            {
                case AutomobileBrands.Ford:
                    factory = new FordFactory();
                    break;
                case AutomobileBrands.Chevrolet:
                    factory = new ChevroletFactory();
                    break;
                case AutomobileBrands.Dodge:
                    factory = new DodgeFactory();
                    break;
                default:
                    throw new ArgumentOutOfRangeException(brand.ToString(), brand, "Brand is not a valid automobile brand.");
            }

            return factory.CreateAutomobile();
        }
    }

    #region Interfaces & Enum
    public enum AutomobileBrands
    {
        Ford,
        Chevrolet,
        Dodge
    }

    public interface IAutomobileFactory
    {
        Automobile CreateAutomobile();
    }

    public interface IAutomobile
    {
        void Start();

        void Stop();
    }
    #endregion

    public abstract class Automobile : IAutomobile
    {
        protected AutomobileBrands BrandName { get; set; }

        public virtual void Start()
        {
            Console.WriteLine(String.Format("The {0} has started.", BrandName));
        }

        public virtual void Stop()
        {
            Console.WriteLine(String.Format("The {0} has stopped.", BrandName));
        }

        public override string ToString()
        {
            return String.Format("This is a {0} automobile.", BrandName);
        }
    }

    #region Concrete Autos
    class Ford : Automobile
    {
        public Ford()
        {
            BrandName = AutomobileBrands.Ford;
        }
    }

    class Chevrolet : Automobile
    {
        public Chevrolet()
        {
            BrandName = AutomobileBrands.Chevrolet;
        }

        public override void Start()
        {
            Console.WriteLine(String.Format("The {0} starts Fast.", BrandName));
        }
    }

    class Dodge : Automobile
    {
        public Dodge()
        {
            BrandName = AutomobileBrands.Dodge;
        }

        public override void Start()
        {
            Console.WriteLine(String.Format("The {0} is slowly starting up.", BrandName));
        }
    }
    #endregion

    #region Concrete Auto Factories
    internal class FordFactory : IAutomobileFactory
    {
        public  Automobile CreateAutomobile()
        {
            return new Ford();
        }
    }

    internal class ChevroletFactory : IAutomobileFactory
    {
        public Automobile CreateAutomobile()
        {
            return new Chevrolet();
        }
    }

    internal class DodgeFactory : IAutomobileFactory
    {
        public Automobile CreateAutomobile()
        {
            return new Dodge();
        }
    }
    #endregion
}

Here’s some additional resources to find information about the Abstract Factory pattern.

http://en.wikipedia.org/wiki/Abstract_factory_pattern

http://www.developer.com/design/article.php/626001/Pattern-Summaries-Abstract-Factory-Pattern.htm

http://www.dofactory.com/Patterns/PatternAbstract.aspx

A Few Good Resources

These are some recent books I’ve read related to software.

Clean Code:  A Handbook of Agile Software Craftsmanship

I highly recommend this book.  Go to the Amazon link above to read more about.

The Design of Design – Essays from a Computer Scientist

An interesting book that discusses the various design approaches.

The Art of Unit Testing

The definitive book on how to properly unit test.

Head First Design Patterns

A straightforward reference to many design patterns with easy to understand examples and excellent descriptions.

Design Patterns:  Elements of Reusable Object-Oriented Software

Another excellent reference for many design patterns used in software today.