Refactoring - improve the code and make it understandable - Part 1

A coder can write code, it will work and will do the job. So writing a code would be pretty straight forward. I found many coder, after finishing their code they want to optimize the code. Then the concept comes REFACTORING.

Now a days many IDEs for example Microsoft Visual Studio 2010 support Refactoring. So it will refactor the code on behalf of the  coder by clicking few options.  For example, in VS 2010 if we click on the Refactor menu item we will see the following menu items:


Refactor
  • Rename
  • Extract Method..
  • Encapsulate Field...
  • Extract Interface...
  • Remove Parameters...
  • Reorder Parameters....

as well as there are many books in regards to the refactoring. I like the book named, Refactoring: Improving the Design of Existing Code by Martin Fowler. I think if we get chance we should read this book.

In this article I am going to write few refactoring methods.

Extract Class - Refactoring
The main objective of this refactoring is related members from one class to another independent class. In this following example Person class has Name, OfficeAreaCode and OfficeNumber. Using this extract class refactoring strategy I am going to move  OfficeAreaCode and OfficeNumber members from Person class to TelephoneNumber class. If we see the class diagram then perhaps it would be more clear.


Fig: Extract class.

Person class before refactoring,

namespace RefactoryExampleLibrary.ExtractClass
{
    public class Person
    {
        public string Name { getset; }
        public string OfficeAreaCode { getset; }
        public string OfficeNumber { getset; }
 
        public Person() { }
 
        public string GetTelephoneNumber()
        {
            return string.Concat(new[] { OfficeAreaCode, OfficeNumber });
        }        
    }
}


After applying the Extract class Refactoring method Person class has been divided into two separate classes.

namespace RefactoryExampleLibrary.ExtractClass
{
    public class PersonAfter
    {
        public string Name { getset; }
        public TelephoneNumber officeNumber;
 
        public PersonAfter()
        {
            officeNumber = new TelephoneNumber();
        }
        public string GetTelephoneNumber()
        {
            return officeNumber.GetTelephoneNumber();
        }
    }
}

namespace RefactoryExampleLibrary.ExtractClass
{
    public class TelephoneNumber
    {
        public string OfficeAreaCode { getset; }
        public string OfficeNumber { getset; }
 
        public TelephoneNumber() { }
 
        public string GetTelephoneNumber()
        {
            return string.Concat(new[] { OfficeAreaCode, OfficeNumber });
        }
 
    }
}




The test class Program will test the above code.

namespace Refactoring_TestHarness
{
    using System;
    using RefactoryExampleLibrary.ExtractClass;
 
    class Program
    {
        static void Main(string[] args)
        {
 
            Person person = new Person()
            {
                Name = "A",
                OfficeAreaCode = "02",
                OfficeNumber = "1111"
            };
            Console.WriteLine("{0}", person.GetTelephoneNumber());
 
            PersonAfter personAfter = new PersonAfter()
            {
                Name = "A",
                officeNumber = new TelephoneNumber()
                {
                    OfficeAreaCode = "02",
                    OfficeNumber = "1111"
                }
            };
}


The output of the above code will exactly same as below,

021111
021111
Press any key to continue . . .


Introduce Parameter Object - Refactoring
The motive of this method is to reduce long parameter list from a class method. For example following GetDateOfBirth method of IntroduceParameterObject is taking three parameter for instance, day, month, year. So instead of passing three parameter we could reduce this to one parameter by implementing one type class such as DobComponents in here.
end code
namespace RefactoryExampleLibrary.IntroduceParameterObject
{
    public class IntroduceParameterObject
    {
        public IntroduceParameterObject() { }
 
        public string GetDateOfBirth(string day, string month, string year)
        {
            string[] dobComponents = { day, month, year };
            return string.Join("/", dobComponents);
        }
        public string GetDateOfBirth(DobComponents components)
        {
            string[] dobComponents = { components.Day, components.Month, components.Year };
            return string.Join("/", dobComponents);
        }
    }
 
    public class DobComponents
    {
        public string Day { getset; }
        public string Month { getset; }
        public string Year { getset; }
 
        public DobComponents() { }
    }
}

namespace Refactoring_TestHarness
{
    using System;
    using RefactoryExampleLibrary.ExtractClass;
    using RefactoryExampleLibrary.IntroduceParameterObject;
 
