Coupling and Cohesion (MVC and LCRP Architectures)

Java 12 min min read Updated: Mar 31, 2026 Intermediate
Coupling and Cohesion (MVC and LCRP Architectures)
Intermediate Topic 21 of 25

Coupling and Cohesion (MVC and LCRP Architectures)

In software design, writing code that merely works is not enough. Good software should also be easy to maintain, extend, test, and reuse. Two very important design concepts that help achieve this are coupling and cohesion.

These concepts are deeply connected to object-oriented programming and architecture design. They influence how classes depend on each other, how responsibilities are grouped, and how flexible the overall system becomes. In Java projects, understanding coupling and cohesion helps in designing better classes, packages, and application layers such as MVC and layered component structures.

Key Concept: Good software design aims for low coupling and high cohesion. MVC and layered architectures apply these ideas by separating responsibilities and reducing unnecessary dependencies.

What is Coupling?

Coupling refers to the degree of dependency between two modules, classes, or components. In simple words, coupling tells us how strongly one part of the system depends on another part.

If one class knows too much about another class or directly depends on its internal details, coupling becomes high. High coupling makes code fragile because changes in one class may force changes in many other classes.

Simple Definition

Coupling measures how connected or dependent classes and modules are.

What is Cohesion?

Cohesion refers to how closely related the responsibilities of a class or module are. A highly cohesive class focuses on one clear task, while a low-cohesion class tries to do too many unrelated things.

High cohesion improves readability, maintainability, and reuse because each class has a clear and focused purpose.

Simple Definition

Cohesion measures how strongly related the contents of a class or module are to one another.

Goal of Good Software Design

The general goal in software engineering is:

  • Low Coupling β†’ fewer unnecessary dependencies
  • High Cohesion β†’ single, clear responsibility
Golden Rule: A good design tries to reduce coupling and increase cohesion.

Understanding Coupling with Real-Life Example

Suppose a classroom projector is directly wired in a way that it only works with one specific laptop model and one exact cable format. If the laptop changes, the projector setup fails. This is high coupling.

Now imagine the projector works through a standard HDMI connection. Any compatible laptop can connect. This is lower coupling because the dependency is reduced and based on a standard contract.

Understanding Cohesion with Real-Life Example

Consider a teacher’s attendance register. If that register only contains attendance details, it is highly cohesive. If the same register also stores salary data, transport route, cafeteria inventory, and exam papers, then it has low cohesion because unrelated responsibilities are mixed together.

High Coupling Example in Java

Let us see a tightly coupled design.

java class MySQLDatabase { void connect() { System.out.println("Connected to MySQL"); } } class UserService { private MySQLDatabase db = new MySQLDatabase(); void saveUser() { db.connect(); System.out.println("User saved"); } }

Here, UserService directly depends on MySQLDatabase. If later we want to switch to PostgreSQL or MongoDB, the UserService class must change.

This is high coupling.

Low Coupling Example in Java

Now let us reduce coupling using abstraction.

java interface Database { void connect(); } class MySQLDatabase implements Database { public void connect() { System.out.println("Connected to MySQL"); } } class PostgreSQLDatabase implements Database { public void connect() { System.out.println("Connected to PostgreSQL"); } } class UserService { private Database db; UserService(Database db) { this.db = db; } void saveUser() { db.connect(); System.out.println("User saved"); } }

Here, UserService depends on the Database interface rather than a concrete database implementation. This design is more flexible and loosely coupled.

Low Cohesion Example

A class with low cohesion tries to handle too many unrelated tasks.

java class EmployeeManager { void addEmployee() { System.out.println("Employee added"); } void generateSalarySlip() { System.out.println("Salary slip generated"); } void sendEmail() { System.out.println("Email sent"); } void backupDatabase() { System.out.println("Database backup done"); } }

This class is handling employee management, payroll, email communication, and database backup. These are unrelated responsibilities, so cohesion is low.

High Cohesion Example

A better design separates responsibilities into focused classes.

