Các Phương pháp Agile – Phần 3: Phát triển Phần mềm Tinh gọn

 Tiếp theo Bài trước

Phát triển Phần Mềm Tinh gọn (Lean Software Development) là một phương pháp theo triết lí Agile, sử dụng Tư duy Tinh gọn (Lean Thinking) và các nguyên lí đặc trưng của Tinh gọn (vốn xuất phát từ ngành sản xuất ô tô – Lean Manufacturing)  được áp dụng cho lĩnh vực phát triển phần mềm. Tên gọi  “Lean Software Development” xuất xứ từ cuốn sách cùng tên của Mary Poppendieck và Tom Poppendieck. Cuốn sách diễn dịch lại Tư duy Tinh gọn với ý nghĩa mới kèm theo các công cụ hữu hiệu để triển khai trong thực tiễn. Trong đó “Bảy nguyên lí” diễn giải Tư duy Tinh gọn trong việc phát triển phần mềm là linh hồn cho quá trình phát tiển phần mềm tinh gọn. Trong các cuốn sách của mình, Mary và Tom Poppendieck còn cung cấp các "công cụ" để thực hiện triết lí tinh gọn trong quá trình phát triển phần mềm.

Bộ sách về Lean Software Development của Poppendieck

Bộ sách về Lean Development của Mary  & Tom Poppendieck

Bảy nguyên lí Tinh gọn

1. Loại bỏ lãng phí

Tất cả mọi thứ không tăng thêm giá trị cho khách hàng được coi là lãng phí (Muda). Chúng  bao gồm:

  •    mã nguồn và chức năng không cần thiết
  •    sự chậm trễ trong quá trình phát triển phần mềm
  •    yêu cầu không rõ ràng
  •    kiểm thử không đủ, để lặp lại quá trình có thể  tránh được
  •    quan liêu
  •    giao tiếp nội bộ chậm chạp

Để có thể loại bỏ lãng phí, người ta phải nhận ra nó. Nếu một số hoạt động có thể được bỏ qua, hoặc kết quả có thể đạt được mà không có nó, đó chính là lãng phí. Ví dụ về lãng phí trong phát triển phần mềm có thể kể đến: làm ra các code chưa hoàn thành rồi bỏ đi trong quá trình phát triển; các quy trình phụ và các tính năng không thường xuyên được sử dụng bởi khách hàng; chờ đợi cho các hoạt động khác, các đội khác, quy trình khác; sản phẩm có lỗi và chất lượng thấp; các công việc quản lí không tạo ra  giá trị thực sự. Phát triển Tinh gọn tập trung loại bỏ các lãng phí để đạt trạng thái Tinh gọn, tạo điều kiện để đạt hiệu quả tối đa.
Để phân biệt và nhận ra lãng phí, kĩ thuật ánh xạ dòng giá trị được sử dụng. Trong đó, một dòng giá trị bắt đầu khi một đơn vị kinh doanh quyết định rằng thông tin tốt hơn sẽ giúp tăng doanh thu hoặc giảm chi phí. Đây là sự bắt đầu của dòng giá trị. Các dòng giá trị kết thúc khi phần mềm được triển khai bắt đầu tạo thêm doanh thu hoặc giảm chi phí. “Tồn kho” (inventory) trong dòng phần mềm giá trị phát triển là một phần thực hiện công việc: yêu cầu không được phân tích và thiết kế, bản thiết kế không được mã hóa, mã nguồn không được kiểm thử và tích hợp, các tính năng không được triển khai, các tính năng đã triển khai nhưng không phải tiết kiệm tiền hoặc giảm chi phí. Khi dòng giá trị phần mềm có ít công việc kiểu như thế, rủi ro sẽ được giảm và năng suất được cải thiện rất nhiều. Bước tiếp theo là chỉ ra nguồn lãng phí và loại bỏ chúng. Việc này cũng nên được thực hiện lặp đi lặp lại loại bỏ hết các quy trình và thủ tục không cần thiết.

