How to Engineer Software

by Steve Tockey

Software can be engineered. Software should be engineered. But true engineering—in the sense of civil engineering, chemical engineering, mechanical engineering, aeronautical engineering, industrial engineering, etc.—of software requires more than just claiming “software engineer” as a job title. This book:

  • Defines what software engineering should really mean and shows how and why software needs to be developed this way
  • Presents the true nature of code—what lines of code actually mean—and draws out vital implications from that
  • Explains how the common difficulties experienced on mainstream software projects are avoided when this approach is applied

The approach in this book derives from work started in 1987 and has been used on a variety of software projects including real-time / embedded, scientific & engineering, and business data processing. All of these projects met or favorably exceeded stakeholder expectations for schedule, cost, content, software quality and long-term maintenance.

This book is aimed at the software development and maintenance technical community: developers, development leads, architects, etc. with intent to prepare them to be true Software engineers. Business analysts and Software Quality Assurance (SQA) professionals can also benefit from sections in the book.

Buy the Book

About the author

Steve Tockey is the Principal Consultant at Construx Software. He has been employed in the software industry since 1977, and has worked as a programmer, analyst, designer, researcher, consultant, and adjunct professor. During his career, which has included stints at Lawrence Livermore National Laboratory, The Boeing Company, and Rockwell Collins, Inc., Steve has obtained an in-depth knowledge of software engineering practices, including project management, estimation, quality techniques, object-oriented development and distributed object computing.

Steve has a Master’s of Software Engineering from Seattle University as well as a Bachelor of Arts in Computer Science from the University of California, Berkeley.

Read Steve’s full bio

Foreword to the Chinese translation of
How to Engineer Software

By Steve McConnell

It is both a pleasure and a privilege to write the foreword to How to Engineer Software: A Model-Based Approach by Steve Tockey. My connection to this book is not simply academic or professional—it’s personal. I’ve had the good fortune of knowing Steve for over two decades. For more than 20 years, we’ve worked side by side, collaborated on challenging problems, debated ideas, shared insights, and—most importantly—built a deep and lasting professional respect for one another.

From the very first project we tackled together, it was evident that Steve brought something extraordinary to the table. He’s not just a software engineer; he’s a systems thinker, a disciplined problem-solver, and a passionate educator. He possesses a rare combination of analytical rigor and clarity of thought, paired with an ability to communicate complex ideas in ways that are both comprehensible and compelling. Over the past 20+ years, Steve and I have dissected legacy systems, coached teams, developed curricula, and shared countless hours of discussion on everything from requirements modeling to design verification to the perennial debate over how to realize a vision of engineered software. Through all of it, Steve has consistently demonstrated a level of rigor, thoughtfulness, and integrity that is exceedingly rare—not just in software, but in any professional discipline.

For the entire time I have known him, Steve has maintained an unwavering commitment to doing things right. He has always advocated for approaches that are grounded in engineering discipline. For Steve, software isn’t merely written—it’s engineered. It’s not about hacking together code that happens to work. It’s about deliberately crafting solutions that are understandable, maintainable, testable, and economically viable.

That philosophy runs through every page of this book.

How to Engineer Software is more than a reference—it’s a framework. It provides a structured, model-based methodology for software development that is as intellectually robust as it is practically applicable. This is not a book about trendy technologies or fleeting practices. Rather, it is a thoughtful and thorough exposition of enduring principles that can guide both novice and veteran practitioners through the complexities of software creation.

At its core, the book embodies three key values that define Steve’s approach: clarity, consistency, and conscientiousness.

Clarity is evident in the way concepts are introduced and developed. Whether Steve is unpacking the semantic nuances of a state model or explaining the economics of error handling, he does so with a precision that helps the reader not only understand what is being said, but also why it matters. He makes distinctions that are too often blurred—between phases and activities, between specification and implementation, between correctness and completeness—and in doing so, he illuminates the terrain of software engineering in a way that is both logical and enlightening.

Consistency pervades the methodology itself. Steve does not advocate a one-size-fits-all solution, nor does he propose rigid dogma. Instead, he lays out a coherent framework that can be adapted intelligently to different contexts. He champions a meta-process—a process for selecting and tailoring processes—that reflects his belief in engineering as a discipline that must be simultaneously principled and pragmatic. The approach is model-based not for the sake of formality, but because models help manage complexity, clarify intent, and support verification. It’s a method designed for those who take their craft seriously.

Conscientiousness comes through in the tone of the writing and the depth of the content. This is a book written by someone who cares—about the reader, about the discipline, and about the future of software engineering. Steve doesn’t gloss over challenges. He acknowledges them, addresses them, and equips readers with the tools they need to confront them. Whether discussing agile vs. waterfall methods, formal correctness proofs, or estimation techniques, he approaches each topic with honesty, nuance, and a wealth of experience.

