Jul 01

In general, the name of a class should reflect the responsibility of the class in question. Note that I say responsibility in singular form. This is because every class should provide features as a small and concise package, covering only a single reasonably sized area of responsibility. A class should not take multiple responsibilities because it would muddle its intent, make it less modular, hinder reusability and, in spirit of this blog entry, make class naming more difficult.

As developers, we often see the class names listed in alphabetical form, for example in a file explorer or an IDE. If we are unsure which class exactly we are looking for, the class name usually gives us a good idea what the class’ responsibility is.

As a real world example, consider Symbian’s RWriteStream class, which provides a base class for writing to different destinations (for example, a descriptor or a file; descriptor being basically a string) in a stream form. That is, you open a write stream to a descriptor or a file, write to it using one or more WriteL() calls, and close it when you’re done.

There are classes that derive from RWriteStream that are used for writing to a descriptor or a file, amongst other types of destination. Consider what happens when you don’t know which exact class you are looking for, but you know, or at least suspect, that there’s a RWriteStream derived class that is able to write to a descriptor. The Symbian documentation doesn’t tell you what classes are derived from RWriteStream, so no luck there. Next you have a look at the table of contents of the documentation, which will show you multiple classes, ordered alphabetically as follows (I’ve highlighted RWriteStream for your convenience):

  • RBufReadStream
  • RBufWriteStream
  • RDesReadStream
  • RDesWriteStream
  • RDictionaryReadStream
  • RDictionaryWriteStream
  • RFileReadStream
  • RFileWriteStream
  • RMemReadStream
  • RMemWriteStream
  • RReadStream
  • RShareBufReadStream
  • RShareBufWriteStream
  • RStoreReadStream
  • RStoreWriteStream
  • RWriteStream

In this simple example, after looking for it a for a moment you can spot the probable class you need to use, i.e. RDesWriteStream. But consider how much easier it would be to find the class if the classes were named so that the parts of the class names were ordered so that they would present the most generic part first, followed by the more specific parts one after another. For example, RDesWriteStream would become RStreamWriterDes (notice the added ‘r’ for better English), RFileWriteStream would become RStreamWriterFile and so on. These class names would depict that the classes are based on streams, they write to the streams (instead of reading), and their destination (i.e. a descriptor or a file.)

Following the from-generic-to-specific naming convention (don’t know of any existing name for it!) specified above, the alphabetical list would become like this:

  • RStreamReader
  • RStreamReaderBuf
  • RStreamReaderDes
  • RStreamReaderDictionary
  • RStreamReaderFile
  • RStreamReaderMem
  • RStreamReaderShareBuf
  • RStreamReaderStore
  • RStreamWriter
  • RStreamWriterBuf
  • RStreamWriterDes
  • RStreamWriterDictionary
  • RStreamWriterFile
  • RStreamWriterMem
  • RStreamWriterShareBuf
  • RStreamWriterStore

In the example above, the stream sister classes can be categorized into reader and writer classes, and further based on their source/destination. I bet you can spot the RStreamWriterDes class much easier from this more ordered looking list.

This is but a single example. The fact of the matter is that our job is hard and frustrating enough as it is. There’s no need to name classes that are similar in purpose in a form that just confuses their users. Strive to name your classes so that the correct ones are easily found by your customers.

Finally there is, of course, the question when to go for the from-generic-to-specific class naming idiom. Essentially, the more classes you have that provide similar functionality and derive from a common base, the more reason you have to go for it. The obvious minimum (in my experience) would be three derived classes, preferably four. Also, keep in mind possible future classes that may be written later on. If you are sure there are going to be e.g. three or more “sister” classes to the one you are writing, by all means go for the naming idiom. You may well earn the right to pat yourself on the back later on.

Leave a Reply

preload preload preload