Question

A class is too large and becomes unwieldy to work with. In Objective-C I'd be tempted to use Categories to break the class up, but then: wouldn't categories just be dividing a house full of too much junk into rooms? The same question applies to partial classes in C#, I suppose.

Under what conditions can categories be used to solve a "class too large" code smell? When is it not correct and the class really needs to "be restructured or broken into smaller classes?"

Was it helpful?

Solution

A very good principle to refer to is the SOLID principle. In particular the "S" stands for "Single responsibility"

Single responsibility principle

the notion that an object should have only a single responsibility.

When classes get too big, it is likely they have too many responsibilities. Can you define two or more responsibilities within the boundaries of what the class is doing? If so, separate it into two, or more, classes. You can then aggregate them back using a façade or composite pattern.

In other words:

  • the code you have in the class should be split in different classes according to the Single Responsibility principle
  • the original God class becomes a composite or façade: it uses all the new classes, exposes the same methods to the rest of the system, but does not implement any functionality in itself, besides "converting" the old-style god-class calls in the new-style SOLID calls.

This means that regions do exactly nothing to solve your problem, from an object-oriented point of view. In fact, they are actually counterproductive as they contribute to hiding the problem.

See also this Jeff Atwood article:

http://www.codinghorror.com/blog/2008/07/the-problem-with-code-folding.html

CodingHorror-regions

OTHER TIPS

I must admit I never used Objective-C, but of course, I used C#.

Said this, partial classes are the same thing that classes, splitting a class into multiple files doesn't make the class smaller, only splitted in file. The usage of the class will be the same.

So I don't agree partial classes will solve that problem, they were invented mostly for other things, like, windows forms, wpf, autogenerated code. They are useful also in other situations where classes cannot be logically splitted, but usually, should be avoided.

I think you should divide your class in several classes, a class starts to smell after 1k LOC (lines of code), also if the class is splitted in multiple files.

Use inheritance or split the class in several classes connected by fields and properties. In the example provided by chemicalNova i would split that in several classes, not in several files.

I remember when I was a novice, we had this god class "BusinessService", or something similar. Anytime someone had locked it in TFS, you were left out of luck. So I had this brilliant idea, why don't we split it into partial classes. We ended up with something like "BusinessService1.cs" .. "BusinessService6.cs". It was a complete mess, and a complete frustration to find where things are.

I think every time you need to use partial class, it is a design mistake. If Microsoft forces you to do so (wpf, winforms, etc) - it's their design mistake.

Theres nothing wrong with splitting a class into partials. Its something that few developers take advantage of.

Personally, I like to split larger classes into partials where the business side of things for each partial have similar functionality - but only if during design time it looks like said class will become quite big. Otherwise, I split related functionality into region's.

As an example, if I am to have a "UserService" that is within a data layer, I might split it into several partials like so:

UserServiceQueries.cs
UserServiceUpdates.cs
UserServiceInserts.cs
UserServiceLogicalFunctions.cs

..however, they contain partial classes of "UserService". I don't usually use ORM's a lot, so this is perfect for me because each piece of related functionality can become quite large (obviously this is a basic example).

In closing: take advantage of what is supplied. If you're getting code smell from your class being huge.. you've only got 2 choices.. re-write it, or split it up (if it definitely needs to be this large).

My opinion anyway.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top