java class EmployeeService { void addEmployee() { System.out.println("Employee added"); } } class PayrollService { void generateSalarySlip() { System.out.println("Salary slip generated"); } } class EmailService { void sendEmail() { System.out.println("Email sent"); } } class BackupService { void backupDatabase() { System.out.println("Database backup done"); } }

Each class now has a single, focused responsibility. This is high cohesion.

Types of Coupling

Coupling can be discussed at different levels, from very bad to better design quality.

  • Content coupling
  • Common coupling
  • Control coupling
  • Stamp coupling
  • Data coupling
  • Message coupling

1. Content Coupling

One module directly uses or changes the internal logic of another module. This is one of the worst forms of coupling.

2. Common Coupling

Multiple modules depend on shared global data. Changes in shared data affect many modules.

3. Control Coupling

One module controls the behavior of another by passing flags or control information.

4. Stamp Coupling

A whole data structure is passed even when only part of it is needed.

5. Data Coupling

Modules communicate only by passing the required data. This is better design.

6. Message Coupling

Communication happens through messages or interface-based interaction. This is considered very loose coupling in object-oriented design.

Types of Cohesion

Cohesion also ranges from very poor to very strong.

  • Coincidental cohesion
  • Logical cohesion
  • Temporal cohesion
  • Procedural cohesion
  • Communicational cohesion
  • Sequential cohesion
  • Functional cohesion

Functional Cohesion

This is the best type of cohesion. A class or module performs one well-defined task.

Example:

java class TaxCalculator { double calculateTax(double income) { return income * 0.1; } }

This class is focused on one responsibility only.

Coupling and Cohesion Together

Coupling and cohesion should be understood together:

  • If a class has too many dependencies on other classes, coupling is high
  • If a class does too many unrelated things, cohesion is low

The ideal design is:

  • low coupling
  • high cohesion

What is MVC Architecture?

MVC stands for Model View Controller. It is a design architecture used to separate application logic into different components.

MVC applies coupling and cohesion principles in a practical architectural way.

Components of MVC

1. Model

The model represents the data and business logic of the application.

Example:

  • Student
  • Product
  • Order

2. View

The view is responsible for presentation. It displays data to the user.

3. Controller

The controller handles user input and coordinates between model and view.

MVC Example in Simple Terms

Suppose we build a student management application:

  • Model: Student class containing student data
  • View: Student page or UI displaying student details
  • Controller: Code that receives user actions and updates the model/view

Because responsibilities are separated:

  • cohesion increases
  • coupling reduces
  • maintenance becomes easier

Simple MVC Style Example

java class StudentModel { String name; int age; StudentModel(String name, int age) { this.name = name; this.age = age; } } class StudentView { void displayStudent(String name, int age) { System.out.println("Student Name: " + name); System.out.println("Student Age: " + age); } } class StudentController { private StudentModel model; private StudentView view; StudentController(StudentModel model, StudentView view) { this.model = model; this.view = view; } void updateView() { view.displayStudent(model.name, model.age); } } public class Main { public static void main(String[] args) { StudentModel model = new StudentModel("Amit", 20); StudentView view = new StudentView(); StudentController controller = new StudentController(model, view); controller.updateView(); } }

In this design:

  • the model handles data
  • the view handles presentation
  • the controller handles coordination

How MVC Improves Cohesion and Coupling

  • Each layer has a focused responsibility β†’ high cohesion
  • Layers communicate through controlled interfaces β†’ lower coupling
  • UI changes do not force business logic changes
  • Data structure changes are easier to manage

What is LCRP Architecture?

In practical Java design discussions, LCRP is often understood as a layered or component-based responsibility pattern where responsibilities are separated into logical layers or reusable components. The central idea is still the same:

  • separate concerns clearly
  • keep classes focused
  • reduce dependency across layers
  • promote reuse and maintainability

In many projects, this appears as a layered architecture such as:

  • Presentation Layer
  • Controller or Request Layer
  • Service Layer
  • Repository or Data Access Layer

Layered/LCRP Style Architecture Example

