# Layered Architecture (3-Tier / N-Tier)

## 📚 สารบัญ

1. [หลักการพื้นฐาน](#หลักการพื้นฐาน)
2. [โครงสร้างชั้นต่างๆ](#โครงสร้างชั้นต่างๆ)
3. [ข้อดี และข้อเสีย](#ข้อดี-และข้อเสีย)
4. [Code Examples](#code-examples)
5. [Real World Examples](#real-world-examples)
6. [Best Practices](#best-practices)

---

## 🎯 หลักการพื้นฐาน

### Layered Architecture คืออะไร?

**นิยาม:** สถาปัตยกรรมที่แบ่งระบบออกเป็นชั้น (Layers) โดยแต่ละชั้นมีหน้าที่เฉพาะเจาะจง และชั้นต่างๆ ติดต่อกันในลักษณะตั้งฉากเท่านั้น

### หลักการหลัก

```
1️⃣  Separation of Concerns
   - แต่ละชั้นมีความรับผิดชอบเฉพาะเจาะจง
   - ไม่ปะปนความจำเป็น

2️⃣  Layering (ชั้นต่อชั้น)
   - ชั้นบน ← → ชั้นล่าง
   - ห้ามข้ามชั้น (Strict layering) หรืออนุญาต (Relaxed layering)

3️⃣  Isolation
   - เปลี่ยนชั้นหนึ่ง ไม่ต้องแก้อื่น

4️⃣  Testability
   - แต่ละชั้นทดสอบได้ง่าย
```

### Strict Layering vs Relaxed Layering

```
STRICT LAYERING (เข้มงวด):
┌──────────────┐
│ Presentation │
└──────┬───────┘
       ↓↑
┌──────────────┐
│  Business    │
└──────┬───────┘
       ↓↑
┌──────────────┐
│Data Access   │
└──────────────┘

ข้อจำกัด: Presentation ไม่เข้าถึง Data Access โดยตรง
ข้อดี: Strict control, Clean separation
ข้อเสีย: Performance overhead

RELAXED LAYERING (ผ่อนปรน):
┌──────────────┐
│ Presentation │
└──────┬───────┘
       ↓↑
┌──────────────┐
│  Business    │
└──────┬───────┘
       ↓↑ ↙─────────────────┐
┌──────────────┐             │
│Data Access   │←────────────┘
└──────────────┘

ข้อจำกัด: Presentation สามารถเข้าถึง Data Access ได้
ข้อดี: Better performance, Flexibility
ข้อเสีย: Risk of coupling
```

---

## 🏗️ โครงสร้างชั้นต่างๆ

### 4-Tier Layered Architecture

```
┌────────────────────────────────────────────┐
│        1️⃣  PRESENTATION LAYER             │
│     (User Interface / REST API)            │
│  - Controllers / Routes                    │
│  - Request Validation                      │
│  - Response Formatting                     │
│  - Error Handling HTTP Middleware          │
└────────────────┬─────────────────────────┘
                 ↓↑
┌────────────────────────────────────────────┐
│      2️⃣  BUSINESS LOGIC LAYER             │
│      (Application / Services)              │
│  - Business rules & logic                  │
│  - Service classes                         │
│  - Workflows & orchestration               │
│  - Domain validations                      │
│  - Use case implementations                │
└────────────────┬─────────────────────────┘
                 ↓↑
┌────────────────────────────────────────────┐
│      3️⃣  DATA ACCESS LAYER               │
│    (Persistence / Repository)              │
│  - Database queries                        │
│  - ORM mapping                             │
│  - Repository pattern                      │
│  - Transaction management                  │
│  - Caching layer                           │
└────────────────┬─────────────────────────┘
                 ↓↑
┌────────────────────────────────────────────┐
│        4️⃣  DATABASE LAYER                │
│        (External Resources)                │
│  - MySQL / PostgreSQL                      │
│  - Tables & Relationships                  │
│  - Indexes & Constraints                   │
│  - Stored Procedures (optional)            │
└────────────────────────────────────────────┘
```

### แต่ละชั้นอธิบายละเอียด

#### 1. Presentation Layer (UI / API Layer)

**ความรับผิดชอบ:**

- รับ request จากไคลเอนต์
- ตรวจสอบ input
- เรียก business logic
- ส่ง response กลับ

**ชั้นนี้มี:**

- Controllers / Route handlers
- Middleware (Authentication, Validation)
- Request/Response DTOs (Data Transfer Objects)
- Exception handlers
- Logging

**ตัวอย่าง:**

```javascript
// UserController.js
router.post("/api/v1/users", async (req, res) => {
  try {
    const { email, password, name } = req.body;
    const user = await userService.createUser(email, password, name);
    res.status(201).json(user);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
});
```

#### 2. Business Logic Layer (Service Layer)

**ความรับผิดชอบ:**

- ตรวจสอบกฎธุรกิจ
- ประมวลผลข้อมูล
- ตัดสินใจ
- Orchestrate repositories

**ชั้นนี้มี:**

- Service classes
- Business rule implementations
- Validations
- Calculations
- Transformations

**ตัวอย่าง:**

```javascript
// UserService.js
class UserService {
  async createUser(email, password, name) {
    // Validate email format
    if (!this.isValidEmail(email)) {
      throw new Error("Invalid email format");
    }

    // Check if user exists
    const exists = await this.userRepository.findByEmail(email);
    if (exists) {
      throw new Error("Email already exists");
    }

    // Hash password (business logic)
    const hashedPassword = await bcrypt.hash(password, 10);

    // Call repository to save
    return await this.userRepository.save({
      email,
      password: hashedPassword,
      name,
    });
  }
}
```

#### 3. Data Access Layer (Repository Layer)

**ความรับผิดชอบ:**

- Query database
- Map domain objects ↔ database records
- Handle transactions
- Cache management

**ชั้นนี้มี:**

- Repository classes
- Query builders
- ORM configurations
- Cache handlers
- Data mappers

**ตัวอย่าง:**

```javascript
// UserRepository.js
class UserRepository {
  async findById(id) {
    const cachedUser = await cache.get(`user:${id}`);
    if (cachedUser) return JSON.parse(cachedUser);

    const user = await db.query("SELECT * FROM users WHERE id = ?", [id]);
    await cache.set(`user:${id}`, JSON.stringify(user), 3600);
    return user;
  }

  async save(userData) {
    const result = await db.query(
      "INSERT INTO users (email, password, name) VALUES (?, ?, ?)",
      [userData.email, userData.password, userData.name]
    );
    return { id: result.insertId, ...userData };
  }
}
```

#### 4. Database Layer

**ความรับผิดชอบ:**

- เก็บข้อมูล
- ความสัมพันธ์
- Constraints
- Performance optimization

**ชั้นนี้มี:**

- Database server
- Tables & Schemas
- Relationships (Foreign keys)
- Indexes
- Triggers (optional)

**ตัวอย่าง:**

```sql
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  email VARCHAR(100) UNIQUE NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  name VARCHAR(100) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_email (email)
);
```

---

## ✅ ข้อดี และข้อเสีย

### ✅ ข้อดี

| ข้อดี             | อธิบาย                               |
| ----------------- | ------------------------------------ |
| **Simple & Easy** | เข้าใจง่าย สำหรับผู้เริ่มต้น         |
| **Organization**  | Code organized cleanly               |
| **Scalability**   | ปรับปรุงได้ไปยังระดับหนึ่ง           |
| **Testability**   | Test layer by layer                  |
| **Reusability**   | Services reusable across controllers |
| **Maintenance**   | ค้นหา bugs ได้ง่าย                   |
| **Team**          | ทีมเล็กสามารถจัดการได้               |
| **Performance**   | Suitable for medium load             |

### ❌ ข้อเสีย

| ข้อเสีย                     | อธิบาย                                       |
| --------------------------- | -------------------------------------------- |
| **Monolithic**              | ขนาดใหญ่ => ยากต่อการ scale                  |
| **Tight Coupling**          | Layers ผูกติดแน่น                            |
| **Single Point of Failure** | Database down = ทั้งระบบ down                |
| **Limited Tech Diversity**  | ทั้งระบบใช้ tech stack เดียว                 |
| **Deployment**              | Deploy ทั้งระบบ ไม่ได้ deploy บาง features   |
| **Database Bottleneck**     | ทั้งระบบ query database เดียว                |
| **Hard to Scale**           | Horizontal scaling ยาก                       |
| **Performance**             | Performance overhead จาก layer communication |

### เมื่อใดควรใช้ Layered Architecture?

```
✅ ใช้เมื่อ:
- Project ขนาด Small-Medium
- Team ≤ 10 developers
- Monolithic approach suitable
- Simple business logic
- Time to market สำคัญ
- Need simple deployment

❌ ไม่ใช้เมื่อ:
- Project มี 100+ developers
- Need independent scaling
- Need independent deployment
- Require technology diversity
- Complex domain logic
- High-traffic system
```

---

## 💻 Code Examples

### ❌ BAD: No Layers (All in One)

```javascript
// ❌ BAD: Everything mixed together
const express = require("express");
const app = express();

app.post("/users", async (req, res) => {
  try {
    // Validation - mixing concerns
    if (!req.body.email || !req.body.password) {
      return res.status(400).json({ error: "Missing fields" });
    }

    // Database connection - direct
    const connection = await mysql.createConnection({
      host: "localhost",
      user: "root",
      password: "password",
      database: "myapp",
    });

    // Business logic - not separated
    const password = req.body.password;
    const hashedPassword = await bcrypt.hash(password, 10);

    // Database query - direct
    const [result] = await connection.query(
      "INSERT INTO users (email, password_hash, name) VALUES (?, ?, ?)",
      [req.body.email, hashedPassword, req.body.name]
    );

    // Response
    res.status(201).json({ id: result.insertId });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(3000);

// Problems:
// 1. ✗ Controller ทำทุกอย่าง
// 2. ✗ Database connection ซ้ำๆ
// 3. ✗ Hard to test
// 4. ✗ Hard to reuse
// 5. ✗ Impossible to change database
```

### ✅ GOOD: Layered Architecture

```javascript
// ============================================
// LAYER 1: Database Layer (config)
// ============================================
// database.js
const mysql = require("mysql2/promise");

const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  waitForConnections: true,
  connectionLimit: 10,
});

module.exports = pool;

// ============================================
// LAYER 2: Data Access Layer (Repository)
// ============================================
// repositories/UserRepository.js
const db = require("../config/database");
const cache = require("../config/cache");

class UserRepository {
  async findById(id) {
    // Check cache first
    const cached = await cache.get(`user:${id}`);
    if (cached) return JSON.parse(cached);

    // Query database
    const [rows] = await db.query(
      "SELECT id, email, name, created_at FROM users WHERE id = ?",
      [id]
    );

    if (rows.length === 0) return null;

    const user = rows[0];

    // Cache result
    await cache.set(`user:${id}`, JSON.stringify(user), 3600);

    return user;
  }

  async findByEmail(email) {
    const [rows] = await db.query("SELECT * FROM users WHERE email = ?", [
      email,
    ]);
    return rows.length > 0 ? rows[0] : null;
  }

  async save(userData) {
    const [result] = await db.query(
      "INSERT INTO users (email, password_hash, name) VALUES (?, ?, ?)",
      [userData.email, userData.passwordHash, userData.name]
    );
    return { id: result.insertId, ...userData };
  }

  async update(id, userData) {
    await db.query("UPDATE users SET email = ?, name = ? WHERE id = ?", [
      userData.email,
      userData.name,
      id,
    ]);
    // Invalidate cache
    await cache.del(`user:${id}`);
    return { id, ...userData };
  }

  async delete(id) {
    await db.query("DELETE FROM users WHERE id = ?", [id]);
    await cache.del(`user:${id}`);
  }
}

module.exports = new UserRepository();

// ============================================
// LAYER 3: Business Logic Layer (Service)
// ============================================
// services/UserService.js
const UserRepository = require("../repositories/UserRepository");
const bcrypt = require("bcryptjs");
const { ValidationError } = require("../errors/CustomErrors");

class UserService {
  // Business rule: Email format
  isValidEmail(email) {
    const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return regex.test(email);
  }

  // Business rule: Password strength
  isStrongPassword(password) {
    return password.length >= 8;
  }

  async createUser(email, password, name) {
    // Business validations
    if (!this.isValidEmail(email)) {
      throw new ValidationError("Invalid email format");
    }

    if (!this.isStrongPassword(password)) {
      throw new ValidationError("Password must be at least 8 characters");
    }

    if (!name || name.trim().length === 0) {
      throw new ValidationError("Name is required");
    }

    // Check if user exists
    const existing = await UserRepository.findByEmail(email);
    if (existing) {
      throw new ValidationError("Email already registered");
    }

    // Hash password (business rule)
    const hashedPassword = await bcrypt.hash(password, 10);

    // Call repository
    return await UserRepository.save({
      email,
      passwordHash: hashedPassword,
      name,
    });
  }

  async getUserById(id) {
    const user = await UserRepository.findById(id);
    if (!user) {
      throw new ValidationError("User not found");
    }
    return user;
  }

  async updateUser(id, updateData) {
    const user = await this.getUserById(id);

    // Business validations
    if (updateData.email && !this.isValidEmail(updateData.email)) {
      throw new ValidationError("Invalid email format");
    }

    if (updateData.email && updateData.email !== user.email) {
      const existing = await UserRepository.findByEmail(updateData.email);
      if (existing) {
        throw new ValidationError("Email already in use");
      }
    }

    return await UserRepository.update(id, updateData);
  }

  async deleteUser(id) {
    await this.getUserById(id); // Validate exists
    return await UserRepository.delete(id);
  }
}

module.exports = new UserService();

// ============================================
// LAYER 4: Presentation Layer (Controller)
// ============================================
// controllers/UserController.js
const UserService = require("../services/UserService");
const { asyncHandler } = require("../middleware/asyncHandler");

class UserController {
  // POST /api/v1/users
  createUser = asyncHandler(async (req, res) => {
    const { email, password, name } = req.body;

    const user = await UserService.createUser(email, password, name);

    res.status(201).json({
      success: true,
      data: user,
      message: "User created successfully",
    });
  });

  // GET /api/v1/users/:id
  getUser = asyncHandler(async (req, res) => {
    const { id } = req.params;

    const user = await UserService.getUserById(id);

    res.status(200).json({
      success: true,
      data: user,
    });
  });

  // PUT /api/v1/users/:id
  updateUser = asyncHandler(async (req, res) => {
    const { id } = req.params;
    const { email, name } = req.body;

    const user = await UserService.updateUser(id, { email, name });

    res.status(200).json({
      success: true,
      data: user,
      message: "User updated successfully",
    });
  });

  // DELETE /api/v1/users/:id
  deleteUser = asyncHandler(async (req, res) => {
    const { id } = req.params;

    await UserService.deleteUser(id);

    res.status(204).send();
  });
}

module.exports = new UserController();

// ============================================
// ROUTES
// ============================================
// routes/userRoutes.js
const express = require("express");
const router = express.Router();
const UserController = require("../controllers/UserController");
const auth = require("../middleware/auth");

router.post("/users", UserController.createUser);
router.get("/users/:id", auth, UserController.getUser);
router.put("/users/:id", auth, UserController.updateUser);
router.delete("/users/:id", auth, UserController.deleteUser);

module.exports = router;

// ============================================
// MAIN APPLICATION
// ============================================
// app.js
const express = require("express");
const userRoutes = require("./routes/userRoutes");
const errorHandler = require("./middleware/errorHandler");

const app = express();

// Middleware
app.use(express.json());

// Routes
app.use("/api/v1", userRoutes);

// Error handling
app.use(errorHandler);

app.listen(process.env.PORT || 3000, () => {
  console.log("Server running on port 3000");
});

// ============================================
// Benefits:
// ✓ Clear separation of concerns
// ✓ Easy to test (mock each layer)
// ✓ Easy to understand
// ✓ Easy to maintain
// ✓ Reusable services
// ✓ Cache management
// ✓ Easy database switching
```

### Unit Testing Example

```javascript
// tests/services/UserService.test.js
const UserService = require("../../services/UserService");
const MockUserRepository = require("../mocks/MockUserRepository");

describe("UserService", () => {
  let userService;

  beforeEach(() => {
    // Inject mock repository
    userService = new UserService(new MockUserRepository());
  });

  test("should create user with valid data", async () => {
    const result = await userService.createUser(
      "test@example.com",
      "SecurePass123",
      "Test User"
    );

    expect(result).toHaveProperty("id");
    expect(result.email).toBe("test@example.com");
  });

  test("should reject invalid email", async () => {
    await expect(
      userService.createUser("invalid", "SecurePass123", "Test")
    ).rejects.toThrow("Invalid email format");
  });

  test("should reject weak password", async () => {
    await expect(
      userService.createUser("test@example.com", "123", "Test")
    ).rejects.toThrow("Password must be at least 8 characters");
  });

  test("should reject duplicate email", async () => {
    await userService.createUser("test@example.com", "SecurePass123", "Test");

    await expect(
      userService.createUser("test@example.com", "OtherPass123", "Other")
    ).rejects.toThrow("Email already registered");
  });
});
```

---

## 🌍 Real World Examples

### Example 1: E-Commerce Website

```
┌──────────────────────────────┐
│   PRESENTATION LAYER         │
│ ┌────────────────────────┐   │
│ │ UserController         │   │
│ │ ProductController      │   │
│ │ OrderController        │   │
│ │ CartController         │   │
│ └────────────────────────┘   │
└──────────────┬───────────────┘
               ↓↑
┌──────────────────────────────┐
│   BUSINESS LOGIC LAYER       │
│ ┌────────────────────────┐   │
│ │ UserService            │   │
│ │ ProductService         │   │
│ │ OrderService           │   │
│ │ PaymentService         │   │
│ │ NotificationService    │   │
│ └────────────────────────┘   │
└──────────────┬───────────────┘
               ↓↑
┌──────────────────────────────┐
│   DATA ACCESS LAYER          │
│ ┌────────────────────────┐   │
│ │ UserRepository         │   │
│ │ ProductRepository      │   │
│ │ OrderRepository        │   │
│ │ CartRepository         │   │
│ │ ReviewRepository       │   │
│ └────────────────────────┘   │
└──────────────┬───────────────┘
               ↓↑
┌──────────────────────────────┐
│   DATABASE LAYER             │
│ ┌────────────────────────┐   │
│ │ Users Table            │   │
│ │ Products Table         │   │
│ │ Orders Table           │   │
│ │ OrderItems Table       │   │
│ │ Reviews Table          │   │
│ │ Cart Table             │   │
│ └────────────────────────┘   │
└──────────────────────────────┘
```

**User Flow:**

```
1. User clicks "Add to Cart" button
   ↓
2. Frontend sends POST /api/v1/cart
   ↓
3. CartController receives request
   ↓
4. Validates JWT token (Presentation)
   ↓
5. Calls CartService.addItem(userId, productId)
   ↓
6. CartService:
      - Validates product exists
      - Checks inventory
      - Calculates price
      - Calls CartRepository
   ↓
7. CartRepository:
      - Queries cart_items table
      - Updates quantity if exists
      - Inserts new item if not
      - Returns updated cart
   ↓
8. CartService:
      - Formats response
      - Returns to controller
   ↓
9. CartController:
      - Returns JSON response (200)
   ↓
10. Frontend updates UI
```

### Example 2: Banking System

```
┌────────────────────────────┐
│   Banking Application      │
│   PRESENTATION LAYER       │
│ - AccountController        │
│ - TransferController       │
│ - LoanController           │
└────────────┬───────────────┘
             ↓↑
┌────────────────────────────┐
│   BUSINESS LOGIC LAYER     │
│ - AccountService           │
│   * Balance validation     │
│   * Interest calculation   │
│ - TransferService          │
│   * Fraud detection        │
│   * Transaction rules      │
│ - LoanService              │
│   * Credit calculation     │
│   * Eligibility check      │
└────────────┬───────────────┘
             ↓↑
┌────────────────────────────┐
│   DATA ACCESS LAYER        │
│ - AccountRepository        │
│ - TransactionRepository    │
│ - LoanRepository           │
│ - AuditRepository          │
└────────────┬───────────────┘
             ↓↑
┌────────────────────────────┐
│   DATABASE                 │
│ - Accounts                 │
│ - Transactions             │
│ - Loans                    │
│ - AuditLog                 │
└────────────────────────────┘
```

### Example 3: Social Media Platform

```
Layers:
- Presentation: PostController, CommentController, UserController
- Business: PostService (validate content, filter spam)
- Data Access: PostRepository, CommentRepository
- Database: posts, comments, users tables

Request Flow: Create Post
1. User submits post → PostController
2. Validate not spam → PostService
3. Save to database → PostRepository
4. Return response → PostController
```

---

## 🛡️ Best Practices

### 1. Strict vs Relaxed Layering

```javascript
// ✅ GOOD: Strict Layering
// Controller calls Service only
controller.call(service);

// Service calls Repository only
service.call(repository);

// ❌ BAD: Relaxed Layering (too much)
// Controller calls both Service and Repository
controller.call(service);
controller.call(repository); // ← Violates layering
```

### 2. Dependency Injection

```javascript
// ✅ GOOD: Use DI
class UserService {
  constructor(userRepository) {
    this.userRepository = userRepository;
  }
}

// ❌ BAD: Hard-coded dependency
class UserService {
  constructor() {
    this.userRepository = new UserRepository(); // Tightly coupled
  }
}
```

### 3. DTO (Data Transfer Objects)

```javascript
// ✅ GOOD: Use DTOs to decouple
class CreateUserDTO {
  constructor(email, password, name) {
    this.email = email;
    this.password = password;
    this.name = name;
  }
}

// In Controller
const dto = new CreateUserDTO(req.body.email, req.body.password, req.body.name);
const user = await userService.createUser(dto);

// ❌ BAD: Pass raw request objects
const user = await userService.createUser(req.body);
```

### 4. Layer-specific Validation

```javascript
// ✅ GOOD: Each layer validates
// Presentation Layer: Input format
if (!email || !password) throw new ValidationError();

// Business Logic: Business rules
if (password.length < 8) throw new ValidationError();

// Data Access: Database constraints
await db.query(...); // DB constraints handle duplicates

// ❌ BAD: All validation in one place
```

### 5. Consistent Error Handling

```javascript
// ✅ GOOD: Custom error hierarchy
class AppError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.statusCode = statusCode;
  }
}

class ValidationError extends AppError {
  constructor(message) {
    super(message, 400);
  }
}

class NotFoundError extends AppError {
  constructor(message) {
    super(message, 404);
  }
}

// In service
if (!user) throw new NotFoundError("User not found");
```

### 6. Asynchronous Operations

```javascript
// ✅ GOOD: Use async/await
async createUser(userData) {
  const hashedPassword = await bcrypt.hash(userData.password, 10);
  return await this.repository.save({
    ...userData,
    passwordHash: hashedPassword
  });
}

// ❌ BAD: Mixing callbacks
createUser(userData, callback) {
  bcrypt.hash(userData.password, 10, (err, hash) => {
    this.repository.save({...userData, passwordHash: hash}, callback);
  });
}
```

### 7. Caching Strategy

```javascript
// ✅ GOOD: Cache in data access layer
async findById(id) {
  const cached = await cache.get(`user:${id}`);
  if (cached) return JSON.parse(cached);

  const user = await db.query(...);
  await cache.set(`user:${id}`, JSON.stringify(user), 3600);
  return user;
}

// When updating, invalidate cache
async update(id, data) {
  await db.query(...);
  await cache.del(`user:${id}`);
}
```

### 8. Logging Strategy

```javascript
// ✅ GOOD: Log at each layer
// Presentation Layer: HTTP requests
logger.info(`POST /api/v1/users - ${JSON.stringify(req.body)}`);

// Business Layer: Business events
logger.info(`User created with email: ${email}`);

// Data Layer: Database operations
logger.debug(`Executing query: SELECT * FROM users WHERE id = ${id}`);

// Service Layer: Errors
logger.error(`Failed to create user: ${error.message}`);
```

---

## 📊 Comparison Table

| Aspect          | Layered    | Microservices | Event-Driven |
| --------------- | ---------- | ------------- | ------------ |
| **Complexity**  | Simple     | Complex       | Complex      |
| **Scalability** | Medium     | High          | High         |
| **Team Size**   | 3-10       | 20+           | 8-15         |
| **Deployment**  | Monolithic | Independent   | Independent  |
| **Testing**     | Easy       | Moderate      | Hard         |
| **Debugging**   | Easy       | Hard          | Very Hard    |
| **Tech Stack**  | Single     | Multiple      | Multiple     |
| **Best For**    | SMEs       | Large Systems | Real-time    |

---

## ✅ ตรวจสอบความเข้าใจ

**คำถามตัวเอง:**

1. ✓ แต่ละชั้นมีหน้าที่อะไร?
2. ✓ ชั้นไหนเข้าถึง Database ได้?
3. ✓ Strict vs Relaxed layering ต่างกันอย่างไร?
4. ✓ เมื่อไดควรใช้ Layered architecture?
5. ✓ ข้อเสีย principal ของ Layered คืออะไร?
6. ✓ Dependency Injection ทำไมสำคัญ?
7. ✓ Testing ทำได้ง่ายไหม?

---

## 📚 สรุป

### Key Takeaways

```
✅ Layered = Clear separation of concerns
✅ Simple, organized, easy to understand
✅ Good for small-medium projects
✅ Each layer has specific responsibility
✅ Easier to test and maintain
✅ Not suitable for very large systems
❌ Can become monolithic
❌ Limited scaling
❌ Tech stack limited to one
```

### เมื่อไดควรเลือก Layered Architecture

```
✅ USE IF:
- 3-10 developers
- Project ขนาด small-medium
- Simple business logic
- Single tech stack
- Need quick market entry
- Small budget

❌ DON'T USE IF:
- 100+ developers
- Need to scale independently
- Deploy different services
- Tech diversity needed
- Very complex domain
- High-traffic system
```

---
