35

In any given class definition, I've seen the method definitions ordered in various ways: alphabetical, chronological based on most common usage, alphabetical grouped by visibility, alphabetical with getters and setters grouped together, etc. When I start writing a new class, I tend to just type everything in, then reorder when I'm done writing the entire class. On that note, I've got three questions:

  1. Does order matter?
  2. Is there a "best" order?
  3. I'm guessing there's not, so what are the pros and cons of the different ordering strategies?
49

In some programming languages, order does matter because you can't utilize things until after they've been declared. But barring that, for most languages it doesn't matter to the compiler. So then, you're left with it mattering to humans.

My favorite Martin Fowler quote is: Any fool can write code that a computer can understand. Good programmers write code that humans can understand. So I'd say that the ordering of your class should depend on what makes it easy for humans to understand.

I personally prefer the step-down treatment that Bob Martin gives in his Clean Code book. Member variables at the top of the class, then constructors, then all other methods. And you order the methods to be close together with how they are used within the class (rather than arbitrarily putting all public then private then protected). He calls it minimizing the "vertical distance" or something like that (don't have the book on me at the moment).

Edit:

The basic idea of "vertical distance" is that you want to avoid making people jump all around your source code just to understand it. If things are related, they should be closer together. Unrelated things can be farther apart.

Chapter 5 of Clean Code (great book, btw) goes into a ton of detail on how Mr. Martin suggests ordering code. He suggests that reading code should work kind of like reading a newspaper article: the high-level details come first (at the top) and you get more detail as you read down. He says, "If one function calls another, they should be vertically close, and the caller should be above the callee, if at all possible." Additionally, related concepts should be close together.

So here's a contrived example which is bad in many ways (poor OO design; never use double for money) but illustrates the idea:

public class Employee {
  ...
  public String getEmployeeId() { return employeeId; }
  public String getFirstName() { return firstName; }
  public String getLastName() { return lastName; }

  public double calculatePaycheck() {
    double pay = getSalary() / PAY_PERIODS_PER_YEAR;
    if (isEligibleForBonus()) {
      pay += calculateBonus();
    }
    return pay;
  }

  private double getSalary() { ... }

  private boolean isEligibleForBonus() {
    return (isFullTimeEmployee() && didCompleteBonusObjectives());
  }

  public boolean isFullTimeEmployee() { ... }
  private boolean didCompleteBonusObjectives() { ... }
  private double calculateBonus() { ... }
}

The methods are ordered so they are close to the ones that call them, working our way down from the top. If we had put all the private methods below the public ones, then you'd have to do more jumping around to follow the flow of the program.

getFirstName and getLastName are conceptually related (and getEmployeeId probably is too), so they are close together. We could move them all down to the bottom, but we wouldn't want to see getFirstName at the top and getLastName at the bottom.

Hopefully this gives you the basic idea. If you're interested in this kind of thing, I strongly recommend reading Clean Code.

  • I need to know how setters and getters of instance variables need to be placed. Should It come right after the class constructor or at the bottom of the class ? – srinivas Mar 2 '18 at 5:10
  • Personally I like them at the top after the constructor. But it doesn't really matter; I'd recommend consistency in your project and with your team as a good way to decide. – Allan Mar 8 '18 at 18:08
  • Shouldn't calculateBonus() come before isFullTimeEmployee() and didCompleteBonusObjectives()? – winklerrr Dec 11 '18 at 16:55
  • @winklerrr I can see an argument for that. I placed them where I did because isFullTimeEmployee and didCompleteBonusObjectives are used by isEligibleForBonus so they ought to be vertically close to it. But you could potentially move calculateBonus up to put it closer to where it's called. Unfortunately, as you have functions calling functions eventually you end up with issues (like one shared functions called by multiple others) where there isn't a perfect ordering. Then it's left up to your best judgement. I recommend keeping classes and functions small to mitigate those problems. – Allan Jan 2 at 23:18
2

I generally order my methods by relation and order of usage.

Take a networking class, I'm going to group all the TCP methods together, then all the UDP methods together. The inside TCP I would have the setup method as the first, maybe send a given message second and close tcp socket as third.

Obviously not all classes will fit in that pattern, but that is my general workflow.

I do it that way for debugging more than anything else, when I have an issue and I want to jump to the method, I don't think how is it spelled, I think what is it responsible for and go to that section.

This way in particular makes sense to a third party viewing / using your code as its grouped together and will be following the order its being used, so the code they will write with your class will follow the same structure as the class.

As regards does it matter ?

for readability, definitely.

other than that not really, only in cases where certain languages you can't call the method unless its defined above where its called etc.

0

Ideally, your classes are so small that it doesn't matter. If you only have a dozen methods, and your editor or IDE supports folding, you don't have a problem, because the entire list of methods fits in 12 lines.

Failing that, the top-level distinction should be public vs. private. List the public methods first: these are what people are going to be looking for the most, because they define the way your class interfaces with the rest of the codebase.

Then, inside each of these, it makes the most sense to group methods by functionality: constructors and destructors in one block, getters/setters in another, operator overloads, static methods, and the rest of the bunch. In C++, I like to keep operator= close to the constructors though, because it's closely related to the copy constructor, and also because I want to be able to quickly spot whether all (or none) of default ctor, copy ctor, operator= and dtor exist.

-1

tl;dr

Only if the language you're working in requires a specific ordering. Other than that, the ordering is up to you. Pick a system which is consistent and makes sense, and try to stick with it as much as possible.


1 . Does order matter?

Only if the language you are working needs to have a function defined earlier in the file than where it is called, such as in this example:

void funcA()
{
   funcB();
}

void funcB()
{
   //do something interesting...
}

you will get an error because you call funcB() before you use it. I think this is an issue in PL/SQL and possibly in C as well, but you can have forward declarations such as:

void funcB();

void funcA()
{
   funcB();
}

void funcB()
{
   //do something interesting...
}

This the only situation I can think of where if the ordering is "wrong", you won't even be able to compile.

Otherwise, you can always re-order them however you want. You could probably even write a tool to do that for you (if you can't find one out there).

2 . Is there a "best" order?

If the language/environment doesn't have ordering requirements, then the "best" order is the one that works best for you. For me, I like to have all getters/setters together, usually at the beginning of the class (but after constructors/static initializers), and then the private methods, then protected, then public. In each scope-based group there is usually no ordering, though overloaded methods I try to keep together, in order of number of parameters. I also try to keep methods with related functionality together, though sometimes I have to break my scope-based ordering to do so; and sometimes trying to maintain scope-based ordering breaks group-by-functionality. And my IDE can give me an alphabetic outline view, so that's good too. ;)

Some languages, like C# have the ability to group code in "regions" that have no effect on compilation but might make it easier to keep related functions together, then hide/display them with the IDE. As MainMa pointed out, there are some who consider this a bad practice. I have seen good and bad examples of regions being used this way, so if you're going to go this way, be careful.

protected by gnat Dec 19 '17 at 16:53

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.