Let us see a simple layered design for user registration:

  • Controller: receives request
  • Service: applies business rules
  • Repository: saves data
java class UserRepository { void saveUser(String name) { System.out.println("User saved in database: " + name); } } class UserService { private UserRepository repository; UserService(UserRepository repository) { this.repository = repository; } void registerUser(String name) { System.out.println("Applying business rules for: " + name); repository.saveUser(name); } } class UserController { private UserService service; UserController(UserService service) { this.service = service; } void handleRequest(String name) { service.registerUser(name); } } public class Main { public static void main(String[] args) { UserRepository repo = new UserRepository(); UserService service = new UserService(repo); UserController controller = new UserController(service); controller.handleRequest("Amit"); } }

This design improves:

  • cohesion because each layer has one job
  • coupling because dependencies are more controlled

Benefits of MVC and Layered/LCRP Style Design

  • clear separation of concerns
  • easy maintenance
  • better unit testing
  • reusability of business logic
  • less risk when modifying one layer
  • better scalability for large applications

Poor Design Example Without Coupling/Cohesion Focus

Let us look at a bad example where one class does everything.

java class UserManager { void takeInput() { System.out.println("Reading user input"); } void validateData() { System.out.println("Validating user data"); } void saveToDatabase() { System.out.println("Saving to database"); } void generateHtmlResponse() { System.out.println("Generating HTML response"); } }

This class has low cohesion because it handles UI, validation, database work, and response generation. It also creates stronger coupling because one class becomes central to too many responsibilities.

Improved Design Example

java class InputHandler { void takeInput() { System.out.println("Reading user input"); } } class Validator { void validateData() { System.out.println("Validating user data"); } } class UserRepository { void saveToDatabase() { System.out.println("Saving to database"); } } class ResponseRenderer { void generateHtmlResponse() { System.out.println("Generating HTML response"); } }

Now each class has a focused responsibility, so cohesion is higher.

How to Achieve Low Coupling

  • use interfaces and abstractions
  • avoid direct dependency on concrete classes where unnecessary
  • use dependency injection
  • separate layers clearly
  • avoid global shared state

How to Achieve High Cohesion

  • assign one main responsibility per class
  • avoid mixing unrelated logic in one class
  • group strongly related methods together
  • follow single responsibility thinking

Coupling vs Cohesion Summary Table

Point Coupling Cohesion
Meaning Dependency between modules/classes Relatedness of responsibilities inside a class/module
Good design wants Low coupling High cohesion
Effect on maintenance Lower is better Higher is better
Problem if poor Changes spread across system Class becomes confusing and overloaded

Common Mistakes

  • Putting too much logic into one class
  • Creating direct dependency on concrete implementations everywhere
  • Mixing UI, business logic, and data access in the same class
  • Using inheritance where composition or interfaces would be better
  • Ignoring architecture separation in small projects that later grow

Best Practices

  • Design classes with one clear responsibility
  • Reduce direct dependency between modules
  • Use interfaces for flexible design
  • Apply MVC or layered architecture in medium and large projects
  • Review classes regularly for hidden coupling and poor cohesion

Interview-Oriented Points

  • Good software design aims for low coupling and high cohesion
  • Coupling means dependency between modules
  • Cohesion means how closely related responsibilities are within a module
  • MVC separates model, view, and controller responsibilities
  • Layered architectures improve maintainability and testability
  • Interfaces and dependency injection help reduce coupling
  • Single responsibility thinking improves cohesion

Conclusion

Coupling and cohesion are two of the most important quality indicators in software design. They directly affect how easy a system is to understand, test, maintain, and extend.

Architectures such as MVC and layered/LCRP-style designs put these ideas into practice by clearly separating responsibilities and reducing unnecessary dependencies. A Java developer who understands coupling and cohesion can design much stronger and more professional software systems.

Quick Summary: Coupling measures dependency between modules, cohesion measures focus within a module, and strong architectures like MVC improve design by aiming for low coupling and high cohesion.

Get Newsletter

Subscibe to our newsletter and we will notify you about the newest updates on Edugators