My recent post/article on LinkedIn seems to have garnered quite a bit of attention, and several comments that I just can't agree with.
Over the years, I’ve seen the same objections to model-driven development surface again and again. Someone will say that models are fine for sketches and communication but useless for real implementation, or that once you add all the necessary detail, the model becomes unreadable anyway. Another common claim is that you simply cannot manage models the way you manage source code. I can understand these arguments, but in my opinion, they reflect a partial view of what modeling tools and processes can actually do when you commit to using them seriously.
I first started learning about these approaches in 1998 through Shlaer-Mellor methods. In 2002, I began working hands-on with Executable UML and Pathmate on Rational Rose. For more than a decade now, I have relied on Sparx Enterprise Architect with heavily customized templates. That experience has included generating 100% of production-ready code for embedded and desktop applications in Java, C#, and C++. The generated code is indistinguishable from careful hand-written work, unless I intentionally embed traceability signals for my own benefit during reviews or maintenance.
One persistent misconception is that a useful model must stay so high-level that it omits critical details. The thinking goes that if you try to capture everything, the model will balloon and lose its value as a communication tool. In practice, I have found the opposite dynamic at work. A well-structured model is not a single giant diagram. It is a collection of coordinated views—class models, state machines, activity diagrams, sequence diagrams, decision tables—at different levels of abstraction. You navigate between them. The tooling hides or reveals detail as needed. This layered structure actually makes it easier to reason about complex behaviors than scrolling through thousands of lines of intertwined source code.
Behavioral logic translates particularly well. State diagrams, activity flows, and decision models can drive code generation directly through templates. When the templates are mature, the output looks like careful hand-written work. You can configure the generator to insert traceability markers so that every relevant line of code points back to its model element. None of this requires sacrificing readability at the modeling level; it requires investing in the right structure and templates up front.
Early on, I was generally disappointed in the stock templates that shipped with the tools. They fell short of what I knew was possible. From the very beginning, I focused on improving template quality, and over time, I achieved substantial gains. At this point, the generated code shows fewer inconsistencies than typical hand-written code produced with auto-completion and formatting automations. The discipline enforced by the model and templates simply leads to more consistent results.
Another frequent objection is that models cannot be version-controlled, diffed, or merged the way text files can. I understand where the concern comes from—many modeling tools historically stored information in proprietary formats. In my experience with modern Sparx Enterprise Architect, the diffing, merging, and auditing capabilities are very good. They are at least equal to the same activities in text, and in some ways better. Sparx Systems demonstrates these features clearly on its YouTube channel. You see changes presented in full graphical context, with selective merging of attributes and elements through dialogs. The tool handles the comparison and integration at the model level in ways that feel natural for the work.
I sometimes hear that programming languages remain the best way for humans to communicate intent to machines. There is truth in that for certain low-level implementation details. In my experience, though, the model serves a different and complementary purpose. It lets you express and verify architecture, constraints, and high-level behavior first. The generator then handles the mechanical translation according to rules you have encoded in the templates. This division of labor reduces certain classes of defects. It also opens doors to capabilities I have not leaned on as heavily: model-level debugging, executable state-machine simulation, and links to physical modeling environments. When everything aligns, you catch problems earlier and spend less time chasing integration surprises.
None of this is magic, and it is not the right approach for every project or team. There are upfront costs in learning the modeling discipline and tuning the generation process. Occasionally, I have made false starts; over-modeling things that should have stayed simple, or expecting the tool to compensate for unclear thinking. What I have observed after two decades of use, is that model-driven techniques deliver the strongest returns on systems with significant behavioral complexity, especially where safety or reliability matter. The abstraction helps you see the forest, while the templates ensure the trees are built correctly.
The field has evolved since the early MDA discussions I followed in the early 2000s. Tooling has improved. Practices have matured. Yet the core myths persist in online discussions and hallway conversations. They often rest on impressions formed from lightweight diagramming rather than full code-generating model-driven workflows. Some caution is to be expected. Software engineering has seen plenty of over-hyped approaches that failed to deliver. My own conclusions come from what I have built and maintained.
I encourage you to evaluate these ideas for your own work. I suggest starting small: pick a well-bounded application or module, spend some time improving the templates, generate the code, and compare the result honestly against hand-written alternatives. Track defects, maintenance effort, and your own ability to reason about the design. Over time, the evidence accumulates. For me, it has shown that models, when used as implementation assets rather than just pretty pictures, are more than communication tools. They become a practical way to direct the machine while keeping the human view clear and organized.
I still write plenty of code by hand when it's a better fit. The two approaches are not in conflict. They can even co-exist within a single project. They are different levels of conversation with the machine. Getting that conversation right has been one of the more satisfying parts of the work.