In my opnion, a system’s use case specification is a valuable tool for problem analysis in software design. Simply listing the use cases before designing a system can help drive software design in the right direction and improve solution quality in the end.

Additionally, I find that the process of defining use cases can make you think once again about the purpose of the system and different aspects of its operation from the standpoint of users.

What is a Use Case

For our purposes, use cases are all actions users or other entities can perform in the system.

There’s plenty of in-depth information on use case discovery and specification. But that’s beyond the scope of this post. See recommended reading for suggested resources if you are interested.

Here I only want to cover the usefulness of the technique to the design process.

Use Cases Don’t Have to be Complex

Formal specification of use cases is indeed a big topic. Luckily, we can get most of the design benefit with a very simple form of use case specification.

Simply write down their titles.

Lets see how this basic format is useful to a system’s designer.

Functional Partitioning

Some background first.

Functional partitioning is one of the first steps of design. It’s the process of splitting a system into smaller, more manageable modules.

One good property of a well-defined module is functional cohesion. In a functionally-cohesive module all of it’s sub-modules serve one common purpose.

That will be our design quality goal.

Now, as an example, let’s consider some use cases of a simple CMS or a blog engine.

  • create post
  • publish post
  • change theme
  • view post
  • set permalink style
  • comment
  • add tag
  • install plug-in
  • upgrade platform

How does this help us with partitioning?

If you look closely at the list, you will notice that some cases are different from the others. The biggest difference I’m seeing is that we have post-related use cases and site- or infrastructure-related use cases.

This is exactly the kind of cohesion-based split we are looking for. We end up with a PostManagement module that handles operations on posts and a SiteAdministration module for the other stuff.

Those two are unlikely to have overlapping logic, mutual dependencies or similar issues. This is a clean separation of concerns.

Functional Partitioning of a System

We can further split the PostManagement module on the basis of rendering vs managing posts.

Functional Partitioning of a System

Core Contract Definition

In many applications you can use a list of use cases to define the contract of core application modules. Specifically, a set of use cases can be a model for the following (similar) design elements:

If we wanted to create an application service responsible for working with posts, each service method would implement one use case:

public interface PostAppService
	int CreatePost(string name, string content);
	void AddComment(int postId, string text);
	void AddTag(int postId, string tag);
	void PublishPost(int postId);

The benefit of this approach is that use cases are easily traceable to the implementation. This helps to debug the system and just in general provides structure and consistency to the design.

Overview of all System’s Functionality

Another feature of a set of system use cases is that it represents a short, but complete overview of system’s functionality. This is useful not only for design, but also for things like:

  • explaining the system to another person (work best when combined with a context diagram)
  • work prioritization
  • a roadmap for implementation
  • a roadmap for acceptance testing

As you can see, defining use cases is a good time investment for any software project. Especially when done upfront as part of analysis.