All the wrong ways to solve a problem

time to read 4 min | 684 words

How do you design your system? Let's take the following imaginary scenario:

"You have to calculate the salary of an employee. The salaries for employees hired before 01/01/2000 are hourly, and for employees hired after 01/01/2000 are paid globally. Managers are paid the same as employees (including hourly/globally based on hired date) but with additional 15% of the base salary. It is expected that in the future there will be more types of employees with different ways of calculating their salaries."

The way I see it, there are several ways to do it. Going with objects all the way:

I can't begin to describe the problems this approach is going to cause. This is truly a misuse of OOP. Unless you've mixins, this will lead to very complex code and derived-typed-per-attribute. Let's try to make this a little more realistic.

This requires an if statement, and ifs are evil for this type of stuff. Tomorrow we will need to have an employee that is the CEO son, so he gets the manager's benefits, but none of the other stuff (access to corporate data, etc). Of course, this object class completely ignores the other attributes that the Employee and Manager may

have. Let's go in the completely functional direction for a second, shall we?

If you can program like this in a language that is not meant for it, go right ahead. Don't worry about maintainability; it's going to require a re-write anyway.

Now let's try to do it using a service, like this:

 

I wince when I see the service code, in a few months time that method would have stuff like:

if(e.Name == "John Fairfield") // son of the CEO

ֲ ֲ  return salary * 1.20;

And that is the stuff that I can predict. The client code is nice and easy, but the complexity is in the service. ֲ In many cases, this is just fine; the complexity for this particular issue is isolated in a specific point and can be dealt with independently of all the other parts of the system. The problems come when you don't have a simple logic like the above. What happens if you have 17 types of employees, each of which may require a different salary calculation based on a dozen parameters?

 

In those cases, I think that a good way to solve this would be to implement the service using some sort of a smart rule engine that can decide at run time which salary calculation fits the employee. I don't have a diagram for that because I can't envision right now a way that I can hand an employee to the engine and it can decide which rule should handle the employee. The problem is that multiply rules may match the employee, and I can't think of an easy way to make it choose the most appropriate one.

 

Never mind, the issue I had when I started to write this post was what do you do when you have five or six such variations (independently variable, by the way) that you need to implement.

I'm talking about a general level architecture, by the way. I'm thinking about trying a series of services, (internal to the app, not necessarily web services) that understand the variations, as well as normal object hierarchy where needed. Right now, I don't have a clear cut policy on what I will put in the objects and what I will put into external services.