Click here to Skip to main content
11,415,390 members (83,228 online)
Click here to Skip to main content

Code Simplified!!

, 20 Jul 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
This article focuses on improving the maintainability of your code thus decreasing the cyclomatic complexity and lines of code, using existing features of .NET.

Introduction

Today, any software implementation is talking to external or internal systems (e.g., SOA), there are lots of entities, lot of code and of course lot of mappings. This article focuses on improving the maintainability of your code thus decreasing the cyclomatic complexity and lines of code, using existing features of .NET.

Background

Few days ago I was implementing a new functionality wherein I found the existing code consumes loads of entities and has huge code for just one to one mapping. I ran the code metrics (from VS 2010) and found the code is not maintainable. If this code is so difficult to read and understand for me as a developer then what about the person who will maintain it later?

This made me to search about few small tweaks to improve the code quality.

Beauty of code

There are many simple ways (which we usually forget or ignore) while coding which can make our code look beautiful and maintainable. 

  1. Inline Initialization

So instead of :-

PersonalInfo entity = new PersonalInfo();
AddressEntity nameAndAddress = new AddressEntity();
nameAndAddress.DayPhone = Convert.ToString(orderEntity.dely_phone_day);
nameAndAddress.EveningPhone = Convert.ToString(orderEntity.dely_phone_eve);
nameAndAddress.AddressLine1 = orderEntity.dely_address1;
nameAndAddress.AddressLine2 = orderEntity.dely_address2;
nameAndAddress.AddressLine3 = orderEntity.dely_address3;
nameAndAddress.AddressLine4 = orderEntity.dely_address4;
nameAndAddress.AddressLine5 = orderEntity.dely_address5;
nameAndAddress.ZipCode = orderEntity.Postcode;
nameAndAddress.FirstName = orderEntity.NickName;
nameAndAddress.Title = orderEntity.dely_address_no.ToString();
entity.Address = nameAndAddress;

We can write:

AddressEntity nameAndAddress = new AddressEntity()
{
    DayPhone = Convert.ToString(orderEntity.dely_phone_day),
    EveningPhone = Convert.ToString(orderEntity.dely_phone_eve),
    AddressLine1 = orderEntity.dely_address1,
    AddressLine2 = orderEntity.dely_address2,
    AddressLine3 = orderEntity.dely_address3,
    AddressLine4 = orderEntity.dely_address4,
    AddressLine5 = orderEntity.dely_address5,
    ZipCode = orderEntity.Postcode,
    FirstName = orderEntity.NickName,
    Title = orderEntity.dely_address_no.ToString()
}; 

 This way you can achieve:-

  • Better readability
  • Better maintainability
  • While calculating code metrics this will be considered as one single line.So, this will reduce the lines of code  (for this example from 13 lines of code to 1)
  • Will prevent duplicate assignment (for entities with large no. of properties this will be very useful) 
  • Faster to code

    2.  Mapping Functions

When we do one to one mapping, what's the first thing we do? We write a method, something like this

public static MyEntity MapServiceEntityToMyEntity(ServiceEntity response) 

This is how it is called

ServiceEntity response = GetServiceResponse(params); 
MyEntity entity = Mapper.MapToMyEntity(response);  

The mapper class gradually grows and grows. 

The problem comes when there are multiple developers working on same piece of code and one of your peers while implementing a new functionality is not able to find this function properly and decides to write his own mapping method. Something like this 

public static  MyEntity MapToMyEntity(ServiceEntity response) 

What happens next? The code complies and the mapping also works. But this increases lines of code, it has duplicate code and most importantly, the person who will maintain this code will pray for your death

What can we do about it? Always remember one simple thing. When you convert a Type "A" to Type "B" then your mapping class/method should always have one and only one function doing this. We can ensure this by creating extension methods. Also we can agree upon a naming convention for it.

I chose to overload all functions in the name of "Map". So my "Mapper.cs" contains all methods named as "Map". Below is one example.

 public static MyEntity Map(this ServiceEntity response)  

This way you can achieve:-

  • Prevent duplication of mapping functions
  • Easy to code
ServiceEntity response = GetServiceResponse(params);
MyEntity entity = response.Map();  

You can make it even easier

MyEntity entity = GetServiceResponse(params).Map();

  • Reduce lines of code 
  3. Mapping Lists [this section requires knowledge of Linq and PLinq] 

When we map a list, I have seen many doing something like:-

List<AddressEntity> listOfAddresses = new List<AddressEntity>();
foreach (ServiceResponse serviceAddress in response)
{
    AddressEntity address = new AddressEntity();
    address.DayPhone = serviceAddress.DayPhone;
    address.EveningPhone = serviceAddress.EveningPhone;
    address.HouseNumber = serviceAddress.HouseNo;
    address.Road = serviceAddress.Road;
    address.City = serviceAddress.City;
    address.Country = serviceAddress.Country;
    address.ZIpCOde = serviceAddress.ZipCode;
    listOfAddresses.Add(address);
}

We can straightaway improve this by using Linq

