4/19/14

Traits in Scala

Scala is a popular programming language that combines the best features of object-oriented and functional programming languages. It has some really cool features that are not available in other languages like C# or Java. Traits is one such feature that provides a viable solution for the problems associated with multiple inheritance in other languages.

Multiple inheritance is not allowed in Java/C# and the only other way to build common functionality among a set of related classes is via interfaces. But interfaces are abstract and require concrete implementation. The other option is to create a class that implements the desired interfaces and then inherit from that class. This is not very convenient.

Following are some of the cool features of a trait:
  • A Trait is much like an abstract class in C#. It can contain abstract members as well as concrete implementations
  • A Trait can contain abstract fields as well as concrete fields
  • A class in Scala can only have one base class but it can implement any number of Traits. So a lot of concrete implementations are readily available for use. 
  • A Trait can extend other Traits.
  • A Trait can extend other classes
  • An instance of a class can implement a Trait. So, not the class, but the desired instances of that class can implement Traits as needed. 
Following are some code samples of Traits:

An abstract Trait called Runner that has an abstract method called Run

trait Runner
{
   def Run(destination:String) //a string input param called "destination"

}


A class called Athlete that provides the implementation for the Trait:
class Athlete extends Runner
{
  //override keyword is not necessary while implementing an abstract method of a trait
  def Run(destination:string) {println(destination)}
}


A concrete Trait called Runner that has a concrete method called Run
trait Runner
{
  def Run(destination:String)  //a string input param called "destination"
  {
    println(destination)

   }
}


A class called Athlete that implements the Trait and calls the Run method. In Scala slang "The Runner functionality is mixed in with the Athlete class"
class Athlete extends Runner { def PrintDestination(destination:String) { Run(destination); } }


A trait called MarathonRunner that extends the trait Runner

trait MarathonRunner extends Runner
{
  def PrintMarathonDestination(destination:String)
  {
   Run(destination)
   }
}


A class called Athlete that implements both Runner and MarathonRunner
class Athlete extends Runner with MarathonRunner { }
NOTE : In Scala, the first trait is implemented using the extends keyword and the second trait is implemented using the with keyword


Let us say that there is a trait called HalfMarathonRunner, an instance of the class Athlete can implement this trait:
val objAthlete = new Athlete with HalfMarathonRunner


A trait with an abstract field
trait Runner
{
 val MaxDistance:int //no initial value means abstract
}


a trait with a concrete field
trait Runner
{
  val MaxDistance = 15
}

2/9/14

Randomizing Display Ads

I was working on the home page of a website that had a small area on the top right corner that was set aside for advertisements. The real-estate had to be shared by four different Ads provided they satisfied the criteria for display. Each had a different criteria that determined their eligibility for display. Criteria included the logged-in user's age, postal code and gender.

So it was possible that at any given time there could be one, two, three or four Ads eligible for display.Then the Ads that were eligible for display had to be randomized to ensure that each had an equal likelihood of appearing on the page.

The model for the page was as follows:


 public class MyHomeModel
  {
   public bool ShowNexusAd {get;set;}
   public bool ShowIpadAd {get;set;}
   public bool ShowSurfaceAd {get;set;}
   public bool ShowKindleAd {get;set;}
  }


So when we returned the model to the view, each of the properties had to have a value of true or false, that would be used in the view to determine whether to hide or show the particular Ad as follows:

@if(model.ShowNexusAd)
{
  //show Nexus Ad
}


For randomization, I decide to use the Random class in .NET to generate a random number in a specified range (1-9) and then use the value generated to determine which ad to show. The code would like this:

if(ShowNexusAd && ShowIpadAd && ShowSurfaceAd && ShowKindleAd)
{
   //generate a number between 1 and 9(including 1)
   Random randomNumber = new Random(1,9) 
   if(randomNumber <=2)
      ShowNexusAd = true;
   if(randomNumber >2 && randomNumber <=4)
      ShowIpadAd = true;
   if(randomNumber >4 && randomNumber <=6)
      ShowSurfaceAd = true;
   if(randomNumber >6 && randomNumber <=8)
      ShowKindleAd = true;
}


