# Syllabus software engineering (1)

## Tổng quan các giai đoạn

| Giai đoạn | Tên | Số tuần | Ngày | Ghi chú |
| --- | --- | --- | --- | --- |
| 0 | Foundations for OOP | 5 | 1–35 |  |
| 1 | Object Oriented Programming | 9 | 36–98 |  |
| 2 | Refactoring & Code Smells | 4 | 99–126 |  |
| 3 | Design Patterns | 9 | 127–189 |  |
| 4 | **Testing & Quality Engineering** | 4 | 190–217 |  |
| 5 | Concurrency | 7 | 218–266 |  |
| 6 | **Networking & OS I/O** | 4 | 267–294 |  |
| 7 | Domain Driven Design | 8 | 295–350 |  |
| 8 | Architecture Patterns | 11 | 351–427 |  |
| 9 | **Security & API Design** | 4 | 428–455 |  |
| 10 | Framework Internals | 18 | 456–581 |  |
| 11 | Database Internals | 9 | 582–644 |  |
| 12 | Distributed Systems | 11 | 645–721 |  |
| 13 | **DevOps/Infra & Observability** | 6 | 722–763 |  |
| 14 | Runtime Internals | 20 | 764–903 |  |
| 15 | Source Code Reading (sprint có cấu trúc) | 8 | 904–959 | Nên duy trì tiếp tục sau mốc này |
| 16 | **System Design Practice** | 6 | 960–1001 |  |
| 17 | Framework Engineering (Capstone) | 14 | 1002–1099 |  |

# Giai đoạn 0 - Foundations for OOP (Ngày 1–35)

Mục tiêu chung: hiểu những thứ OOP đang che giấu bên dưới - phần cứng, bộ nhớ, cách hàm được gọi.

## Nhóm 1: Computer Architecture (Ngày 1–7)

**Ngày 1: CPU & Chu kỳ thực thi lệnh**

*   Mục tiêu: Hiểu CPU thực thi một lệnh máy như thế nào.
    
*   Lý thuyết: Fetch–Decode–Execute cycle, Instruction Set, ALU, Control Unit.
    
*   Thực hành: Viết pseudo-trace cho 1 đoạn C đơn giản, mô tả từng bước CPU xử lý.
    

**Ngày 2: Cache (L1/L2/L3)**

*   Mục tiêu: Hiểu vì sao cache tồn tại và ảnh hưởng đến performance.
    
*   Lý thuyết: Cache line, cache hit/miss, spatial vs temporal locality.
    
*   Thực hành: Viết 2 vòng lặp duyệt mảng 2D theo row-major và column-major, đo thời gian chạy khác nhau.
    

**Ngày 3: Register & Memory Hierarchy**

*   Mục tiêu: Nắm được thứ bậc tốc độ Register → Cache → RAM → Disk.
    
*   Lý thuyết: Register file, độ trễ truy cập từng tầng, nguyên lý đánh đổi tốc độ/dung lượng.
    
*   Thực hành: Vẽ sơ đồ memory hierarchy kèm số liệu latency thực tế (ns) cho từng tầng.
    

**Ngày 4: Virtual Memory**

*   Mục tiêu: Hiểu vì sao mỗi process "thấy" toàn bộ không gian địa chỉ riêng.
    
*   Lý thuyết: Paging, Page Table, TLB, Page Fault.
    
*   Thực hành: Dùng `/proc/[pid]/maps` (Linux) xem address space của một chương trình C đang chạy.
    

**Ngày 5: Context Switch & Process vs Thread**

*   Mục tiêu: Phân biệt process và thread ở tầng OS.
    
*   Lý thuyết: Process Control Block, thread stack riêng - heap chung, chi phí context switch.
    
*   Thực hành: Viết chương trình đo thời gian context switch bằng cách tạo nhiều thread/process.
    

**Ngày 6: Lab tổng hợp Computer Architecture**

*   Mục tiêu: Thấy tác động thực tế của cache/memory lên hiệu năng code.
    
*   Lý thuyết: Ôn lại cache miss, false sharing.
    
*   Thực hành: Benchmark một hàm xử lý mảng lớn trước/sau khi tối ưu locality, ghi lại số liệu.
    

**Ngày 7: Review & Quiz Computer Architecture**

*   Mục tiêu: Củng cố kiến thức tuần 1.
    
*   Lý thuyết: Tự tổng hợp lại bằng sơ đồ tư duy (CPU – Cache – Register – Memory – Context switch).
    
*   Thực hành: Tự đặt và trả lời 10 câu hỏi giải thích "tại sao" (không phải "là gì").
    

## Nhóm 2: Data Structures - tự cài đặt bằng C++ (Ngày 8–17)

**Ngày 8: Dynamic Array - Lý thuyết & khởi tạo**

*   Mục tiêu: Hiểu cơ chế mảng động hoạt động bên dưới `std::vector`.
    
*   Lý thuyết: Contiguous memory, capacity vs size.
    
*   Thực hành: Khởi tạo class `DynamicArray<T>` với constructor cấp phát bộ nhớ thô.
    

**Ngày 9: Dynamic Array - Resize & Amortized Complexity**

*   Mục tiêu: Hiểu vì sao `push_back` là O(1) amortized.
    
*   Lý thuyết: Growth factor (x1.5 vs x2), amortized analysis.
    
*   Thực hành: Cài `push_back` với resize, in ra số lần cấp phát lại khi thêm 10,000 phần tử.
    

**Ngày 10: Singly Linked List**

*   Mục tiêu: Cài đặt cấu trúc con trỏ nối tiếp cơ bản.
    
*   Lý thuyết: Node, head/tail pointer, trade-off vs array.
    
*   Thực hành: Cài insert đầu/cuối, delete, traverse cho Singly Linked List.
    

**Ngày 11: Doubly Linked List**

*   Mục tiêu: Mở rộng thêm khả năng duyệt ngược.
    
*   Lý thuyết: Prev/next pointer, chi phí bộ nhớ tăng thêm.
    
*   Thực hành: Cài Doubly Linked List, so sánh chi phí insert/delete giữa vị trí đầu/giữa/cuối với Singly.
    

**Ngày 12: Stack**

*   Mục tiêu: Hiểu 2 cách cài Stack và ưu nhược điểm.
    
*   Lý thuyết: LIFO, array-based vs linked-based stack.
    
*   Thực hành: Cài `Stack<T>` bằng cả 2 cách, viết test push/pop/peek.
    

**Ngày 13: Queue**

*   Mục tiêu: Cài Queue hiệu quả bằng circular buffer.
    
*   Lý thuyết: FIFO, circular buffer, vấn đề "wasted space" của queue mảng thường.
    
*   Thực hành: Cài `CircularQueue<T>` với enqueue/dequeue O(1).
    

**Ngày 14: Hash Table - Collision Resolution**

