Skip to Content
“Superset Hell” is my name for an anti-pattern in enterprise software development I encounter quite frequently: Developing the superset instead of the intersection of requirements in a shared component. I’m quite sure you have seen it before.

An example

To give you an example, suppose you’re developing a central business partner management application that is supposed to be used by a number of business applications.

  • Human Resources requests the fields “Name”, “Salary” and “Entry Date”.
  • CRM requests “Name”, “Sales Representative”, and “Sales Area”.
  • Financials requests “Name” and “Debtor Status”.

If your architectural style is to take all these requirements and solve them in a cross-component software, you’re in Superset Hell™.
The cross-application component becomes a shared API by and for all of its consumers, resulting in a tight coupling of every user of the component with every other user of the component. In this blog I have worked out some examples and details of the possible consequences of this type of coupling.

Using the intersection vs. the superset

Figure 1: Using the intersection vs. the subset

Superset Hell as a danger to maintainability and agility

Software architecture degenerates, but cross-application components that do not have an absolutely water-proof insulation against the specifics of their consuming applications decay at the rate of raw hamburger meat left out in the sun at noon.
Very soon, their code will be cluttered with IFs and ELSEs covering particular exceptions from the general rules as required by a number of consumers. Looking into the code, you will be baffled by data structures containing elements that are populated only under conditions and with semantics that are Too Complicated To Explain™. Senior team members sigh and point out that things are “historically grown”. (Note to junior project members: This means that you would be better off throwing them away, were it not for the risk of introducing new bugs.)
Any software with these characteristics is extremely difficult to use and maintain.

  • As a new consumer of the software, you never know if there isn’t a hidden pre-condition or post-condition that will break your neck.
  • Maintaining the software is difficult because diversity drives complexity stronger than genericity. For example, it is harder to understand and change code with many nested IFs and ELSEs than code with field symbols. (Generic code, though abstract, is often structurally simpler than application code expressing real-life business logic. This is why system programming is for sissies. Just kidding.)

Vulnerable areas

All cross-application, cross-business domain components are naturally vulnerable to Superset Hell. This goes especially for areas which are close to the business logic, but represent an orthogonal aspect that crosses most applications. Examples are:

  • File Import/Export Services
  • Output Management and Printing
  • Records Management
  • Workflows
  • Master Data Management
  • Dispute Management
  • Archiving
  • Organizational Management

The way out of Superset Hell

A good way out of Superset Hell is provided by the following architectural pattern:

  • For cross-application business components: Address only the overlap of requirements in the cross-component software (with some good measure).
  • For technical components: Keep them purely technical.
  • Provide a release-stable plug-in mechanism for each particular application to integrate their specific extensions.
  • Avoid applications using each other’s add-ons whenever possible.

The following features of the ABAP Objects language and the Web Application Server ABAP will support you:

  • Object-orientation – especially polymorphy through interfaces – is excellent for creating plug-in architectures.
  • BAdIs are one very well-documented and fast example for this. Read all about them.
  • Avoid inheritance (subclassing) unless the superclass defines a concise and stable API for subclasses. Prefer interfaces for polymorphy and composition for extending functionality.
  • The Switch and Enhancements Framework introduces many valuable tools to define, implement, seamlessly integrate and manage enhancements to underlying software layers.
  • Reduce complexity and achieve encapsulation by hiding implementation details in private and protected members of ABAP classes.
  • The ABAP package concept helps you with encapsulation on a higher level by allowing you to declare which elements of a package are visible outside the package, and enforce the usage of your software through released APIs.
To report this post you need to login first.

2 Comments

You must be Logged on to comment or reply to a post.

  1. Vijay Vijayasankar
    Great blog ! You have made the case really well.
    I just wanted to throw in a couple of thoughts.

    When number of applications that need cross-app data increases, finding a common intersection leads to compromises. Short example : if 5 out of 6 apps need a field, but one does not – do we include this as part of cross app data?

    A strict definition of intersection could lead to “very light” applications, which of course maybe good for long term – but will increase development and testing time in short term, since all consuming teams will have to develop enhancements of some sort to live with the cross-app layer. Then subjective judgments happen on how much the consuming apps will change over time, and the road to hell will open 🙂

    (0) 
    1. Thorsten Franz Post author
      Hi Vijay,
      You’re right, those compromises on field level happen frequently, and often the overall quality suffers from them. I should have written something about that.
      In my opinion, the best recipe against this kind of “architectural degradation by majority voce” would be to have a clear-cut definition of the cross-application component from the beginning on, and use that to decide whether a new feature goes into it or not.
      So we would be looking at all the components and their intersection in the beginning, derive a workable definition of scope and responsibilities from this, but stop looking at intersections afterwards. This seems a logical consequence of the fact that each of the participating components change shape over time (and so do their intersections), whereas a jointly used component should remain as stable as possible.
      Cheers,
      Thorsten
      (0) 

Leave a Reply