Thursday, December 1, 2022

Problem and Solution Spaces

The ‘problem’ space is the physical/digital issues and data that are facing a group of users for a given domain.

The ‘solution’ space is the set of all functionality embedded into a software system that can be used to address some of the issues in that problem space.

Keeping those two strictly separate from each other makes it far easier to design complex systems.

A ‘feature’ is something the users need to deal with one or more of their issues in the problem space. That feature then maps over to one or more parts of functionality in the solution space.

It’s a bad idea to let any solution terminology infect the description of the problem specifications. It is usually a good idea to push a lot of the problem terminology into the solution design.

That is, a common feature in a lot of systems is the ability to manage a particular category of data. Which is often mapped to ‘new’, ‘edit’, and ‘delete’ GUI screens in the software. It would be a mistake to call “editing” that data a feature. It is not a feature, it is just one of the parts of the functionality needed to address “managing” that data. It would be good to be more precise about the naming of that data. So, it’s asymmetrical.

Now it may seem overly pedantic to discuss it this way, but there are deep seeded reasons why it is better.

An obvious one is that just implementing part of the functionality is not actually implementing the whole feature. So, we see a lot of systems out there with ‘incomplete’ features and they are extremely frustrating to use. Partially solving any problems often just makes those problems worse.

Another good reason to do this is that the terminology and necessity in the problem space does not always map nicely into the solution space. In fact, usually, it is kind of horribly denormalized, if not entirely irrational. People want to work in a way that is comfortable for them, which is usually far more difficult to implement. Because of this, we often stumble into the problem of whether a ‘simplification’ of any kind is just effective for the programmer or whether it really benefits the user. It is rarely both. It’s a classic trade-off.

If you do some ‘analysis’, that should be purely in the problem space. If you do some ‘design’, then it quite obviously needs to be in the solution space. If they are kept distinct, then we have a way of not blurring the lines and injecting noise into the outputs. The users need to keep track of something happening in their business. That is their feature. If that actuates into a portal screen or a report or some other construction, that is part of the design of the solution.

One place that is super common to see a mess is in classic requirements. They are often a haphazard mix between features, implementations, designs, conventions, abstractions, etc. Pretty much anything from either space gets brutally mixed and matched and combined into a swamp. This is the key reason why they don’t get cross-checked properly and validated early on. This leads to confusion, ambiguities, and tonnes of scope creep. It’s a bigger reason why a lot of systems derail than methodology. If the requirements are convoluted, then any attempts to clean them up without splitting out the spaces will fail too, and sometimes just make the confusion worse.

If you had a clean list of features and another clean list of functions, then you could just mechanically go through all of them and see which functions address which features. You can see if the feature is fully or partially addressed. You can see useless functions. You would also see which features are not addressed at all. That would let you double-check that the solution design will actually help to ensure it is a good fit.

A big problem with modern software development is that the definitions we use in our industry are vague, blurry, convoluted, and often deliberately scrambled.

No comments:

Post a Comment

Thanks for the Feedback!