Enterprise Design Pattern: Implementing the Service Layer Pattern in Python

Introduction As enterprise applications grow, their complexity increases. One key practice to keep code manageable is to separate business logic from controllers or data access code. That’s where the Service Layer Pattern comes in. Documented in Martin Fowler’s Catalog of Patterns of Enterprise Application Architecture, this pattern proposes isolating all business rules into a dedicated layer, improving modularity, scalability, and testability. What is the Service Layer Pattern? The Service Layer acts as an intermediate layer between the application interface (e.g., API, UI) and the domain or persistence layers. It groups domain operations that follow business rules. Why use it? Avoid duplicated logic across controllers. Organize and centralize business rules. Make the system easier to maintain and test. Real-World Example in Python Let’s build a basic system to manage purchase orders. We’ll implement: Order model OrderRepository to simulate storage OrderService with business rules Project Structure project/ ├── models.py ├── order_repository.py ├── order_service.py └── main.py models.py class Order: def __init__(self, order_id, customer, total): self.id = order_id self.customer = customer self.total = total self.status = "PENDING" def approve(self): if self.total > 0: self.status = "APPROVED" order_repository.py class OrderRepository: def __init__(self): self.orders = [] def add(self, order): self.orders.append(order) def list_all(self): return self.orders order_service.py from models import Order from order_repository import OrderRepository class OrderService: def __init__(self, repository: OrderRepository): self.repository = repository def create_order(self, order_id, customer, total): if total

May 1, 2025 - 22:38
 0
Enterprise Design Pattern: Implementing the Service Layer Pattern in Python

Introduction

As enterprise applications grow, their complexity increases. One key practice to keep code manageable is to separate business logic from controllers or data access code. That’s where the Service Layer Pattern comes in.

Documented in Martin Fowler’s Catalog of Patterns of Enterprise Application Architecture, this pattern proposes isolating all business rules into a dedicated layer, improving modularity, scalability, and testability.

What is the Service Layer Pattern?

The Service Layer acts as an intermediate layer between the application interface (e.g., API, UI) and the domain or persistence layers. It groups domain operations that follow business rules.

Why use it?

  • Avoid duplicated logic across controllers.
  • Organize and centralize business rules.
  • Make the system easier to maintain and test.

Real-World Example in Python

Let’s build a basic system to manage purchase orders. We’ll implement:

  • Order model
  • OrderRepository to simulate storage
  • OrderService with business rules

Project Structure

project/
├── models.py
├── order_repository.py
├── order_service.py
└── main.py

models.py

class Order:
    def __init__(self, order_id, customer, total):
        self.id = order_id
        self.customer = customer
        self.total = total
        self.status = "PENDING"

    def approve(self):
        if self.total > 0:
            self.status = "APPROVED"

order_repository.py

class OrderRepository:
    def __init__(self):
        self.orders = []

    def add(self, order):
        self.orders.append(order)

    def list_all(self):
        return self.orders

order_service.py

from models import Order
from order_repository import OrderRepository

class OrderService:
    def __init__(self, repository: OrderRepository):
        self.repository = repository

    def create_order(self, order_id, customer, total):
        if total <= 0:
            raise ValueError("Total must be greater than zero")
        order = Order(order_id, customer, total)
        self.repository.add(order)
        return order

    def approve_order(self, order_id):
        for order in self.repository.list_all():
            if order.id == order_id:
                order.approve()
                return order
        raise ValueError("Order not found")

main.py

from order_repository import OrderRepository
from order_service import OrderService

repo = OrderRepository()
service = OrderService(repo)

# Create valid order
order = service.create_order(1, "Client A", 150.0)
print(f"Created order: {order.customer}, total: {order.total}, status: {order.status}")

# Approve the order
approved = service.approve_order(1)
print(f"Updated order: {approved.customer}, status: {approved.status}")