#Google Analytic Tracker

Pages

Apr 16, 2007

Model View Presenter (MVP) Design Pattern Introduction

As a software developer, I often think how am I able to test my User Interface. There are many business logic that I really what to test, yet, they are embedded with the user interface class which makes it very hard to write automated test.

From one of my old project, I came across this design pattern call Model View Presenter. It is a derivative of Model View Controller.  There a number of articles regarding this design pattern. What I decided to do is put my own explanation on the blog, which reinforce my understand of MVP and hope helps others to understand.

What is MVP?

Typical UI - Data Model

[UI Control (i.e. DataGrid) ] ----> [Data Model (i.e. Database Model)]

Basic Model View Presenter

[UI Control] <-----> Presenter ----->[Data Model]

As  you can see, there is a Presenter Layer in MVP. This layer separate the business logic from your UI Controller. The Presenter will handle the business logic and your UI will focus on the user interaction.

The Goals of MVP

  1. Reduce complexity in a UI by extracting the business logic
  2. Help developer write automated unit test for your business logic
  3. Increase business logic reusable for other UI Controls.

Ask your application grow, your UI complexity increases as time goes. It is a good idea to extract the business logic out so that your UI can focus on the user interactions.

Since the Presenter is not a UI, you can write unit tests for your Presenter class, instead of clicking your UI.

Once you have your Presenter, you can create other UI Controls that uses the same Presenters.

For example:

[UI Control One (e.g. DataGrid)] <------------> [Presenter] ---> [Data Model]