*   Mục tiêu: Hiểu 2 chiến lược xử lý va chạm hash.
    
*   Lý thuyết: Separate chaining vs open addressing (linear/quadratic probing).
    
*   Thực hành: Cài `HashMap<K,V>` bằng separate chaining.
    

**Ngày 15: Hash Table - Load Factor & Resize**

*   Mục tiêu: Hiểu khi nào và tại sao hash table cần resize.
    
*   Lý thuyết: Load factor, rehashing, hàm hash tốt vs xấu.
    
*   Thực hành: Thêm cơ chế auto-resize khi load factor > 0.75, benchmark trước/sau.
    

**Ngày 16: Binary Search Tree**

*   Mục tiêu: Cài đặt cấu trúc cây tìm kiếm nhị phân cơ bản.
    
*   Lý thuyết: BST property, insert/delete/search, traversal (in-order, pre-order, post-order).
    
*   Thực hành: Cài `BST<T>` đầy đủ insert/delete/search + in-order traversal.
    

**Ngày 17: Heap (Binary Heap)**

*   Mục tiêu: Hiểu cấu trúc dùng cho priority queue.
    
*   Lý thuyết: Min-heap/max-heap, heapify up/down, array representation của heap.
    
*   Thực hành: Cài `MinHeap<T>` với insert và extract-min.
    

## Nhóm 3: Memory Model - So sánh C++/Java/Python (Ngày 18–24)

**Ngày 18: C++ - Stack vs Heap**

*   Mục tiêu: Phân biệt rõ vùng nhớ stack và heap trong C++.
    
*   Lý thuyết: Lifetime, `new`/`delete`, con trỏ vs giá trị.
    
*   Thực hành: Viết chương trình in địa chỉ biến stack và biến heap, quan sát khác biệt.
    

**Ngày 19: C++ - RAII**

*   Mục tiêu: Hiểu nguyên lý quản lý tài nguyên gắn với lifetime object.
    
*   Lý thuyết: RAII, destructor tự động, vì sao C++ không cần GC.
    
*   Thực hành: Viết một class `FileGuard` tự đóng file trong destructor.
    

**Ngày 20: Java - Heap, Stack & Object Allocation**

*   Mục tiêu: Hiểu Java quản lý object khác C++ thế nào.
    
*   Lý thuyết: Mọi object nằm trên heap, stack chỉ chứa reference & primitive.
    
*   Thực hành: Dùng JVM flag in ra thông tin heap khi chạy 1 chương trình Java đơn giản.
    

**Ngày 21: Java - Garbage Collector tổng quan**

*   Mục tiêu: Hiểu ý tưởng generational GC.
    
*   Lý thuyết: Young/Old generation, Minor GC vs Major GC, GC roots.
    
*   Thực hành: Bật GC log, quan sát các lần GC chạy khi tạo nhiều object tạm.
    

**Ngày 22: Python - Object Reference & Reference Counting**

*   Mục tiêu: Hiểu mô hình biến trong Python là reference, không phải giá trị.
    
*   Lý thuyết: Mọi thứ là object, refcount tăng/giảm khi gán/xóa biến.
    
*   Thực hành: Dùng `sys.getrefcount()` quan sát refcount thay đổi qua các thao tác gán.
    

**Ngày 23: Python - Garbage Collector (Cycle Detector)**

*   Mục tiêu: Hiểu vì sao refcounting không đủ, cần thêm cycle collector.
    
*   Lý thuyết: Reference cycle, generational GC của CPython, `gc` module.
    
*   Thực hành: Tạo 1 cycle tham chiếu vòng, quan sát `gc.collect()` dọn nó.
    

**Ngày 24: Tổng hợp so sánh 3 memory model**

*   Mục tiêu: Có bảng so sánh rõ ràng để dùng về sau.
    
*   Lý thuyết: Tự lập bảng: cơ chế cấp phát, cơ chế giải phóng, ai chịu trách nhiệm, chi phí.
    
*   Thực hành: Viết cùng 1 bài toán (linked list có cycle) bằng cả 3 ngôn ngữ, so sánh cách mỗi ngôn ngữ xử lý bộ nhớ.
    

## Nhóm 4: Function Call Internals (Ngày 25–29)

**Ngày 25: Call Stack & Stack Frame**

*   Mục tiêu: Hiểu cấu trúc 1 stack frame khi gọi hàm.
    
*   Lý thuyết: Return address, saved registers, local variables, stack pointer/base pointer.
    
*   Thực hành: Vẽ sơ đồ stack frame cho 1 hàm C có tham số và biến local.
    

**Ngày 26: Recursion & Stack Depth**

*   Mục tiêu: Hiểu giới hạn thực tế của đệ quy.
    
*   Lý thuyết: Stack overflow, tail call, vì sao không phải ngôn ngữ nào cũng tối ưu tail call.
    
*   Thực hành: Viết hàm đệ quy tính giai thừa, tìm độ sâu tối đa trước khi stack overflow.
    

**Ngày 27: Calling Convention**

*   Mục tiêu: Hiểu quy ước truyền tham số ở tầng thấp.
    
*   Lý thuyết: cdecl, stdcall, System V AMD64 ABI (truyền qua register vs stack).
    
*   Thực hành: Đọc tài liệu System V ABI, tóm tắt cách 6 tham số đầu được truyền qua register nào.
    

**Ngày 28: Nhìn Function Call ở tầng Assembly**

*   Mục tiêu: Thấy tận mắt lời gọi hàm biến thành assembly.
    
*   Lý thuyết: `call`/`ret` instruction, `push`/`pop` cho stack frame.
    
*   Thực hành: Dùng `objdump -d` hoặc `gdb` disassemble một hàm C đơn giản, chỉ ra đoạn prologue/epilogue.
    

**Ngày 29: Ôn tập Function Call Internals**

*   Mục tiêu: Củng cố nhóm kiến thức tuần.
    
*   Lý thuyết: Tổng hợp lại toàn bộ pipeline: gọi hàm → tạo stack frame → thực thi → return → dọn stack frame.
    
*   Thực hành: Tự vẽ full diagram từ lúc gọi hàm đến khi return, áp cho ví dụ đệ quy 2 tầng.
    

## Nhóm 5: Project - Tự viết vector/hashmap/linked\_list (Ngày 30–35)

**Ngày 30: Setup Project & Vector Skeleton**

*   Mục tiêu: Khởi động project tổng hợp, thiết kế API cho `vector<T>`.
    
*   Lý thuyết: Thiết kế interface trước khi implement (push\_back, size, operator\[\], iterator).
    
*   Thực hành: Tạo repo, viết header `vector.hpp` với skeleton class + test framework cơ bản (catch2 hoặc tự viết assert).
    

**Ngày 31: Hoàn thiện Vector**

*   Mục tiêu: Vector chạy đúng và hiệu năng chấp nhận được.
    