One of the things I most appreciate about this book is that it meets the reader wherever they are in their journey. For those early in their careers, it provides a solid foundation in how software should be built—an anchor against the chaos of ad hoc development. For seasoned professionals, it offers structure and validation—a mirror that reflects what’s been learned through years of trial and error, now organized into a methodical, reusable form. And for educators, it serves as a resource that bridges the often wide gap between academic theory and industry practice.

What also stands out is the breadth and integration of topics. Requirements engineering, modeling techniques, interface design, detailed coding practices, formal verification, error handling, estimation models—it’s all here. And yet, Steve manages to thread a narrative that ties these components together in a unified vision of software development. While recognizing the unique aspects of each knowledge area, he doesn’t treat them as isolated silos but as interlocking parts of an engineering discipline.

This integrated view of software engineering is especially important in today’s world. Software systems have become ubiquitous, and the cost of failure—whether financial, ethical, or human— has grown accordingly. In such a landscape, the call for professionalism in software development is louder than ever. Steve answers that call with this book. He makes the case, both implicitly and explicitly, that software development should be held to the same standard of engineering excellence as any other domain that shapes the world we live in.

Over the course of our two-decade collaboration, I’ve seen Steve hold that standard in every piece of work he touches. He has a passion for doing things right—not just for the sake of correctness, but for the people who rely on the systems we build. That same care and passion are reflected in this book. It is the distillation of decades of experience, the result of countless hours of deep thinking, real-world application, and hard-won lessons.

This book distills a career’s worth of experience, insight, and hard-won lessons into a form that others can learn from, build on, and extend. It is a contribution to the profession, a roadmap for those who want to elevate their practice, and a call to action for those who believe that software can—and must—be done better.

To those of you reading this foreword before diving into the book itself, I encourage you to do so with curiosity, openness, and a willingness to be challenged. There are no gimmicks here, no hand-waving, no hype. What you will find instead is substance—clear, actionable, thoughtful substance—delivered with care by someone who has spent a lifetime mastering his craft.

In closing, I want to reiterate how deeply I respect Steve—not only as a colleague and co- conspirator in the art and science of software, but as a person. He is thoughtful, generous with his insights, and unfailingly principled. This book reflects those qualities. It is rigorous but accessible, structured yet flexible, and above all, honest. It doesn’t promise shortcuts. It promises understanding. And that, in the world of software engineering, is the most valuable promise one can make.

—Steve McConnell
Chairman, Construx Software

 

After “Philosophy” and “Cleanliness,” Moving Toward “Engineering”

When I first leafed through the manuscript for Steve Tockey’s *How to Engineer Software: A Model-Based Approach* (Chinese title: *Model-Driven Software Design: Delivering Reliable Software Efficiently and Cost-Effectively*), a sensation—at once familiar and unfamiliar—spontaneously arose within me.

What felt familiar was this: as a deep practitioner and translator in the field of software engineering, I had the privilege of introducing John Ousterhout’s *A Philosophy of Software Design* and Robert C. Martin’s *Clean Architecture* to the Chinese-speaking world. These two works—one focused on managing complexity through “strategic programming,” the other on establishing system boundaries via the Dependency Principle—both pointed toward the “design” layer of software development: how to make code clearer, architecture more robust, and systems more readily comprehensible to the human mind.

What felt unfamiliar—and indeed, struck me with profound impact—was the radically different perspective offered by Tockey’s book. If *A Philosophy of Software Design* teaches us how to “write good code,” and *Clean Architecture* teaches us how to “build good architecture,” then this book poses a more fundamental—and far grander—question: On what grounds can we truly be certain that the software we are building is “correct”—both in terms of its business logic and its design logic?

Tockey’s answer is nothing short of subversive. He attempts to steer software engineering away from being a craft based merely on “taste,” “experience,” or “best practices,” and bring it back into the true realm of “engineering.” Drawing upon the foundational principles of computer science and discrete mathematics, he proposes an engineering pathway grounded in *Semantic Modeling*.

This led me to a profound realization: we often overestimate the value of “cleanliness,” while underestimating the power of “precision.”

In *A Philosophy of Software Design*, Ousterhout emphasizes that complexity is cumulative and that we must employ modularity to combat it. Tockey, however, points out that without a precise, unambiguous semantic model serving as a foundation, modularity may amount to nothing more than “neatly organizing errors.”

In *Clean Architecture*, Martin emphasizes the separation of business logic from technical implementation. Tockey, for his part, offers a concrete methodology: completely decoupling business complexity from technical complexity through the use of models. Only when business logic is precisely articulated as a model—rather than remaining as obscure logic scattered throughout the code—do we truly attain architectural freedom. Developers are then free to seek out the optimal design and code implementation without the fear of compromising core business rules.

