“Thou shalt organize your code so that it is easily maintainable else thou shalt be dubbed a code sinner!” -anonymous
A recent blog post about the importance of code organization by Michael Braude, an x-coworker of mine at Microsoft, really hit a spot as I have been trying recently to figure out why a big part of the code base at the company where I currently work in Southern California was organized in such a way where a single .cs file would contain a significant number of classes. Typically, you notice that when a lot of your code is the result of codegen generated by some tool (like serializable code generated from XML schemas). But, looking at our code, it was obvious that this was not the case. Some of those files contained more than 40 classes. Wild!
To make matters worse, I noticed another weird syndrome in our code base. I call this the “inner class mania desease”. It happens that one of the development teams in our company came up with a serialization mechanism that requires declaring an inner class within any class that you would like to make serializable using this custom serialization. And that inner class will contain a list of all the XML elements forming the XML fragment. Here’s an example illustrating this:
1: public partial class FooBar : XmlConvertableBase
2: {
3: private static class XmlTag
4: {
5: public const string Root = "FooBar";
6: public const string Name = "Name";
7: public const string Address = "Address";
8: public const string City = "City";
9: public const string Country = "Country";
10: }
11:
12: public override string XmlTagRoot
13: {
14: get { return XmlTag.Root; }
15: }
16:
17: public override void WriteXml(XmlWriter xmlWriter)
18: {
19: XmlUtility.WriteOptionalElement(xmlWriter, XmlTag.Name, Name);
20: …
21: }
22: }
Now picture this: this technique sprinkled all over the code base wherever there is a class that needs to be serializable… This pattern not only pertains to code organization but also to re-inventing the wheel by creating your own custom serialization technique, especially when it adds no value over what you get from the XmlSerializer or the DataContractSerializer. So far, I still don’t know the reason they had to do all that. From a coding perspective, it adds a huge mess across the code base. All serializable objects are now super-bloated with redundant and repetitive serialization logic that repeats across all objects, unnecessarily. This certainly makes the code more difficult to maintain. Obviously, no one reviewed the design and recommended a better way to solve the problem. Future users and maintainers of the code base end up paying the price.
To me, the whole point behind code organization is maintainability. Whether it is you reading the code you wrote a while back, or someone else having to work on some code you wrote, it is important that the code does not require too much time to browse through. If a source code file has two dozen classes in it, it starts to become a big hassle to navigate through the code, especially when the code is across multiple logical layers that span across several projects. No one would really want to spend the bulk of their time scrolling through a long source code file; it is totally inefficient.
Coincidently, in the August issue of MSDN Magazine, Scott Mitchell talks about a tool called NArrange that seems to be created to try and address code organization issues. It seems that it will organize a source code file for you by logically grouping the different code artifacts in code regions. Here’s a description of NArrange copied from the tool’s website:
There are several reasons you may want to consider using NArrange for your .NET software project:
- Reduces the amount of time developers spend arranging members within code files. With NArrange, you don't need to worry about where you place a new member definition in a class... just type away and run NArrange prior to compilation. After formatting, the new member will be automatically moved to the appropriate location in the source file.
- Helps enforce coding style standards
- When used as part of check-in procedures, NArrange can help reduce source code repository conflicts.
- NArrange can automatically group similar code members into predefined region blocks, if supported by the language (C# and VB).
- Reduces the amount of time spent searching for specific members in a code file. Through standard arrangement of source code files, every member of the team will know exactly where in a file to look for private fields, constructors, etc.
- Flexibility - NArrange allows you to configure how members are organized (grouping, sorting, regions, etc.)
- Sort Usings
There is also more information on how to use NArrange on CodeProject, including a description of how you can modify the default NArrange configuration file to change the ordering of the regions created by NArrange as well as the region names.