views:

197

answers:

6

I try to name a class (also members, properties and so forth) as exact as I can. But sometimes I’m not sure if this is so clever if the class name becomes huge (50 chars and more). The handling is so what uncomfortable and the code becomes difficult to read.

The question occured for me seldom and therefore I don’t have much experience with working with such long names but from time to time (now) it occurs. How other people handle this? Have you an approximate upper limit and then make abbreviations or is it worth the pain to handle such long names?

Update

As requested here an example of such a long class name.

ProjectContractChargingPeriodProjectAccountReferenceVM

The first Project represents the domain, it may be omitted because the namespace implies already that it handles projects. The problem with that is, that if I do this with this class name, then I must do it with all classes of this namespace and that I definitively don’t like because then many (short) class-names of this namespace will lose their expressiveness. [Project]ContractChargingPeriod describes the object, this class is used for and ProjectAccountReference means that the class is a reference to a ProjectAccount. With ProjectAccount is the same problem as with the ProjectContract. Only using Account is not meaningful because in the app exists also other Account-Classes. The Reference is a little bit weak because in reality it’s a little bit more than only a reference, but this is the general purpose. The VM is an abbreviation I always use and it stands for ViewModel. I think this is legal because everyone who works with WPF knows what VM means.

I have to say, that the class is used to wrap a class out of an ORM that is built with an elder tool I created a long time ago. The classes there represent quasi 1:1 the ERM and I am aware that this is not optimal, but changing it would be a major effort.

+3  A: 

