Recently (weeks ago) I saw something that ACRONYMED part of my programming approach.
There is only a single point in the entire code-base that knows the TRUTH of "that".
I generally use "Knowledge". SPOK wouldn't be bad. Maybe make it "Certain Knowledge". SPOCK!!! LIVE LONG AND .... OK
SPOT. While TRUTH works, I will speak (write) about knowledge. Mostly because I anthropomophize the hell out of code. It KNOWS something... and only ONE place in the code show KNOW that. Only one.
I get some flack when I go as far as wrapping system code. Like
substring. But... I want there to be a SINGLE POINT OF TRUTH for how the system performs substring.
I get A LOT of pushback when I suggest we wrap numeric operations. Such as additiona,
+. Now, for RAW numbers, no. I don't... except in practice examples. Mostly because raw numbers show not exist in your system. It is someting... REPRESENT THE CONCEPT... I'll get back to that.
If I have two objects that CAN be added, let's say, Vectors. Then I'll have a Vector class and yes, I will wrap the operation of adding two Vectors together.
Now, depending on the language, there's options. In C# I can do operator overloading. In Scala I create new operators.
In Kotlin I can create infix notation and make it whatever I want. Lots of choices.
Most of these though end up putting the code to add Vectors together in the Vector class itself.
That velocity class is going to get SO OVER LOADED. I can add, subtract, multiple... and more... math... operations...
Nope. This is one of the Fluent Type things I continue to use. Classes for each operation.
I can define the behaviors in the interface, and in the class just return other classes. My Vector class knows the "value" of the vector and what to delegate to.
That's it. If I need to change how I multiple vectors... I will only change the
Sure, if I had it in the Vector class, I'd only modify the Vector class. But I'd also modify that for changes in addition, substraction, transformation... EVERYTHING. The Vector class then KNOWS EVERYTHING.
SPOT alone is not enough. SRP is useful. They push your code into the right direction. "Once and Only Once". All these get us closer. But it all feels like they fall short of "Represent the concept". Or more wordy
Have a representation for every concept that exist in the code.
This is what I do.
Multiplying vectors is a concept that exists in the code. CREATE A REPRESENTATION FOR IT!!!
SPOT allows you to put the code for it in the Vector class. If it's in a single place, DONE!
SRP allows you to put all vector code in the Vector class. It handles "Vectors". IF each method does one thing... DONE!
But it's going to grow and be cumbersome and treacherous.
What we need to do is Represent the concept. I am using "represent" as short hand for "create a class". I don't want to limit to to OOP language. You can do this in any paradigm; and I think it'll make it simpler... but I haven't been deep in those, so... pinch of salt.
In OOP - Absolutely. It will improve the maintainability of the code.
Create a class for the concept that exists in the code. Not just "things". How things interact (eg multiplication) need to be represented.
How decisioins are made should be represented. Yes... I am saying that an
if statement should (generally) exist as it's own class with each flow another class that gets invoked.
I'll caveat that this doesn't always get this extreme, but damn it clears things up. Testing is EASY as well. So I try to.
SPOT, SRP... good guides. Represent the concept in the code will further force the code into a certain type of structure... one that starts to force it into GOOD OOP that's easy to maintain.
That's all. Represent the concept. I know I've said it before... but... LOOK! A POST!!!