*   Lý thuyết: Copy constructor, move semantics, iterator invalidation.
    
*   Thực hành: Hoàn thiện `push_back`, `resize`, iterator; viết test so sánh hành vi với `std::vector`.
    

**Ngày 32: Viết HashMap**

*   Mục tiêu: Áp dụng kiến thức Ngày 14–15 vào 1 implementation hoàn chỉnh.
    
*   Lý thuyết: Chọn hash function, thiết kế bucket array.
    
*   Thực hành: Viết `hashmap.hpp` với insert/get/erase cơ bản.
    

**Ngày 33: Hoàn thiện HashMap**

*   Mục tiêu: Xử lý các edge case còn thiếu.
    
*   Lý thuyết: Xử lý collision khi bucket đầy, resize khi load factor cao.
    
*   Thực hành: Thêm auto-resize + test với 100,000 key ngẫu nhiên, đo thời gian insert/lookup.
    

**Ngày 34: Viết Linked List**

*   Mục tiêu: Hoàn thiện thành phần thứ 3 của project.
    
*   Lý thuyết: Ôn lại thiết kế node-based structure, chọn singly hay doubly cho project này.
    
*   Thực hành: Viết `linked_list.hpp` với insert/delete tại vị trí bất kỳ, iterator hỗ trợ range-based for.
    

**Ngày 35: Test & Benchmark tổng kết Giai đoạn 0**

*   Mục tiêu: Đánh giá lại toàn bộ 3 cấu trúc dữ liệu đã viết.
    
*   Lý thuyết: Big-O thực tế vs lý thuyết, ảnh hưởng của cache locality lên kết quả benchmark.
    
*   Thực hành: Viết benchmark suite so sánh `vector`/`hashmap`/`linked_list` tự viết với thư viện chuẩn (`std::vector`, `std::unordered_map`, `std::list`), ghi báo cáo kết quả và giải thích chênh lệch.
    

# Giai đoạn 1 - Object Oriented Programming (Ngày 36–98)

## Module 1: Object Model (Ngày 36–40)

**Ngày 36: Class, Object, Instance**

*   Mục tiêu: Phân biệt rạch ròi 3 khái niệm hay bị dùng lẫn lộn.
    
*   Lý thuyết: Class là blueprint, Object là thực thể trong bộ nhớ, Instance là quan hệ giữa object và class nó thuộc về.
    
*   Thực hành: Viết 1 class `Car` bằng cả Java/C++/Python, tạo 3 instance, in địa chỉ/id để thấy chúng là các object riêng biệt.
    

**Ngày 37: State & Behavior**

*   Mục tiêu: Thiết kế class tách bạch trạng thái và hành vi hợp lý.
    
*   Lý thuyết: State (fields/attributes) mô tả dữ liệu, Behavior (methods) mô tả hành vi tác động lên state.
    
*   Thực hành: Thiết kế class `TrafficLight` với state (màu hiện tại) và behavior (chuyển màu theo quy tắc).
    

**Ngày 38: Java Object Model**

*   Mục tiêu: Hiểu mọi thứ trong Java đều kế thừa từ `Object`.
    
*   Lý thuyết: Reference type, `Object` class (equals, hashCode, toString), object luôn nằm trên heap.
    
*   Thực hành: Override `equals`/`hashCode`/`toString` cho class `Car`, giải thích vì sao cần override đồng thời cả 2 hàm đầu.
    

**Ngày 39: C++ Object Model**

*   Mục tiêu: Hiểu C++ có value semantics, khác Java/Python.
    
*   Lý thuyết: Object có thể nằm trên stack hoặc heap, copy semantics mặc định, không có "mọi thứ kế thừa 1 root class".
    
*   Thực hành: Viết ví dụ minh hoạ copy-by-value khi truyền object C++ vào hàm, so với truyền reference (Java) cho cùng logic.
    

**Ngày 40: Python Object Model & So sánh tổng hợp**

*   Mục tiêu: Hiểu "everything is an object" trong Python, kể cả class.
    
*   Lý thuyết: Class cũng là instance của `type`, mọi biến là reference tới object.
    
*   Thực hành: Lập bảng so sánh Object Model Java vs C++ vs Python (nơi lưu trữ, semantics khi gán, root class).
    

## Module 2: Encapsulation (Ngày 41–46)

**Ngày 41: Access Control**

*   Mục tiêu: Hiểu cơ chế kiểm soát truy cập ở 3 ngôn ngữ.
    
*   Lý thuyết: public/private/protected (Java, C++) vs quy ước `_`/`__` (Python - "consenting adults").
    
*   Thực hành: Viết cùng 1 class với field private, thử truy cập trái phép để thấy compiler/runtime phản ứng khác nhau.
    

**Ngày 42: Invariants**

*   Mục tiêu: Hiểu vì sao encapsulation tồn tại là để bảo vệ invariant.
    
*   Lý thuyết: Invariant là điều kiện luôn đúng trong suốt vòng đời object; setter/method phải giữ invariant đó.
    
*   Thực hành: Liệt kê invariant cho 1 class `Temperature` (ví dụ: không dưới -273.15°C), viết validate trong setter.
    

**Ngày 43: Information Hiding**

*   Mục tiêu: Hiểu lợi ích của việc giấu chi tiết implementation.
    
*   Lý thuyết: Giảm coupling, cho phép thay đổi implementation mà không phá vỡ client code.
    
*   Thực hành: Refactor 1 class đang expose field trực tiếp thành encapsulated, đổi implementation bên trong mà không đổi API.
    

**Ngày 44: Lab - BankAccount**

*   Mục tiêu: Áp dụng encapsulation vào bài toán tài chính có invariant chặt.
    
*   Lý thuyết: Invariant "số dư không âm", "giao dịch phải atomic".
    
*   Thực hành: Viết class `BankAccount` với deposit/withdraw đảm bảo invariant, viết test cho trường hợp withdraw quá số dư.
    

**Ngày 45: Lab - Wallet**

*   Mục tiêu: Thực hành composition + encapsulation.
    
*   Lý thuyết: Wallet chứa nhiều BankAccount, quản lý qua interface thống nhất.
    
*   Thực hành: Viết class `Wallet` chứa list `BankAccount`, thêm method tổng số dư, chuyển tiền giữa 2 account trong cùng wallet.
    

**Ngày 46: Lab - Money (Value Object)**

*   Mục tiêu: Làm quen với khái niệm value object (sẽ gặp lại ở DDD).
    
*   Lý thuyết: Value object bất biến (immutable), so sánh bằng giá trị chứ không bằng identity.
    
*   Thực hành: Viết class `Money` (amount + currency) immutable, override equals theo giá trị, không cho phép cộng 2 currency khác nhau.
    

## Module 3: Constructors & Lifecycle (Ngày 47–54)

**Ngày 47: Java Constructor**

*   Mục tiêu: Hiểu constructor overloading và constructor chaining.
    
