Simplified explanation
Design principles are practical guidelines that help us make better decisions when designing object-oriented software.
They are advice, not strict laws. A principle may work well in many situations, but that does not mean we must follow it in every situation.
Their main purpose is to help us create software that is:
- Easy to change
- Easy to maintain
- Less likely to break
- Easier to reuse
- Able to grow over time
Signs of Bad Design
The instructor describes three common problems:
| Problem | Simple meaning | What it looks like |
|---|---|---|
| Rigid | Hard to change | One small change forces changes across many other classes |
| Fragile | Easy to break | Changing one area unexpectedly breaks an unrelated area |
| Immobile | Hard to reuse | A useful class is too connected to its original application |
1. Rigid design
Rigid software is difficult to change because different parts depend too heavily on each other.
For example, changing the format of an invoice might force changes in the payment, email, and reporting code.
The problem is not the original change. The problem is the long chain of additional changes it creates.
2. Fragile design
Fragile software breaks in unexpected places.
For example, you update the customer class and suddenly the reporting page stops working, even though you did not directly change it.
This usually means parts of the system are connected in unclear or unsafe ways.
3. Immobile design
Immobile software is difficult to reuse.
For example, an email-sending class might be useful in another application, but it cannot be moved because it directly depends on customer, payment, and order classes from the original application.
The class is useful, but it is trapped inside its current system.
Why OOP Concepts Are Not Enough
The four main OOP concepts are still important:
- Inheritance: A class can receive behaviour from another class.
- Encapsulation: A class can protect its data and control how it is changed.
- Polymorphism: Different objects can respond to the same action differently.
- Abstraction: Complicated internal details can be hidden behind a simple way of using something.
However, these are only tools. They do not tell us whether using a particular tool is a good decision.
For example, inheritance allows us to reuse code. But if we use inheritance only because two classes contain similar code, we might connect those classes too closely. Future changes to the parent class could then affect many child classes.
Therefore:
Knowing how to use inheritance is an OOP skill. Knowing when not to use inheritance is a design skill.
What Design Principles Add
Design principles provide an extra layer of guidance on top of OOP concepts.
- OOP concepts give us programming tools.
- Design principles guide our decisions.
- Design patterns provide commonly used structures for recurring problems.
Example: Favor Composition Over Inheritance
Design principles are often expressed using short, memorable phrases.
One example is:
Favor composition over inheritance.
This does not mean inheritance is bad or should never be used. It means we should not automatically choose inheritance whenever we want to reuse some behaviour.
Sometimes it is safer to give an object another object that performs the required work.
For example:
- With inheritance, a
Carmight receive behaviour from anEngine. - With composition, a
Carcontains and uses anEngine.
Composition makes more sense because a car has an engine; it is not a type of engine.
The principle helps us select the more suitable relationship.
Design Principles vs Design Patterns
These terms are connected, but they do not mean the same thing.
| Design principle | Design pattern |
|---|---|
| General guidance | A reusable design structure |
| Helps us make decisions | Shows one established way to solve a problem |
| “Favor composition over inheritance” | Strategy, Observer, Factory, Adapter, etc. |
| Explains what direction to prefer | Demonstrates how classes can be arranged |
Design patterns were developed from solutions that appeared repeatedly when developers followed good design principles.
Important Clarification
Design principles should not be followed blindly.
Before applying one, ask:
- What problem are we trying to solve?
- Is the current design genuinely difficult to change?
- Will this principle make the design simpler?
- Or will it add unnecessary complexity?
A principle is useful when it improves the design, not simply because it has a well-known name.
Main Lesson
OOP concepts tell us what we can do. Design principles help us decide what we should do. Design patterns show us proven ways of doing it.
The goal is not to use as many principles or patterns as possible. The goal is to produce software that remains understandable, flexible, maintainable, and reusable as it changes.