[UI Control Two (e.g. custom ListView]<---------^

So, if one day you don't like your old UI Control, you can create a new one without worrying about the business logic by using the Presenter. Or, if your application allows different view of the same data, you can have multiple UI that uses the Presenter.

MVP Setup

UIControl ----> IView <----Presenter ----> Data Model
     |                                       ^
     |-------------------------------|

IView - an interface which state the contract that what the UIControl needs to have in order to support the Presenter

UIControl - your typical user interface, that must inherit from IView, so that the Presenter can control this UIControl. It should contain no or minimum business logic if possible.

Presenter - the class that can manipulate class that inherits IView . It should contain all the business logic allow us to write tests on it.

Data Model - your database access, file access class, or service access. The idea is to have your Presenter deal with your Data Model, and not your UIControl

MVP Example

I have to apologize that I didn't upload my solution since I just got a new ISP, and I didn't have time to find out what it has to offer! so I will use code snippet

This is a very simple Feedback Controller.

  • Interface IUserFeedBack is our IView
  • MyFeedBackControl is our UIControl
  • UserFeedBackPresenter is our Presenter

IUserFeedBack - this specify what the presenter can do with your UIController. As you can see, this a very basic method that a typical UI will do. However, instead of letting your UI decided when these actions are to be done, your presenter will decide, and your UI just need to do what the function name suggested

   1: using System;
   2:  
   3: namespace MVPExample
   4: {
   5:     /// <summary>
   6:     /// Any control that support IUserFeedBack can work with the UserFeedBackPresenter
   7:     /// </summary>
   8:     public interface IUserFeedBack
   9:     {
  10:         void ClearUserInput();
  11:         void DisplayMessage(String savedMessage);
  12:         void PopulateFeedBackType(String[] data);
  13:         void PopulateItemList(String[] data);
  14:         void SetDefaultFeedBackType(int defaultFeedBackTypeIndex);
  15:         void SetDefaultSelectedOption(int[] defaultSelectedOptions);
  16:     }
  17: }

 

UserFeedBackPresenter - please excuse my poor English spelling and grammar. I have a very simple Presenter which has two important methods: Submit, and Cancel. The Submit() function is called when user submit their feed back though the UI Controller. Once submit is completed, the function will display a message and clear user input. These are the business logic that you may need to do in your presenter, and not your UI Control.

Important: If you look at the constructor, you have to pass a IUserFeedBack object.

   1: using System;
   2: using System.Collections.Generic;
   3:  
   4: using MVPExample;
   5:  
   6: namespace MVPExample
   7: {
   8:     /// <summary>
   9:     /// The presenter is the link between the IUserFeedBack control and your data model
  10:     /// </summary>
  11:     public class UserFeedBackPresenter
  12:     {
  13:         IUserFeedBack userFeedbackControl = null;
  14:         List<String> feedBackTypeList = new List<string>();
  15:         List<String> itemList = new List<string>();
  16:  
  17:         public UserFeedBackPresenter(IUserFeedBack someControl)
  18:         {
  19:             userFeedbackControl = someControl;
  20:  
  21:             feedBackTypeList.Add("Satisfied");
  22:             feedBackTypeList.Add("Alright");
  23:             feedBackTypeList.Add("Unsatisfied");
  24:             feedBackTypeList.Add("No Idea");
  25:  
  26:             userFeedbackControl.PopulateFeedBackType(feedBackTypeList.ToArray());
  27:             userFeedbackControl.SetDefaultFeedBackType(0);
  28:  
  29:             itemList.Add("Customer Service");
  30:             itemList.Add("Product Functionalities");
  31:             itemList.Add("User Interface");
  32:             itemList.Add("Software Defects");
  33:  
  34:             userFeedbackControl.PopulateItemList(itemList.ToArray());
  35:             userFeedbackControl.SetDefaultSelectedOption(new int[] {1,2});
  36:  
  37:         }
  38:  
  39:         public void Submit(string name, string email, string selectedType, string[] selectedOptionList)
  40:         {
  41:             string message = String.Format("Thank you for submitting the following information\nName: {0}\nEmail: {1}\nFeedBack: {2}\nSelected Option:{3}",
  42:                 name, email, selectedType, String.Join(",",  selectedOptionList));
  43:  
  44:             //
  45:             //Save all this information to database, or write stuff to your files
  46:             // 
  47:             //This is where you can access your data model though the presenter, and not the
  48:             //User Interface
  49:             //
  50:  
  51:             //Display message to the user
  52:             userFeedbackControl.DisplayMessage(message);
  53:             userFeedbackControl.ClearUserInput();
  54:  
  55:         }
  56:  
  57:         public void Cancel()
  58:         {
  59:             userFeedbackControl.ClearUserInput();
  60:             userFeedbackControl.DisplayMessage("You have canceled your feedback");
  61:         }
  62:     }
  63: }

 

MyFeedBackControl - this control is derived from UserControl, and IUserFeedBack. It has a combobox that display the type of feedback a user can submit, 2 text boxes that store user name and email,  and a check list box allow user to select what this feedback is related. When user click on the submit, or cancel button, the UI Control doesn't care what the business logic need to do, it lets the presenter deal with it.

Important: If you take a look at the constructor, you see this important part

userFeedBackPresenter = new UserFeedBackPresenter(this);

This passes the control to the presenter, so that presenter can interact with your UIControl.  If we go further from this example, we can have our presenter dictates what field needs to be create during runtime, and the UIControl will only care how to create or what control need to create.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Windows.Forms;
   4:  
   5: namespace MVPExample
   6: {
   7:     public partial class MyFeedBackControl : UserControl, IUserFeedBack
   8:     {
   9:         //The presenter allows the separation between the UI control and the data model
  10:         private UserFeedBackPresenter userFeedBackPresenter;
  11:  
  12:         #region constructor
  13:  
  14:         public MyFeedBackControl()
  15:         {
  16:             InitializeComponent();
  17:             //passing the control to the presenter
  18:             userFeedBackPresenter = new UserFeedBackPresenter(this);
  19:             FeedBackOptionListBox.CheckOnClick = true;
  20:         }
  21:  
  22:         #endregion
  23:  
  24:         #region event handlers
  25:  
  26:         private void btnCancel_Click(object sender, EventArgs e)
  27:         {
  28:             userFeedBackPresenter.Cancel();
  29:         }
  30:  
  31:         private void btnSubmit_Click(object sender, EventArgs e)
  32:         {
  33:             List<string> selectedOptionList = new List<string>();
  34:             foreach (object item in FeedBackOptionListBox.CheckedItems)
  35:             {
  36:                 selectedOptionList.Add(item.ToString());
  37:             }
  38:  
  39:             userFeedBackPresenter.Submit(
  40:                 this.NameTextBox.Text,
  41:                 this.EmailTextBox.Text,
  42:                 this.FeedBackTypeComboBox.SelectedItem.ToString(),
  43:                 selectedOptionList.ToArray());
  44:         }
  45:  
  46:         #endregion
  47:  
  48:         #region IUserFeedBack Members
  49:  
  50:         /// <summary>
  51:         /// Clears the user input on this control.
  52:         /// </summary>
  53:         public void ClearUserInput()
  54:         {
  55:             FeedBackOptionListBox.ClearSelected();
  56:  
  57:             for (int i = 0; i < FeedBackOptionListBox.Items.Count; i++)
  58:             {
  59:                 FeedBackOptionListBox.SetItemChecked(i, false);
  60:             }
  61:  
  62:             FeedBackTypeComboBox.SelectedItem = FeedBackTypeComboBox.Items[0];
  63:             NameTextBox.Clear();
  64:             EmailTextBox.Clear();
  65:         }
  66:  
  67:         public void DisplayMessage(string message)
  68:         {
  69:             MessageBox.Show(message);
  70:         }
  71:  
  72:         public void PopulateFeedBackType(string[] data)
  73:         {
  74:             //Clear all item in combobox
  75:             this.FeedBackTypeComboBox.Items.Clear();
  76:  
  77:             //populate our combobox with Feedback types
  78:             foreach (string item in data)
  79:             {
  80:                 this.FeedBackTypeComboBox.Items.Add(item);
  81:             }
  82:         }
  83:  
  84:         public void PopulateItemList(string[] data)
  85:         {
  86:             this.FeedBackOptionListBox.Items.Clear();
  87:  
  88:             foreach (string item in data)
  89:             {
  90:                 this.FeedBackOptionListBox.Items.Add(item);
  91:             }
  92:         }
  93:  
  94:         public void SetDefaultFeedBackType(int defaultFeedBackTypeIndex)
  95:         {
  96:             this.FeedBackTypeComboBox.SelectedItem = this.FeedBackTypeComboBox.Items[defaultFeedBackTypeIndex];
  97:         }
  98:  
  99:         public void SetDefaultSelectedOption(int[] defaultSelectedOptions)
 100:         {
 101:             this.FeedBackOptionListBox.ClearSelected();
 102:  
 103:             foreach (int index in defaultSelectedOptions)
 104:             {
 105:                 this.FeedBackOptionListBox.SetItemChecked(index, true);
 106:             }
 107:         }
 108:  
 109:         #endregion
 110:     }
 111: }

Conclusion

As I remember someone has said from the Microsoft, they help the developers to write software by providing abstract layer so that developer don't have to worry about the back end stuff. MVP is similar in a sense that the UIControl doesn't need to care what the presenter does behind. You can have 2 developers in a team. One of them only care about what need the UI have to do (Presenter), and the other only care how the UI display and interact with the user (UIControl). As long as they agree on the IView, everything should work!

Where is the Unit Test?

Yea, I am not a big fan of test driven programming methodology YET! I will write another post about testing using mock framework, specifically RhinoMock in the near future. Then I will continue with this example.

Apr 9, 2007

Why use Private Static Method

When I was refactoring old company project code (prior of using Resharper), Resharper always give me this warning, suggesting me convert private method into a private static method.

For me, I understand the advantage of using a public static method. A public static method allow user to execute the method without object instantiation. What about a private static method, what is its advantage of using it? I naively ask the following questions:

1. Is the performance better when using a private static method instead of private method?

2. Does it use less memory space than a non static function?

If we talks about static classes, static variables or public static methods, I definitively understand why we have to use them in certain situation. Let me provide my own explanations for these items in the following order:

Static Variable

- a variable that declares as static will retain its value though out the application runtime. Since it is a static, the information of this variable is stored on the stack (memory), and not on a heap (memory). Static Variable only initialize once, and all object of its class can share this static variable.

Static Method

- a method that only access static variable. Hence, static method can not access to non-static variable inside your class. You will get a compiling error if you do the following:

BAD CODING EXAMPLE:

   1: public class MyNonStaticClass
   2: {
   3:     private int myNonStaticVar;
   4:     private static int myStaticVar;
   5:     
   6:     public static void MyStaticMethod()
   7:     {
   8:         myStaticVar = 15; // Static method can access myStaticVar
   9:         myNonStaticVar = 10; // Compiling ERROR!!! Static method cannot access non-static variable
  10:     }        
  11: }

Static Class

a class only contains static variable and static methods. No doubt,its because it is declared as a static class. You can not instaniate a static class to any new object. The memory of this class is allocated on the stack (unlike an object which is created on the heap). Static class is a sealed class (at least that's what I know about C#), which means it can't be derived into new classes.

STATIC CLASS EXAMPLE:

   1: public static class MyStaticClass
   2: {
   3:     private static int myStaticVar = 10;
   4:     
   5:     public static int DoSomething()
   6:     {
   7:         return myStaticVar++;
   8:     }
   9: }

So let get into a bit more examples

Static Variable in a Non-Static Class

So, what happen when you declare a static variable in a non-static class? First, since it is a non-static class, you can instaniate new objects as usual and yet, all these object SHARES the same static variable.  In addition, static variable is only initialized ONCE, and it has to be initialize before any object is instantiated. So pay attention on how your static variable initialized. To initialize a static variable, you can do it inline or do it in a STATIC Constructor.

STATIC VARIABLE INITIALIZATION EXAMPLE:

   1: public static class MyStaticClass
   2: {
   3:     private static int myStaticVar = 10; // inline initialization
   4:     private static int mySecStaticVar;
   5:     
   6:     //static contructor
   7:     static MyStaticClass()
   8:     {
   9:         mySecStaticVar = 20;
  10:     }
  11: }

We don't know when exactly static variable is initialized, but it has to be initialize before any instance is created, and after the assembly is loaded. Note that STATIC CONSTRUCTOR doesn't take any parameter nor it has privilege access modifier (public, private, internal). This is because it is a class initialization, not a object initialization. Moreover, Static Constructor can also be added in a non-static class:

A SIMPLE STATIC CONTRUCTOR IN A NON-STATIC CLASS:

   1: public class MyNonStaticClass
   2: {
   3:     private int myNonStaticVar;
   4:     private static int myStaticVar;
   5:     
   6:     static MyNonStaticClass()
   7:     {
   8:         myStaticVar = 10;
   9:     }
  10:  
  11:     public MyNonStaticClass()
  12:     {
  13:         myNonStaticVar = 30;
  14:     }
  15: }

STATIC VARIABLE BEING SHARED EXAMPLE:

   1: public class MyNonStaticClass
   2: {
   3:     private static int mySharedVariable;
   4:  
   5:     public int MySharedVariable
   6:     {
   7:         get { return mySharedVariable; }
   8:         set { mySharedVariable = value; }
   9:     }
  10:  
  11:     static MyNonStaticClass()
  12:     {
  13:         mySharedVariable = 10;
  14:         Console.WriteLine("MyNonStaticClass: running static constructor");
  15:     }
  16:  
  17:     public MyNonStaticClass()
  18:     {
  19:         Console.WriteLine("MyNonStaticClass: running normal constructor");
  20:     }
  21: }
  22:  
  23: class Program
  24: {
  25:     static void Main(string[] args)
  26:     {
  27:         MyNonStaticClass myNonStaticClass1 = new MyNonStaticClass();
  28:         MyNonStaticClass myNonStaticClass2 = new MyNonStaticClass();
  29:  
  30:         // Print out myNonStaticClass2.MySharedVariable:
  31:         Console.WriteLine("\nInitially, myNonStaticClass1.MySharedVariable = {0}\n", myNonStaticClass1.MySharedVariable);
  32:         
  33:         // Change myNonStaticClass1.MySharedVariable, which would ultimately chang
  34:         myNonStaticClass2.MySharedVariable = 999;
  35:         Console.WriteLine("Now set myNonStaticClass2.MySharedVariable to 999\n");
  36:  
  37:         // Print out myNonStaticClass2.MySharedVariable:
  38:         Console.WriteLine("result: myNonStaticClass1.MySharedVariable = {0}\n", myNonStaticClass1.MySharedVariable);
  39:         
  40:     }
  41: }
  42:  

If you run the example above, you would see the following output:

MyNonStaticClass: running static constructor

MyNonStaticClass: running normal constructor

MyNonStaticClass: running normal constructor

Initially, myNonStaticClass1.MySharedVariable = 10

Now set myNonStaticClass2.MySharedVariable to 999

result: myNonStaticClass1.MySharedVariable = 999

Press any key to continue . . .

Static Variable in a Static Class

If you have a static class, you have to use static variable only.  So, when to use a static class? You can use it as a utility class which provide basic inputs and output function that doesn't require object creation.  Another situation that I can think of is to use a static class provide a configuration and setting though out the entire application. That way, any other classes or object can access this static class and for sure they will get the same settings from the class. Third one is to set up a singleton design pattern such that all functionality and state of this class is shared in your application.

Situation of creating a Static Variable in a non-static class

If you want to share variables across all instainated object, then create a static variable in a non-static class. This way, all objects will able to share the static variable. However, beware of running into variable synchronization issue with multithreaded programming. Although I am not an expert in this field yet, but this is my word of caution. When multiple threads accessing the same variable, they don't always get the same value in time, because each thread actually has its own variable cache. Each time a thread modify a variable, this value need some time before it is synchronized with other thread's memory cache. (Correct me if I am wrong)

Also, if you want to keep track how many instance of the object is created, you can increment a static variable inside a class contructor.

So, why we have a Private Static Method?

This question has bugged me for a while, because I  don't see the any advantage of using static private method compare with a non-static private method. Unlike a public static method, which can be called without object instances. To access a public static method, you can just access it thought its class name:

EXAMPLE OF ACCESSING A PUBLIC STATIC METHOD

   1: public static class MyStaticClass
   2: {    
   3:     public static int DoStaticMethod()
   4:     {
   5:         return System.Writeline("Executing a static method");
   6:     }
   7: }
   8:  
   9: public class SomeOtherClass
  10: {
  11:     void RunStaticMethod()
  12:     {
  13:         //Accessing a static method though class name
  14:         MyStaticClass.DoStaticMethod();
  15:     }
  16: }

I mean, since static private and non-static private doesn't get exposed to other class, why would I want to make a non-static private method into a static private method if possible?

I encountered this thought because ReSharper gives me warning, or more a suggestion when it detects a method can be made as static private method. Resharper able to determine this by analyzing the variable declaration that I used inside the method scope. If the method doesn't access any global variable, or it only access local or static global variable, then Resharper would suggest you to make this private method into a static private method.

I began to think if it make any different a method is make to static.  Initially, it wasn't convincing since I don't see making the method static makes the program run faster, or save memory.

However, after thinking more about it, marking a function as static actually helps me analysis the code. When I see a method is static, I know that the state of the function only access static and local variable. In addition, if you want to call a method in a static contructor, the method has to be a static (private or public). Further more, I read an article that most of the compiler run more efficient when compiling a static method. I guess it is probably because static method doesn't access reference variable on the heap, instead, it only need to access memory on a stack. If I remember it correctly, it takes more instruction (machine) code to resolve the relative address of a reference variable than a static variable. 

One last word

Be conscience when using static member. Since static member is accessed by all object instances and thread, it should be protected by using locks or some kind of synchronized methods to prevent deadlocks in your application.

Reference

C# Threading Best Practices

Java Note on Static Method