But there is a problem here.......

what if only three of the ads were eligible for display or two or just one? we would end up with code as follows:
if(ShowNexusAd && ShowIpadAd && ShowSurfaceAd && ShowKindleAd)

{
 Random randomNumber = new Random(1,9)
 if(randomNumber <=2) 
  ShowNexusAd = true;
 if(randomNumber >2 && randomNumber <=4) 
  ShowIpadAd = true;
 if(randomNumber >4 && randomNumber <=6) 
  ShowSurfaceAd = true;
 if(randomNumber >6 && randomNumber <=8) 
  ShowKindleAd = true;
}else
if(ShowNexusAd && ShowIpadAd && ShowSurfaceAd )
{
 Random randomNumber = new Random(1,7)
 if(randomNumber <=2) 
  ShowNexusAd = true;
 if(randomNumber >2 && randomNumber <=4) 
  ShowIpadAd = true;
 if(randomNumber >4 && randomNumber <=6) 
  ShowSurfaceAd = true;
}else
if(ShowNexusAd && ShowIpadAd && ShowKindleAd)

{
 Random randomNumber = new Random(1,7)
 if(randomNumber <=2) 
  ShowNexusAd = true;
 if(randomNumber >2 && randomNumber <=4) 
  ShowIpadAd = true;
 if(randomNumber >4 && randomNumber <=6)
  ShowKindleAd= true;
}
.......................and so on with all the possible permutations and combinations

As the number of Ads increase(or even for the existing four Ads) it will become a nightmare to extend this logic and even maintain it. So how do we make the code smart enough to handle this?

I hit upon the following idea(which might not be the greatest idea, but is pretty decent)

I created the following classes:

public abstract class AdDisplayBase
{
 public MyHomeModel ViewModel { get; set; }
 public abstract bool ShowAd { set; }
}

public class NexusAdDisplay : AdDisplayBase
{
 public override bool ShowAd
 {
  set { ViewModel.ShowNexusAd = value; }
 }
}

public class IpadAdDisplay : AdDisplayBase
{
 public override bool ShowAd
 {
  set { ViewModel.ShowIpadAd = value; }
 }
}

public class SurfaceAdDisplay : AdDisplayBase
{
 public override bool ShowAd
 {
  set { ViewModel.ShowSurfaceAd = value; }
 }
}

public class KindleAdDisplay : AdDisplayBase
{
 public override bool ShowAd
 {
  set { ViewModel.ShowKindleAd = value; }
 }
}

My goal was to convert the simple value types(the boolean properties) into reference types, so that I could treat them as objects. This would enable me to add the objects to a collection and handle them in a generic manner. To achieve this, I created an abstraction around the boolean properties by creating a class for each type of Ad.

I then refactored the unmanageable conditional logic above to the following method:

void ManageAdsDisplay(MyHomeModel model)
{
  int randomNum;
  var lstAdsToDisplay = new List();

  if (model.ShowNexusAd ) 
     lstAdsToDisplay.Add(new NexusAdDisplay () { ViewModel = model });
  if (model.ShowIpadAd ) 
     lstAdsToDisplay.Add(new IpadAdDisplay () { ViewModel = model });
  if (model.ShowSurfaceAd ) 
     lstAdsToDisplay.Add(new SurfaceAdDisplay () { ViewModel = model });
  if (model.ShowKindleAd ) 
     lstAdsToDisplay.Add(new KindleAdDisplay () { ViewModel = model });
  
  switch (lstAdsToDisplay.Count)
  {
    case 1:
 lstAdsToDisplay[0].ShowAd = true;
 break;
    case 2:
 randomNum = new Random().Next(1, 9);
 lstAdsToDisplay[0].ShowAd = (randomNum <= 4);
 lstAdsToDisplay[1].ShowAd = (randomNum > 4);
 break;
   case 3:
 randomNum = new Random().Next(1, 10);
 lstAdsToDisplay[0].ShowAd = (randomNum <= 3);
 lstAdsToDisplay[1].ShowAd = (randomNum > 3 && randomNum <= 6);
 lstAdsToDisplay[2].ShowAd = (randomNum > 6 && randomNum <= 9);
 break;
  case 4:
 randomNum = new Random().Next(1, 9);
 lstAdsToDisplay[0].ShowAd = (randomNum <= 2);
 lstAdsToDisplay[1].ShowAd = (randomNum > 2 && randomNum <= 4);
 lstAdsToDisplay[2].ShowAd = (randomNum > 4 && randomNum <= 6);
 lstAdsToDisplay[3].ShowAd = (randomNum > 6 && randomNum <= 8);
 break;
  }
}

