CUPID

The CUPID Properties

One thing that has always been true is that you will continue to learn in software development. Just last week, a friend asked me whether I had heard of the CUPID Properties—I had not. As I began reading an article he’d forwarded, I became more and more delighted with CUPID. 

Dan North and others developed the CUPID Properties as a backlash against the well-known SOLID Principles. If I understand Dan correctly, SOLID can, at best, be difficult to interpret and, at worst, be irrelevant. Even though it took me many years to get my head around SOLID, I can’t entirely agree with Dan’s harsh indictment. The SOLID Principles have become the way I think of classes and modules.

Nonetheless, I always look for better (or at least another) means of expressing the same sentiments as SOLID. And in that regard, CUPID may not be better, but it captures the concepts underpinning well-designed software from a different angle than SOLID.

CUPID

In his article on CUPID—which I highly recommend you read—Dan North condenses the properties of joyful software—code that is a delight to work with—into five succinct characteristics:

  • Composable
  • Unix philosophy
  • Predictable
  • Idiomatic
  • Domain-based

Why properties rather than principles? North speculates—and I mostly agree with him—that principles are black-and-white rules which our code either runs afoul of or complies with. On the other hand, North argues, properties allow for a sliding-scale nature of improvements. Sort of like, we are pretty good in some regard, yet we can improve further. However, occasionally—not often, especially in the wild—code can be so good, so joyful to read and use, that it is exceedingly hard to improve further.

Let’s drill into each of the CUPID Properties.

Composable

Code composed into small, well-designed, easily understood parts, each doing one thing well, sounds like the Single Responsibility Principle (SRP). Yet Dan North claims that’s not the case with CUPID’s first principle of Composability. Supposedly, it encompasses more than the simple concept of ‘one class, one responsibility‘. 

Composable software minimises dependencies on frameworks and libraries. It also reduces dependencies on dependencies; in a statically typed language, we want to avoid depending on classes that reference libraries and SDKs, as such chaining produces a transitive dependency on the external library code. In that way, we reduce such dependencies (or Coupling) by introducing abstractions and depend on those instead. Essentially—Coupling is bad, cohesion good, and concrete stuff depends on abstract stuff

Also, when our code is composable, as per CUPID, it reveals intent everywhere. The requirement for source code to clearly show its reason for existing—its purpose—deserves a property or principle all on its own—it’s that important for maintainability and programmer joy.  

Unix Philosophy

Unix, the most popular OS in the world, follows a simple and consistent design philosophy: Each Unix command does one thing and does it well. Sounds like the SOLID’s Single Responsibility Principle (SRP), right? Yet, North claims the difference lies in Unix providing a single purpose versus the SRP’s single responsibility. He offers the example of a code module producing a report where the content and format change together and claims that the SRP would demand an artificial separation of those responsibilities (content generation & formatting). That’s not the SRP I know, which asserts that ‘we should put together those things that change together and at the same time and separate those from things that change for different reasons and at different times‘. If formatting and content generation in this report tend to change together, the SRP will not protest if they cohabitate in the same module.

So, while I agreed with the idea of a single purpose being a good idea, I had misgivings with the example given. 

Predictable

The third CUPID property of predictability means that software should behave as expected. I couldn’t agree more. North goes further—as much as possible, a system ought to act deterministically—for a given input, it will always produce the same output or effect. Of course, some code will necessarily be non-deterministic, like a random string generator. Yet even then, in a CUPIDful system, the determinism extends to the non-deterministic boundary: The random string subroutine will be invoked with well-defined, deterministic arguments.

Idiomatic

Joyful code is Idiomatic, i.e. it feels natural and is easy to work with. On the other hand, non-idiomatic software is hard to read, cumbersome and fragile to change and cognitively tiring—Anything but joyful. And our jobs should be enjoyable and highly creative and give us energy rather than wear us out. 

There are several idioms we may want to observe. The choice of programming language may impose implicit constraints. In JavaScript, the opening brace (‘{‘) is conventionally placed on the same line as the predicate or function declaration. In C#, it’s traditional to position the opening brace on a new line. 

Furthermore, local programming styles, whether undocumented, generally understood customs or well-documented and enforced standards, are also idioms. To feel comfortable in a code base, it’s best to face only a single coding style rather than many. 

Domain-based

Software exists because it is wanted and needed. North makes the point that software that naturally expresses the behaviour it produces in terms understood by all stakeholders tends to be more joyful than the contrary. The point here is that constantly being engaged in a translation exercise of semantically identical terms is tiring. If the code refers to ‘customers’ while the business knows only of ‘clients’, this state of affairs will grate on both parties and lead to misunderstandings. Best to have a ubiquitous language that all parties have agreed to and will use in all interactions.

Conclusion

In conclusion, I like the CUPID Properties more than I have let on. I will continue to stand firmly by the SOLID Principles, which have much history behind them and are tried and tested by many years of experience. Having said that, I am excited to employ the CUPID Properties as an alternative set of criteria to judge software quality (and joy) at the class and module level. 

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply