Showing posts with label code style. Show all posts
Showing posts with label code style. Show all posts

Sunday, February 14, 2016

One Class Per File

I've been using C# as one of my primary languages for the past 6 years where I currently work. Prior to that I was working with Java. One of the immediate differences that I noticed was that it was not uncommon to have multiple public classes in a source file. C# allows it, so why not.

Coming from a Java background I was used to one public class per file, where the filename needed to match the public classname in the file, and for me... I preferred it that way. I felt that it helped to organize the code. Some may say, having multiple classes in a file can aid in readability/discoverability/understandability/insert-an-ability. All true, they can. It can also be harmful in each of those respects as well... all depends. 

This week I've discovered a new reason why I prefer one class per file. Changes to classes are more traceable if a class has it's own file. Huhhh?




The reasoning goes like this. If I start out and have a couple of small public classes in a file, then tracking changes doesn't seem too difficult. The problem comes in when the classes grow. Your file will becomes larger and larger, and when you look at the file, there might all of a sudden be too many concepts in the file for you to keep track of. This can especially be the case where you can have a file named a name that has nothing to do with any of the classes inside of it (poor form imo, but to each his own). Some of the classes in the file may be related to the filename, but if sloppiness has crept in (not unheard of) then other classes may not be as closely related to that filename. Different concepts and abstractions may have crept into the file, and you may not realize it for a while. Yuck.

Then one day your in the file and your like, ZOMG, this file is too large and has too many concepts in it, I have to tease it apart. And so you do. You become the boy scout and you tease classes out of it, putting them in their respective files with the respective filenames and namespaces. And when you do this, your original file can in the worst case be empty (remember, the filename doesn't have to match any of the classes, and you just teased all of the classes out). And so you delete it. No problemo dude. And then you commit it and push it up to the remote (because your working in git).

And now, well now all of the history that you had in commit messages is gone for every class that was in the original file. It's not like renaming a file in git. You can always use the `--follow` flag on the current file you have to retrieve the full commit history for that file.

git log --follow path/to/filename 

Unless your a good tracker, chances are you're not going to re-discover where those commit messages went for the deleted file. Perhaps you'll never need to. I hope so.

Commit messages are a blessing for both me and my fellow developers because they are in some part a diary of what we were thinking about when we made changes. I've been getting more and more accustomed to making rather large commit messages lately. I'm recording more of the thoughts that I had around the design choices I've used, and perhaps even recording patterns I used in the commit.

The history of changes to a class is important to me. Maybe I've found some religion on this issue, and most probably, I'm going to be more prudent on keeping... one public class per file come Monday.

References:
Brad Abrams - Design Guidelines, Managed code and the .NET Framework
- Source files should contain only one public type, although multiple internal classes are allowed

Tuesday, April 7, 2009

Road rules for commenting your code

I'll never forget the first programming professor I had in college. He was a developer for Coke in Atlanta, GA corporate offices and taught "Intro to Java" as a side gig. He was a good teacher so far as I can remember, very capable at presenting completely foreign material to a diverse group of students in a concise and understandable way, and for that I thank him. He made himself readily available for questions, including business hours when he was on duty at Coke if you had a pressing question that you needed to get in touch with him about.

However, one of the principals that he hammered us on was that you needed to comment all of your code. This included every class, every method...on down to every variable. Closing braces should have a comment on what block it was closing off whether it be an if-elseif block, or a for loop, or the closing brace on your class. Did not matter...it had better have a comment on it or you could count on 2 points coming off of your grade.

It was not until I graduated and entered the working world that I would discover that this was in fact, not the best practice to follow. I was surprised to find that the majority of developers on a large project I was involved with at work shunned the practice of comments (not always, but most of the time you could say). Why? They were quick to point out that comments quickly get outdated, and that it's better to rely on the code to tell you the story instead of the comment. The one caveat to this was that an interface (we were coding in java) should always have comments as it is a public and published contract.

I was reminded of this professor recently after having stumbled upon a series of articles by Robert C. Martin (otherwise known as Uncle Bob). These articles provide you with a glimpse into what you can expect to find in one of the most recent books he has been involved with, Clean Code: A Handbook of Agile Software Craftsmanship. They give a just shy of humorous but pragmatic viewpoint of how comments don't work sometimes... a lot of times. I've not had the chance to read the book yet, but if the article series of excerpts are a good representation of what is in the book, then I intend to be picking it up soon.

My personal viewpoint... definitely comment code that could be confusing. If this is the case though, then perhaps you should try to find a way to refactor the code to make more sense. I agree with my friend, comment interfaces that you write. Remove old commented out code as it is outdated and most likely will never be needed again. And if it is, that's what version control systems are for. And keep comments short and to the point... don't try to tell a story with your comment. If you are, then your code could probably use a refactoring in this instance as well.