    class Program
    {
        static void Main(string[] args)
        {
            IntroduceParameterObject introduceParameterObject = new IntroduceParameterObject();
            Console.WriteLine("IntroduceParameterObject output,");
            Console.WriteLine("{0}", introduceParameterObject.GetDateOfBirth("01""01""0000"));
            Console.WriteLine("{0}", introduceParameterObject.GetDateOfBirth(new DobComponents() { Day = "01", Month = "01", Year = "0000" }));
}
}


The output of the class is as below,

IntroduceParameterObject output,
01/01/0000
01/01/0000
Press any key to continue . . .


Preserve Whole Object - Refactoring
This sort of refactoring reduce local variable dependency of the data and as well delegate the responsibility to the relevant type. In this example, CheckDateRangeWithoutPReserveObject method use Temperature type to get High and Low temperature by storing locally by declaring high and low local variable. Instead of doing this, leave the responsibility to the relevant method to access value. For instance, in here I implement a method name TemperatureWithDays with input parameter type Temperature so then this method can directly access high and low value from the Temperature object. 

namespace RefactoryExampleLibrary.PreserveWholeObject
{
    using System;
    public class PreserveWholeObject
    {
        public PreserveWholeObject() { }
        /*
         * Before Preserve Whole Object
         */
        public bool CheckDateRangeWithoutPreserveWholeObject()
        {
            Temperature temperature = new Temperature();
            int high = temperature.GetHigh();
            int low = temperature.GetLow();
 
            return new DaysTemperature().TemperatureWithDays(high, low);
        }
        /*
         * After Preserve Whole Object
         */
        public bool CheckDateRangePreserveWholeObject()
        {
            return new DaysTemperature().TemperatureWithDays(new Temperature());
        }
    }
 
    internal class DaysTemperature
    {
        public int todayTemperature = 250;
        public DaysTemperature() { }
 
        public bool TemperatureWithDays(int high, int low)
        {
            return (todayTemperature < high && todayTemperature > low);         
        }
 
        public bool TemperatureWithDays(Temperature temperature)
        {
            return (todayTemperature < temperature.GetHigh() && todayTemperature > temperature.GetLow());
        }
    }
 
    internal class Temperature
    {
        public Temperature() { }
 
        public int GetHigh()
        {
            return Int16.MaxValue;
        }
 
        public int GetLow()
        {
            return Int16.MinValue;
        }
    }
}

namespace Refactoring_TestHarness
{
    using System;
    using RefactoryExampleLibrary.PreserveWholeObject;
 
    class Program
    {
        static void Main(string[] args)
        {

            PreserveWholeObject preserveWholeObject = new PreserveWholeObject();
            Console.WriteLine("PreserveWholeObject output:");
            Console.WriteLine("{0}", preserveWholeObject.CheckDateRangeWithoutPreserveWholeObject());
            Console.WriteLine("{0}", preserveWholeObject.CheckDateRangePreserveWholeObject());
        }
}


The output of above code will be as below,

PreserveWholeObject output:
True
True
Press any key to continue . . .


Replace method with method object - Refactoring
Again in here the whole concept is to de-couple logic to the relevant type instead of having in the caller. In this example, I extract the computation logic from the Gamma method's to the Gamma class and call this new compute method of Gamma class from Gamma method.

namespace RefactoryExampleLibrary.ReplaceMethodwithMethodObject
{
    using System;
    public class ReplaceMethodwithMethodObject
    {
        public ReplaceMethodwithMethodObject() { }
 
        public int ComputeGamma()
        {
            return new Account().Gamma(1, 1, 1);
        }
 
        public int ComputeGammaRefactored()
        {
            return new Account_Refactored().Gamma(1, 1, 1);
        }
    }
 
    /*
     * Before Refactoring
     */
    public class Account
    {
        public Account() { }
        public int Gamma(int inputVal, int quantity, int yearToDate)
        {
            int importantValue1 = (inputVal * quantity) + delta();
            int importantValue2 = (inputVal * yearToDate) + 100;
 
            if ((yearToDate - importantValue1) > 100)
                importantValue2 -= 20;
 
            int importantValue3 = importantValue2 * 7;
            // and so on.
            return importantValue3 - 2 * importantValue1;
        }
 
        public int delta()
        {
            return 1;
        }
    }
    /*
     * After Refactoring
     */
 
    public class Account_Refactored
    {
        public int Gamma(int inputVal, int quantity, int yearToDate)
        {
            return new Gamma(this, inputVal, quantity, yearToDate).Compute();
        }
 