By doing this we avoid the need to write complicated and confusing conditional statements and it is pretty easy to extend this design if there are more Ads in the future. To be honest, I am not completely happy with the Switch/Case part of the solution and I am trying to find a better way to do this. It will definitely end up as another blog post if I do.

1/25/14

Adapter Design Pattern

The Adapter design pattern is one of the most basic structural design patterns and it's definition is as follows:

"Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces."

Last week I was working on a part of a web application that pulled a list of users from the Database. This application has a pretty good amount of traffic and as the traffic increased it started putting a lot of load on the DB and slowing down the application. In an attempt to find a viable solution, we decided to try out an in-memory cache to store the user data and speed up access. About 25% of the traffic would get the data from the Cache and the rest would continue to go to the Database.

The code changes for the cache repository had to fit seamlessly into the existing design and the changes had to be made without touching the existing implementation for DB calls. The Adapter pattern turned out to be a perfect choice for the requirement.

Following is the code with just the call to the Database:

public class DbRepository
{
  public IEnumerable<user> GetUsers(int userId)
  {
    //call DB and get data
  }
}

//code calling the repository
public class UserService
{
  public IEnumerable<user> GetAllFriendsFor(int loggedInUserId)
  {
    //call DB repository to get data
   DbRepository repository = new DbRepository();
   return repository.GetUsers(loggedInUserId);    
  }
}

Following is the code after implementing the Adapter design pattern:

public interface IRepository
{
  IEnumerable<user> GetUsers(int userId);
}

public class CacheRepository:IRepository
{
  public IEnumerable<user> GetUsers(int userId)
  {
    //call cache and get data
  }
}

//the adapter
public class DbRepositoryAdapter:DbRepository,IRepository
{
}

public class RepositoryFactory
{ 
  //a variable that determines if the user is in test
  bool UserInCacheTest {get;set;}
  
  //return the appropriate repository
  public IRepository GetRepository()
  {
    if(UserInCacheTest)
   return new CacheRepository();
 
 return new DbRepositoryAdapter();
}
}


//code calling the repository
public class UserService
{
  public IEnumerable<user> GetAllFriendsFor(int userId)
  {
    //call the factory to get the appropriate repository
   IRepository repository = new RepositoryFactory().GetRepository();
   return repository.GetUsers(userId);    
  }
}
Explanation:

  • We create a new interface called IRepository that has a single method. This method will have the same signature as the method in the exisiting DbRepository since we are going to be adapting that repository to fit into the new design. NOTE: Using the same signature as in the existing DbRepository is just a matter of convenience, it is not necessary to do so.
  • We then create a new repository called DbRepositoryAdapter that will inherit from the existing DbRepository and implements the IRepository interface.The DbRepository already has a method with the same signature as the method in IRepository, so it is safe to say that the DbRepositoryAdapter implements the IRepository interface. NOTE: If the signature of the interface method was different, we would need to implement that method and call the DbRepository's method from inside it.
  • We create a new class called CacheRepository that also implements IRepository. 
  • We create a factory class called RepositoryFactory that will return a repository of type IRepository depending on whether the user is in the cache test. 
  • The CacheRepository and the DbRepositoryAdapter both implement IRepository, so we can use interface polymorphism within the UserService to return the appropriate repository.
  • We have incorporated the existing DbRepository into our new design by creating an adapter class on top of it. This way the existing DbRepository class and the new CacheRepository class can work well together.(NOTE: we have not touched the existing DbRepository in any way.). This is the advantage of using the Adapter design pattern.