Principles, SOLID

SOLID – Liskov Substitution Principle (LSP)

As stated previously… I am getting (or trying to get) back to basics.

It is my belief that developers have to often times refactor the way they think and the way they approach things from time to time to make sure that the basics and principles are still strong.

So let’s take a look at one of the principles in SOLID; Liskov Substitution Principle (LSP)

LSP states:

If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T

Right, to many this is as clear as mud. It took me a while to understand what this principle was really talking about at first. Then after reading a few papers written on the subject it became a little more clear. What I have seen many developers do, however, is paraphrase this principle (or actually rewrite it) to make it easier to understand.

Commonly, LSP is paraphrased to state:

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it

So really all we are talking about is making sure our methods use base classes or interfaces as parameters and that the method does not have to know about all of the derived types of the base class or the classes that implement an interface.

Perhaps it is best to use an example to better explain what this principle is talking about.

public class Customer {
  ...
}

public class Vendor : Customer {
  ...
}

public class CustomerValidator {
  public void Validate(Customer customer) {
    if (string.IsNullOrEmpty(customer.Name)) {
      /// indicate that validation has failed
    }
    var vendor = customer as Vendor;
    if (vendor != null) {
      /// we know we are dealing with a Vendor
      /// validate Vendor rules
    }
}

Here we have a Customer class and a Vendor class which inherits from Customer. In the CustomerValidator class we are correctly using the Customer class (which would allow a Customer or Vendor object to be used… good so far) but then the Validate method has to know about the Vendor type and therefore violates LSP. What we can also (hopefully) see here is that we are violating the Open Closed Principle (OCP) due to the fact that any time we create another derived type from Customer we must modify the Validate method to handle the new type (hence it is closed for extension and is open for modification).

So how do we correct the above to remove the LSP violation?

The following is one way (and probably not the best way) to resolve the issues.

public class Validator {
  private readonly IList<string> errors;

  public Validator() {
    this.errors = new List<string>();
  }

  public void Validate(IValidation validation) {
    validation.Validate(errors);
  }
}

public interface IValidation {
  void Validate(IList<string> errors);
}

public CustomerValidation : IValidation {
  private readonly Customer customer;

  public CustomerValidation(Customer customer) {
    this.customer = customer;
  }

  public virtual void Validate(IList<string> errors) {
    /// if we fail validation add an error to the collection
  }
}

public VendorValidation : CustomerValidation {
  private readonly Vendor vendor;

  public VendorValidation(Vendor vendor)
    : base(vendor) {
    this.vendor = vendor;
  }

  public override void Validate(IList<string> errors) {
    /// call the Customer validation routines
    base.Validate(errors);
    /// if we fail validation add an error to the collection
  }
}

Wow. We have changed things up a lot.

If we look at the Validator class we can see that the Validate method takes a parameter which allows us to pass in any class that implements the IValidation interface. This follows LSP because we can substitute any class which implements this interface without changing the behavior. Not only that but the method doesn’t need to know anything about the types which implement the interface. At the same time, we have also solved our OCP violation by making the CustomerValidation class open for extension and closed for modification.

One more important thing that I would like to point out that sometimes get left out when explaining LSP is that exceptions should (or must) follow the same rules. This means that if you are throwing an exception in a method of a base class then any derived type overriding the method should throw the same type of exception. By doing this you can be ensured that your error handling for the base class will be correct for derived types as well. Just something that you should keep in mind.

Standard
Patterns, Principles, SOLID

SOLID – Open Closed Principle (OCP)

As stated previously… I am getting (or trying to get) back to basics.

It is my belief that developers have to often times refactor the way they think and the way they approach things from time to time to make sure that the basics and principles are still strong.

So let’s take a look at one of the principles in SOLID; Open Closed Principle (OCP)

OCP simply states:

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification

In my mind following this principle is not limited to inheriting from a base class and marking methods and properties as virtual. While I do believe that there is a time and a place for following OCP in this manner I feel that this is sometimes the only solution that developers think of when thinking about OCP.

Take the following example of following OCP through inheritance.

public class OrderService {
  private readonly IRepository<Order> repo;

  public OrderService(IRepository<Order> repo) {
    this.repo = repo;
  }