*   Lý thuyết: Nhiều constructor cùng class, `this(...)` gọi constructor khác.
    
*   Thực hành: Viết class `Rectangle` với 3 constructor overload (không tham số, 1 tham số cho hình vuông, 2 tham số).
    

**Ngày 48: Java Lifecycle & GC liên hệ**

*   Mục tiêu: Hiểu object Java "chết" như thế nào (không có destructor tường minh).
    
*   Lý thuyết: Không còn reference trỏ tới → eligible for GC; `finalize()` đã deprecated, vì sao nên tránh.
    
*   Thực hành: Viết ví dụ object mất hết reference, dùng `-Xlog:gc` quan sát khi nó được thu hồi.
    

**Ngày 49: C++ Constructor**

*   Mục tiêu: Nắm các loại constructor trong C++.
    
*   Lý thuyết: Default constructor, parameterized constructor, copy constructor.
    
*   Thực hành: Viết class `Point` với đủ 3 loại constructor, trace khi nào mỗi loại được gọi.
    

**Ngày 50: C++ Destructor & RAII Lifecycle**

*   Mục tiêu: Hiểu vòng đời object C++ gắn liền với scope.
    
*   Lý thuyết: Destructor gọi tự động khi object ra khỏi scope, RAII cho resource management.
    
*   Thực hành: Viết class `ScopedTimer` in ra thời gian sống khi destructor được gọi.
    

**Ngày 51: C++ Rule of Three/Five**

*   Mục tiêu: Hiểu vì sao cần định nghĩa đồng thời copy constructor, copy assignment, destructor (và move variants).
    
*   Lý thuyết: Rule of Three (C++98), Rule of Five (C++11 thêm move constructor/move assignment).
    
*   Thực hành: Viết class quản lý raw pointer, cố tình bỏ qua Rule of Three để thấy lỗi double-free, sau đó sửa đúng.
    

**Ngày 52: Python new vs init**

*   Mục tiêu: Phân biệt 2 bước tạo object trong Python.
    
*   Lý thuyết: `__new__` tạo instance (allocate), `__init__` khởi tạo state (configure) trên instance đã tồn tại.
    
*   Thực hành: Override `__new__` để implement Singleton pattern đơn giản, giải thích vì sao không nên dùng `__init__` cho việc này.
    

**Ngày 53: Python del**

*   Mục tiêu: Hiểu finalizer trong Python và các cạm bẫy.
    
*   Lý thuyết: `__del__` không đảm bảo thời điểm gọi (phụ thuộc GC), không nên dùng cho resource cleanup quan trọng - dùng context manager thay thế.
    
*   Thực hành: So sánh dọn resource bằng `__del__` vs bằng `with` + `__enter__`/`__exit__`.
    

**Ngày 54: So sánh Lifecycle 3 ngôn ngữ**

*   Mục tiêu: Tổng hợp toàn bộ Module 3.
    
*   Lý thuyết: Lập bảng: thời điểm tạo, thời điểm huỷ, ai kiểm soát, cơ chế dọn resource.
    
*   Thực hành: Làm quiz tự đặt 10 câu hỏi tình huống (VD: "Object này bị leak ở ngôn ngữ nào, tại sao?").
    

## Module 4: Inheritance (Ngày 55–60)

**Ngày 55: IS-A Relationship**

*   Mục tiêu: Hiểu khi nào quan hệ kế thừa thực sự hợp lý.
    
*   Lý thuyết: Liskov Substitution Principle sơ khởi - subclass phải thay thế được superclass mà không phá vỡ hành vi.
    
*   Thực hành: Đánh giá 3 ví dụ quan hệ (Square-Rectangle, Dog-Animal, Circle-Ellipse), chỉ ra ví dụ nào IS-A giả.
    

**Ngày 56: Reuse qua Inheritance**

*   Mục tiêu: Hiểu lợi ích tái sử dụng code qua kế thừa, và giới hạn của nó.
    
*   Lý thuyết: Code reuse vs coupling chặt giữa base và derived class.
    
*   Thực hành: Viết 1 hierarchy 2 tầng (`Shape` → `Circle`/`Square`) chia sẻ logic chung ở base class.
    

**Ngày 57: Polymorphism qua Inheritance (preview)**

*   Mục tiêu: Thấy trước lợi ích lớn nhất của inheritance là polymorphism.
    
*   Lý thuyết: Base class reference có thể trỏ tới derived object, gọi method đúng phiên bản derived.
    
*   Thực hành: Viết hàm `printArea(Shape s)` nhận bất kỳ subclass nào của `Shape`.
    

**Ngày 58: Anti-pattern - Fragile Base Class**

*   Mục tiêu: Nhận diện vấn đề khi sửa base class làm vỡ subclass.
    
*   Lý thuyết: Fragile Base Class Problem - thay đổi tưởng chừng vô hại ở base phá vỡ hành vi ở derived.
    
*   Thực hành: Tạo ví dụ minh hoạ: sửa 1 method ở base class làm subclass hoạt động sai, phân tích nguyên nhân.
    

**Ngày 59: Anti-pattern - Deep Inheritance Hierarchy**

*   Mục tiêu: Nhận diện vấn đề khi hierarchy quá sâu.
    
*   Lý thuyết: Khó hiểu, khó test, khó thay đổi khi hierarchy có 5-6 tầng.
    
*   Thực hành: Vẽ sơ đồ 1 hierarchy 5 tầng giả định, chỉ ra vấn đề khi cần thêm behavior mới ở tầng giữa.
    

**Ngày 60: Lab - Refactor Inheritance sai thành đúng**

*   Mục tiêu: Áp dụng kiến thức cả tuần vào 1 case thực tế.
    
*   Lý thuyết: Ôn lại Liskov Substitution Principle.
    
*   Thực hành: Lấy ví dụ Square kế thừa Rectangle (vi phạm LSP), refactor lại thiết kế đúng.
    

## Module 5: Polymorphism (Ngày 61–66)

**Ngày 61: Dynamic Dispatch**

*   Mục tiêu: Hiểu cơ chế chọn đúng phiên bản method lúc runtime.
    
*   Lý thuyết: Dynamic dispatch vs static dispatch, tại sao polymorphism cần dynamic dispatch.
    
*   Thực hành: Viết ví dụ 3 class kế thừa cùng override 1 method, gọi qua base reference, quan sát method nào thực thi.
    

**Ngày 62: Late Binding vs Early Binding**

*   Mục tiêu: Phân biệt thời điểm quyết định method nào được gọi.
    
*   Lý thuyết: Early binding (compile-time, VD: overloading) vs Late binding (runtime, VD: overriding).
    
*   Thực hành: Viết ví dụ minh hoạ cả 2 loại binding trong cùng 1 class, chỉ rõ cái nào xảy ra lúc nào.
    

**Ngày 63: Runtime Polymorphism trong Java**

