SOLID Principles – Interface Segregation Principle

many client-specific interfaces are better than one general-purpose interface.

During interviews when we talk about these principles, candidates try to glide over this one very quickly. People usually understand this principle, and as a result it is considered to be easier to digest even by junior developers. Imagine the surprise on their face, when I ask them “why?”, “convince me that I should respect this principle”. I’m interested in their reasoning to discover their level of understanding. Like the other principles, you will understand it better if you try to not respect it.

In out last example the GeoPaymentModifier was selecting the closest warehouse. Because the closest might not have the ordered good, this can become a more complex task. The responsibility of the GeoPaymentModifier should be to know what amount to charge not to know how to select the best candidate warehouse.

To raise a bit the difficulty, let’s also consider that the warehouse info and their stock is stored in the database. The database abstraction will look something like this:

interface IDataStorageService
{
	IQueryable<UserInfo> Users { get; }
	IQueryable<ClientInformation> Clients { get; }
	IQueryable<Order> Orders { get; }
	IQueryable<WarehouseInfo> Warehouses { get; }

	void CreateOrder(Order order);
}
Continue reading

SOLID Principles – Liskov Substitution Principle

objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.

I noticed that this principle is a mystery even for experienced software developers. The reason for this is that you run into it very rarely, but once you do you’ll understand all the issues that arise from it.

Let’s try to implement the GeoPaymentModifier based on what we decided in the previous posts in the SOLID series. To recap, we receive the requirement to add a shipping cost to the total amount, if the shipping location is further away than 20 km. Since our client has multiple warehouses we need the closest warehouse location. Our class will look something like this:

class GeoPaymentModifier : IPaymentCalcModifier
{
	public WarehouseInfo ClosestWarehouse { get; set; }

	public double Calculate(Order order, double currentPrice)
	{
		return GetDistance(order) > 20
			? currentPrice + 100
			: currentPrice;
	}

	private int GetDistance(Order order)
	{
		int warehouseLoc = ClosestWarehouse.Location;
		int shippingLoc = order.ShippingInfo.Location;
		return Math.Abs(warehouseLoc - shippingLoc);
	}
}
Continue reading

SOLID Principles – Open/Closed Principle

Software entities should be open for extension, but closed for modification.

First time I’ve read this principle my initial react was “WHAT”, are these people high or something? I failed to realize how big difference is between introducing code trough extensions and through modifications. I knew about object oriented programming, abstractions, interfaces but looking back at the way I was coding then, I didn’t make use of the power behind these constructs at their full potential.

Let’s use the PaymentCalcuator example from out Single Responsibility post, there we concluded that how the calculation is done for each is a responsibility on its own. We can think of the following requirement for the payment calculation.

  • 10% discount for VIP customers
  • 10% discount in October
  • 5% for items from which they ordered at least 50

This I pretty simple you might say, so the code will look something like:

class PaymentCalculator
{
	double Calculate(Order order)
	{
		double total = 0;
		foreach(var item in order.Items)
		{
			var price = item.Quantity * item.IndividualPrice;
			if (item.Quantity >= 50)
				price *= 0.95;
			total += price;
		}
		if (order.ClientInfo.IsVIP)
			total *= 0.9;
		if (DateTime.Now.Month == 10)
			total *= 0.9;

		return total;
	}
}
Continue reading

SOLID Principles – Single Responsibility Principle


a class should have only a single responsibility

This is my favorite principle of all. It is the easiest to violate and thus in my opinion, not respecting it is the most common issue I find when I review code. Many people I talk to, mistakenly think that the SRP is trying to keep classes short, but it is much more than that.

Let’s discuss an example. Imagine that we are writing an application for a classic store type business who specializes in selling construction material. We will probably end up having two classes like this.

class Order
{
	IEnumerable<OrderItem> Items { get; set; }
	ClientInformation ClientInfo { get; set; }
	ShippingInformation ShippingInfo { get; set; }
}

class ReportCreator
{
	// Adds an image to specific coordinates
	void AddImage() { }
	// Adds text to specific coordinates
	void AddText() { }
	// Adds table data to specific coordinates
	void AddTable() { }
}
Continue reading

SOLID Principles – Intro

You must be thinking “Great, another schmuck who tries to explain them, the internet doesn’t need another series dedicated to SOLID!” You are right, this topic has been explored many times before, and certainly you will find better explanations out there. Every year thousands of new students enter the workforce in our wonderful industry. Even if there were courses in their University, or made the research themselves, only after they build up more experience can they truly cherish these simple, and in the same time complex principles.

To explain it better, let me use some chess analogy. I love this game and you will see if you follow my writing that I draw great inspiration from it. It heavily influenced the way I work and I apply a lot of habits, which I learned while playing. Try to guess who is better in this position.

Continue reading