The unique value of this book lies in its “rigor.” Through my past work in translation, I have come to deeply appreciate that excellent software literature typically falls into one of two categories: the “inspirational,” which sparks insight and points the way; and the “operational,” which provides tools and standardizes practice. Tockey’s book is a rare example that embodies both qualities—yet, in doing so, it transcends them.

These two elements. The book attempts to establish a “verifiable” engineering feedback loop. What impressed me most is the detailed exposition on how to derive acceptance test cases directly from semantic models. This is not merely a testing technique; it represents a fundamental shift in mindset. It implies that requirements are no longer vague “user stories,” but rather formal descriptions that can be rigorously derived through models; similarly, acceptance criteria are no longer subjective notions of “satisfaction,” but objective, verifiable logical outcomes. For serious engineers who aspire to treat “software as a science,” this unwavering commitment to rigor offers a long-awaited form of redemption.

Of course, I can also appreciate the reservations some readers might harbor: in an era dominated by Agile development, does such a heavy emphasis on “model-first” approaches and “engineering discipline” not seem overly cumbersome? My personal take on this is as follows: Agile addresses the issue of *speed*—specifically, the speed at which we “respond to change”—whereas engineering addresses the issue of *certainty*—specifically, the certainty that we are “building the right thing.” When tackling complex problems in the real world, what we need is not merely speed, but *precision*. The scalable development methodology proposed by Tockey—based on Domain Partitioning and Subdomain Partitioning—is designed precisely to endow a system with the flexibility to adapt to change, all while maintaining engineering rigor.

As the translator of *The Philosophy of Software Design* and *Clean Architecture*, I have long sought a book capable of bridging the gap between “design aesthetics” and “engineering science.” Today, I can say with deep satisfaction that this book has achieved exactly that. If the previous two books taught us how to become excellent “craftsmen” or “engineers,” then this book teaches us how to become responsible “designers.”

After decades of noise and rapid iteration within the software industry, we are finally beginning to return to the true essence of engineering: solving real-world problems with certainty, even within the constraints of limited resources. For all professionals who aspire to liberate software development from the shackles of “uncertainty” and embark upon a path of rigorous technical discipline, Steve Tockey’s book will serve as an indispensable “engineering handbook” for their desktop.

Bingsheng Ru
Chief Technical Expert, CodeWisdom Team, Fudan University
Guest Researcher, Tencent Research Institute
Translator of *The Philosophy of Software Design* and *Clean Architecture*

 

 

Precise Intent: A New Paradigm for Software Engineering in the Era of Large Models

Software—the underlying logic of modern civilization—is built through a process that has long hovered in the nebulous zone between science and art.

We yearn for its precision, yet often find ourselves ensnared by ambiguity; we strive for its stability, yet constantly fall victim to its volatility. This is especially true now, as the tidal wave of Large Language Models (LLMs) sweeps over us with unstoppable force; the paradigm of software engineering is undergoing an unprecedented metamorphosis. The deep-seated contradictions—previously obscured beneath layers of ambiguity and uncertainty—are being amplified as never before and thrust directly into our view.

This is precisely the fog I foresaw—and committed myself to dispelling—when I first introduced the concept of “Software Engineering 3.0” three years ago.

Under this new paradigm, we are no longer content with mere code generation; instead, we call for an intelligent transformation spanning the entire software lifecycle—encompassing LLM-driven requirements analysis and definition, design, code generation, and testing—thereby realizing a process where AI (specifically, human-machine collaboration) permeates every single stage. However, the immense power of these large models has, ironically, acted like an X-ray, clearly exposing a long-neglected truth: if our “intent” itself is ambiguous, then even the most powerful intelligence can yield nothing but ambiguous results.

This implies that, while we embrace the efficiency revolution ushered in by AI, we must—now more than ever—return to the fundamental essence of engineering: utilizing rigorous semantic models to “tame” complexity, and employing precise expressions to “guide” intelligence.

It is at this critical juncture that Mr. Steve Tockey’s *Model-Driven Software Design: A Practical Guide to Delivering Reliable Software* emerges like a guiding lighthouse, cutting through the fog to illuminate the path ahead. As a preeminent authority in the field of UML, Mr. Tockey infuses this work with profound insights and a wealth of practical experience, elevating it far beyond a mere tutorial on tools; it stands, instead, as a true philosophical treatise on the very nature of engineering. He begins by emphatically asserting that software engineering must be firmly rooted in the solid foundations of “computer science” and “discrete mathematics”—a perspective that aligns perfectly with my own philosophy of “returning software development to the essence of engineering.” This represents not merely a steadfast adherence to tradition, but a profound insight into future trends; for only by grounding our work in rigorous theory can we construct the robust bedrock capable of supporting the intelligence of AI.

