views:

876

answers:

5

What should be the general guidelines/gotchas for dividing application code (App_Code) into separate files?

I've found that over time, the original files do not match up well with how the namespace hierarchy evolves. How do I keep application code containers organized intuitively over time?

What PURPOSE should the file divisions aim towards? Code portability? Separation of concerns? General functional context? Frequency of change? Should they strive for 1-1 relationship with classes?

What are the implications of splitting the code into MANY smaller files vs consolidated into few files?

I've often thought about this but never really reached any general conclusions that apply to all situations.

+2  A: 

Most recommendations I saw say that every public type should be in its own file and namespaces should represent the folder structure of the application.

Mehrdad Afshari
+5  A: 

There should be a one-to-one mapping between classes and source files.

Namespaces should be thought of as a package that may encompass one or more classes. Where possible it can be useful to represent these as folders/filters in the Visual Studio project window.

If you find a sizeable class you feel would benefit from being split into separate files then instead consider refactoring and splitting the class itself.

The (acceptable) exception to this is the code that generates the UI which Visual Studio places in a separate file. I would recommend leaving this in its own file and treating it as a transparent editor-owned file as much as possible.

Andrew Grant
+2  A: 

The answer to this question is not absolute as it often depends on the task you have at hand. If you're creating some kind of SDK for reuse by others, then namespaces are very important; however, if you're creating an in-house tool with just a few classes, the namespaces are pretty much unimportant.

Classes

Generally speaking, classes should have their own file as this simplifies how people navigate around the code solution, helping with development and maintenance (it's much harder to merge changes when everyone is changing the same files, for example). It can be acceptable to split one class across multiple files in some situations such as:

  • When there are nested classes, each nested class could have its own file.

  • When there are auto-generated portions to the class such as designer code.

  • When there are fixed portions to the class such as a common set of hidden properties or a common implementation of an interface.

In one of our projects, we have a common implementation of an interface that many classes expose. As we don't have multiple inheritance, we take a mix-in approach whereby we autogenerate an additional file for each class. This could be done manually, instead of automatically (and was, originally).

There are other situations, but this is somewhat subjective and dependent on your own project's requirements.

Namespaces

Namespaces should generally focus on sensible groupings of your types. A namespace should allow a developer to intuitively locate what they are looking for. For many small projects, a single namespace such as MyAwesomeTool is sufficient, but for a larger project with many classes will need a more logical grouping. Such large projects, like SDKs or the .NET BCL rely on the namespaces to breakdown the otherwise overwhelmingly large collection of types. Each namespace level provides additional information of what might be found there, such as System.Windows.Forms or System.Drawing or Microsoft.VisualBasic.

When creating namespaces, every consideration must be given to the purpose of that namespace and the associated project. If the project is in-house and small, call the namespace what you like as it is merely a necessity for grouping your types; if the project is externally visible or contains a large amount of types, think carefully about logical and meaningful groupings that will enable others to intuitively find the types they are looking for.

Conclusion

There are no hard and fast rules that work in every situation. How you arrange your code into files relates to your own development processes, impacting you and your team; all your classes in one file will be hell to develop with but the compiled product won't act any different (provided the one file approach didn't lead to errors), whereas the arrangement of your namespaces relates to future development and the consumers of those namespaces, so the consequences of getting it wrong can be more serious.

  • Aim to organise your classes in a way that simplifies current development and future maintenance.
  • Aim to organise your namespaces in a way that simplifies all development and, where appropriate, the experience of your end users.
Jeff Yates
+1  A: 

I do 99% 1 to 1 class to file. The only exception is if you have a large number or very simple little classes that all implement the same interface and shouldn't change much. You might want to just go ahead and put these in one file. Custom exceptions can be a good example. Most of the time (in my experience), there is no code other than creating custom messages or things of that nature.

Namespaces should be organized first by separation of concerns. The Data objects should be in a different namespace than the domain objects, for example. Then, you might have a smaller subdomain for each group of objects at the "aggregate root" level. Usually, each of these smallest namespaces corresponds to its own project and DLL.

Charles Graham
A: 

As far as classes go, I tend to follow the Java rule: "One Public class per file" I may include a private class in with the public if that public class is the sole user. (Although, enums are making this less of a factor); However, if it's used by many public classes in the same namespace, then I'll put it in it's own file.

I'll tend to use namespaces along the lines of:

MyAwesomeApp.UI
MyAwesomeApp.Business
MyAwesomeApp.Data

to reflect the seperation of layers.

chris