(I use Java/C++, and have used other OO languages, but not C#, what I say here pretty much applies to all the languages I have used)

I use descriptive class names. I don't think I have made it to 50 characters however :-) Generally long class names are not public, and are usually hidden behind an interface and a factory. The interface has a much shorter name than the classes.

One thing you might do is, assuming you have a number of long-named classes that are closely related, put them into a package. One way to spot this is if the classes all have the same prefix word(s). If there are a number of classes that all start with the same name then, perhaps, the name should be a package instead.

TofuBeer
+2  A: 

Have you an approximate upper limit and then make abbreviations or is it worth the pain to handle such long names?

Neither. No abbreviations except extremely well-knonw ones like URL or HTTP. And perhaps for local variables with very small scope. Otherwise, think harder about how to get names that are both descriptive and not very long (I'd say anything over 30 characters is too long).

Usually, long names contain redundant or irrelevant information that can be left out. For example, don't put information in there that is already provided from context (i.e. information in member names that is already present in the class name). And avoid unspecific filler words like "data", "information", "handler", "manager", "helper", "compute", "processor" - they describe pretty much all code and so contain no real information (and some of them reflect procedural concepts and are almost a code smell for that alone).

Michael Borgwardt
+1 for no abbreviations/acronyms. Using domain abbreviations or acronyms is an additional communication barrier and make understanding an object model harder. More harm than benefit.
Pascal Thivent
Your class names *should* reflect coding concepts and design patterns. A class that creates `Customer` objects using a factory pattern *should* be called `CustomerFactory`. However, you should *not* let such terms leak into your domain vocabulary.
Niels van der Rest
+2  A: 

A long class name may be a hint that your class has to many responsibilities (notice I said 'may').

See SRP for further details (sorry, I'm in a hurry ^^).

Helper Method
+1  A: 

50 chars is pushing the large end of class names but is not inconceivable. As far as Java is concerned the max limit for the fully qualified class name (includes package) is 2 bytes.

In the wild, the Spring libraries are notorious for long class names. For example, the class AbstractTransactionalDataSourceSpringContextTests comes in at 49 characters. This provides unit testing with the injection of spring beans (SpringContextTests); data source injection (DataSource); tests are transactionally aware (Transactional); the class in question is abstract (Abstract).

Trying to squeeze that into less than 49 chars would be a challenge. This info could be provided in the documentation instead, but for classes that use/extend this class that would not be immediately obvious. This may reduce the understanding for developers reading your unit tests, so there is definitely a tradeoff here that you will have to think about.

krock
And the other Spring winner is `AbstractInterruptibleBatchPreparedStatementSetter` (also 49 chars).
Pascal Thivent
Some languages support attributes: `Transactional` for example might be declared by decorating the class with a `TransactionalAttribute` attribute.
ChrisW
With their annotation support you do not have to extend any spring class at all to get the benefits of IoC in your unit tests. You can add the annotations `@RunWith(SpringJUnit4ClassRunner.class)` and dd `@Transactional` to the tests you want to run in transactions.
krock
+2  A: 

How other people handle this? Have you an approximate upper limit and then make abbreviations or is it worth the pain to handle such long names?

A class is supposed to represent a type of thing: it's a noun (not a verb, and certainly not a whole a sentence).

I like to describe my things using one or two words, maybe three: just one noun, or a compound noun (like in German), or maybe an adjective and a noun.

For example, here's a list of some of my classes in one project:

Ancestors.cs
Block.cs
BlockCollection.cs
BlockDocument.cs
BlockInline.cs
BlockInlineText.cs
BlockListBullet.cs
BlockListItem.cs
BlockP.cs
BlockSequence.cs
BlockTable.cs
BlockText.cs
BlockTextParent.cs
Border.cs
BorderEdges.cs
Box.cs
Canvass.cs
CaretLocation.cs
CaretLocationAndNode.cs
CaretLocationAndPoint.cs
CaretLocationData
CaretLocationPair.cs
CaretLocationPairAndPoint.cs
CaretsInBlock.cs
DebugDumpDom.cs
DebugOutput.cs
Display.cs
Displayed.cs
DocumentHandle.cs
DomDocument.cs
DomDocumentFragment.cs
DomElementBody
DomElementHandle.cs
DomElementTag.cs
DomEvent.cs
DomList.cs
DomNode.cs
DomNodeChild.cs
DomRange.cs
DomRangeBase.cs
DomTextBody.cs
DomTextHandle.cs
Edge.cs
Editing.cs
EditingState.cs
Editor.cs
EditorAction
EditorActions
EditorMutations.cs
EditorTransaction
EventListeners.cs
ExtractedRangeInDomDocument.cs
ExtraDebugInformation.cs
FormControl.cs
... etc ...

As you can see, most class names are just two words (a compound noun).

I also use namespaces to separate classes into different categories and different projects (which helps to keep the names of the classes shorter: because some or most of the hierarchical information is in the namespace name, not the class name).

If I'm fortunate, then class names are unique or almost unique after the first few letters: so if I type in the first few letters, I can then select the specific class using Intellisense. For that reason, I don't need to use abbreviations.

ChrisW
Some of these classes look more like attributes. CaretLocation, ExtractedRangeInDomDocument, etc. Also, class names that have the word `And` is a good sign that you actually have two classes.
Dave Jarvis
@Dave Jarvis - Yes they are actually two classes: a class with `And` in its name is a group of things. For example, `CaretLocationAndNode` is constructed from a `CaretLocation` instance and a `DomNode` instance (and includes references to these instances among its data members).
ChrisW
+1 There's nothing wrong with introducing many classes, as long as it's meaningful in your domain. I'd rather have an `AmountAndCurrency` class instead of two separate objects describing the value of a product. The `AmountAndCurrency` concept usually goes by the name `Price`, but not *all* valid compound classes have an actual name of its own.
Niels van der Rest
Here I have both: separate objects, and combined objects. `DomNode` instances are the fabric of the tree-like document; `CaretLocation` instances are the user selection on the rendered document; and `CaretLocationAndNode` instances are temporary/transient objects which contain the information needed to raise the mouse events to which a user can subscribe. `DomNode` is happy and self-contained (and sufficiently complicated already) without knowing about `CaretLocation`, and likewise `CaretLocation` doesn't know about `DomNode`: hence the need for a third class, which combines/aggregates them.
ChrisW
A: 

Regarding the example of ProjectContractChargingPeriodProjectAccountReferenceVM, you can refactor it into something like this:

namespace Project
{
  public class ContractChargingPeriod implements IAccountReference
  {
    ...
  }

  public interface IAccountReference
  {
    ...
  }
}

The ContractChargingPeriod is dealing with all the business logic related to contract charging periods. The fact that it implements IAccountReference also tells that the object refers to an account, but without specifying this in the class name.

You can create simple viewmodels that reflect the contents of these types, but the viewmodels themselves should not contain any business logic. The viewmodels can use the same structure as the example above, but should be defined in a separate namespace.

Niels van der Rest