There seem to be many different ways of organizing methods in a class. I could group methods by access, and order them alphabetically. I could group related methods together. I could use a mix of the two, or something else entirely. Is there a standard way to approach this? If not, how do you approach it?
No, most people just group methods by logical similarity, or not at all. It doesn't really matter - classes shouldn't get too big, and with a decent IDE you can just ctrl+click to goto to any method definition anyways.
I suggest first grouping by interface they come thru, with a nice comment saying the interface name - because these are non-obvious.
Then, by relation, and only then sorting alphabetically.
Use a lot of blank lines to reduce the reader's cognitive load.
I group my method by functionality, ranging from most generic to most concrete, all that inside a region, so I can hide unnecessary details.
I do not order them by access modifier, nor do I order them alphabetically. (I think this is quite a burden when you add or rename a method in that class ... ).
If necessary, I group them by functionality. I mean: I put related methods toghether.
But, if you follow the SRP (Single Responsability Principle), then I think that ordering methods is in most of the circumstances a non-issue; since, when you follow SRP, your classes wouldn't have very much methods.
Microsoft's StyleCop tool does a nice job of defining element order within a class. You can also write extensions to the tool to conform to your company's coding standards. That being said, StyleCop is a good starting point.
Since Visual Studio has tools for navigating quickly to methods by name, I prefer to put private member variables and constructors close to the top and group methods by functionality (ie, helper methods are close by to the methods that call them). I also group properties together. If a class becomes substantial, I make use of #region directives to show the organization.
I'm not sure there's a consistently standard way... but I group related methods together, perhaps sub-grouped by accessor. Makes it the easiest for finding related things later down the track.
StyleCop enforces some things here:
Within a class, struct, or interface, elements must be positioned in the following order:
- Fields
- Constructors
- Finalizers (Destructors)
- Delegates
- Events
- Enums
- Interfaces
- Properties
- Indexers
- Methods
- Structs
- Classes
Furthermore, elements are ordered by access:
public
internal
protected internal
protected
private
As well as a few other rules:
- Contants have to appear before fields
static
elements have to appear before instance elements.
This might be a good baseline to start. As for additional ordering rules, I usually group related methods together.
I tend to find grouping of related methods far more useful when reading someone else's source code, than some arbitrary pseudo-order such as alphabetical.
Although the book is specifically about Java, Uncle Bob's Clean Code contains some excellent general principles for readability in OO classes. In particular, he uses the metaphor of a well-written newspaper article, with a headline at the top followed by a synopsis paragraph and then increasing detail as you read further down the article. By aiming for a similar top-down structure in your classes, it makes the task of reading or understanding your code much easier for others.
I use NArrange which does most of the things I want: Group fields, methods... alphabetically and by access modifiers. It also enforces some Style Cop rules (e.g. order of element types, location of using statements). NArrange is configurable to quite some degree, you do not have to live with the default configuration if you do not like it.
In Addition I use partial classes if I want to group certain methods that somehow belong together (e.g. events) and I group these files with another tool: VsCommands.
Whatever you do, put it in your standards and be consistent. We use a custom Regionerate configuration to order our methods. Everyone on the team uses the same configuration.
EDIT: We're now using ReSharper's Code Cleanup with a custom Type Members Layout.