tags:

views:

273

answers:

5

Hello. I've a need to add method that will calculate a weighted sum of worker salary and his superior salary. I would like something like this:

class CompanyFinanse
{
      public decimal WeightedSumOfWorkerSalaryAndSuperior(Worker WorkerA, Worker Superior)
      {
           return WorkerA.Salary + Superior.Salary * 2;
      }
}

Is this a good design or should I put this method somewhere else? I'm just staring designing project and think about a good, Object Oriented way of organize methods in classes. So I would like start from beginning with OOP on my mind. Best practice needed!

+5  A: 

For your design to be Object Oriented, you should start by thinking of the purpose of the entire application. If there is only one method in your application (weighted sum), then there isn't too much design to go on.

If this is a finance application, maybe you could have a Salary class which contains a worker's salary and some utility functions.

For the method you pointed out, if the Worker class has a reference to his Superior, you could make this method part of the Worker class.

Without more information on the purpose of the application, it's difficult to give good guidance.

brien
Thank you for answer. I just think general about this. So what bothers me is how to decide on the design. This method will be used for sure in several places in this system, because it will work as a company finance system.
Just write the function in whichever class you have, and move it later, if it becomes apparent that it fits better somewhere else.
jalf
+6  A: 

I would either put it in the worker class, or have a static function in a finance library. I don't think a Finance object really makes sense, I think it would be more of a set of business rules than anything, so it would be static.

public class Worker {
     public Worker Superior {get;set;}
     public readonly decimal WeightedSalary {
         get {
              return (Superior.Salary * 2) + (this.Salary)
         }
     }
     public decimal Salary {get;set;}
}

or

public static class Finance {
     public static decimal WeightedSumOfWorkerSalaryAndSuperior(Worker WorkerA, Worker Superior) {
         return WorkerA.Salary + Superior.Salary * 2; }
}
Shawn Simon
I'd go for your the first option in this answer.
Gorpik
someone edited this to add static in the method declaration, but im not sure if it's needed because its declared on the class... hrm
Shawn Simon
+2  A: 

So it may be impossible to give you a complete answer about "best practices" without knowing more about your domain, but I can tell you that you may be setting yourself up for disaster by thinking about the implementation details this early.

If you're like me then you were taught that good OOD/OOP is meticulously detailed and involves BDUF. It wasn't until later in my career that I found out this is the reason so many projects become egregiously unmaintainable later on down the road. Assumptions are made about how the project might work, instead of allowing the design to emerge naturally from how the code is actually going to be used.

Simply stated: You need to being doing BDD / TDD (Behavior/Test Driven Development).

  1. Start with a rough domain model sketched out, but avoid too much detail.
  2. Pick a functional area that you want to get started with. Preferably at the top of the model, or one the user will be interacting with.
  3. Brainstorm on expected functionality that the unit should have and make a list.
  4. Start the TDD cycle on that unit and then refactor aggressively as you go.

What you will end up with is exactly what you do need, and nothing you don't (most of the time). You gain the added benefit of having full test coverage so you can refactor later on down the road without worrying about breaking stuff :)

I know I haven't given you any code here, but that is because anything I give you will probably be wrong, and then you will be stuck with it. Only you know how the code is actually going to be used, and you should start by writing the code in that way. TDD focuses on how the code should look, and then you can fill in the implementation details as you go.

A full explanation of this is beyond the scope of this post, but there are a myriad of resources available online as well as a number of books that are excellent resources for beginning the practice of TDD. These two guys should get you off to a good start.

Josh
A: 

Following up on the answer by brien, I suggest looking at the practice of CRC cards (Class-Responsibility-Collaboration). There are many sources of information, including:

Understanding which class should "own" a particular behavior (and/or which classes should collaborate in implementing a given use case), is in general a top-down kind of discussion driven by the overall design of what your system is doing for its users.

joel.neely
A: 

It is easy to find out whether your code needs improvement. There is a code smell in your snippet. You should address that.

It is good that you have very declarative name for the method. But it is too long. It sounds like if you keep that method in this Finanse class it is inevitable that you have to use all those words in the method name to get the sense of what that method is intended to do.

It basically means that this method may not belong to this class.

One way to address this code smell is to see if you could get a shorter method name if we have the method on other class. I see you have Worker and Salary classes.

Assuming those are the only classes left and you don't want to add up more classes, I would put this on Salary. Salary knows how to calculate weighted salary given another salary (Superior salary in this case) as input. You don't need more than two words for the method name now.

@Shawn's answer is one variation of addressing this code smell. (I think you can call it as 'long method name' code smell)

ragu.pattabi