2. Khuếch trương việc học

Phát triển phần mềm là một quá trình học tập liên tục để tạo ra tri thức mới. Phương pháp tốt nhất để cải thiện một môi trường phát triển phần mềm là khuếch trương việc học tập.
Quá trình học tập được đẩy nhanh tiến độ bằng cách sử dụng các chu kỳ lặp đi lặp lại ngắn – cùng với kĩ thuật tái cấu trúc (refactoring ) và kiểm thử tích hợp. Tăng cường thông tin phản hồi thông qua các buổi họp ngắn với khách hàng để xác định tình hình hiện tại và phác thảo những nỗ lực phát triển và điều chỉnh để cải thiện trong tương lai. Trong những phiên làm việc này, cả hai đại diện khách hàng và đội ngũ phát triển tìm hiểu thêm về vấn đề và tìm ra các giải pháp để đi tiếp. Vì vậy, khách hàng hiểu rõ hơn về nhu cầu của họ, dựa trên kết quả hiện có của các nỗ lực phát triển, còn các nhà phát triển thì có thể tìm hiểu làm thế nào để đáp ứng tốt hơn những nhu cầu đó. Thay vì bổ sung thêm tài liệu hoặc kế hoạch chi tiết, các ý tưởng khác nhau có thể được thử nghiệm bằng cách viết mã và tạo ra các bản build. Quá trình thu thập yêu cầu người dùng có thể được đơn giản hóa bằng việc làm các bản mẫu: trình diễn các giao diện trên màn hình (screen) cho người sử dụng cuối cùng và nhận lấy các dữ liệu của họ. Một ý tưởng quan trọng khác trong quá trình giao tiếp và học tập với khách hàng là phát triển dựa-theo-lô (set-based development) – kĩ thuật này giúp tập trung vào trao đổi về các ràng buộc của các giải pháp trong tương lai, những ý tưởng nào không thực sự là giải pháp; từ đó thúc đẩy việc đưa ra giải pháp thông qua đối thoại với khách hàng.

3. Quyết định càng muộn càng tốt

Do việc phát triển phần mềm luôn đi kèm với  nhiều yếu tố không chắc chắn, nên để có kết quả tốt hơn, chúng ta phải quyết định dựa trên nhiều lựa chọn (options), trì hoãn quyết định càng lâu càng tốt cho đến khi chúng có thể được thực hiện dựa trên dữ kiện thực tiễn (facts) chứ  không phải trên các giả định và dự đoán không chắc chắn. Một hệ thống càng phức tạp, thì càng chứa nhiều khả năng thay đổi, do đó cần thiết phải tạo ra các “độ trễ” cho các quyết định quan trọng. Cách tiếp cận lặp (iterative) thúc đẩy nguyên tắc này – khả năng thích ứng với những thay đổi và sửa chữa những sai lầm, những thứ có thể rất tốn kém nếu được phát hiện muộn, sau khi hệ thống đã được phát hành.
Cách tiếp cận trì hoãn này cũng có thể giúp khách hành nhận ra được những yêu cầu thực sự của họ vốn chỉ tường minh khi họ đã có những trải nghiệm rõ ràng về sản phẩm. Sự trì hoãn này sẽ giúp khách hàng loại bỏ các yêu cầu vốn không ổn trong các giả định ban đầu, giúp giảm thiểu lãng phí.

4. Chuyển giao càng nhanh càng tốt

