Skip to content
advanced Phase 108 · Code Review

Architecture Review

45m
1 problems
Topic Progress 0%

Architecture Review Overview

What to Review

Architecture Review Areas:
├── Module boundaries
├── Dependency direction
├── Layer violations
├── Coupling analysis
├── Interface usage
└── SOLID principles

Review Criteria:
├── Separation of concerns
├── Single responsibility
├── Dependency inversion
├── Interface segregation
└── Open/closed principle

Module Boundaries

Good Module Design:
├── Clear responsibility
├── Minimal public API
├── Internal implementation hidden
├── Dependencies on abstractions
└── No circular dependencies

Bad Module Design:
├── Multiple responsibilities
├── Large public API
├── Internal details exposed
├── Dependencies on implementations
└── Circular dependencies

Review Checklist

$architectureChecklist = [
    'module_boundaries' => [
        'Clear responsibility defined',
        'Minimal public API',
        'Internal implementation hidden'
    ],
    'dependencies' => [
        'No circular dependencies',
        'Dependencies on abstractions',
        'Proper dependency injection'
    ],
    'layers' => [
        'Controller → Service → Repository',
        'No direct database access from controller',
        'Business logic in service layer'
    ],
    'patterns' => [
        'Repository pattern used',
        'Service layer implements business logic',
        'Factory pattern for object creation'
    ]
];

Module Boundaries

Check Module Responsibilities

// Bad: Module does too much
class CatalogModule
{
    // Product management
    // Category management
    // Search functionality
    // Inventory management
    // Price calculation
}

// Good: Single responsibility
class ProductModule
{
    // Product management only
}

class CategoryModule
{
    // Category management only
}

class SearchModule
{
    // Search functionality only
}

Public API Review

// Bad: Exposing internal details
class ProductRepository
{
    public function getCollection() // Exposes collection
    {
        return $this->collectionFactory->create();
    }
}

// Good: Minimal public API
class ProductRepository
{
    public function get($id) // Returns single product
    {
        // Implementation hidden
    }
    
    public function getList($criteria) // Returns filtered list
    {
        // Implementation hidden
    }
}

Circular Dependency Check

// Check for circular dependencies
class DependencyAnalyzer
{
    public function analyze($module)
    {
        $dependencies = $this->getDependencies($module);
        
        foreach ($dependencies as $dependency) {
            $depDependencies = $this->getDependencies($dependency);
            
            if (in_array($module, $depDependencies)) {
                return false; // Circular dependency
            }
        }
        
        return true; // No circular dependency
    }
}

// Example circular dependency
// Module A depends on Module B
// Module B depends on Module A
// This is a circular dependency
``

Dependency Direction

Dependency Rule

Dependency Rule:
├── Dependencies should point inward
├── Outer layers depend on inner layers
├── Inner layers don't depend on outer
└── Business logic doesn't depend on UI

Example:
├── Controller → Service (OK)
├── Service → Repository (OK)
├── Repository → Service (BAD)
└── Controller → Database (BAD)

Check Dependency Direction

// Good: Proper dependency direction
class ProductController
{
    public function __construct(
        ProductService $productService // Depends on service
    ) {}
}

class ProductService
{
    public function __construct(
        ProductRepository $repository // Depends on repository
    ) {}
}

// Bad: Wrong dependency direction
class ProductService
{
    public function __construct(
        ProductController $controller // Depends on controller
    ) {}
}

Interface Dependencies

// Good: Depend on abstractions
class ProductService
{
    public function __construct(
        ProductRepositoryInterface $repository // Interface
    ) {}
}

// Bad: Depend on implementations
class ProductService
{
    public function __construct(
        MysqlProductRepository $repository // Concrete class
    ) {}
}

Dependency Inversion

// Dependency Inversion Principle
// High-level modules should not depend on low-level modules
// Both should depend on abstractions

// Bad: High-level depends on low-level
class OrderService
{
    public function __construct(
        MysqlOrderRepository $repository // Low-level
    ) {}
}

// Good: Both depend on abstraction
class OrderService
{
    public function __construct(
        OrderRepositoryInterface $repository // Abstraction
    ) {}
}

class MysqlOrderRepository implements OrderRepositoryInterface
{
    // Implementation
}

Layer Violations

MVC Layers

MVC Layers:
├── Controller: Handles HTTP request
├── Model: Business logic
├── View: Presentation
├── Repository: Data access
└── Service: Business operations

Violation Examples:
├── Controller accessing database directly
├── Model handling HTTP requests
├── View containing business logic
├── Repository containing business logic
└── Service handling HTTP responses

Check Layer Violations

// Bad: Controller accessing database
class ProductController
{
    public function viewAction()
    {
        $db = $this->_objectManager->create('Magento\Framework\DB\Adapter\Pdo\Mysql');
        $result = $db->fetchRow('SELECT * FROM catalog_product_entity WHERE entity_id = ?', [$id]);
        // Violation: Controller directly accessing database
    }
}

// Good: Controller using service
class ProductController
{
    public function viewAction()
    {
        $product = $this->productService->get($id);
        // Proper: Controller uses service layer
    }
}

// Bad: Repository with business logic
class ProductRepository
{
    public function get($id)
    {
        $product = $this->load($id);
        
        // Business logic in repository
        if ($product->getPrice() > 100) {
            $product->setSpecialPrice($product->getPrice() * 0.9);
        }
        
        return $product;
    }
}

// Good: Repository only handles data access
class ProductRepository
{
    public function get($id)
    {
        return $this->load($id);
    }
}

// Business logic in service
class ProductService
{
    public function get($id)
    {
        $product = $this->repository->get($id);
        $this->applySpecialPrice($product);
        return $product;
    }
}

Practice Problems

0 / 1 solved
Architecture Review Exercise

Review module with circular dependencies and layer violations.

Solution
// Findings:
// 1. Circular: A ↔ B → Use interface
// 2. Violation: Controller → DB → Use service
// 3. Missing: Interface abstraction
// 4. Fix: Dependency inversion
// 5. Result: Proper layer structure

Quiz

1. What is a circular dependency?

Question 1 options

2. What is the dependency rule?

Question 2 options

3. What is a layer violation?

Question 3 options

4. What is Dependency Inversion Principle?

Question 4 options

Flashcards

Question

Module boundary check?

Answer

Clear responsibility, minimal API, hidden implementation

Question

Dependency direction?

Answer

Controller → Service → Repository (inward)

Question

Layer violation?

Answer

Controller accessing database directly

Question

Dependency Inversion?

Answer

Both depend on abstractions, not implementations

Question

Circular dependency?

Answer

Module A and B depend on each other

Revision Notes

Key Takeaways

  • 1. Module boundaries: Clear responsibility, minimal API
  • 2. Dependencies: Point inward (Controller → Service → Repository)
  • 3. Layer violations: Controller accessing database
  • 4. Dependency Inversion: Depend on abstractions
  • 5. Circular dependencies: Avoid at all costs

Interview Tips

  • Explain module boundary checks
  • Discuss dependency direction rules
  • Know layer violation examples
  • Understand SOLID principles

Cheat Sheet

Architecture Review

  • Boundaries: Clear responsibility, minimal API
  • Direction: Controller → Service → Repository
  • Violation: Controller → Database
  • Inversion: Depend on abstractions
  • Circular: Avoid A ↔ B