Giáo trình Bản đồ tư duy

Giáo trình tổng quan

Trang này cho bạn bản đồ tư duy về OOP và Design Patterns trước khi đi vào từng chương. Đọc xong sẽ trả lời được: OOP là gì, vì sao có 4 trụ cột, SOLID giải vấn đề gì, 23 GoF pattern phân loại ra sao, và khi nào nên (hoặc KHÔNG nên) dùng pattern.

1. OOP — Object-Oriented Programming

OOP là paradigm (mô hình lập trình) tổ chức code quanh các đối tượng (object) chứa cả data (thuộc tính / state) và behavior (phương thức / hành vi). Đối lập với procedural programming nơi data và function tách rời.

Alan Kay (cha đẻ Smalltalk, 1970s) định nghĩa OOP qua 3 ý chính:

"OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things."

3 ý chính của Kay:

1.1. Lịch sử ngắn

NămSự kiện
1967Simula 67 (Norway) — class, inheritance đầu tiên
1972Smalltalk-72 (Alan Kay, Xerox PARC) — "pure OOP"
1983C++ (Bjarne Stroustrup) — OOP cho hệ thống
1991Python — OOP friendly, dynamic
1995Java — "write once, run anywhere"; OOP mainstream
1995JavaScript — prototype-based, "OOP nhưng khác"
1994"Design Patterns" book (Gang of Four) xuất bản — 23 patterns kinh điển
2000s+C#, Scala, Kotlin, Swift, Rust — OOP + functional hybrid
2010s+Composition over inheritance, FP elements vào OOP, immutability quay lại

2. 4 Trụ cột OOP

┌───────────────────────────────────────────────────────┐ │ OOP │ └───────────────────────────────────────────────────────┘ │ ┌───────────┬────────────┼────────────┬─────────────┐ ▼ ▼ ▼ ▼ ▼ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │Encapsu- │ │Abstrac- │ │Inherit- │ │Polymorphism │ │lation │ │tion │ │ance │ │ │ ├─────────┤ ├──────────┤ ├──────────┤ ├──────────────┤ │Đóng gói │ │Trừu tượng│ │Kế thừa │ │Đa hình │ │state + │ │— ẩn chi │ │— "is-a" │ │— cùng method │ │method; │ │tiết, lộ │ │relation- │ │khác hành vi │ │ẩn nội bộ│ │interface │ │ship │ │theo type │ └─────────┘ └──────────┘ └──────────┘ └──────────────┘

2.1. Encapsulation (đóng gói)

State của object chỉ truy cập được qua method công khai. Các trường nội bộ là private. Người dùng không cần biết object lưu data thế nào → có thể đổi implementation mà không phá API.

2.2. Abstraction (trừu tượng hóa)

Tách cái gì object làm khỏi cách nó làm. Abstract class / interface mô tả contract, không lo implementation. Người gọi chỉ cần biết "tôi gọi save()" — không quan tâm là DB nào, file nào.

2.3. Inheritance (kế thừa)

Class B kế thừa từ class A → B có mọi field/method của A + có thể thêm/override. "is-a" relationship: Dog is-a Animal.

Cảnh báo: kế thừa quá tay là nguyên nhân hàng đầu của code khó maintain (sẽ bàn ở Ch3 — composition over inheritance).

2.4. Polymorphism (đa hình)

Cùng 1 method, nhiều type khác nhau cho hành vi khác nhau. animal.speak()Dog kêu "woof", Cat kêu "meow", Cow kêu "moo". Code gọi không cần biết type cụ thể — chỉ biết Animal.

3 dạng polymorphism:

3. SOLID — 5 nguyên lý kinh điển

Robert C. Martin (Uncle Bob) đặt tên 5 nguyên lý vào 2000:

LetterTênTóm tắt 1 dòng
SSingle Responsibility Principle1 class chỉ có 1 lý do để thay đổi.
OOpen/Closed PrincipleMở để mở rộng, đóng để sửa đổi.
LLiskov Substitution PrincipleSubtype phải thay thế được supertype không phá hành vi.
IInterface Segregation PrincipleNhiều interface nhỏ tốt hơn 1 interface to.
DDependency Inversion PrinciplePhụ thuộc abstraction, không phụ thuộc concrete.

SOLID không phải luật bất biến — chúng là heuristic. Áp dụng đúng → code dễ thay đổi. Áp dụng cứng nhắc → over-engineer.

4. Design Patterns — 23 GoF

Năm 1994, "Gang of Four" (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) xuất bản "Design Patterns: Elements of Reusable Object-Oriented Software". Quyển sách là vốn từ vựng chung cho thiết kế phần mềm. Khi đồng nghiệp nói "đây là Decorator" — bạn hiểu cấu trúc ngay, không cần giải thích.