Càng phát hành sớm các gói sản phẩm, bạn càng nhận lại được nhiều phản hồi sớm hơn về sản phẩm, và chúng có thể được đưa vào các cải tiến trong các phân đoạn tiếp theo của quá trình phát triển. Phân đoạn càng ngắn thì quá trình học tập và giao tiếp càng hiệu quả.
Khách hàng thì luôn đánh giá cao việc chuyển giao nhanh chóng các sản phẩm chất lượng vì chúng thường gia tăng tính linh hoạt trong hoạt động của họ. Công ty có thể chuyển giao nhanh hơn tốc độ thay đổi tư duy của khách hàng.
Đây là nguyên lí bổ sung cho nguyên lí “Quyết định càng muộn càng tốt”: càng chuyển giao nhanh, bạn càng có cơ hội để trì hoãn các quyết định. Ví dụ: bạn có thể thay đổi một chức năng trong 1 tuần, khi đó bạn không phải quyết định điều gì cho tới tuần sau, trước khi sự thay đổi là thực sự cần thiết.
Nguyên lí này cũng cho phép triển khai “hệ thống kéo” (pull system) trong phần mềm. Theo đó, bạn chỉ phát triển những gì khách hàng đang muốn có, chứ không phải là những gì họ muốn “từ ngày hôm qua”, do vậy sẽ giảm được các “lãng phí” không cần thiết (là các chức năng sẽ không được dùng trong thực tế).

5. Trao quyền cho nhóm

Cách tiếp cận tinh gọn ủng hộ việc “tìm người giỏi và để cho họ làm công việc của riêng mình”, quy trình khích lệ, tìm lỗi, loại bỏ những trở ngại, và không quản lý vi mô. Các cấp quản lí không tập trung vào việc chỉ cho developer những gì họ phải làm, mà chủ yếu lắng nghe họ, đưa ra các phân tích, lời khuyên và tìm kiếm các cải tiến. Với niềm tin “tất cả là ở con người”, Lean ủng hộ chủ trương động viên và khuyến khích để vươn cao hơn trong công việc của mình. Các nhà phát triển nên được trao quyền tiếp cận khách hàng, các lãnh đạo cung cấp hỗ trợ và giúp đỡ trong các tình huống khó khăn, cũng như đảm bảo rằng sự hoài nghi không hủy hoại tinh thần của đội. Các quyết định đi từ dưới lên (bottom-up) chứ không chỉ là từ cấp lãnh đạo (top-down).

6. Tạo ra tính toàn vẹn tự thân

Hơn cả “chất lượng”, tính toàn vẹn (integrity) là điều khiến người dùng muốn dùng sản phẩm. Phần mềm cần được đặt trong một hệ thống đầy đủ để được phát triển cho đúng. Bản thân nó không phải là “cái đích”, phần mềm luôn là phương tiện để người dùng đạt được “đích”.
Toàn vẹn có hai dạng: toàn vẹn nhận thức (hay toàn vẹn ngoại tại- external integrity) và toàn vẹn khái niệm (hay toàn vẹn nội tại – internal integrity). Trong đó toàn vẹn ngoại tại phản ánh sự nhận thức từ phía khách hàng về sự cân bằng giữa chức năng, tính khả dụng, độ tin cậy và các yếu tố kinh tế.
Còn toàn vẹn nội tại có nghĩa là các thành phần riêng biệt của hệ thống làm việc tốt với nhau như một tổng thể với sự cân bằng giữa tính linh hoạt, khả năng bảo trì, sự hiệu quả và tính đáp ứng. Điều này có thể đạt được bằng sự hiểu biết các miền vấn đề và giải quyết nó cùng một lúc, không phải theo trình tự. Do đó cần có thông tin đầy đủ, đa chiều từ nhiều phía với các hình thức giao tiếp trực diện thay vì các mớ tài liệu dày cộm. Luồng thông tin cần phải là đa chiều: từ developer tới khách hàng và phản hồi ngược lại.
Để đạt được toàn vẹn nhận thức, cần phải có được toàn vẹn khái niệm trước đã.
Một trong những cách làm đúng đắn để có được sự toàn vẹn kiến ​​trúc là tái cấu trúc. Cùng với sự gia tăng tính năng là sự gia tăng sự phức tạp và lộn xộn trong cơ sở mã nguồn (codebase). Tái cấu trúc để giữ tính đơn giản (simplicity), rõ ràng, tối thiểu hóa các tính năng trong các đoạn mã nguồn. Sự lặp lại trong mã nguồn là những dấu hiệu cho thấy có thiết kế mã xấu và cần phải tránh. Quá trình xây dựng hoàn chỉnh và tự động nên được đi kèm với một bộ đầy đủ và tự động hóa các kiểm thử mức lập trình (developer testing) và mức khách hàng (customer tests), có versioning thống nhất, đồng bộ và có ý nghĩa nghĩa. Cuối cùng, sự toàn vẹn cần được xác nhận với các kiểm thử kỹ lưỡng để đảm bảo hệ thống có  những gì khách hàng mong đợi. Kiểm thử tự động cũng được coi là một phần của quá trình sản xuất, và do đó nếu chúng không có giá trị thì có thể bị xem là lãng phí. Kiểm thử tự động không phải là một mục tiêu, mà là một phương tiện để hoàn thành công việc, đặc biệt là trong việc giảm thiểu các lỗi.

