Logic Fault

Have you considered running your software on a computer?


On Code Organization

It is easier to feel good about reading SOLID-factored code, but it is easier to read and understand under-abstracted code quickly.

Default to putting related code as close together as possible. The more lines of indirection you add to service2.insert(service1.select(...)) the harder it is for people to maintain the code.

If primitive data (say a string of “customer ID”) is what’s present at the top of the call stack and that primitive data is the only thing needed to perform business side effects at the bottom of the call stack, do not convert that data into a more complex business object. E.g. if a “customer ID” string is available at the top, and it can be used to build a multifield “customer” object, but only the “ID” field of said object is used in a “select-from-where-customer-ID-equals” at the bottom of the stack, don’t hydrate the ID into a full Customer object. Hydration often involves I/O and extra computation, and obscures the actual behaviour of downstream code: in this regard, the presence of the ID in the top-level call signatures indicates to readers that only locator keys are needed by the code below. That’s a strong hint about the IO interactions and behaviour of the function in question, if you’re reading in a hurry (which, see “On Maintainers”, most people are).

Passing complex objects (that is, deliberately providing “too much” data downstream) should only be done:

  1. For extremely public/high rate-of-change entry points, or
  2. Reactively when additional data becomes needed downstream. Follow the rule of two here. In the above example, if customer ID and a field keyed off of it became necessary for the “select”, it would be appropriate to add a single-column lookup for that field next to the “select”. If more fields became necessary, or if they became needed elsewhere, that would potentially be reason to refactor the code to (re)hydrate entire complex “customer” objects.
  3. If good support for sparse objects is available. Such support is rare, and good support is rarer still.