DEV Community

Saras Growth Space
Saras Growth Space

Posted on

LLD Object-Oriented Design: Cross-Cutting Concerns (Logging, Retry, Monitoring)

Once your system is properly layered, a new problem appears:

Some responsibilities do not belong to a single layer, but still affect the entire system.

These are called cross-cutting concerns.


What are Cross-Cutting Concerns?

They are features that:

  • span multiple layers
  • affect many classes or services
  • are not part of core business logic

Examples:

  • logging
  • error handling
  • retry mechanisms
  • monitoring
  • authentication
  • caching (sometimes)

Why They Are a Problem

If handled incorrectly, they lead to:

  • duplicated code everywhere
  • cluttered business logic
  • hard-to-maintain services
  • inconsistent behavior

Bad Design: Mixing Concerns Everywhere

class OrderService:
    def place_order(self):
        print("LOG: placing order")
        try:
            # business logic
            pass
        except Exception as e:
            print("LOG: error occurred")
Enter fullscreen mode Exit fullscreen mode

Problems:

  • logging repeated in every service
  • retry logic scattered
  • business logic polluted

Good Design: Separation of Concerns

Cross-cutting logic should be handled separately from core business logic.


1. Logging as a Separate Layer

Instead of writing logs everywhere:

  • use logging utilities
  • or interceptors
  • or decorators

Example

def log(func):
    def wrapper(*args, **kwargs):
        print("LOG: start")
        result = func(*args, **kwargs)
        print("LOG: end")
        return result
    return wrapper
Enter fullscreen mode Exit fullscreen mode

2. Retry Mechanism

Retry logic should not be inside business services.

It should be abstracted.


Example

def retry(func):
    def wrapper(*args, **kwargs):
        for _ in range(3):
            try:
                return func(*args, **kwargs)
            except:
                pass
    return wrapper
Enter fullscreen mode Exit fullscreen mode

3. Monitoring & Observability

Monitoring should:

  • track system behavior
  • not interfere with business logic

It runs alongside execution, not inside it.


Key Insight

Cross-cutting concerns should surround business logic, not mix with it.


How to Handle Cross-Cutting Concerns

There are multiple approaches:

1. Decorators (simple systems)

Wrap behavior externally.

2. Middleware (web systems)

Intercept requests and responses.

3. Aspect-Oriented Design (advanced systems)

Inject behavior at runtime.


Real System Example

Order Service Without Clean Separation

  • logging inside service
  • retry inside service
  • error handling repeated

Order Service With Clean Separation

  • service handles only business logic
  • logging handled externally
  • retry handled by wrapper
  • monitoring handled by system layer

Why This Matters in LLD

Without proper separation:

  • services become bloated
  • logic becomes unreadable
  • debugging becomes complex

With proper separation:

  • business logic stays clean
  • system behavior is consistent
  • scaling becomes easier

Design Principle

Cross-cutting concerns should be handled outside core business logic to keep systems clean and maintainable.


One-Line Takeaway

Logging, retry, and monitoring should wrap around business logic, not live inside it.

Top comments (0)