Home > Backend Development > PHP Tutorial > Separation of Concerns (SoC)

Separation of Concerns (SoC)

Barbara Streisand
Release: 2024-12-07 07:52:17
Original
870 people have browsed it

Separation of Concerns (SoC)

Key Implementation Examples

1. Database Layer Separation

// Bad - Mixed concerns
class User {
    public function save() {
        $db = new PDO('mysql:host=localhost;dbname=app', 'user', 'pass');
        $stmt = $db->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
        $stmt->execute([$this->name, $this->email]);
    }
}

// Good - Separated database logic
class User {
    private string $name;
    private string $email;
}

class UserRepository {
    private PDO $db;

    public function save(User $user) {
        $stmt = $this->db->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
        $stmt->execute([$user->getName(), $user->getEmail()]);
    }
}
Copy after login

The good example separates data structure (User) from storage logic (UserRepository). This makes the code more maintainable and allows changing the storage method without modifying the User class.

2. Validation Separation

// Bad - Mixed validation and business logic
class Order {
    public function process() {
        if (empty($this->items)) {
            throw new Exception('Order cannot be empty');
        }
        if ($this->total < 0) {
            throw new Exception('Invalid total amount');
        }
        // Process order...
    }
}

// Good - Separated validation
class OrderValidator {
    public function validate(Order $order): array {
        $errors = [];
        if (empty($order->getItems())) {
            $errors[] = 'Order cannot be empty';
        }
        if ($order->getTotal() < 0) {
            $errors[] = 'Invalid total amount';
        }
        return $errors;
    }
}

class Order {
    public function process() {
        // Only handles order processing
    }
}
Copy after login

The validation logic is moved to a dedicated validator class, allowing the Order class to focus on business logic.

3. View/Template Separation

// Bad - Mixed HTML and logic
class ProductPage {
    public function show($id) {
        $product = $this->getProduct($id);
        echo "<h1>{$product->name}</h1>";
        echo "<p>Price: ${$product->price}</p>";
    }
}

// Good - Separated presentation
class ProductController {
    public function show($id) {
        $product = $this->productRepository->find($id);
        return $this->view->render('product/show', ['product' => $product]);
    }
}

// product/show.php template
<h1><?= htmlspecialchars($product->name) ?></h1>
<p>Price: $<?= htmlspecialchars($product->price) ?></p>
Copy after login

The good example separates display logic into templates, making the code more maintainable and allowing designers to work independently.

4. Service Layer Separation

// Bad - Mixed business logic
class OrderController {
    public function checkout() {
        $order = new Order($_POST['items']);
        $payment = new Payment($_POST['card']);
        $payment->process();
        $order->updateStatus('paid');
        $email = new EmailService();
        $email->sendConfirmation($order);
    }
}

// Good - Separated services
class OrderService {
    private PaymentService $paymentService;
    private EmailService $emailService;

    public function processOrder(Order $order, PaymentData $paymentData): void {
        $this->paymentService->process($paymentData);
        $order->updateStatus('paid');
        $this->emailService->sendConfirmation($order);
    }
}

class OrderController {
    public function checkout() {
        $this->orderService->processOrder($order, $paymentData);
    }
}
Copy after login

The service layer handles complex business logic, keeping the controller focused on request handling.

5. Configuration Separation

// Bad - Hardcoded configuration
class EmailSender {
    private $host = 'smtp.example.com';
    private $port = 587;

    public function send($message) {
        // Sending logic using hardcoded values
    }
}

// Good - Separated configuration
// config/mail.php
return [
    'host' => 'smtp.example.com',
    'port' => 587
];

class EmailSender {
    private array $config;

    public function __construct(array $config) {
        $this->config = $config;
    }

    public function send($message) {
        // Sending logic using config values
    }
}
Copy after login

Configuration is separated from the implementation, making the code more flexible and maintainable. Settings can be changed without modifying the code.

The above is the detailed content of Separation of Concerns (SoC). For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template