Nền tảng về Design Patterns, Layered Architecture, Hexagonal và Clean Architecture
Design Patterns to Architectures: change pressure, refactoring to patterns, dependency rule and application structure
Khoá nền tảng về design pattern và kiến trúc ứng dụng, xoay quanh câu hỏi: phần nào sẽ thay đổi, và phần code nào đang phụ thuộc vào phần code nào. Bạn học cách chọn hoặc gỡ một pattern, đặt ranh giới theo Layered, Hexagonal, Clean Architecture, và yêu cầu AI tổ chức code theo cấu trúc bạn kiểm tra lại được.
- 43 bài
- 12h25p
- 42 quiz
- 3 bài học thử miễn phí
Bạn sẽ làm được gì
Khoá học bắt đầu từ một cảm giác nhiều developer đã quen: code vẫn chạy đúng, nhưng yêu cầu sau tốn công hơn yêu cầu trước. Design pattern và kiến trúc ứng dụng là những cách sắp xếp code để một thay đổi không lan vào phần logic không liên quan; khoá học cung cấp cách chọn chúng theo đúng vấn đề, kèm cái giá của từng lựa chọn. Khi AI viết phần lớn code, kiến thức này càng cần thiết: code theo một cấu trúc quen thuộc thì AI dễ đọc và sửa đúng chỗ hơn, còn bạn dù không tự tay viết pattern vẫn cần hiểu nó để yêu cầu đúng và kiểm tra lại kết quả.
- Gọi tên áp lực thay đổi— Bạn chỉ ra được phần hay thay đổi đang viết lẫn với phần ít thay đổi, trước khi nghĩ tới pattern nào.
- Đoán phạm vi một thay đổi— Bạn lần theo chiều dependency để biết file nào phải sửa theo, và đo coupling bằng số chỗ phải sửa thay vì cảm giác.
- Chọn hoặc gỡ một pattern— Bạn quyết định dựa trên áp lực mà pattern giải quyết và cái giá nó thêm vào, kể cả khi if/else vẫn là đủ.
- Đọc kiến trúc từ import graph— Bạn thấy chiều phụ thuộc thật qua các lệnh import thay vì tin vào sơ đồ, rồi giữ luật về chiều phụ thuộc bằng architecture check.
- Đặt ranh giới đúng chỗ— Bạn đặt port, adapter, use case hay repository ở nơi có thay đổi thật, để đổi database hay service bên ngoài mà không mở file chứa luật nghiệp vụ.
- Phân biệt Hexagonal, Onion và Clean— Bạn thấy ba kiến trúc cùng dựa trên một luật phụ thuộc, và biết chỗ chúng thật sự khác nhau.
- Yêu cầu AI tổ chức code— Bạn dùng tên pattern và tên cấu trúc để yêu cầu coding agent sắp xếp code, rồi kiểm tra lại kết quả qua chiều import.
Đây là khoá nền tảng cơ bản về design pattern và kiến trúc ứng dụng, độc lập với ngôn ngữ và framework: code minh họa bằng TypeScript chỉ để đọc.
Khoá học dành cho ai
- Phù hợp nhấtDeveloper đã viết ứng dụng thật— Code chạy được nhưng càng về sau càng khó sửa, và bạn muốn tự quyết định cấu trúc thay vì học thuộc pattern.
- Người viết code cùng AI— Bạn cần tên gọi chính xác để yêu cầu coding agent tổ chức code, và cách kiểm tra lại code nó viết.
- Người thấy lý thuyết còn xa vời— Bạn từng đọc về SOLID, GoF hay Clean Architecture nhưng thấy chúng xa code mình viết.
Bạn sẽ học theo cách nào
- Vấn đề trước, tên gọi sau— Mỗi bài thường bắt đầu từ một ví dụ nhỏ như service cộng hai số, kèm theo một yêu cầu thay đổi; pattern chỉ được gọi tên khi bạn đã thấy yêu cầu chạm vào đâu.
- Hình vẽ cấu trúc code— Hình minh họa cho thấy file, chiều import và chỗ yêu cầu thay đổi chạm tới, trước và sau khi sắp xếp lại.
- Trước và sau trên cùng một yêu cầu— Bạn so sánh code trước và sau trên chính yêu cầu đó, kèm cái giá phải trả.
- Quiz ngắn sau mỗi bài— Vài câu hỏi yêu cầu bạn dự đoán hoặc quyết định trên một đoạn code.
- Luyện tập cùng coding agent— Mỗi bài có một kit để coding agent của bạn dựng ví dụ thành repo nhỏ có test, bằng ngôn ngữ bạn chọn; bạn tự làm yêu cầu thay đổi, rồi agent chấm theo tiêu chí của kit.
Những điều cần lưu ý
Không dạy ngôn ngữ hay framework — Code TypeScript có chú thích và chỉ để đọc; bạn cần đọc được function, class, interface ở một ngôn ngữ bất kỳ, và mang cách nhìn sang ngôn ngữ của mình.
Không đi hết 23 pattern — Bạn đi sâu vào những pattern ứng với áp lực thay đổi hay gặp, và nhận ra pattern mà ngôn ngữ đã làm giúp.
Không bàn kiến trúc cấp hệ thống — Microservices, event sourcing hay DDD ở cấp chiến lược nằm ngoài khoá học; bạn nhận được cách tổ chức bên trong một ứng dụng.
Không có cấu trúc chuẩn để chép — Bạn nhận được cách quyết định cho từng áp lực, kể cả quyết định không thêm tầng nào.
Mentor
Khoá học dạy những gì
Cả khoá học dựa trên một câu hỏi: phần nào sẽ thay đổi, và phần code nào đang phụ thuộc vào phần code nào. Phần A đặt câu hỏi ấy ở cấp vài object, nơi nó dẫn tới design pattern; phần B nâng nó lên cấp cả ứng dụng, nơi câu trả lời nằm ở chiều import giữa các tầng và module. Mỗi lời giải đều có cái giá phải trả, như lời khuyên của Martin Fowler trong Is Design Dead?: pattern nào không đáng với độ phức tạp nó thêm vào thì đừng ngại gỡ ra. Phần kiến trúc bám theo hai bài viết gốc, Hexagonal Architecture của Alistair Cockburn và The Clean Architecture của Robert C. Martin.
Tìm chỗ code khó sửa, rồi học ba khái niệm nền
Nhóm đầu tiên đặt vài yêu cầu thay đổi lên một đoạn code checkout đang chạy đúng, xem mỗi yêu cầu bắt bạn sửa những chỗ nào, và đọc code smell như tín hiệu để hỏi tiếp. Tiếp theo là ba khái niệm nền: dependency (A dùng B thì khi B đổi, A có thể phải sửa), coupling và cohesion (đo bằng số chỗ phải sửa cho một thay đổi), và decoupling bằng interface. Trên một service chỉ cộng hai số, interface cho phép đổi cách nhận dữ liệu, cách trả kết quả và cách lưu mà không đụng vào phép cộng.
Design pattern theo từng tình huống thay đổi
Các pattern được sắp xếp theo tình huống bạn hay gặp: nhiều cách tính cho cùng một kết quả (Strategy), một khung chung có vài bước khác nhau (Template Method), hành vi đổi theo trạng thái (State), hành động cần xếp hàng hoặc hoàn tác (Command), thêm một bên cần nhận thông báo (Observer) và dữ liệu dạng cây (Composite). Rồi đến thư viện ngoài không khớp với code (Adapter, Facade), thêm log, cache, retry mà không sửa code gốc (Decorator, Proxy), chỗ quyết định tạo object nào (Factory, Builder, Abstract Factory) và object toàn cục làm khổ lúc viết test (Singleton, dependency injection). Mỗi pattern có một bản gọn bằng TypeScript, kèm cái giá và dấu hiệu cho thấy chưa nên dùng.
Pattern mà ngôn ngữ đã làm giúp, và lúc nên gỡ pattern
Iterator, Visitor, Prototype hay Memento hiếm khi cần dựng thành bộ class, vì ngôn ngữ đã có
for...of, generator, tagged union và các cách sao chép dữ liệu. Chain of Responsibility và Mediator bạn chủ yếu gặp trong code của framework, còn Bridge, Flyweight và Null Object thì hiếm khi cần đến. Phần A khép lại bằng chiều ngược lại: pattern là khoản đầu tư cho một thay đổi được đoán trước, và khi thay đổi đó không đến thì gỡ nó ra bằng refactoring giữ nguyên hành vi.Chia tầng, import graph và các mẫu để dựng phần lõi
Phần B mở đầu bằng layered architecture và câu hỏi vì sao một thay đổi ở database vẫn lan lên dù đã chia tầng. Bạn học đọc import graph để thấy kiến trúc thật, rồi giữ luật về chiều phụ thuộc bằng architecture check. Tiếp theo là các mẫu trong Patterns of Enterprise Application Architecture của Martin Fowler: Transaction Script, Domain Model, Active Record, Data Mapper, Repository, Unit of Work và Service Layer.
Dependency Inversion và Hexagonal architecture
Dependency Inversion đặt interface ở phía cần nó, để mũi tên import đổi chiều trong khi chiều gọi vẫn giữ nguyên. Hexagonal architecture dựa trên đó để tách phần nghiệp vụ khỏi mọi thứ bên ngoài, như khi phần tìm kiếm sản phẩm chuyển từ Postgres sang Elasticsearch mà luật tìm kiếm không phải viết lại. Driving adapter cho phép gọi cùng một nghiệp vụ từ web, CLI, job hay test. Driven adapter đổi mã lỗi hay timeout của service bên ngoài thành kết quả mà lõi hiểu. Còn composition root là nơi ứng dụng được lắp ráp khác nhau cho test, dev và production.
Onion, Clean Architecture và một luật phụ thuộc chung
Layered architecture theo cách của Eric Evans cho thấy application service, domain service và infrastructure service thuộc ba tầng khác nhau. Onion architecture đưa database ra vòng ngoài, còn Clean Architecture phát biểu thành dependency rule: mọi phụ thuộc trong source code chỉ hướng vào trong. Nhóm này còn đi qua input và output boundary, Humble Object, partial boundary, rồi đặt ba bộ nhãn Hexagonal, Onion và Clean lên cùng một import graph để thấy chỗ chúng thật sự khác nhau.
Chia code theo hướng thay đổi, và biết khi nào dừng
Nhóm cuối hỏi code nên chia theo tầng hay theo tính năng, và khi nào đáng dùng vertical slice hay modular monolith. Rồi đến chiều ngược lại: khi nào ba tầng và bốn interface là quá nhiều cho một app. Khoá học kết bằng một case study: service đặt hàng viết theo layered phải chuyển phần hỏi tồn kho sang kho của đối tác, và bạn quyết định ranh giới nào đáng tách thành port, làm theo thứ tự nào, dừng ở đâu.
Nội dung khóa học
Các bài còn lại mở sau khi ghi danh
- Từ design patterns tới architecture: vì sao mỗi yêu cầu mới lại làm code khó sửa hơnCourse opening: from change pressure to design patterns to application architectureBài đọc · 19 phút · Không tính tiến độHọc thử
- Code smell và áp lực thay đổi: tìm chỗ code khó sửa trước khi nghĩ tới patternChange pressure, code smells and volatility: what changes together and what changes apartBài đọc · 17 phút · có quizHọc thử
- Dependency: A dùng B thì khi B đổi, file nào phải sửa theoDependencies and dependency direction: import, call, transitive dependency, who must change when what changesBài đọc · 13 phút · có quizHọc thử
- Coupling và cohesion: đổi một file thì phải sửa thêm mấy fileCoupling and cohesion: tight vs loose coupling, what changes together stays together, measured by the cost of one changeBài đọc · 17 phút · có quizCần đăng nhập
- Decoupling bằng interface: đổi cách nhận, cách trả, cách lưu mà không đụng logicDecoupling with an interface: the seam, injection as plumbing, one logic behind HTTP or CLI input, JSON or text output and a swappable storeBài đọc · 15 phút · có quizCần đăng nhập
- Strategy pattern: khi nào if/else vẫn là đủStrategy pattern: interchangeable algorithms, function types and when a conditional is simplerBài đọc · 18 phút · có quizCần đăng nhập
- Template Method và composition: giữ khung xử lý chung ở lớp cha hay truyền các bước từ ngoài vàoTemplate Method vs composition: inheritance, delegation, hooks and the fragile base classBài đọc · 17 phút · có quizCần đăng nhập
- State pattern: đổi hành vi theo trạng thái mà không thêm mãi if/elseState pattern: state machines, transition tables and discriminated unionsBài đọc · 17 phút · có quizCần đăng nhập
- Command pattern: khi một hành động cần được xếp hàng, ghi lại hoặc hoàn tácCommand pattern: requests as objects, undo, queueing, logging and when a closure is enoughBài đọc · 16 phút · có quizCần đăng nhập
- Observer pattern: thêm một bên cần nhận thông báo là phải sửa hàm phát thông báoObserver pattern: in-process events, subscription, hidden control flow and unsubscribe leaksBài đọc · 16 phút · có quizCần đăng nhập
- Composite pattern: dữ liệu dạng cây mà code cứ phải kiểm tra đâu là lá, đâu là nhánhComposite pattern: uniform treatment of leaves and groups, recursion and tagged unionsBài đọc · 16 phút · có quizCần đăng nhập
- Adapter và Facade: khi thư viện ngoài không khớp với code, hoặc bắt bạn gọi quá nhiều bướcAdapter and Facade: translating interfaces and semantics, simplifying a subsystem, structural typingBài đọc · 19 phút · có quizCần đăng nhập
- Decorator và Proxy: thêm log, cache, retry mà không sửa code gốcDecorator and Proxy: wrapping the same interface, stacking order, access control and higher-order functionsBài đọc · 19 phút · có quizCần đăng nhập
- Factory và Builder: quyết định tạo object nằm ở đâu, và khi nào object literal đã đủFactory and Builder: who decides which object to create, and when an object literal is enoughBài đọc · 19 phút · có quizCần đăng nhập
- Abstract Factory: khi nhiều thành phần phải đi cùng một bộAbstract Factory: consistent families of objects, kits and when tokens are enoughBài đọc · 18 phút · có quizCần đăng nhập
- Singleton và dependency injection: tiện lúc viết, khổ lúc testSingleton to dependency injection: global access, hidden dependencies, test isolation and constructor injectionBài đọc · 16 phút · có quizCần đăng nhập
- Iterator, Visitor, Prototype, Memento, Interpreter: những pattern mà TypeScript đã có sẵn cách viết gọnIterator, Visitor, Prototype, Memento and Interpreter in modern TypeScript: language features that absorb patternsBài đọc · 21 phút · có quizCần đăng nhập
- Chain of Responsibility, Mediator, Bridge, Flyweight, Null Object: có sẵn hay hiếm khi cầnChain of Responsibility, Mediator, Bridge, Flyweight and Null Object: recognizing them in frameworks and knowing when they are really neededBài đọc · 22 phút · có quizCần đăng nhập
- Gỡ pattern thừa: khi pattern không còn đáng giữRemoving patterns: speculative generality, inline refactorings and the evidence on pattern costBài đọc · 17 phút · có quizCần đăng nhập
- Layered architecture: chia tầng rồi mà một thay đổi vẫn lan qua mọi tầngLayered architecture: layer responsibilities, strict vs relaxed layering, layer vs tier, transitive dependencies and the cost of layeringBài đọc · 17 phút · có quizCần đăng nhập
- Import graph và architecture check: sơ đồ một đằng, code import một nẻoSource dependency graphs: reading import direction, cycles and forbidden edges; enforcing dependency rules with automated architecture checksBài đọc · 18 phút · có quizCần đăng nhập
- Transaction Script và Domain Model: luật nghiệp vụ nằm trong hàm hay trong objectTransaction Script vs Domain Model (and Table Module): choosing the thickness of the core, anemic domain modelBài đọc · 17 phút · có quizCần đăng nhập
- Active Record và Data Mapper: object tự lưu xuống database hay giao việc lưu cho mapperActive Record vs Data Mapper (Table and Row Data Gateway for recognition): persistence-aware vs persistence-ignorant domain objects, who owns the mappingBài đọc · 18 phút · có quizCần đăng nhập
- Repository: interface đã giấu database mà vẫn làm mất nghĩa của dữ liệuRepository: collection-like, domain-shaped persistence contracts, not-found and conflict semantics, generic repositories and swapping data sourcesBài đọc · 19 phút · có quizCần đăng nhập
- Unit of Work: một thao tác sửa ba bảng, lỗi giữa chừng thì saoUnit of Work and Optimistic Offline Lock: business transactions, change tracking, commit and rollback, version conflictsBài đọc · 18 phút · có quizCần đăng nhập
- Service Layer và use case: khi luật nghiệp vụ nằm rải rác trong controller và câu SQLApplication layer and use cases: input command, domain invariant, dependency calls, result; Service LayerBài đọc · 17 phút · có quizCần đăng nhập
- Dependency Inversion: đã inject rồi mà nghiệp vụ vẫn phụ thuộc thư viện ngoàiDependency Inversion Principle: interface ownership, Separated Interface, call direction vs source dependency, DI vs DIP, seams that are not realBài đọc · 19 phút · có quizCần đăng nhập
- Hexagonal architecture: phần nghiệp vụ không cần biết mình được gọi từ đâu và đang gọi ra hệ thống nàoHexagonal architecture (Ports and Adapters): inside vs outside, primary and secondary actors, ports as purposeful conversations, how many portsBài đọc · 17 phút · có quizCần đăng nhập
- Driving adapter: cùng một nghiệp vụ, gọi từ web, CLI, job hay testDriving side of ports and adapters: primary adapters, one port many drivers, the test harness as a driverBài đọc · 17 phút · có quizCần đăng nhập
- Driven adapter và test double: test với mock thì xanh, lên production thì vẫn hỏngDriven side of ports and adapters: secondary adapters, in-memory fakes, contract tests shared by fake and real adapters, translating external semantics at the adapterBài đọc · 16 phút · có quizCần đăng nhập
- Composition root: ứng dụng được lắp ráp ở đâu, và lắp khác nhau cho test, dev, production thế nàoComposition root, Configurable Receiver and the Main component: wiring adapters per environment, from test-to-test to real-to-realBài đọc · 17 phút · có quizCần đăng nhập
- DDD layered architecture: cùng gọi là service mà thuộc ba tầng khác nhauEvans’ layered architecture: UI, application, domain and infrastructure layers; application vs domain vs infrastructure services; isolating the domainBài đọc · 17 phút · có quizCần đăng nhập
- Onion architecture: khi database không còn nằm ở tâmOnion architecture: domain-centred rings, repository interfaces in the core, infrastructure at the edge, how it differs from traditional layering while reusing DDD layer names and ports and adaptersBài đọc · 17 phút · có quizCần đăng nhập
- Clean Architecture: luật phụ thuộc và vì sao database, web, framework chỉ là chi tiếtClean Architecture: the dependency rule, the four circles, policy and level, entities vs use cases, frameworks as detailsBài đọc · 18 phút · có quizCần đăng nhập
- Use case interactor: kết quả đi ra ngoài thế nào mà lõi không phụ thuộc giao diệnClean Architecture use cases: input and output boundaries, request and response models, crossing boundaries against the flow of controlBài đọc · 18 phút · có quizCần đăng nhập
- Humble Object: tách logic ra khỏi phần code khó testHumble Object in Clean Architecture: controllers, presenters, view models and gateways; separating hard-to-test behaviour from testable logicBài đọc · 18 phút · có quizCần đăng nhập
- Partial boundaries: khi làm ranh giới đầy đủ quá tốn kém, nên dừng ở mức nàoPartial boundaries and the cost of boundaries: skip the last step, one-dimensional boundaries, facades, and when to upgrade to a full boundaryBài đọc · 16 phút · có quizCần đăng nhập
- Hexagonal, Onion, Clean: ba cái tên, một luật phụ thuộcHexagonal vs Onion vs Clean Architecture: one dependency rule, how much each prescribes about the core, and cargo-cult structuresBài đọc · 16 phút · có quizCần đăng nhập
- Vertical slice: thêm một field mà phải sửa năm folderPackage by layer vs package by feature vs vertical slice architecture; Screaming ArchitectureBài đọc · 17 phút · có quizCần đăng nhập
- Modular monolith: đã chia module mà module nào cũng gọi thẳng vào bên trong module khácModular monolith: modules by business capability, public API, enforced boundaries, module vs service boundaryBài đọc · 17 phút · có quizCần đăng nhập
- Module data ownership: module này join thẳng vào bảng của module kiaModular monolith internals: data ownership per module, cross-module queries, in-process calls vs in-process events, keeping the extraction optionBài đọc · 16 phút · có quizCần đăng nhập
- Over-layering: khi ba tầng và bốn interface là quá nhiều cho một appWhen not to layer: thin CRUD, test-induced design damage, over-abstraction and the cost of indirectionBài đọc · 17 phút · có quizCần đăng nhập
- Layered sang Hexagonal: đổi cấu trúc từng bước trên một codebase, và biết dừng ở đâuWorked case: incremental layered-to-hexagonal restructuring, choosing local vs structural change, what to keep and what to removeBài đọc · 18 phút · có quizCần đăng nhập
Vì sao có khoá học này
AI giờ viết cả một module trong vài phút, và code thường chạy đúng ngay lần đầu. Cái khó đến ở yêu cầu thứ ba, thứ tư, khi thêm một cách thanh toán hay đổi nơi lưu dữ liệu lại phải mở những file tưởng như không liên quan. Viết code đã nhanh hơn nhiều, còn mỗi lần sửa tốn bao nhiêu công thì vẫn do cấu trúc quyết định.
Muốn thiết kế tốt hơn, nhiều người học thuộc 23 pattern từ sơ đồ UML hoặc chép nguyên một template Clean Architecture, tức là đặt lời giải lên trước vấn đề. Chính những người viết sách về pattern cũng nhắc điều ngược lại: năm 2009, các tác giả GoF tự xếp lại nhóm pattern cốt lõi và Erich Gamma muốn bỏ Singleton, còn Joshua Kerievsky kể ông từng dùng Strategy ở chỗ một câu điều kiện là đủ.
Khoá học này đặt lại thứ tự: yêu cầu thay đổi đến trước, tên pattern đến sau. AI viết khung một pattern rất nhanh; còn có nên dùng, dùng ở đâu và gỡ khi nào là những quyết định bạn mang theo vào mọi codebase.
Những vấn đề thường gặp khi áp dụng design pattern và kiến trúc
Phản xạ tự nhiên khi thấy code khó sửa là tìm một pattern hay kiến trúc có tên để gắn vào. Có lúc đúng, nhưng nhiều khi lời giải được chọn trước khi vấn đề được gọi tên.
- Dấu hiệuMỗi lần thêm một cách thanh toán hay đổi phí ship, bạn lại phải sửa cùng một hàm checkout ngày càng dàiThực raphần hay đổi đang viết lẫn với phần ít đổi, nên yêu cầu nào cũng mở lại cả khối logic.
- Dấu hiệuBạn tách khối if/else ba nhánh thành Strategy, code dài ra mà lần sửa sau không nhẹ hơnThực rapattern được đưa vào trước khi có áp lực thay đổi thật, và khi các nhánh ít đổi thì if/else vẫn gọn hơn.
- Dấu hiệuCode đã dùng interface và dependency injection mà đổi thư viện gửi email vẫn phải sửa phần nghiệp vụThực rainterface được viết theo hình dạng của thư viện, trong khi nó phải do phía nghiệp vụ đặt ra.
- Dấu hiệuTest với mock xanh hết, lên production vẫn hỏngThực ramock chỉ giữ hình dạng của lời gọi, còn mã lỗi hay timeout của service thật phải được adapter xử lý và được contract test đối chiếu với bản thật.
- Dấu hiệuMột app CRUD nhỏ dựng theo template Clean Architecture, mỗi tính năng đi qua rất nhiều fileThực ramỗi tầng và mỗi interface là thêm một chỗ phải đọc qua, và chỉ đáng giá khi phía sau có thay đổi thật.
Mỗi tình huống trên được phân tích trong một bài riêng, trên một ví dụ nhỏ.
Câu hỏi thường gặp
Mình thanh toán bằng cách nào?
Bạn thanh toán bằng chuyển khoản ngân hàng qua mã VietQR ở bước checkout. 200Lab không thu thập thông tin thẻ của bạn.
Thanh toán xong bao lâu thì vào học được?
Hệ thống tự đối soát giao dịch, thường trong vài phút là khoá học có trong trang học của bạn. Bạn nhớ giữ nguyên nội dung chuyển khoản mà hệ thống đưa ra.
Mã QR hết hạn thì sao?
Mỗi đơn hàng có hiệu lực 30 phút. Nếu quá thời gian đó, bạn mở lại đơn và tạo mã QR mới, không cần đặt lại từ đầu.
Mình được truy cập khoá học trong bao lâu?
Thời hạn truy cập đi theo gói bạn mua và được ghi ngay dưới giá ở hộp mua.
Mình có nhận được các cập nhật của khoá học sau khi mua không?
Có. Khi khoá học được bổ sung hoặc cập nhật bài học, bạn nhận được các thay đổi đó trong suốt thời hạn truy cập của mình, không phải trả thêm.
Mình học trên điện thoại được không?
Được. 200Lab chạy trên trình duyệt của cả máy tính lẫn điện thoại, bạn không cần cài ứng dụng. Tiến độ học được lưu theo tài khoản nên bạn đổi thiết bị vẫn học tiếp được.
Học xong mình có nhận certificate không?
Có. Khi hoàn thành khoá học bạn nhận certificate có mã xác thực. Người khác có thể kiểm tra mã đó trên trang xác thực certificate của 200Lab nếu bạn chọn công khai.
Mình có thể học thử trước khi mua không?
Có. Khoá học này có bài học thử: bạn bấm nút Học thử ngay trong hộp mua, và các bài đó được đánh dấu trong chương trình học.
Bắt đầu từ đâu
Bài đầu tiên trả lời vì sao mỗi yêu cầu mới lại làm code khó sửa hơn, dù code không sai. Bài này đứng đầu vì nó đặt ra câu hỏi cả khoá học dựa vào: phần nào sẽ thay đổi, và phần code nào đang phụ thuộc vào phần code nào. Có câu hỏi đó, mỗi pattern và kiến trúc bạn gặp sau này là một cách trả lời bạn tự cân nhắc được.