        public int delta()
        {
            return 1;
        }
    }
 
 
    public class Gamma
    {
        private Account_Refactored account;
        private int inputVal, quantity, yearToDate;
        private int importantValue1, importantValue2, importantValue3;
 
        public Gamma(Account_Refactored accountSource, int inputValArgs, int quantityArgs, int yearToDateArgs)
        {
            account = accountSource;
            inputVal = inputValArgs;
            quantity = quantityArgs;
            yearToDate = yearToDateArgs;
        }
 
        public int Compute()
        {
            int importantValue1 = (inputVal * quantity) + account.delta();
            int importantValue2 = (inputVal * yearToDate) + 100;
            if ((yearToDate - importantValue1) > 100)
                importantValue2 -= 20;
            int importantValue3 = importantValue2 * 7;
            // and so on.
            return importantValue3 - 2 * importantValue1;
        }
    }
}

namespace Refactoring_TestHarness
{
    using System;
    using RefactoryExampleLibrary.ReplaceMethodwithMethodObject;
 
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Replace method with method object");
            ReplaceMethodwithMethodObject replaceMethodwithMethodObject = new ReplaceMethodwithMethodObject();
            Console.WriteLine("{0}", replaceMethodwithMethodObject.ComputeGamma());
            Console.WriteLine("{0}", replaceMethodwithMethodObject.ComputeGammaRefactored());
        }
    }
}

The output of the above program is as below,

Replace method with method object
703
703
Press any key to continue . . .


Split temporary variable - Refactoring
I think this is  pretty good method to make code more understandable for other coder. For example in here, following code is less understandable 
long temp = Quantity * Price * 2;
temp = Quantity * temp; 


compare to  
long area = Quantity * Price * 2;
long length = Quantity * area;

I used following code to implement the concept,

namespace RefactoryExampleLibrary.SplitTemporaryVariable
{
    public class SplitTemporaryVariable
    {
        private long quantity = 10;
        private long price = 11;
 
        public SplitTemporaryVariable() { }
        /*
         * Before implementing the Split Temporary variables.
         */
        public long SplitTemporaryVariableBefore() {
            long temp = Quantity * Price * 2;
            temp = Quantity * temp; 
            return temp;
        }
        /*
         * After implementing the Split Temporary variables.
         */
        public long SplitTemporaryVariableAfter()
        {
            long area = Quantity * Price * 2;
            long length = Quantity * area;
            return length;
        }
 
        public long Quantity
        {
            get { return quantity; }
            set { quantity = value; }
        }
        public long Price
        {
            get { return price; }
            set { price = value; }
        }
    }
}


and following code to test the SplitTemporaryVariable,
namespace Refactoring_TestHarness
{
    using RefactoryExampleLibrary.SplitTemporaryVariable;
    using System;
 
    class Program
    {
        static void Main(string[] args)
        {
            SplitTemporaryVariable splitTemporaryVariable = new SplitTemporaryVariable();
            Console.WriteLine("Split Temporary Variable");
            Console.WriteLine("{0}",splitTemporaryVariable.SplitTemporaryVariableBefore());
            Console.WriteLine("{0}", splitTemporaryVariable.SplitTemporaryVariableAfter());
        }
    }
}


The output of the above code is as below,

Split Temporary Variable
110
110
Press any key to continue . . .



I will discuss about some other refactoring methods on part 2 of this article.

Happy to learn from others.

Thanks
mohammad

 Few C# and Application Design books from Amazon,

A fun with CheckBoxList, Lambda Expression and SelectedItem

Friend of mine wanted to select the items of CheckBoxList based on the value from a Enum List. Then I thought I should try. This article is about that. So what I did I created a simple website with a default page and CheckBoxList in the page. On the page load event the list will be populated based on the value in the List.

The code I wrote is as below,

Default.aspx page

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="WebApplication2._Default" %>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <asp:CheckBoxList ID="cboList" runat="server">
        <asp:ListItem Text="One" Value="One"></asp:ListItem>
        <asp:ListItem Text="Two" Value="Two"></asp:ListItem>
        <asp:ListItem Text="Three" Value="Three"></asp:ListItem>
    </asp:CheckBoxList>
</asp:Content>


and the code behind for the Default.aspx is as below,

namespace WebApplication2
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.UI;
    using System.Web.UI.WebControls;
 