*   Mục tiêu: Hiểu Java mặc định virtual (trừ static/final/private).
    
*   Lý thuyết: Mọi method instance trong Java là virtual by default.
    
*   Thực hành: Viết ví dụ override method, thử đánh dấu `final` để thấy compiler chặn override.
    

**Ngày 64: Runtime Polymorphism trong C++**

*   Mục tiêu: Hiểu C++ cần khai báo `virtual` tường minh.
    
*   Lý thuyết: Không có `virtual` → static binding (khác Java); vtable sẽ học sâu ở Module 8.
    
*   Thực hành: Viết ví dụ base class không có `virtual`, gọi qua pointer, so sánh kết quả khi thêm `virtual`.
    

**Ngày 65: Duck Typing trong Python**

*   Mục tiêu: Hiểu polymorphism không cần inheritance trong Python.
    
*   Lý thuyết: "If it walks like a duck and quacks like a duck..." - chỉ cần có đúng method là dùng được.
    
*   Thực hành: Viết hàm nhận bất kỳ object nào có method `.quack()`, không cần base class chung.
    

**Ngày 66: Lab - Payment Gateway**

*   Mục tiêu: Áp dụng polymorphism vào bài toán thực tế.
    
*   Lý thuyết: Ôn lại toàn bộ Module 5.
    
*   Thực hành: Thiết kế `PaymentMethod` (abstract) với `CreditCard`/`Paypal`/`BankTransfer`, viết hàm xử lý thanh toán generic qua interface chung.
    

## Module 6: Abstraction (Ngày 67–72)

**Ngày 67: Interface vs Abstract Class**

*   Mục tiêu: Phân biệt 2 công cụ abstraction chính.
    
*   Lý thuyết: Interface = pure contract (không implementation), Abstract class = contract + có thể có implementation chung.
    
*   Thực hành: Lập bảng khi nào dùng interface, khi nào dùng abstract class.
    

**Ngày 68: Interface trong Java**

*   Mục tiêu: Thực hành interface Java, bao gồm default method.
    
*   Lý thuyết: `interface` keyword, multiple interface implementation, default method (Java 8+).
    
*   Thực hành: Viết interface `Drivable` với default method, 2 class implement.
    

**Ngày 69: Abstract Class trong C++**

*   Mục tiêu: Thực hành pure virtual function.
    
*   Lý thuyết: `virtual ... = 0`, abstract class không thể instantiate.
    
*   Thực hành: Viết abstract class `Shape` với pure virtual `area()`, 2 class con implement.
    

**Ngày 70: Duck Typing / Protocol trong Python**

*   Mục tiêu: Hiểu cách Python formalize abstraction qua `abc` module.
    
*   Lý thuyết: `ABC`, `@abstractmethod`, Protocol (structural typing, PEP 544).
    
*   Thực hành: Viết abstract base class bằng `ABC`, so sánh với dùng `Protocol` (không cần kế thừa).
    

**Ngày 71: Contract - Design by Contract**

*   Mục tiêu: Hiểu khái niệm hợp đồng giữa method và caller.
    
