7 Comments The use of partial classes - 02/2/09
Yesterday, I came across some code using partial classes. I couldn’t avoid thinking a little more about the subject.
Partial classes were introduced in the .NET Framework 2.0, and here you can read what Microsoft has to say about it.
As we all know, we can define partial classes in C# to split a class in two (or more) different files. These are the prerequisites and consequences:
- All parts use the partial keyword in the class definition
- All parts must be in the same namespace
- All parts should have the same visibility
- You can still only specify one base class
- You can still implement many interfaces
Now, that’s obvious… Why am I telling you this? Well, because I’ve seen a lot developers misusing partial classes.
Microsoft states that splitting a class definition is desirable:
- When working on large projects, spreading a class over separate files allows multiple programmers to work on it simultaneously.
- When working with automatically generated source, code can be added to the class without having to recreate the source file. Visual Studio uses this approach when creating Windows Forms, Web Service wrapper code, and so on. You can create code that uses these classes without having to edit the file created by Visual Studio.
I only agree with the second usage. We all like the fact we don’t have our “Windows designer generated code” wondering around in our clean classes. That pile of disturbing code is moved to a partial designer-class. Our classes remain clean, without the code bloat needed to do the visual positioning stuff. The same applies to ASP.NET development. We’ve got all our HTML in the aspx file, while we’ve got our .cs file to delegate all the work to the controller in the MVC-story.
If you’re generating code, say with a software factory, you should also use partial classes. Imagine a class is generated and it works fine. But now, you need some more functionality or business rules, and you need to add them to the class. If for some reason later, you need to regenerate your code because of a major change you’ve made, you would lose all your custom development if you wouldn’t have put it in a partial class.
So, these are the cases where I agree and even strongly recommend the use of partial classes.
But let me get back to point number one in which MS states that splitting a class is desirable when working on large projects so multiple programmers can work on it simultaneously.
I do not agree at all.
I can’t avoid remembering a codebase I worked on some months ago. It contained classes, that were huge! It contained methods for all sorts of things: parsing XML files, saving and retrieving data, executing calculations on data, checking business rules on data, … I automatically feel sick when I think about it.
They had splitted the class into two partial classes for two reasons:
1) so multiple programmers could work on it (as MS encourages)
2) since the class was so big, it wasn’t handy to work in it (too much scrolling)
I hope you havn’t thrown up by now and you’re still with me.
If a class is so big you feel the need to split it up to keep it bearable to even read it, you’ve seriously been messing around with the SOLID principles, the DRY principle, and God knows what more… Thus, it’s time to think and refactor.
If your class contains methods that do CRUD operations, parse XML files, execute calculations and check on business rules, it’s obvious several developers will be needing that class at the same time. But splitting the class into two (or more) partial classes is not a solution.
It’s time to refactor the code, and look for places you’ve violated the Single Responsibility Principle (to start with). That’ll be a lot of places, if you have such spaghetti code!
The parsing should be handled by another class, the CRUD-operations should be handled by a repository (again, read the blue bible and also the follow-up book), the calculations should be handled in their own classes, and you should consider the specification pattern to perform business validation.
If you’ve got clean code, that follows the SOLID principles, you won’t feel the need to use partial classes.
I guess I have a set of rules before you decide to make use of partial classes:
1) If you need to be working with several developers on one class and you’re not working on the same functionality, you should check if you havn’t violated SRP (and I’m sure you have, since a class should only have one reason to change, remember?).
2) If you’re sure you havn’t violated SRP, check it with a co-worker to make sure.
3) If SRP was not violated, check how OCP, LSP and DIP-friendly your code is (if needed, again with co-workers). If these rules are broken, you’ll be making changes when you shouldn’t be making them. You’ll need to refactor your code to allow extensibility without changing existing classes.
4) If two developers need to access the same class to work on the same functionality, you’ve got some serious communication issues. It’s important to know what you’re colleagues are doing, so even if you’re not scrumming, you could gather on the coffee-break and discuss it. Maybe then you’ll decide to pair-program that piece of functionality.
5) Is it really that important to change that class right now? Can’t you just wait until your co-worker is done? It’s not going to take that long. Remember the class is only solving one responsibility
If you still need to be accessing the same class, at the same moment, for another reason, consider shared-checkout, and merging your changes afterwards. Merging mechanisms are still improving day by day, so just give it a try before using partial classes.
I’m not against partial classes or anything. I only want to say you shouldn’t misuse them.