With its unique problem-oriented approach, this book precisely targets the core pain points that have long plagued software development. Why are requirements constantly shifting? Why are we perpetually engaged in rework? Why is code so difficult to comprehend? Why does testing invariably lag behind the pace of development? And why, even with the adoption of Agile methodologies, do these fundamental pain points remain unresolved? Mr. Tockey meticulously unravels these seemingly disparate issues, tracing them all back to a single root cause: the lack of a precise means to capture and articulate software semantics.

In the era of Software Engineering 3.0, this diagnosis proves particularly critical. As we attempt to leverage Large Language Models (LLMs) to interpret requirements, generate code, or even formulate testing strategies, any semantic ambiguity inevitably leads to “intelligent distortion.” This book offers the key to resolving this dilemma: through “semantic modeling,” it establishes a shared, precise “basis for understanding” accessible to both AI and humans.

Furthermore, the theoretical depth of this work commands my utmost admiration. The book’s incisive dissection of the “essence of code”—distinguishing between syntax and semantics, and expounding upon the concept of contracts, pattern-based design and Liskov Substitutability—along with the core insight of viewing code as a “semantic mapping”—represent profound wisdom. This deep-seated understanding—rather than merely adhering to surface-level syntactic rules—serves as the cornerstone for building reliable and scalable software. During the design and coding phases, this book builds upon the foundation of semantic modeling to comprehensively detail the complete workflow—encompassing interface design, high-level design, detailed design, and coding—while emphasizing the critical importance of “programming by intent” and software correctness proofs. These concepts are not merely programming techniques; rather, they represent a higher-dimensional perspective on the very essence of software construction. For AI-assisted development, such theoretical underpinnings are absolutely vital. Without grasping the concept of code as a “semantic mapping,” we cannot effectively guide Large Language Models (LLMs) to generate and verify high-quality code.

Even more commendably, this book is far from being a purely theoretical exercise; it is imbued with immense practical value. Through operational examples woven throughout the text, it demonstrates the complete transformation process from semantic models to executable code, thereby rendering abstract theories concrete and actionable. Of particular note is the book’s detailed explanation of how to derive “verification (acceptance) test cases” directly from semantic models—a process that offers direct, practical guidance for those of us currently exploring LLM-driven automated testing. Precise software documentation is assigned a crucial mission within the book: to enhance the efficiency of development and maintenance. Moreover, these structured documents themselves serve as high-quality inputs for LLMs, facilitating knowledge acquisition, intelligent Q&A, and maintenance assistance. Furthermore, the exploration of project estimation methodologies—specifically the integration of economic principles into software development and maintenance—provides invaluable perspectives on how to deliver software more efficiently and cost-effectively in the AI ​​era.

In summary, Mr. Tockey’s *Model-Driven Software Design* is a work of exceptional foresight and practical guidance. It not only systematically elucidates the application of UML within the context of model-driven software engineering but, through its profound insights into the fundamental nature of software engineering, also outlines a grand blueprint for building efficient, cost-effective, and reliable software in the era of Large Language Models. Within the context of “Software Engineering 3.0,” we are transitioning from a “code-centric” approach to a “model-centric” one. This book arrives at a most opportune moment, serving as a bridge connecting these two ends of the spectrum; it teaches us how to leverage human intellect to construct precise semantic models, and—building upon these foundations—how to harness the immense power of AI to achieve a qualitative leap in software development.

I firmly believe that everyone—whether they are students of software engineering, seasoned engineers honing their craft in the trenches of practice, or industry elites dedicated to driving paradigm shifts in the field—will derive abundant intellectual nourishment from Mr. Tockey’s work. This book will not only assist readers in integrating computational theory, practical experience, and engineering judgment to develop and maintain software both economically and efficiently, but it will also inspire us to engage in deep reflection: in a future defined by human-AI collaboration, how can we best fulfill our roles as software designers, guardians of semantics, and practitioners of engineering principles?

Shaomin Zhu
Professor, Tongji University
Author of *Software Engineering 3.0*
CCF Distinguished Member

He makes the case, both implicitly and explicitly, that software development should be held to the same standard of engineering excellence as any other domain that shapes the world we live in.
—Steve McConnell, author of Code Complete

Through my past work in translation, I have come to deeply appreciate that excellent software literature typically falls into one of two categories: the “inspirational,” which sparks insight and points the way; and the “operational,” which provides tools and standardizes practice. Tockey’s book is a rare example that embodies both qualities—yet, in doing so, it transcends them.
—Bingsheng Ru, Professor, Fudan University

[It] is a work of exceptional foresight and practical guidance. It not only systematically elucidates the application of UML within the context of model-driven software engineering but, through its profound insights into the fundamental nature of software engineering, also outlines a grand blueprint for building efficient, cost-effective, and reliable software in the era of Large Language Models.
—Shaomin Zhu, Professor, Tongji University