Back in the 1980's, when dinosaurs roamed the Earth, people defined programs as data flowing between multiple processing units or functions, each manipulating or otherwise using the data as it passed through. Languages like COBOL supported and amplified this thinking. Antiquated terms like "data processing" and "information technology" still reflect it.
For most of us working in the 21st century, a data-flow-first architecture is destructive. (I am not a fan of functional programming, but that's another post.) Probably the worst side effect is strong coupling between processing units, which depend heavily on the previous step in the chain, so are coupled to their predecessor unit. Touch anything in the flow, and you have to touch everything. The flow is a rope tying everything together in undesirable ways. This is a maintenance nightmare, and if you're using AI assistance, leaves you open to unexpected bugs in distant parts of the chain.
Fortunately, with the usual rare exceptions, most of us don't see our systems primarily as data-manipulation or report-writing engines. We care more about what the system does than how it does it. The data is buried somewhere in the "how," but our customers don't care much about that. No customer on the planet chooses your product based on the database it uses. That's just an implementation detail.
That shift from data to "doing" meant we had to program in a new way. Object orientation (which does not mean what many think—it has nothing much to do with subclassing and interfaces and the other semantic baggage you find in so-called OO languages) came along. An object is defined as what it does, not what it contains. You ask an object to do something for you without caring how it does it. The data is hidden—abstracted. The rule is: Ask for help, not for information. Ask the thing that has the data to do the work. If one object can't do everything you ask, then it delegates to other objects that can. Data stays put in the objects. The point of that structure is that the object is only loosely coupled to the clients. It's easy to make radical changes to the implementation without affecting the rest of the system.
Entire architectures are now built around this way of thinking, though the notion of an "object" has expanded to any bounded component, e.g., a microservice. There's no central database—microservices each have their own, just as the data in a class should be private. Significant systems we use every day (e.g., Netflix) follow this model. Most modern architects (myself and Robert Martin, among them) think of the database as an implementation detail, best abstracted away.
Nonetheless, I still run across people convinced that we are doing data processing and build their systems accordingly. (CRUD APIs & getter/setters are a huge red flag.) To me, applying data-centric thinking to most modern programming problems is like trying to cut through steel with ice cream. It's not an ideal tool.
Discussion about this post
No posts