*   Lý thuyết: Precondition, postcondition, class invariant (Bertrand Meyer's Design by Contract).
    
*   Thực hành: Viết precondition/postcondition dạng assertion cho 1 method `withdraw(amount)`.
    

**Ngày 72: Lab - Storage Abstraction**

*   Mục tiêu: Áp dụng abstraction vào bài toán thực tế thường gặp production.
    
*   Lý thuyết: Ôn lại Module 6.
    
*   Thực hành: Thiết kế interface `Storage` với `S3`/`Local`/`GCS` implementation, viết code client không phụ thuộc implementation cụ thể.
    

## Module 7: Composition (Ngày 73–77)

**Ngày 73: HAS-A Relationship**

*   Mục tiêu: Hiểu quan hệ "chứa" khác với "là" (inheritance) thế nào.
    
*   Lý thuyết: Composition = object này chứa object khác như 1 field.
    
*   Thực hành: Viết ví dụ `Car` HAS-A `Engine`, so sánh với thiết kế sai `Car` IS-A `Engine`.
    

**Ngày 74: Delegation**

*   Mục tiêu: Hiểu cách object A "nhờ" object B thực hiện hành vi.
    
*   Lý thuyết: Delegation pattern, forwarding method calls.
    
*   Thực hành: Viết class `Car` delegate method `start()` cho `Engine.start()`.
    

**Ngày 75: Composition over Inheritance**

*   Mục tiêu: Hiểu nguyên lý thiết kế nổi tiếng này thực sự nghĩa là gì.
    
*   Lý thuyết: Composition linh hoạt hơn, tránh Fragile Base Class, dễ thay đổi hành vi lúc runtime.
    
*   Thực hành: So sánh 2 thiết kế cho cùng bài toán (VD: Character trong game) - 1 bản dùng inheritance sâu, 1 bản dùng composition.
    

**Ngày 76: Refactor Inheritance Tree → Composition**

*   Mục tiêu: Thực hành refactor thực tế.
    
*   Lý thuyết: Ôn lại kỹ thuật Extract Interface, Replace Inheritance with Delegation.
    
*   Thực hành: Lấy hierarchy `Bird` → `FlyingBird`/`SwimmingBird`/`Penguin` (vốn có vấn đề), refactor sang composition dùng `FlyBehavior`/`SwimBehavior`.
    

**Ngày 77: Lab hoàn thiện Composition**

*   Mục tiêu: Chốt lại Module 7 bằng review.
    
*   Lý thuyết: Tổng hợp lại khi nào composition thắng inheritance, khi nào không.
    
*   Thực hành: Viết report ngắn (1 trang) so sánh ưu nhược 2 cách tiếp cận dựa trên các lab đã làm.
    

## Module 8: Object Internals (Ngày 78–86)

**Ngày 78: C++ vtable**

*   Mục tiêu: Hiểu cơ chế bảng ảo đứng sau `virtual` function.
    
*   Lý thuyết: Virtual table (vtable) là mảng con trỏ hàm, mỗi class có polymorphic behavior sẽ có 1 vtable riêng.
    
*   Thực hành: Vẽ sơ đồ vtable cho 1 hierarchy 2 tầng có override.
    

**Ngày 79: C++ vptr & Object Layout**

*   Mục tiêu: Hiểu object polymorphic có thêm 1 con trỏ ẩn.
    
*   Lý thuyết: vptr (virtual pointer) nằm đầu object, trỏ tới vtable của class thực sự.
    
*   Thực hành: Dùng `sizeof()` so sánh kích thước object có và không có virtual function, giải thích chênh lệch.
    

**Ngày 80: C++ Multiple Inheritance & vtable phức tạp**

*   Mục tiêu: Hiểu vtable trở nên phức tạp thế nào khi đa kế thừa.
    
*   Lý thuyết: Nhiều vptr trong 1 object, vấn đề diamond inheritance.
    
*   Thực hành: Viết ví dụ diamond inheritance với `virtual` base class, giải thích cách C++ giải quyết bằng virtual inheritance.
    

**Ngày 81: Java invokevirtual**

*   Mục tiêu: Hiểu bytecode Java thực hiện dynamic dispatch ra sao.
    
*   Lý thuyết: JVM bytecode instruction `invokevirtual` - lookup method table dựa trên runtime class.
    
*   Thực hành: Compile 1 class Java đơn giản, dùng `javap -c` xem bytecode, tìm instruction `invokevirtual`.
    

**Ngày 82: Java invokeinterface**

*   Mục tiêu: Hiểu vì sao gọi qua interface cần instruction riêng.
    
*   Lý thuyết: `invokeinterface` khác `invokevirtual` vì lookup phức tạp hơn (object có thể implement nhiều interface).
    
*   Thực hành: Viết ví dụ gọi method qua interface reference, dùng `javap -c` so sánh bytecode với gọi qua class reference.
    

**Ngày 83: Java Method Dispatch Table**

*   Mục tiêu: Hiểu JVM tổ chức method table tương đương vtable ra sao.
    
*   Lý thuyết: Method table trong class metadata của JVM, so sánh khái niệm với vtable C++.
    
*   Thực hành: Lập bảng so sánh cơ chế dispatch Java vs C++ (điểm giống và khác).
    

**Ngày 84: Python MRO**

*   Mục tiêu: Hiểu Python giải quyết đa kế thừa bằng thuật toán tuyến tính hoá.
    
*   Lý thuyết: Method Resolution Order, thuật toán C3 linearization.
    
*   Thực hành: Viết 1 ví dụ đa kế thừa (diamond) trong Python, in `ClassName.__mro__`, giải thích thứ tự.
    

**Ngày 85: Python Descriptor Protocol**

*   Mục tiêu: Hiểu cơ chế đứng sau `property`, method binding.
    
*   Lý thuyết: `__get__`/`__set__`/`__delete__`, descriptor là nền tảng của `property`, `staticmethod`, `classmethod`.
    
*   Thực hành: Tự viết 1 descriptor đơn giản validate giá trị khi gán (tương tự property có validation).
    

**Ngày 86: Tổng hợp Object Internals**

*   Mục tiêu: Chốt lại toàn bộ Module 8.
    
*   Lý thuyết: So sánh 3 cơ chế dispatch: vtable (C++) vs method table (JVM) vs MRO + descriptor (Python).
    
*   Thực hành: Viết bài tổng hợp (dạng bảng) so sánh chi phí runtime của mỗi cơ chế dispatch.
    

## Project: Plugin System (Ngày 87–98)

**Ngày 87: Thiết kế kiến trúc Plugin System**

*   Mục tiêu: Lên thiết kế tổng thể trước khi code.
    
*   Lý thuyết: Plugin architecture cần: contract (interface), discovery mechanism, lifecycle management.
    
*   Thực hành: Vẽ sơ đồ kiến trúc Plugin System sẽ xây (chọn 1 ngôn ngữ chính, khuyến nghị Java hoặc Python).
    

**Ngày 88: Định nghĩa Plugin Interface**

*   Mục tiêu: Thiết kế contract chuẩn cho mọi plugin.
    
*   Lý thuyết: Interface tối thiểu cần có (VD: `name()`, `execute()`, `init(config)`).
    
*   Thực hành: Viết interface/abstract class `Plugin`.
    

**Ngày 89: Plugin Registry**

*   Mục tiêu: Xây nơi lưu trữ và tra cứu plugin đã đăng ký.
    
*   Lý thuyết: Registry pattern - trung tâm quản lý các instance plugin.
    
*   Thực hành: Viết class `PluginRegistry` với `register()`/`get()`/`getAll()`.
    

**Ngày 90: Plugin Loader - Load động**

*   Mục tiêu: Load plugin không cần hard-code trong source.
    
*   Lý thuyết: Java dùng reflection (`Class.forName`), Python dùng `importlib`, C++ dùng `dlopen`.
    
*   Thực hành: Viết `PluginLoader` load class plugin từ tên string cấu hình, khởi tạo qua reflection/importlib.
    

**Ngày 91: Plugin mẫu 1 - Logging Plugin**

*   Mục tiêu: Có plugin thực tế đầu tiên chạy qua hệ thống.
    
*   Lý thuyết: Ôn lại interface đã định nghĩa Ngày 88.
    
*   Thực hành: Viết `LoggingPlugin` implement interface, đăng ký và chạy qua registry.
    

**Ngày 92: Plugin mẫu 2 - Validation Plugin**

*   Mục tiêu: Thêm plugin thứ 2 để kiểm tra tính mở rộng.
    
*   Lý thuyết: Đảm bảo thêm plugin mới không cần sửa code core.
    
*   Thực hành: Viết `ValidationPlugin`, verify Open/Closed Principle được giữ vững.
    

**Ngày 93: Plugin mẫu 3 - Notification Plugin**

*   Mục tiêu: Có đủ 3 plugin để test hệ thống chạy nhiều plugin cùng lúc.
    
*   Lý thuyết: Thứ tự thực thi plugin, có cần priority không.
    
*   Thực hành: Viết `NotificationPlugin`, chạy pipeline cả 3 plugin tuần tự.
    

**Ngày 94: Plugin Lifecycle**

*   Mục tiêu: Thêm quản lý vòng đời cho plugin.
    
*   Lý thuyết: init → start → stop, tương tự lifecycle của framework thật (Spring bean lifecycle sẽ gặp lại sau).
    
*   Thực hành: Thêm method `init()`/`start()`/`stop()` vào interface, cập nhật cả 3 plugin mẫu.
    

**Ngày 95: Plugin Configuration**

*   Mục tiêu: Cho phép mỗi plugin có config riêng.
    
*   Lý thuyết: Configuration injection - mỗi plugin nhận 1 config object/map lúc init.
    
*   Thực hành: Thêm file config (JSON/YAML) chứa cấu hình riêng từng plugin, load và inject vào `init()`.
    

**Ngày 96: Error Handling & Isolation**

*   Mục tiêu: Đảm bảo 1 plugin lỗi không kéo sập cả hệ thống.
    
*   Lý thuyết: Fault isolation, try/catch quanh từng plugin execution, logging lỗi riêng biệt.
    
*   Thực hành: Cố tình viết 1 plugin lỗi (throw exception), verify hệ thống vẫn chạy tiếp các plugin khác.
    

**Ngày 97: Test toàn bộ Plugin System**

*   Mục tiêu: Đảm bảo hệ thống hoạt động đúng ở nhiều kịch bản.
    
*   Lý thuyết: Ôn lại toàn bộ thiết kế đã xây.
    
*   Thực hành: Viết test suite: load nhiều plugin, plugin lỗi, plugin config sai, thứ tự thực thi.
    

**Ngày 98: Review & Retrospective Giai đoạn 1**

*   Mục tiêu: Tổng kết toàn bộ giai đoạn OOP.
    
*   Lý thuyết: Nhìn lại 8 module đã học, liên hệ chúng với Plugin System vừa xây (module nào được dùng ở đâu).
    
*   Thực hành: Viết báo cáo retrospective: những gì khó nhất, những gì áp dụng được ngay vào công việc hiện tại.
    

# Giai đoạn 2 - Refactoring & Code Smells (Ngày 99–126)

Tài liệu chính: *Refactoring* (Martin Fowler). Mục tiêu: nhìn ra code "xấu" và có kỹ thuật sửa nó an toàn, có hệ thống - không phải sửa cảm tính.

## Nhóm 1: Code Smells (Ngày 99–108)

**Ngày 99: Giới thiệu Code Smells**

*   Mục tiêu: Hiểu khái niệm code smell và vì sao nó quan trọng hơn "code sai".
    
*   Lý thuyết: Code smell không phải bug - là dấu hiệu cảnh báo thiết kế có vấn đề, dễ dẫn tới bug/khó bảo trì về sau.
    
*   Thực hành: Đọc lại 1 đoạn code cũ của chính bạn (dự án cũ), liệt kê cảm giác "khó chịu" khi đọc - đó chính là smell.
    

**Ngày 100: Long Method**

*   Mục tiêu: Nhận diện và hiểu tác hại của method quá dài.
    
*   Lý thuyết: Method dài thường làm nhiều việc, khó test, khó đặt tên rõ nghĩa.
    
*   Thực hành: Tìm 1 method > 50 dòng trong codebase thật, liệt kê các "đoạn logic con" có thể tách ra.
    

**Ngày 101: God Object (God Class)**

*   Mục tiêu: Nhận diện class ôm quá nhiều trách nhiệm.
    
*   Lý thuyết: Vi phạm Single Responsibility Principle, thường là class kiểu `Manager`/`Utils`/`Helper` phình to dần.
    
*   Thực hành: Tìm 1 class có > 10 method không liên quan nhau, phân nhóm các method theo trách nhiệm.
    

**Ngày 102: Shotgun Surgery**

*   Mục tiêu: Nhận diện khi 1 thay đổi nhỏ buộc phải sửa ở rất nhiều nơi.
    
*   Lý thuyết: Logic liên quan bị rải rác thay vì tập trung - ngược lại với Divergent Change.
    
*   Thực hành: Giả lập 1 thay đổi yêu cầu (VD: đổi định dạng ngày tháng) trên 1 codebase, đếm số file phải sửa.
    

**Ngày 103: Feature Envy**

*   Mục tiêu: Nhận diện method "ganh tị" dữ liệu của class khác.
    
*   Lý thuyết: Method dùng dữ liệu của class khác nhiều hơn dữ liệu của chính class nó - dấu hiệu đặt sai vị trí.
    
*   Thực hành: Tìm 1 method truy cập field của object khác nhiều lần liên tiếp, đánh giá xem có nên move sang class kia không.
    

**Ngày 104: Data Clumps**

*   Mục tiêu: Nhận diện nhóm dữ liệu hay đi chung nhưng chưa được gom thành object.
    
*   Lý thuyết: VD: `street, city, zipcode` luôn xuất hiện cùng nhau ở nhiều method → nên là 1 class `Address`.
    
*   Thực hành: Tìm 3 method có cùng nhóm tham số lặp lại, đề xuất object gom nhóm.
    

**Ngày 105: Duplicate Code**

*   Mục tiêu: Nhận diện logic trùng lặp - smell phổ biến và nguy hiểm nhất.
    
*   Lý thuyết: Duplicate code làm tăng chi phí bảo trì gấp N lần (N = số chỗ trùng); "Rule of Three" khi nào nên trừu tượng hoá.
    
*   Thực hành: Dùng công cụ phát hiện duplicate code (hoặc tìm thủ công) trên 1 project, liệt kê top 3 đoạn trùng lặp nhiều nhất.
    

**Ngày 106: Primitive Obsession**

*   Mục tiêu: Nhận diện lạm dụng kiểu nguyên thuỷ thay vì object có ý nghĩa.
    
*   Lý thuyết: VD: dùng `String` cho email/phone/currency thay vì class riêng - mất khả năng validate và mất ý nghĩa domain.
    
*   Thực hành: Tìm 3 chỗ dùng `String`/`int` cho khái niệm domain có quy tắc riêng, đề xuất value object thay thế.
    

**Ngày 107: Switch Statements / Conditional Complexity**

*   Mục tiêu: Nhận diện switch/if-else phình to lặp lại nhiều nơi theo cùng 1 loại điều kiện.
    
*   Lý thuyết: Khi cùng 1 switch trên "loại" xuất hiện ở nhiều method → dấu hiệu cần polymorphism (sẽ học kỹ thuật sửa ở Ngày 111).
    
*   Thực hành: Tìm 1 switch/if-else theo `type`/`enum` xuất hiện ở ít nhất 2 nơi trong codebase.
    

**Ngày 108: Lab tổng hợp - Phát hiện Code Smells**

*   Mục tiêu: Luyện khả năng "ngửi" smell trên codebase thật, chưa sửa vội.
    
*   Lý thuyết: Ôn lại toàn bộ 8 smell đã học.
    
*   Thực hành: Chọn 1 open-source project vừa (hoặc project cũ của bạn), viết báo cáo liệt kê ít nhất 10 smell tìm thấy, phân loại theo từng nhóm.
    

## Nhóm 2: Refactoring Techniques (Ngày 109–118)

**Ngày 109: Extract Method**

*   Mục tiêu: Học kỹ thuật cơ bản nhất, dùng để sửa Long Method.
    
*   Lý thuyết: Tách 1 đoạn logic thành method riêng có tên rõ nghĩa, giữ nguyên hành vi.
    
*   Thực hành: Áp dụng Extract Method lên method dài đã tìm ở Ngày 100.
    

**Ngày 110: Introduce Parameter Object**

*   Mục tiêu: Học kỹ thuật sửa Data Clumps.
    
*   Lý thuyết: Gom nhóm tham số hay đi cùng nhau thành 1 object truyền vào.
    
*   Thực hành: Áp dụng lên nhóm tham số đã tìm ở Ngày 104, tạo class `Address`/tương tự.
    

**Ngày 111: Replace Conditional with Polymorphism**

*   Mục tiêu: Học kỹ thuật sửa Switch Statements - liên hệ trực tiếp Module 5 (Polymorphism) đã học.
    
*   Lý thuyết: Thay switch theo type bằng cách để mỗi type override 1 method riêng.
    
*   Thực hành: Áp dụng lên switch đã tìm ở Ngày 107, tạo hierarchy/interface thay thế.
    

**Ngày 112: Move Method**

*   Mục tiêu: Học kỹ thuật sửa Feature Envy.
    
*   Lý thuyết: Chuyển method sang class mà nó thực sự "quan tâm" dữ liệu nhiều nhất.
    
*   Thực hành: Áp dụng lên method đã tìm ở Ngày 103.
    

**Ngày 113: Extract Class**

*   Mục tiêu: Học kỹ thuật sửa God Object.
    
*   Lý thuyết: Tách 1 nhóm field + method liên quan thành class mới, giữ lại quan hệ composition với class gốc.
    
*   Thực hành: Áp dụng lên God Class đã tìm ở Ngày 101, tách thành 2-3 class có trách nhiệm rõ ràng.
    

**Ngày 114: Replace Temp with Query**

*   Mục tiêu: Học kỹ thuật giảm biến tạm, tăng khả năng Extract Method sau này.
    
*   Lý thuyết: Biến tạm chỉ dùng 1 lần nên thay bằng method trả về giá trị đó - dễ tách nhỏ hơn.
    
*   Thực hành: Tìm 1 method có biến tạm tính toán phức tạp, thay bằng method riêng.
    

**Ngày 115: Inline Method & Inline Class**

*   Mục tiêu: Học kỹ thuật ngược lại Extract - đôi khi gộp lại mới là refactor đúng.
    
*   Lý thuyết: Khi 1 method/class quá nhỏ và không còn ý nghĩa tách riêng, nên gộp lại để giảm indirection thừa.
    
*   Thực hành: Tìm 1 ví dụ over-engineered (quá nhiều lớp indirection cho logic đơn giản), áp dụng Inline.
    

**Ngày 116: Encapsulate Field & Encapsulate Collection**

*   Mục tiêu: Học kỹ thuật bảo vệ state khỏi bị sửa trực tiếp từ bên ngoài.
    
*   Lý thuyết: Field/collection public dễ bị mutate không kiểm soát - bọc qua getter trả về bản sao/view bất biến.
    
*   Thực hành: Tìm 1 class expose `List` trực tiếp, sửa lại để trả về unmodifiable view.
    

**Ngày 117: Lab - Áp dụng chuỗi kỹ thuật liên tiếp**

*   Mục tiêu: Luyện phản xạ chọn đúng kỹ thuật cho đúng smell, áp dụng nối tiếp nhau.
    
*   Lý thuyết: Refactoring thường là chuỗi bước nhỏ (baby steps), không phải 1 lần sửa lớn.
    
*   Thực hành: Lấy 1 method vừa dài vừa có switch vừa có data clump, áp dụng liên tiếp Extract Method → Replace Conditional with Polymorphism → Introduce Parameter Object.
    

**Ngày 118: Ôn tập Refactoring Techniques**

*   Mục tiêu: Củng cố toàn bộ nhóm kỹ thuật.
    
*   Lý thuyết: Lập bảng "Smell → Technique tương ứng" để dùng làm cheat-sheet về sau.
    
*   Thực hành: Tự làm quiz: cho 5 đoạn code có smell khác nhau, chọn đúng kỹ thuật sửa cho từng đoạn.
    

## Nhóm 3: Project - Refactor hệ thống E-commerce (Ngày 119–126)

**Ngày 119: Phân tích codebase E-commerce xấu**

*   Mục tiêu: Có bức tranh tổng thể trước khi sửa.
    
*   Lý thuyết: Luôn phân tích/lập bản đồ smell trước khi refactor, tránh sửa tuỳ hứng.
    
*   Thực hành: Chuẩn bị (hoặc viết sẵn) 1 codebase E-commerce nhỏ có chủ đích chứa nhiều smell (Order, Product, Payment, Customer), liệt kê toàn bộ smell tìm thấy theo từng module.
    

**Ngày 120: Refactor Order Module**

*   Mục tiêu: Áp dụng kỹ thuật vào module đầu tiên.
    
*   Lý thuyết: Ôn lại Extract Method, Extract Class cho God Object.
    
*   Thực hành: Refactor class `Order`/`OrderService` đang ôm quá nhiều logic (tính tiền, validate, gửi email...) thành các class tách bạch.
    

**Ngày 121: Refactor Product/Inventory Module**

*   Mục tiêu: Xử lý smell Data Clumps và Primitive Obsession thường gặp ở module này.
    
*   Lý thuyết: Ôn lại Introduce Parameter Object, value object cho `Price`/`SKU`.
    
*   Thực hành: Refactor `Product` class, gom nhóm dữ liệu rời rạc thành value object.
    

**Ngày 122: Refactor Payment Module**

*   Mục tiêu: Xử lý switch statement điển hình theo loại phương thức thanh toán.
    
*   Lý thuyết: Ôn lại Replace Conditional with Polymorphism (đã làm ở Lab OOP Ngày 66 - liên hệ lại).
    
*   Thực hành: Refactor logic xử lý payment đang if-else theo type thành hierarchy polymorphism.
    

**Ngày 123: Refactor Customer/User Module**

*   Mục tiêu: Xử lý Feature Envy và Shotgun Surgery thường gặp ở module quản lý user.
    
*   Lý thuyết: Ôn lại Move Method.
    
*   Thực hành: Refactor các method đang truy cập chéo dữ liệu giữa `Customer` và `Order` về đúng vị trí.
    

**Ngày 124: Characterization Tests**

*   Mục tiêu: Đảm bảo refactor không phá vỡ hành vi cũ.
    
*   Lý thuyết: Characterization test - viết test ghi lại hành vi hiện tại của code (kể cả khi chưa chắc đúng) trước khi refactor, để có lưới an toàn.
    
*   Thực hành: Viết bộ test bao phủ toàn bộ 4 module trước khi refactor (nếu chưa làm), verify test vẫn pass sau khi đã refactor ở các ngày trước.
    

**Ngày 125: Đo lường cải thiện**

*   Mục tiêu: Định lượng kết quả refactor, không chỉ cảm tính "sạch hơn".
    
*   Lý thuyết: Cyclomatic complexity, coupling giữa class, số dòng/method trung bình - công cụ đo (VD: SonarQube, hoặc thủ công).
    
*   Thực hành: Đo các chỉ số trên trước/sau refactor cho cả 4 module, lập bảng so sánh.
    

**Ngày 126: Review & Retrospective Giai đoạn 2**

*   Mục tiêu: Tổng kết toàn bộ giai đoạn Refactoring.
    
*   Lý thuyết: Nhìn lại mối liên hệ Smell → Technique → Kết quả đo lường được.
    
*   Thực hành: Viết báo cáo retrospective, đề xuất quy trình refactor bạn sẽ áp dụng cho công việc thực tế (VD: mỗi PR nên kèm 1 refactor nhỏ, definition of done bao gồm "không còn smell rõ ràng").
