# Aspect Oriented Programming (AOP)

Aspect Oriented Programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does this by adding additional behavior to existing code (an "advice") without modifying the code itself.

## 1. Cross-Cutting Concerns

In standard Object Oriented Programming (OOP), classes are modularized based on their primary responsibility. However, some functionalities span across multiple unrelated modules.

*   **Core Concerns:** The primary business logic (e.g., `calculateTax`, `saveUser`).
*   **Cross-Cutting Concerns:** Logic that is needed everywhere (e.g., Logging, Security, Caching, Transaction Management).

Without AOP, you end up with **Code Tangling** (business logic mixed with logging) and **Code Scattering** (logging logic duplicated in 50 files).

## 2. Key Concepts

*   **Aspect:** A module that encapsulates a cross-cutting concern (e.g., a `LoggingAspect` class).
*   **Join Point:** A point during the execution of a program, such as the execution of a method or the handling of an exception.
*   **Advice:** The action taken by an aspect at a particular join point.
    *   *Before:* Run before the method executes.
    *   *After:* Run after the method completes.
    *   *Around:* Wraps the method (can run before, after, or prevent execution).
*   **Pointcut:** A predicate that matches join points. It defines *where* the advice should run (e.g., "All methods starting with `save`").

## 3. Implementation Example (TypeScript Decorators)

In many modern languages, AOP is implemented using Decorators or Proxies.

```typescript
// The Aspect (Advice)
function LogExecutionTime(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;

    // Replacing the original method with a wrapper
    descriptor.value = function (...args: any[]) {
        console.log(`Starting ${propertyKey}...`);
        const start = performance.now();
        
        const result = originalMethod.apply(this, args);
        
        const end = performance.now();
        console.log(`Finished ${propertyKey} in ${end - start}ms`);
        return result;
    };

    return descriptor;
}

class UserService {
    @LogExecutionTime // Applying the Aspect
    saveUser(name: string) {
        // Business logic only! No logging code here.
        console.log(`Saving user ${name} to DB...`);
    }
}
```

[[programming/object-oriented-programming]]
[[programming/javascript/typescript/decorators]]
[[programming/dependency-injection]]