Software Engineering Principles and Practices / Software Design

Design Conceps

To build high-quality software, engineers follow several core principles that ensure the system is easy to understand, maintain, and extend.


🌫️ Abstraction

Abstraction is the act of representing essential features without including the background details or explanations. It helps in managing complexity by letting us focus on what an object does rather than how it does it.

  • Example: When you drive a car, the "steering wheel" is an abstraction. You don't need to know how the rack-and-pinion gears are moving the tires to turn the vehicle.


🏛️ Architecture

Software Architecture is the high-level structure of the system. It defines the major components, their relationships, and how they communicate.

  • Common Patterns: Client-Server, Microservices, Layered (N-Tier).


🧱 Modularity

This is the practice of dividing a software system into multiple independent modules, where each module handles one specific portion of the functionality.

  • Benefit: If one module breaks (e.g., the payment gateway), it shouldn’t necessarily crash the entire system (the product catalog).


⚖️ Coupling and Cohesion (The "Golden Rules")

These are the two most important metrics for judging a design's quality.

A. Cohesion (Internal Strength)

Cohesion measures how closely related the functions within a single module are.

  • Goal: High Cohesion. A module should do one thing and do it well.

  • Example: A "UserAccount" module should only handle user data, not also calculate shipping taxes.

B. Coupling (External Dependency)

Coupling measures the degree of interdependence between different modules.

  • Goal: Low (Loose) Coupling. Modules should be as independent as possible.

  • Example: If changing the "Database" module requires you to rewrite the "User Interface" module, your coupling is too high.


🔒 Encapsulation (Information Hiding)

Encapsulation is the process of hiding the internal details of a module/object and only exposing a controlled interface to the outside world.

  • Why? It prevents other parts of the program from accidentally changing private data, which reduces bugs.


🔍 Refinement

Refinement is the process of "Top-Down" design. You start with a high-level statement of a function and progressively break it down into more detailed steps until it is close to actual code.


📊 Summary: Characteristics of Good Design

Concept

Goal

Resulting Benefit

Abstraction

Hide unnecessary detail

Reduced complexity

Cohesion

Keep related things together

Easier to understand

Coupling

Minimize dependencies

Easier to change/update

Modularity

Break into smaller parts

Better team collaboration


💡 The "Clean Design" Test

Ask yourself: “If I have to change the database from MySQL to MongoDB next month, how many files will I have to edit?” * If the answer is one file, you have a great design (Low Coupling).

  • If the answer is every file, the design has failed.