List<AddressEntity> listOfAddresses = 
  new List<AddressEntity>(response.Select<ServiceResponse,AddressEntity>(serviceAddress =>
                new AddressEntity()
{
    DayPhone = serviceAddress.DayPhone,
    EveningPhone = serviceAddress.EveningPhone,
    HouseNumber = serviceAddress.HouseNo,
    Road = serviceAddress.Road,
    City = serviceAddress.City,
    Country = serviceAddress.Country,
    ZipCOde = serviceAddress.ZipCode
}));

If the internal mapping requires some heavy operations (like calculating total or checking a property) and you are not bothered about the order of the elements in the list. You can further use parallel Linq or PLinq (remember-make sure the operations/variables/methods used under parallel loop are all thread safe)

List<AddressEntity> listOfAddresses = 
  new List<AddressEntity>(response.AsParallel().Select<ServiceResponse,AddressEntity>(serviceAddress =>
new AddressEntity()
{
    DayPhone = serviceAddress.DayPhone,
    EveningPhone = serviceAddress.EveningPhone,
    HouseNumber = serviceAddress.HouseNo,
    Road = serviceAddress.Road,
    City = serviceAddress.City,
    Country = serviceAddress.Country,
    ZipCOde = serviceAddress.ZipCode
}));

More on parallel programming - http://msdn.microsoft.com/en-us/library/ff963553.

When you refactor your code  this way make sure that the performance is intact. Though it is out of scope of this article, but I would suggest do some performance tweaks especially on loops and use the best possible option (for, foreach, Linq,Plinq, Parallel for and foreach) for a particular logic. 

One good link is - http://www.codeproject.com/Articles/6759/FOREACH-Vs-FOR-C  

Another very useful link - http://geekswithblogs.net/BlackRabbitCoder/archive/2010/08/26/c.net-five-little-wonders-that-make-code-better-1-of.aspx

 

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

indranil pal
Software Developer (Senior)
India India
I have been working as a developer in SOA and SaaS based projects.
Have worked mainly on Asp.Net, ajax, jQuery,c#, .Net 3.5 and 4.0.
You can reach me on ip_28@yahoo.co.in

Comments and Discussions

 
GeneralMy vote of 1 Pin
Member 432723030-Jul-12 1:55
memberMember 432723030-Jul-12 1:55 
GeneralRe: My vote of 1 Pin
ip283-Sep-12 9:41
memberip283-Sep-12 9:41 
QuestionNot an article Pin
mark merrens20-Jul-12 8:55
membermark merrens20-Jul-12 8:55 
AnswerRe: Not an article Pin
ip2820-Jul-12 9:47
memberip2820-Jul-12 9:47 
GeneralWhen I clicked on link next to "One good link is". Pin
Kiran Sonawane18-Jul-12 23:29
memberKiran Sonawane18-Jul-12 23:29 
GeneralRe: When I clicked on link next to "One good link is". Pin
ip2819-Jul-12 8:27
memberip2819-Jul-12 8:27 
GeneralMy vote of 3 Pin
Klaus Luedenscheidt18-Jul-12 20:22
memberKlaus Luedenscheidt18-Jul-12 20:22 
GeneralRe: My vote of 3 Pin
ip2819-Jul-12 9:02
memberip2819-Jul-12 9:02 
GeneralRe: My vote of 3 Pin
gggustafson20-Jul-12 6:02
membergggustafson20-Jul-12 6:02 
GeneralRe: My vote of 3 Pin
ip2820-Jul-12 7:44
memberip2820-Jul-12 7:44 
GeneralRe: My vote of 3 Pin
Klaus Luedenscheidt20-Jul-12 20:08
memberKlaus Luedenscheidt20-Jul-12 20:08 
SuggestionSuggestions... Pin
Andrew Rissing18-Jul-12 12:11
memberAndrew Rissing18-Jul-12 12:11 
GeneralRe: Suggestions... Pin
James Hurburgh18-Jul-12 21:57
memberJames Hurburgh18-Jul-12 21:57 
GeneralRe: Suggestions... Pin
ip2819-Jul-12 9:24
memberip2819-Jul-12 9:24 
GeneralRe: Suggestions... Pin
James Hurburgh19-Jul-12 14:10
memberJames Hurburgh19-Jul-12 14:10 
GeneralRe: Suggestions... Pin
ip2819-Jul-12 22:07
memberip2819-Jul-12 22:07 
GeneralRe: Suggestions... Pin
StockportJambo20-Jul-12 7:34
memberStockportJambo20-Jul-12 7:34 
GeneralRe: Suggestions... Pin
ip2820-Jul-12 7:46
memberip2820-Jul-12 7:46 
GeneralRe: Suggestions... Pin
ip2819-Jul-12 9:12
memberip2819-Jul-12 9:12 
GeneralRe: Suggestions... Pin
Andrew Rissing19-Jul-12 10:53
memberAndrew Rissing19-Jul-12 10:53 
GeneralRe: Suggestions... Pin
ip2819-Jul-12 22:08
memberip2819-Jul-12 22:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150427.4 | Last Updated 20 Jul 2012
Article Copyright 2012 by indranil pal
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid