Recently, I was working with a colleague in refactoring one of our projects. As we added tests, we found few code issues and continued refactoring. Was feeling happy as our unit tests were rearing benefits. However, we know TDD or unit testing does not guarantee clean code. As we progressed, the naming conventions consumed a lot of our time. And eventually, it brought us to a discussion about why specific naming conventions can create a better design. Thought I will share our discussions and practices here.

While we design classes for application, we often think of it as a different subject than ourselves (programmer). When I say different subject, we think of it as a different object and not as a person. When a programmer considers classes/interfaces as personalities and thinks from the perspective of the class, design can change drastically. This is what we call “Perspective designing”. Let’s take an Example:

public interface ITotalTaxCalculator { decimal Calculate(IEnumerable products); } public class TotalTaxCalculator : ITotalTaxCalculator { public decimal Calculate(IEnumerable products) { decimal total = 0.0; //add total of products etc.... foreach (var product in products) { using(var dbContext = new ProductContext()) { var productInDb = dbContext.FistOrDefault(prod => prod.Id == product.Id) total += (total * productInDb.taxRate); } } return total; } }

In the above example, the name of the class and interface are perfectly fine. But they are impersonal and it’s very hard to think of it as a person and bring in perspective thinking with these names. So we refactored them to ‘ICanCalculateTotalTax’ and ‘TotalTaxMan’.

public interface ICanCalculateTotalTax { decimal Calculate(IEnumerable products); } public class TotalTaxMan : ICanCalculatorTotalTax { public decimal Calculate(IEnumerable products) { decimal total = 0.0; //add total of products etc.... //blah blah blah.. total += (total * taxRate); return total; } }

These naming conversions have lots of inspiration from in NServiceBus for their class/Interface names. With the new class and interface names, it’s easy to think of them as personalities. However, this does not guarantee good design. So we needed refactoring. Perspective thinking comes in handy especially while we do refactoring When my colleague and I started putting ourselves in the place of each of the classes. We had very reasonable questions which triggered our object-oriented thinking.

Example1: As ‘ICanCalculateTotalTax’ , why I am having database related behavior?

Example2: As ‘ICanCalculateTax’, why I am having logic to find which language it needs to be presented?

These questions helped us to refactor the code to follow good design principles. When we implement these interfaces/abstract classes, we have clarity on what the class is capable of doing. So we generalized these naming conventions & questioning attitude and derived below two rules to do Perspective designing (think like a class).

Give personality to the names of classes/interfaces (example: ICanCalculateTax)

(example: ICanCalculateTax) Use the Agile User Stories way of articulating what the class should and should not do. (example: As ‘ICanCalculateTax’, I should be able to provide behavior to calculate tax)

I think, “Perspective designing” can make classes more object-oriented and best practice like SOLID principles automatically fall in line. Let me know your thoughts.