
3 chiến thuật kinh điển: Defensive, Offensive và Aggressive
Last updated: August 08, 2025 Xem trên toàn màn hình



- 18 Dec 2024
Những Câu Thành Ngữ Khuyến Khích Tư Duy Ngược 759
- 10 Sep 2023
Định luật Murphy giải thích tại sao chúng ta luôn gặp xui xẻo vào những lúc tưởng thuận lợi 654
- 04 Jan 2023
Phát triển phần mềm linh hoạt theo mô hình Big Bang 571
- 18 May 2021
Cây cầu hiện đại vô dụng nhất thế giới và câu chuyện cái kết của thay đổi yêu cầu 501
- 03 Nov 2022
Bài học từ chuyện hai viên gạch xấu xí 476
- 03 Mar 2020
Giả định (Assumption ) là gì? Tại sao giả định rất quan trọng với dự án? 416
- 03 May 2022
Mô hình Hybrid Agile là gì? 404
- 18 Mar 2021
Kỹ thuật ước lượng dự án phần mềm linh hoạt dựa vào Story Point - phương pháp T-Shirt Sizing 362
- 02 Aug 2023
Tổng hợp một số project tham khảo khi xây dựng các ứng dụng theo mô hình Microservices 320
- 20 Jul 2021
Quản lý và đánh giá công việc theo quy trình TIGO SmartWork 310
- 02 Aug 2021
Product Owner làm gì trước khi bắt đầu sprint đầu tiên của dự án (Sprint Zero)? 302
- 01 Aug 2023
Phân tích yêu cầu phần mềm sẽ nhìn vào thực trạng (AS-IS) hay tương lai (TO-BE)? 286
- 28 Jun 2024
Tại sao các kỹ sư IT giỏi nhất lại là những người theo thuyết bất khả tri về công nghệ (technology agnostics)? 251
- 02 Mar 2018
Tại sao ví Scrum như dòng điện xoay chiều? 219
- 14 Apr 2019
Product Backlog là gì? Các đặc điểm cơ bản của một Product Backlog 218
- 08 Jan 2022
Yêu cầu thay đổi (Change Request) là gì? Làm thế nào để kiểm soát Change Request? 184
- 01 Dec 2023
Tư duy ngược - Chuyện số 1: Nơi nguy hiểm nhất là nơi an toàn nhất 184
- 10 May 2021
Phát triển Phần mềm Tinh gọn (Lean Software Development) 173
- 08 Feb 2021
Quy trình nâng cấp phần mềm quản trị doanh nghiệp TIGO ERP 160
- 14 Dec 2022
Phương pháp kiểm tra Fagan Inspection là gì? 151
- 24 Mar 2019
Scrum giống như bà mẹ chồng, giúp bạn nhìn ra các lỗi sai 149
- 21 Apr 2020
Bảo trì phần mềm là gì? Phân biệt các loại bảo trì 129
- 22 Jul 2020
Quản lý dự án phần mềm trong thực tế và câu chuyện thành công của InfoSys 85
- 01 Jun 2025
Thiết Kế Hướng Miền (Domain-Driven Design) hình thành như thế nào trong kiến trúc Lưới Dữ Liệu (Data Mesh)? 24
- 06 Dec 2025
Sức mạnh của phương pháp 30-for-30: Bạn đã bao giờ cam kết 30 ngày liên tục cho một mục tiêu? 17
- 05 Aug 2023
Phân biệt Quality và Grade 11
Lập trường phát triển (Development stance)
Một cách tiếp cận phát triển phần mềm được định hướng bởi triết lý hoặc tư duy nền tảng, được gọi là development stance, và nó cũng ảnh hưởng đến văn hóa cũng như cách ra quyết định của nhóm. Đây là khái niệm linh hoạt và trừu tượng hơn, cho phép tùy chỉnh dựa trên yêu cầu và bối cảnh của dự án.
Phương pháp phát triển (Development method / methodology)
Phương pháp phát triển là một tập hợp có tổ chức và được tiêu chuẩn hóa gồm các quy trình, kỹ thuật và công cụ được sử dụng trong phát triển phần mềm, cung cấp kế hoạch từng bước rõ ràng để hoàn thành dự án. Nó có những quy tắc và hướng dẫn rõ ràng nhằm đảm bảo tính nhất quán và tuân thủ best practices (thực hành tốt nhất), vì vậy mang tính ràng buộc và nghiêm ngặt hơn.
Lập trình chiến thuật phòng thủ (Defensive programming)
"Defensive programming" dịch sang tiếng Việt chuẩn nhất là "lập trình phòng thủ".
Trong ngữ cảnh kỹ thuật, lập trình phòng thủ nghĩa là viết code với tư duy dự đoán và xử lý trước các tình huống bất thường hoặc lỗi để phần mềm vẫn chạy ổn định, ngay cả khi dữ liệu đầu vào, trạng thái hệ thống hoặc tương tác người dùng không như mong đợi.
Khái niệm của cách tiếp cận này là phát triển mã nguồn (code) có thể chạy đúng ngay cả khi gặp các trạng thái bất ngờ, dữ liệu đầu vào từ người dùng không lường trước, v.v. Điều đó có nghĩa là lập trình viên cần dự đoán các trạng thái khác nhau và xử lý chúng để phần mềm tiếp tục chạy bình thường.
Để làm được điều này, cần xem xét một số yếu tố:
- Xử lý toàn diện các dữ liệu, đầu vào bất ngờ từ người dùng hoặc nguồn khác.
- Nâng cao chất lượng code và giảm lỗi thông qua code review (xem xét mã), phân tích tĩnh và động (static/dynamic analysis).
- Phát triển và chạy các cấp độ kiểm thử khác nhau như unit test (kiểm thử đơn vị), functional test (kiểm thử chức năng),... càng nhiều càng tốt.
Điểm mạnh của cách này là đảm bảo mọi bản cập nhật mới đều vượt qua cả các bài test cũ lẫn mới, kể cả những tình huống "không nên xảy ra". Ví dụ: danh sách rỗng (empty list), null pointer (con trỏ rỗng), hoặc dữ liệu vượt quá độ dài cho phép. Trong defensive programming, ta thậm chí bao quát cả lỗi nội bộ — mặc dù điều này có thể kém hiệu quả.
Tuy nhiên, tồn tại một nghịch lý: ta không thể bao quát mọi trạng thái có thể xảy ra, và việc cố làm vậy chỉ khiến code phức tạp hơn, tốn nhiều tài nguyên (tiền bạc, thời gian, năng lượng).
Khi nào nên dùng Defensive programming?
- Khi giao tiếp trực tiếp với thế giới vật lý, đặc biệt là phần cứng hoặc bất kỳ loại kết nối/thư viện nào có thể có hành vi không lường trước (timeout, hỏng hóc...).
- Trong môi trường production (sản phẩm thực tế) hơn là giai đoạn phát triển, để tránh ẩn giấu lỗi khiến lập trình viên không nhận biết vấn đề.
Ưu điểm
- Giúp hệ thống quan trọng ổn định và đáng tin cậy hơn.
- Bao quát cả các tình huống hiếm gặp.
Nhược điểm
- Có thể che giấu lỗi.
- Khó debug (gỡ lỗi) nếu chỉ dựa vào logging.
- Code phức tạp hơn để bao quát mọi trạng thái.
Ví dụ
public class DefensiveProgramming {
public static int divide(int numerator, int denominator) {
if (denominator == 0) {
System.out.println("Error: Division by zero is not allowed.");
return -1; // Return an error code or throw an exception
}
return numerator / denominator;
}
public static void main(String[] args) {
int result = divide(10, 0);
if (result != -1) {
System.out.println("Result: " + result);
}
}
}
Lập trình chiến thuật tấn công (Offensive programming)
"Offensive programming" thường được dịch sang tiếng Việt là "lập trình tấn công".
Tuy nhiên, nếu muốn giữ đúng sắc thái chuyên môn hơn, có thể dùng:
- Lập trình chủ động bộc lộ lỗi – nhấn mạnh mục tiêu của phương pháp là để lỗi nội bộ tự lộ ra (fail fast) thay vì che giấu như trong defensive programming.
- Lập trình phản công – cách dịch mang tính ẩn dụ, nhưng có thể gây hiểu nhầm nếu người đọc không quen thuật ngữ.
Offensive programming có thể được coi là một nhánh của defensive programming nhưng với tư duy khác. Nếu defensive programming cố xử lý mọi ngoại lệ cả từ nguyên nhân bên ngoài lẫn bên trong, thì offensive programming tập trung để nguyên nhân nội bộ tự phát sinh và chỉ bắt lỗi từ nguồn bên ngoài. Nó chia lỗi thành hai loại: acceptable (chấp nhận được) và preventable (ngăn ngừa được).
Acceptable (chấp nhận được)
- Dữ liệu đầu vào không hợp lệ từ bên ngoài, bao gồm cả người dùng.
- Lỗi liên quan phần cứng.
- Ngoại lệ từ tài nguyên hệ thống như lưu trữ, mạng, bộ nhớ.
Preventable (cần ngăn ngừa)
- Giá trị đầu vào cho hàm nội bộ nằm ngoài điều kiện xác định (range, length).
- Hành vi hoặc giá trị trả về khi gặp điều kiện chưa xác định.
- Tham số đầu vào của hàm không hợp lệ.
Nói ngắn gọn, offensive programming làm cho lỗi trở nên rõ ràng và dễ phát hiện.
Ưu điểm
- Tốt cho giai đoạn phát triển.
- Code đơn giản hơn defensive programming.
- Không che giấu lỗi.
- Ép buộc xử lý lỗi sớm (Fail Fast).
Nhược điểm
- Có thể ảnh hưởng danh tiếng do crash.
- Làm hệ thống kém ổn định.
- Không dùng được cho hệ thống quan trọng, thời gian thực hoặc an toàn tuyệt đối.
- Khách hàng khó chấp nhận nếu lỗi xảy ra thường xuyên.
Ví dụ
public class OffensiveProgramming {
public static int divide(int numerator, int denominator) {
assert (denominator != 0) : "Denominator cannot be zero";
return numerator / denominator;
}
public static void main(String[] args) {
int result = divide(10, 0); // Will throw an AssertionError if assertions are enabled
System.out.println("Result: " + result);
}
}
Lập trình chiến thuật Aggressive (Aggressive programming)
"Aggressive programming" dịch sang tiếng Việt là "lập trình hung hăng".
Tuy nhiên, nếu muốn nghe tự nhiên và mang sắc thái chuyên môn hơn, bạn có thể dùng:
- Lập trình tăng tốc – nhấn mạnh yếu tố chạy đua với thời gian, tập trung vào tính năng cốt lõi để kịp deadline.
- Lập trình ưu tiên tốc độ – cách diễn đạt dễ hiểu hơn cho người không quen thuật ngữ.
Trong các tài liệu kỹ thuật, nhiều người vẫn giữ nguyên cách dịch "lập trình hung hăng" kèm giải thích:
Trong các dự án cần gấp (time-critical), thời gian bàn giao là yếu tố sống còn, ta cần tập trung vào những tính năng và chức năng quan trọng nhất của phần mềm, thay vì mọi khía cạnh. Điều này thường xảy ra khi cần ra mắt prototype (bản mẫu) nhanh chóng.
Ở giai đoạn này, ưu tiên dành nhiều nguồn lực nhất cho việc phát triển tính năng, đồng thời vẫn có kế hoạch kiểm thử phù hợp. Sau khi bàn giao, cần quay lại cải thiện các phần đã bỏ qua. Ví dụ: thay đổi cách giao tiếp giữa các module, cấu trúc module...
Best practice (Thực hành tốt nhất)
- Trong giai đoạn phát triển: dùng offensive programming để phát hiện lỗi càng sớm càng tốt.
- Khi xử lý dữ liệu từ nguồn bên ngoài (đặc biệt liên quan phần cứng): dùng defensive programming.
- Khi ra bản phát hành: báo lỗi một cách âm thầm (logging), để sản phẩm tiếp tục hoạt động, sau đó sửa trong bản cập nhật mới.
Kết bài, xin trích dẫn câu nói nổi tiếng của Sheryl Sandberg, giám đốc công nghệ của tập đoàn Facebook.