In this post we describe a situation between me, the head of engineering, and a PM (Don) that wants to push a (not very good) solution to one of the engineering team. The engineers are pushing back, and Don does not understand why. Everybody is in good faith, but they do not understand each other…
Let me try to explain the issue here from my point of view. This is a classic problem in software engineering, and it happens all the time: however, if you want to understand it you will have to take a bit of time, at least as much I invested to write this, so please sit down, relax, and enjoy the ride!
abstraction consists in capturing those portions of reality that are significant for your problem
One of the core concepts of software engineering is abstraction, which consists in capturing those portions of reality that are significant for your problem: software systems tries to represent reality, but its complexity can be overwhelming. Imagine that you want to model a car: how would you do that? Would you represent it with four wheels, four doors, a bonnet? Or would you consider its speed on the road, its position on the territory? What about the current angle of the steering wheel? The number of revs of the engine? I could go on forever. The fact is that you have to capture a portion of it, the parts that make sense for your problem. So, if you plan to manage a factory that build cars, then the structural abstraction (wheels, bonnet, doors) is a good one, while if you are building a navigation system you will be mostly interested in its position, speed and similar.
models are implementations of abstraction in the software realm
Once you have defined the overall abstraction that you want to use, then you end up defining your models, which basically are implementations of the abstraction in the software realm, defining structure and behavior based on our requirements. In an Object Oriented approach those are usually represented (unsurprisingly) by objects, which may have (on some typed languages) also a generalization, which is basically a blueprint to create objects (usually called “class”, but that’s not really important). They may also have some form of persistent representation, which can be stored in a relational database (like MySql) in the form of records on tables, or as a document on a nosql database (like Mongo). They also have a tight relation to the user experience, which should be built around such models and should match the mental model that we (and our users) will instinctively adopt and use.
on every change the models must be improved to accommodate future changes
I hope it’s clear now why models are so important, and how pervasive they are: basically they are the foundation of our software, get them wrong or screw them, and you will have very big problems. For that reason maintaining and evolving these models correctly is extremely important, and the trick is to make sure that at every change we make, the models are improved so that’s easier to accommodate changes in the future.
your change does not evolve the model, it violates the underlying abstraction, and makes it harder to change
Now, the change that you are suggesting consists in picking a portion of that model and changing it violating the underlying abstraction: you are basically proposing to screw it. You are not evolving it, you are not making it easier to change in the future, you are just patching it. And when you continuously make changes like these then you end up with a pile of crap that you won’t be able to change at all. Sounds familiar?
do not offer solutions, state the problem
For that reason the engineers are resisting this action. So, do not offer solutions: state the problem, and trust your team to come back to the right solution! And if it’s not right.. well, failure should be part of the process. Like Lynda Resnick once said, “you will learn more from your failures than your successes“.