A more succinct definition leading to better code modularization
To me the Integration Operation Segregation Principle (IOSP) is maybe the most important principle of clean code development. The reason: It’s so simple to follow. Because you can recognize if it’s been applied by looking at the code alone. IOSP code has a certain form. A form that supports understandability and testability.
I’ve defined the IOSP before:
And I’ve developed it in detail in my book from the original definition of object orientation:
It works great “under battle conditions” in projects when crafting new code or refactoring old code. I’m very, very happy with it.
A more succinct definition
But still… Sometimes I’m thinking there could be an even simpler definition.
And there is. The other day I came across one:
Integration Operation Segregation Principle (IOSP)
Let your functions be either Integrations or Operations.
Integration: A function composed only of calls to functions in the same code base.
Operation: A function composed only of calls to functions in another code base.
Operators (e.g. +, -, ^) and control flow structures (e.g. if-then-else, for, try-catch) are deemed to be also just functions in another code base: the standard library of a programming language. Or they are syntactic sugar for calling them.
What’s another code base? That’s obviously code you haven’t written yourself, e.g. a library or a framework from a 3rd party. In addition to that, though, also your own code can be considered “another code base”: that’s the case if you separate your code into libraries whose source code you “put out of sight”, i.e. which you really, really consider black boxes while writing a function in another part of your software.
If you want to give your own different code bases a telling form, wrap the code into a component (see here for a description of what I mean by that). The contract of a component pushes the implementation behind a border making it somewhat “foreign” or “3rd party” with regard to the code where you’re writing a function.
Or maybe even host your code in another service, i.e. pushing it even further out, making it an even deeper shaded black box.
The separate contract of a component and service to me is a barrier for change. It’s hiding details. It’s defining a service to be (re-)used in other code bases.
IOSP as a driver for modularization
Turning this around, the IOSP is a great help for modularization. Because as soon as you feel hampered by the IOSP since it’s “forcing” you to keep logic down in the leafs of a function call tree, i.e. in operations, and those are growing bigger and bigger… you can wrap logic into a function and refactor it into another component, and call that in your operation. Like you do with a standard library function.
Of course, not only the IOSP should be applied to your code base, but also the Single Level of Abstraction (SLA) principle. So you’ll have to check your operations calling some of your components for “smoothness” with regard to the SLA. But in general I’d say it’s just fine to call your own functions living in another component from an operation.
Yes, I like this updated definition of the IOSP. Makes it easier to explain. Makes it a natural force for splitting up your code into modules.
I hope you like it, too.