  public virtual void Save(Order order) {
    repo.Save(order);
  }
}

public class EmailOrderService : OrderService {
  private readonly ISmptService emailService;

  public EmailOrderService(IRepository<Order> repo, ISmptService emailService)
    : base(repo) {
    this.emailService = emailService;
  }

  public override void Save(Order order) {
    base.Save(order);
    emailService.SendNotification(order);
  }
}

Ok so now we have these classes and we are clearly following OCP but I believe that there is an alternative through use of the Strategy pattern which would make this a little cleaner.

public class OrderService {
    private readonly IRepository<Order> repo;

    public OrderService(IRepository<Order> repo) {
        this.repo = repo;
    }

    public void Save(Order order) {
        repo.Save(order);
    }

    public void Save(Order order, IOrderStrategy strategy) {
        this.Save(order);
        strategy.Process(order);
    }
}

public class EmailOrderStrategy : IOrderStrategy {
    private readonly ISmptService emailService;

    public EmailOrderStrategy(ISmptService emailService) {
        this.emailService = emailService;
    }

    public void Process (Order order) {
        emailService.SendNotification(order);
    }
}

Here we can see that OCP is still being followed since the OrderService class is still open for extension via the IOrderStrategy and is closed for modification. We don’t need to mark any methods as virtual and don’t need to inherit from the OrderService class. What is even better is that we could have implemented a Specification pattern along with the Strategy pattern and really get cooking.

public class OrderService {
    ...
    public void Save(Order order, IEnumerable<IOrderStrategy> strategies) {
        this.Save(order);
        foreach (var strategy in strategies) {
            if (strategy.CanProcess(order))
                strategy.Process(order);
        }
    }
}

public class EmailOrderStrategy : IOrderStrategy {
    ...
    public bool CanProcess(Order order) {
        return order.SendEmail;
    }
    ...
}

So I guess all this really means is that OCP shouldn’t only be thought of as marking methods and properties as virtual. OCP should be thought about and reasoned about a little more deeply and carefully.

And granted the examples given here have holes and are more than likely not the best code you have ever seen but it is the ideas these examples show that should be taken.

Standard
Principles, SOLID

SOLID – Single Responsibility Principle (SRP)

As stated previously… I am getting (or trying to get) back to basics.

It is my belief that developers have to often times refactor the way they think and the way they approach things from time to time to make sure that the basics and the principles are still strong.

So let’s take a look at one of the principles in SOLID; Single Responsibility Principle (SRP)

SRP simply states:

There should be one and only one reason for a class to change

Um… yeah! That makes sense… I guess

So what types of change are we really talking about when dealing with SRP?

This is a question that I have always had trouble answering for two reasons: 1) didn’t really understand SRP to begin with and 2) my focus was always in the wrong area. I have always understood SRP through examples of classes that violated SRP in that it would take someone to state that a given class was violating SRP and why. Then I would simply remember that pattern or example and avoid it rather than taking the time to learn what it meant. When I started taking the time to learn it and gain a better understanding I started to take things too literal. (If I needed to change a method in a class was that violating SRP?)

What I started to do was to think about things as a whole. In other words, while “change” is a very important word in the definition of SRP, the word “class” was what I was missing. When I finally took the word “class” into context… I had my “ah ha” moment (it was really like a “duh” moment).

Ah ha…!

Ok, great. So what does that mean?

The word “class” is a little tricky beast that can mean so many things to different people at different times that I feel it losses it’s importance. Case in point, I find my self interchanging the word “object” with “class” as in “new up a StringBuilder class.” While I don’t think that I will ever stop doing that or stop using the word “class” in my everyday vernacular, I think that word “class” in terms of SRP needs to be changed to “concern.”

So I started to take the common (or the one most popularized) definition of SRP and replace “class” with “concern”:

There should be one and only one reason for a concern to change

Wait for it… ah ha! By making this contextual change I started to realize that my classes needed to be responsible for a single concern.

Now I could start looking at classes in terms of their concern. Thinking about a class that dealt with a Customer object and it’s database interactions became a concern. And with that thinking I realized that the class had one responsibility, interacting with the database for the Customer object. So now the only reason for the class to change was to change the way the Customer object interacted with the database.

Standard