Fundamentals 21 min read

Common Object‑Oriented Design Principles: SOLID, Dependency Inversion, Interface Segregation, Composite Reuse, and the Law of Demeter

This article summarizes the most widely used object‑oriented design principles—including the five SOLID rules, the Composite/Aggregate Reuse Principle, the Law of Demeter, and related guidelines—explaining their definitions, analyses, advantages, and practical examples for improving software modularity and maintainability.

Java Captain
Java Captain
Java Captain
Common Object‑Oriented Design Principles: SOLID, Dependency Inversion, Interface Segregation, Composite Reuse, and the Law of Demeter

1. Development Principles

The classic object‑oriented design principles, regardless of programming language, provide guidance for system design and development. This article summarizes these common principles and explains their significance.

The basic SOLID principles consist of five rules, often supplemented by the Law of Demeter and the Composite/Aggregate Reuse Principle, resulting in six or seven widely referenced principles.

2. S – Single‑Responsibility Principle (SRP)

Each class should have only one reason to change, meaning it should perform a single responsibility. This promotes low coupling and high cohesion by encapsulating a single responsibility within a class.

1. Definition

Every object should have a single responsibility, fully encapsulated by the class, i.e., only one cause for the class to change.

2. Principle Analysis

The more responsibilities a class (or module, method) has, the less reusable it becomes, and changes to one responsibility may affect others. Responsibilities are divided into data responsibilities (attributes) and behavior responsibilities (methods).

Applying SRP leads to high cohesion, low coupling, clearer class responsibilities, improved readability, easier maintenance, and reduced risk of change.

3. Advantages

Reduced class complexity and clear responsibilities.

Improved readability and maintainability.

Changes affect only the relevant class, enhancing extensibility.

4. Example

Separation of Entity, DAO, Service, Controller, and Util classes in a Spring MVC application.

3. O – Open‑Closed Principle (OCP)

Software entities (classes, modules, functions) should be open for extension but closed for modification.

1. Definition

A system should allow new behavior to be added without changing existing source code, achieved through abstraction.

2. Principle Analysis

When requirements change, extend existing entities rather than modify them, preserving stability. Abstract classes and interfaces define the contract; concrete implementations are extended.

3. Example

Template Method and Observer patterns illustrate the Open‑Closed Principle.

4. L – Liskov Substitution Principle (LSP)

Objects of a superclass must be replaceable with objects of a subclass without altering program correctness.

1. Definition

If any object of type S can be substituted by an object of type T such that programs using T behave identically, then S is a subtype of T.

2. Principle Analysis

The principle ensures that subclass instances can be used wherever base class instances are expected, preserving behavior and avoiding runtime errors.

5. I – Interface Segregation Principle (ISP)

Clients should not be forced to depend on interfaces they do not use.

1. Definition

Split large interfaces into smaller, role‑specific ones so that clients only need the methods they require.

2. Principle Analysis

Each interface represents a single role.

Provide only the behavior needed by the client.

Combine with SRP to keep interfaces cohesive and minimal.

6. D – Dependency Inversion Principle (DIP)

High‑level modules should not depend on low‑level modules; both should depend on abstractions.

1. Definition

Abstractions must not depend on details; details must depend on abstractions. Program to interfaces, not implementations.

2. Principle Analysis

Using abstract classes or interfaces decouples high‑level logic from concrete implementations, enabling flexible extensions.

3. Example 1

Dependency relationships in UML are shown as dashed arrows from the dependent to the depended‑upon element.

4. Example 2

A data conversion module that supports multiple source types (DatabaseSource, TextSource) and target formats (XMLTransformer, XLSTransformer) can be refactored with DIP to avoid modifying the main class when adding new sources or formats.

7. Composite/Aggregate Reuse Principle (CARP)

Prefer object composition over inheritance to achieve reuse.

1. Definition

Use object composition (or aggregation) rather than inheritance to reuse existing functionality.

2. Principle Analysis

Inheritance offers static reuse but reduces encapsulation and flexibility.

Composition provides lower coupling, selective behavior, and runtime flexibility.

Composition is generally preferred unless inheritance is clearly justified and Liskov Substitution is satisfied.

8. Law of Demeter (LoD)

Minimize knowledge of other classes to reduce coupling.

1. Definition

Also known as the Least Knowledge Principle: a class should only talk to its immediate friends (itself, method parameters, its own fields, objects created within the method, or elements of a field collection).

2. Analysis

Limiting interactions lowers coupling, improves reuse, and makes changes less risky.

3. Example

Facade pattern and Mediator pattern illustrate LoD in practice.

9. Q&A

1. Other object‑oriented design principles?

Encapsulation of change, favor composition over inheritance, program to interfaces, design for loose coupling, keep classes closed for modification (OCP), depend on abstractions (DIP), talk only to friends (LoD), and ensure a class has a single reason to change (SRP).

2. Explain Liskov Substitution Principle

Strict definition: substituting any instance of a subtype for a base type must not alter program behavior. Informal definition: wherever a base class is used, a subclass can be used transparently.

3. When is the Law of Demeter violated?

When a class communicates with “strangers” (objects it does not directly own or know), increasing coupling.

4. Example of a design pattern that follows the Open‑Closed Principle

The Strategy pattern (e.g., Java’s Collections.sort() using a Comparator) allows new strategies to be added without modifying existing sorting code.

5. When to use the Flyweight pattern?

When many identical immutable objects are needed; sharing them reduces memory usage (e.g., Java String, Integer, and Long pools).

Original source: https://www.cnblogs.com/pengdai

software architecturedependency inversiondesign principlesobject-orientedSOLIDInterface Segregation
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

login 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.