7. Thấy toàn cảnh

Hệ thống phần mềm ngày nay không đơn giản là tổng gộp của các bộ phận, mà còn là sản phẩm của sự tương tác giữa các thành đó. Vì vậy cần thiết phải tính đến các tác động toàn cục khi thực hiện các công việc tối ưu hóa cục bộ.
Lỗi trong phần mềm có xu hướng tích lũy trong quá trình phát triển và có liên hệ chặt chẽ với nhau. Cần dừng lại và phân tích các triệu chứng bất ổn khi bắt gặp. Hãy truy nguyên gốc rễ vấn đề. Bằng cách phân rã các nhiệm vụ lớn thành các nhiệm vụ nhỏ hơn, và tiêu chuẩn hóa các giai đoạn phát triển khác nhau, nguyên nhân gốc rễ của các lỗi này cần được phát hiện và loại bỏ.

Các “Công cụ” Tinh gọn

Chữ “Công cụ” (tool) là từ dùng của Poppendieck, với nghĩa rộng bao hàm phương pháp và công cụ tư duy để hiện thực hóa các nguyên lí tinh gọn trong thực tiễn. Hai mươi hai công cụ được liệt kê trong bảng đưới đây:

Công cụ

Để

#1 Nhìn ra Lãng phí

#2 Ánh xạ Dòng Giá trị

Loại bỏ lãng phí

#3 Phản hồi

#4 Phân đoạn

#5 Đồng bộ hóa

#6 Phát triển theo lô

Khuếch trương việc học

#7 Tư duy Lựa chọn

#8 Trách nhiệm Phút cuối

#9 Ra quyết định

Quyết định càng muộn càng tốt

#10 Hệ thống kéo

#11 Lý thuyết Hàng đợi

#12 Giá của Trì hoãn

Chuyển giao càng nhanh càng tốt

#13 Tự-Xác-định

#14 Động viên

#15 Lãnh đạo

#16 Chuyên môn

Trao quyền cho nhóm

#17 Toàn vẹn Nhận thức

#18 Toàn vẹn Khái niệm

#19 Tái cấu trúc

#20 Kiểm thử

Tạo ra tính toàn vẹn tự thân

#21 Đo lường

#22 Hợp đồng

Thấy toàn cảnh

Các công cụ này được mô tả rất chi tiết trong “Lean Software Development – An agile toolkit” và “Implementing Lean Software Development: From Concept to Cash“, cùng với nó là các biện pháp thực hành cụ thể để giúp những người thực hành Agile có thể vận dụng các nguyên lí tinh gọn vào hoạt động phát triển phần mềm một cách hữu hiệu. Trong cuốn sách gần đây nhất – “Leading Lean Software Development”, các tác giả đã cung cấp các thảo luận chi tiết hơn nữa về phương diện lãnh đạo để có được sự thành công trong áp dụng Lean, trong đó có thảo luận kĩ hơn về các vấn đề con người, văn hóa tinh gọn, tư duy hệ thống … để mở rộng tầm phạm vi ảnh hưởng của Tinh gọn ra phạm vi tổ chức.

Còn tiếp …