    public partial class _Default : Page
    {
        public enum MyEnum
        {
            One,
            Two,
            Three
        };
 
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            IList<MyEnum> myEnums = new List<MyEnum>();
            myEnums.Add(MyEnum.One);
            myEnums.Add(MyEnum.Three);
 
            UsingQueryExpression(myEnums);
            UsingGenericLambdaExpression(myEnums);
            UsingLambdaExpression(myEnums);
        }
 
        private void UsingQueryExpression(IList<MyEnum> myEnums)
        {
            var temp = (from listItem in cboList.Items.Cast<ListItem>()
                       join myEnum in myEnums on listItem.Value equals myEnum.ToString()
                       select (listItem.Selected = true)).ToList();
        }
 
        private void UsingGenericLambdaExpression(IList<MyEnum> myEnums)
        {
            var temp = cboList.Items.Cast<ListItem>()
                .Join(
                myEnums,
                listItem => listItem.Value,
                myEnum => myEnum.ToString(),
                ((listItem, myEnum) => listItem.Selected = true)
                ).ToList();
        }
 
        private void UsingLambdaExpression(IList<MyEnum> myEnums)
        {
            var temp = cboList.Items.Cast<ListItem>()
                .Join<ListItemMyEnumstringListItem>(
                myEnums,
                listItem => listItem.Value,
                myEnum => myEnum.ToString(),
                ((myEnum, listItem) => myEnum))
                .Select(selectedListItem => selectedListItem.Selected = true).ToList();
        }
    }
}


happy to learn from others.

Thanks
mohammad

Multi items Return from a Method

Tonight I was watching a TV show on YouTube. Suddenly one thing just come up my mind. I can accept multiple items as input parameter in a method, how can I get multiple items back from a Method as return.
So after a little bit thinking I found few ways, for example define a type with return items or define a anonymous type with return items and then return this anonymous type from that Method.

The code I wrote for this is as below,

namespace MultiItemsReturn
{
    using System;
    using System.Runtime.InteropServices;
    class Program
    {
        static void Main(string[] args)
        {
            ReturnTester returnTester = new ReturnTester();
            var areaUsingDynamic = returnTester.AreaModifierUsingDynamic(10, 12);
            var areaUsingType = returnTester.AreaModifierUsingType(10, 12);
            Console.WriteLine("{0} - {1}, {2}, {3}", areaUsingDynamic.description, areaUsingDynamic.height, areaUsingDynamic.width, areaUsingDynamic.area);
            Console.WriteLine("{0} - {1}, {2}, {3}", areaUsingType.Description, areaUsingType.Height, areaUsingType.Width, areaUsingType.TotalArea);
        }
    }
 
    public class ReturnTester
    {
        public const string ReturnTesterDescription = "Mutltiple items returns";
        private const int proportion = 100;
 
        public ReturnTester() { }
 
        public dynamic AreaModifierUsingDynamic(int width, int height, string description = ReturnTester.ReturnTesterDescription)
        {
            return new
            {
                width = width * proportion,
                height = height * proportion,
                area = width * height,
                description = description
            };
        }
 
        public Area AreaModifierUsingType(int width, int height, string description = ReturnTester.ReturnTesterDescription)
        {
            return new Area
            {
                Width = width * proportion,
                Height = height * proportion,
                TotalArea = width * height,
                Description = description
            };
        }
    }
 
    public class Area
    {
        public int Width { getset; }
        public int Height { getset; }
        public int TotalArea { getset; }
        public string Description { getset; }
    }
}

The output of the code is as below,


Mutltiple items returns - 1200, 1000, 120
Mutltiple items returns - 1200, 1000, 120
Press any key to continue . . . .


happy to learn from others.

Thanks
mohammad

Windows Communication Foundation - How to create a WCF Service contracts, Service, Service Proxy and consume a service from client application.

I was trying to write something about WCF service, How to create a service, service contract, service proxy and consume that service a client application.
The situation is I  am going to implement is , service will implement a GeometryService. This service will implement How to calculate Area. So from client user will send height and width to the service and service will calculate the area and send back the result to the client.

The architecture of this article's example will be as below,

Fig: Architecture diagram of the example.

So in this example I going to implement following components,

  1. GeometryContracts.dll (implemented as class library)
  2. GeometryServices.dll (implemented as class library)
  3. GeometryServicesHost (implemented as WCF application)
  4. GeometryServiceProxy.dll (implemented as class library)
and a test program named TestHarness.exe. 

