HXA articles

Reusability By Orthogonalysis

To make software reusable, divide it into orthogonal facilities – because that makes available maximal functionality with minimal dependencies.

1000 words (5 minutes)


Introduction

“I am making some software. How can I ensure it is reusable?”.

Let us bifurcate the question of software reusability into two considerations, ‘external’ and ‘internal’.

The external concern is what the software does, what functionality it offers. The internal concern is how that given functionality is arranged or available. One might express the distinction between external and internal as that between content and form.

These can be addressed and handled independently, and so less complexly. And this partitioning leads us toward an answer to the overall question of reusability that is both clear and general.

External

The external is the dominant concern, though more preliminary than central to the enquiry.

The generality and reusability of software is ultimately limited by what it does – it is not something that can be added-on, adscititiously. If software offers only insubstantial function, mere re-arrangement of it can make little improvement.

So to make something general/reusable, you must first make it useful. And that is not a matter of code-twiddling, it is about deeply understanding the domain and requirements.

First, set the overall functionality: by gathering info, getting the requirements, as and when needed and available, and design to fit them. Properly establishing the functionality founds the assumptions on which any furtherance of reuse can be properly deliberated.

Speculation and generalisation of what might later be needed or useful is ever a temptation in software, and if you are at such liberty, here is where it can be indulged. But such extras belong only in this ‘external’-focused half of the activity, and must be isolated from the second half.

Internal

The internal is the subservient, secondary concern, but it is usually taken as the heart of reusability questions.

Because where requirements are imposed from outside and a matter of the domain, here is still some choice as a matter more purely of code. Further, that choice is more determinate and tractable. Marshalling requirements is quite unbounded and difficult, but deciding the arrangement of software is circumscribed in a non-contingent logical sphere.

The conscious, sharp separation of external/internal now yields its pay-off: we are freed from worrying about what functionality, or what might change, and are left a much more determinate job. One can now more clearly ask, given that limited, fixed functionality how can we make the best of it, regarding reusability? And since the question is posed abstract of any particularities of function the answer will serve generally for all software. We could now plausibly deduce some clear and general guide.

The question of software reusability becomes this: one of optimally dividing up the parts. And this ‘internal’-focused half of the activity is a strict refactoring: functionality is held constant and adjustments are only synonymorphological – confined to the representation. So how should your software be divided it up?

——

Software (re)usability in general is set by two factors, a positive and a negative: what a part offers its users and what it demands of them. The more it offers, the more situations a part might be valuable, but the more it demands, the fewer situations a part can be accommodated.

Since the functionality offered overall has already been fixed (by the ‘external’ consideration), the only way to offer more is to: 1, expose hidden functionality; 2, minimise the demands made by it.

The best way to achieve those is to divide the software into pieces (as a supplement alongside the whole), and make those pieces orthogonal – non-overlapping – in functionality. This offers all the functionality that can be extracted, while each piece makes no more demand than needed to enable its offering. Together, these maximise functionality, and minimise dependencies.

Comment

What about the ‘single responsibility principle’ – is this not the same?

The problem with that formulation is absoluteness: it is difficult to answer, it is too large and confounded a question. What is a single responsibility? In what sense? Software is by nature always subdividable, so to see something as single must disqualify some decompositions and not others – what is the criterion?

But orthogonality is defined relatively. The criterion of what is permissible for each part to do is simply what other parts do not. We need not try to condense from the varied air of software culture some exogenous criterion, or divine singleness as some obscure inherent property, we can instead more mechanically compare one part with another.

(And if the ‘single responsibility principle’ is defined as ‘single reason to change’, well, ‘change’ is a very confused and problematic motive in software engineering design ...).

——

Orthogonal division might recall another older prescription for design: to make (APIs) ‘minimal, complete, and primitive’. What of that?

The ‘minimal’ and ‘complete’ clauses are actually redundant: they prescribe merely that the functionality offered should be no more than the requirements say, and no less. The ‘primitive’ clause is what approximates to orthogonality, but if that is its intent, it expresses it weakly and implicitly.

——

Is not orthogonality of function here still ill-defined and troublingly vague? Does it not rest heavily on human judgement?

Of course, in the final reckoning, but, broadly, those deciding the quality are those acting upon it. If an average programmer deems some function/division orthogonal, that is OK because they are the ones who need to be satisfied.

——

Does this really furnish a sufficient optimum? Is it not over-simplified?

Maybe for any n pieces there is an optimal division, and that target not easily seen, or maybe there are conflicts or other accidentals that impede attainment of a good orthogonality. These and so on are not addressed.

But these are all non-critical shortfalls or refinements. A rough optimal from a rough orthogonality is adequate – this is after all a secondary concern of making the software, and an uncertain one. The greater speculation of value warrants the lesser commitment of work.

——

Finally, there is the cost. Dressing all those parts of the code to be neatly separately accessible/usable is a modest task, yet not negligible. Do you really care or need to provide for reuse? If not, do not bother with all this.


Metadata

DC: {
   title: "Reusability By Orthogonalysis",
   creator: "Harrison Ainsworth",

   date: "2016-04-24",
   date: "2016-03-23",

   type: "article",
   format: "text/html",

   language: "en-GB",
   subject: "software engineering",
   description: "To make software reusable, divide it into orthogonal facilities -- because that makes available maximal functionality with minimal dependencies.",

   identifier: "urn:uuid:AA599023-0DA3-42EF-B3EA-971CC2725E89",
   relation: "http://www.hxa.name/articles/content/Reusability-By-Orthogonalysis_hxa7241_2016.html",

   rights: "Creative Commons BY-SA 4.0 License"
}