23 pattern chia 3 nhóm:

Creational (5)

Tập trung vào cách tạo object — giấu logic khởi tạo.

  • Factory Method
  • Abstract Factory
  • Builder
  • Prototype
  • Singleton

Structural (7)

Tập trung cấu trúc — ghép object thành cấu trúc lớn.

  • Adapter
  • Bridge
  • Composite
  • Decorator
  • Facade
  • Flyweight
  • Proxy

Behavioral (11)

Tập trung tương tác và trách nhiệm giữa các object.

Phần 1 — Ch6

  • Chain of Responsibility
  • Command
  • Iterator
  • Mediator
  • Memento
  • Observer

Phần 2 — Ch7

  • State
  • Strategy
  • Template Method
  • Visitor
  • Interpreter

4.1. Pattern không phải tất cả

Sau 1994, cộng đồng phát triển thêm rất nhiều pattern hữu ích:

23 GoF là nền tảng. Nắm vững GoF → tự đọc và áp dụng pattern hiện đại dễ dàng.

5. Khi nào nên (và KHÔNG nên) dùng pattern

Quy tắc ngón tay cái Nên: khi bạn nhận ra mình đang giải đúng vấn đề mà 1 pattern đã đặt tên — và áp dụng giúp code đơn giản hơn. KHÔNG nên: khi bạn thấy "có vẻ giống" — đôi khi 3 dòng if/else đơn giản hơn cả 5 class với interface và factory.

5.1. Anti-pattern: "Pattern Hammer"

Sau khi đọc xong sách Design Patterns, dev mới thường cố ép mọi vấn đề thành 1 pattern. Mọi class có Factory, mọi flow có State Machine, mọi event có Observer. Code biến thành mê cung 50 file cho việc 1 file đủ.

Pattern là giải pháp cho vấn đề cụ thể. Trước khi áp dụng, phải có vấn đề rõ ràng. Code over-engineered còn tệ hơn code "thô" mà rõ.

5.2. Khi pattern KHÔNG cần thiết

5.3. Khi pattern THỰC SỰ giúp

6. Refactoring & Code Smells

Martin Fowler (sách Refactoring, 1999) định nghĩa refactoring: "Cải thiện cấu trúc nội bộ của code mà không thay đổi hành vi quan sát được."

Trigger để refactor là code smell — dấu hiệu code có vấn đề:

Sẽ đào sâu Ch8.

7. DDD-lite — vốn ngắn cho project hiện đại

Eric Evans (sách Domain-Driven Design, 2003) đặt nền cho cách tổ chức code phức tạp xoay quanh business domain. Bạn không cần đọc cả sách 500 trang — chỉ cần nắm 5 building block:

Khái niệmÝ nghĩa
EntityObject có identity ổn định (User, Order). Hai User cùng email vẫn là 2 entity khác nhau nếu khác id.
Value ObjectObject bất biến, định danh qua giá trị (Money, Address, Email). 100 VND = 100 VND.
AggregateCụm Entity + VO được transaction-protect cùng nhau (Order + OrderItems). Có "aggregate root".
RepositoryTập trừu tượng để load/save aggregate; ẩn DB.
Domain ServiceLogic không thuộc về 1 entity (vd: TransferService chuyển tiền giữa 2 account).

Sẽ phân tích Ch8 với case study e-commerce.

8. Lộ trình học đề xuất

  1. Tuần 1: Ch1 + Ch2. Code 4 mini-class minh họa 4 trụ cột. Refactor 1 đoạn code mình từng viết theo SOLID.
  2. Tuần 2: Ch3. Tạo 1 immutable Money class. Áp dụng DI cho 1 service. Đọc Item 17–18 Effective Java (composition vs inheritance).
  3. Tuần 3: Ch4 + Ch5. Implement 5 creational + 7 structural pattern bằng TypeScript. Mỗi pattern 1 file ngắn ~50 dòng.
  4. Tuần 4: Ch6 + Ch7. 11 behavioral pattern. Đặc biệt chú ý phân biệt: Strategy vs State, Template vs Strategy, Visitor vs Iterator.
  5. Tuần 5: Ch8. Refactor 1 codebase nhỏ có sẵn (open-source) theo cataloged code smells. Áp dụng DDD-lite cho 1 ý tưởng app cá nhân.
Mẹo phỏng vấn Câu hỏi "Bạn dùng pattern X chưa?" — đừng kể tên pattern. Kể vấn đề bạn gặp, tại sao chọn pattern đó, có những lựa chọn nào khác và tại sao loại. Senior phỏng vấn quan tâm bạn tư duy thiết kế, không phải bạn nhớ tên pattern.

Sẵn sàng chưa? Bắt đầu từ Chương 1 — OOP Fundamentals & 4 Pillars.