GeometryContracts.dll will define all the contracts which will be used by the GeometryServices.dll. GeometryServices.dll will be host on IIS using GeometryServicesHost WCF application.  GeometryServicProxy.dll will be implemented using GeometryContracts.dll and ClientBase class of System.ServiceModel and will be used by Client application in this example TestHarness.exe application. So the following sequence diagram shows how the client application TestHarness.exe will use GeometryContracts.dll and GeometryServiceProxy.dll to consume the GeometryServices via IIS.




Fig: The sequence diagram, How client consume services via Proxy and Contracts.

Before we further just  have a quick look the structure of the solution,

GeometryContracts.dll class library will implement following types,

  • Data contract named Area.cs
  • Service contract ISurfaceArea.cs

GeometryServices.dll class library will implement following types as service which will implement the service definition ISurfaceArea.cs,

  • SurfaceAreaService.cs

GeometryServicesHost Wcf Application will have following files

  • SurfaceAreaService.svc
  • Web.config

GeometryServiceProxy.dll  will implmented following files,

  • SurfaceAreaServiceProxy.cs

TestHarness console application will be implemented  following files,

  • Program.cs
  • App.config

All the code is now I am going to include below,

GeometryContracts  created as class library project with following source code, when created this library I have add references following assembly,

System.Runtime.Serialization and
System.ServiceModel
Area.cs
namespace GeometryContracts
{
    using System.Runtime.Serialization;
    [DataContract]
    public class Area
    {
        [DataMember]
        public decimal Height { getset; }
        [DataMember]
        public decimal Width { getset; }
 
    }
}
ISurfaceArea.cs

namespace GeometryContracts
{
    using System.ServiceModel;
    [ServiceContract]
    public interface ISurfaceArea
    {
        [OperationContract]
        decimal CalculateArea(Area area);
    }
}


GeometryServices.dll created as a class library with following assembly references
System.ServiceModel and project references GeometryContracts the one I just created above. This library will have following source code,
SurfaceAreaService.cs
namespace GeometryServices
{
    using System;
    using GeometryContracts;
    public class SurfaceAreaService : ISurfaceArea
    {
        #region ISurfaceArea Members
 
        public decimal CalculateArea(Area area)
        {
            return area.Width * area.Height;
        }
        #endregion
    }
}



GeometryServicesHost Wcf application hosted on the local (the one comes with OS by default) IIS  and it will implement following source code,
SurfaceAreaService.svc


<%@ ServiceHost Language="C#" Debug="true" Service="GeometryServices.SurfaceAreaService" %>
There wont be any C# class file for the above file.
Web.Config
<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="GeometryServices.SurfaceAreaService">
        <endpoint address="" binding="basicHttpBinding" contract="GeometryContracts.ISurfaceArea">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>



GeometryServiceProxy.dll will implemet the proxy for the client. This class library will have System.ServieModel as assembly reference and GeometryContracts.dll as project reference. This library will implement following files,


GeometryServiceProxy.cs
namespace GeometryServiceProxy
{
    using System.ServiceModel;
    using GeometryContracts;
 
    public class SurfaceAreaServiceProxy : ClientBase<ISurfaceArea>, ISurfaceArea
    {
        #region ISurfaceArea Members
        public decimal CalculateArea(Area area)
        {
            return base.Channel.CalculateArea(area);
        }
        #endregion
    }
}

So the service has been created and hosted on IIS. I will consume the service from the client application TestHarness.exe. This TestHarness is console application. This application will have GeometryContracts.dll and GeometryServiceProxy.dll as projects reference and with following source code,

Program.cs

namespace TestHarness
{
    using System;
    using GeometryServiceProxy;
    using GeometryContracts;
    class Program
    {
        static void Main(string[] args)
        {
            Area area = new Area();
            area.Height = 2;
            area.Width = 3;
            SurfaceAreaServiceProxy proxy = new SurfaceAreaServiceProxy();
            Console.WriteLine(proxy.CalculateArea(area));
        }
    }
}

and the App.config file with following contents
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint address="http://localhost/GeometryServicesHost/SurfaceAreaService.svc"
       binding="basicHttpBinding" bindingConfiguration=""
       contract="GeometryContracts.ISurfaceArea" name="basicEndPoint" />
    </client>
  </system.serviceModel>
</configuration>

I have completed the Service and Client side. When I run the application it will give output as below,

6.
This is just a simple application where I tried to show how to create and consume a WCF service. Happy to learn ideas from others.

Thanks
mohammad