Fundamentals 21 min read

Why Object‑Oriented Design Still Matters: From Machine Code to Domain‑Driven Architecture

This article traces the evolution of programming paradigms—from low‑level machine code through procedural and object‑oriented approaches—explains the pitfalls of poor abstraction, introduces domain‑driven design, and reviews key software design principles such as SOLID, OCP, DIP, PLOA and KISS.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
Why Object‑Oriented Design Still Matters: From Machine Code to Domain‑Driven Architecture

Preface

During the European Renaissance, Copernicus proposed the heliocentric model, which was initially rejected but later validated. A similar story unfolded in software engineering: Simula introduced object‑oriented programming half a century ago, yet it was not immediately accepted. Later thinkers like Robert C. Martin and Martin Fowler reaffirmed its value.

Evolution of Programming Paradigms

From the 1950s to today, programming languages have progressed from machine‑oriented to procedural and finally to object‑oriented, while the core purpose of programming remains unchanged.

1 Machine‑oriented

Early computers executed binary machine code directly (e.g., 0000 for read, 0001 for save). Although fastest, it was unmaintainable, leading to the invention of assembly language, which remained low‑level and costly.

2 Procedural

Procedural programming focuses on breaking a problem into a sequence of steps implemented as functions, improving clarity and development speed compared to machine code. However, as business logic grows, procedural code becomes harder to maintain and extend.

3 Object‑Oriented

Object‑oriented programming (OOP) abstracts commonality, encapsulates logic, and uses polymorphism for extensibility. While OOP may be overkill for simple systems, it excels in complex domains where reusable components and clear boundaries are needed.

Domain‑Driven Design

Is It Really Object‑Oriented?

public String pick(String salesId, String customerId){
    // Verify sales role
    Operator operator = dao.find("db_operator", salesId);
    if(!"SALES".equals(operator.getRole())){
        return "operator not sales";
    }
    // Check sales capacity
    int hold = dao.find("sales_hold", salesId);
    List<CustomerVo> customers = dao.find("db_sales_customer", salesId);
    if(customers.size() >= hold){
        return "hold is full";
    }
    // Verify customer can be picked
    Opportunity opp = dao.find("db_opportunity", customerId);
    if(opp.getOwnerId() != null){
        return "can not pick other's customer";
    }
    // Pick the customer
    opp.setOwnerId(salesId);
    dao.save(opp);
    return "success";
}

This Java snippet appears object‑oriented but actually follows a procedural, event‑driven style with little encapsulation, making it hard to reuse and extend.

In early system design, simple procedural code may suffice, but as complexity grows, maintenance costs explode, turning such code into technical debt.

Domain‑Driven Design

By introducing a “Opportunity” model that links customers and sales, and encapsulating behaviors like pick, open, and distribute, we can use OOP features to define boundaries, abstract, and encapsulate business logic.

Domain‑driven design treats the model as the language backbone; changes to the model drive code refactoring.

Use the model as the backbone of a language, Recognize that a change in the language is a change to the model. Then refactor the code, renaming classes, methods, and modules to conform to the new model. --- Eric Evans, *Domain‑Driven Design Reference*

Software Complexity

Robert C. Martin distinguishes data‑driven from domain‑driven development. Simple data‑driven approaches keep initial complexity low but can cause a steep rise as the system evolves. Starting with domain modeling and OOP can control complexity, though it incurs higher upfront cost.

The goal of software architecture is to minimize the human resources required to build and maintain the required system. --- Robert C. Martin, *Clean Architecture*

Quality of Abstractions

1 Coupling

Coupling measures the strength of inter‑module relationships; high coupling hinders independent understanding and modification. Reducing unnecessary dependencies lowers complexity.

Complexity is caused by two things: dependencies and obscurity. --- John Ousterhout, *A Philosophy of Software Design*

2 Cohesion

Cohesion measures how closely related elements within a module are. Functional cohesion—where elements work together to provide a clear behavior—is ideal.

3 Sufficiency

Sufficiency requires a class or module to expose enough features to be useful; missing essential operations render it ineffective.

4 Completeness

Completeness ensures a module captures all meaningful aspects of an abstraction, beyond the minimal sufficient set.

5 Fundamentality

Fundamentality concerns providing the most basic, effective operations. Redundant or overly specific methods (e.g., an “add2” when “add” exists) violate this principle.

Software Design Principles

1 Open‑Closed Principle (OCP)

Software entities should be open for extension, but closed for modification. --- Bertrand Meyer, *Object Oriented Software Construction*

Violating OCP leads to code that must be edited for every new case. Using abstractions (e.g., strategy pattern) allows adding new behavior without modifying existing modules.

public List<User> sort(List<User> users, Enum type){
    if(type == AGE){
        users = resortListByAge(users);
    } else if(type == NAME){
        users = resortListByName(users);
    } else if(type == HEALTH){
        users = resortListByHealth(users);
    }
    return users;
}

The above example tightly couples sorting logic to the method, breaching OCP.

2 Dependency Inversion Principle (DIP)

High‑level modules should not depend upon low‑level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions. --- Robert C. Martin, *C++ Report 1996*

DIP encourages depending on interfaces rather than concrete implementations, making systems more flexible.

3 Other Principles

Beyond SOLID, other useful principles include:

PLOA Minimal Surprise Principle

If a necessary feature has a high astonishment factor, it may be necessary to redesign the feature. --- Michael F. Cowlishaw

Code that surprises developers should be reconsidered. Example:

public synchronized void setFormatter(Formatter newFormatter) throws SecurityException {
    checkPermission();
    // Check for a null pointer:
    newFormatter.getClass();
    formatter = newFormatter;
}

KISS Simple Principle

Keep it Simple and Stupid. --- Robert S. Kaplan

Simplicity reduces cognitive load; over‑engineering makes systems harder to understand.

Conclusion

The ultimate goal of software design is to reduce complexity. Learn the fundamental rules first, then know when it is appropriate to break them.

You should not slavishly follow these rules, but violate them only occasionally and with good reason. Learning the art of programming, like most other disciplines, consists of first learning the rules and then learning when to break them. --- Josh Bloch, *Effective Java*

References

Object Oriented Analysis and Design with Applications

Clean Architecture

A Philosophy of Software Design

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Software ArchitectureProgramming Paradigmsdesign principlesobject‑oriented programmingSOLIDabstraction
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.