Mình làm gì khi làm việc với một dự án mới?

Mình làm gì khi làm việc với một dự án mới?

Đây là một trình tự mà có lẽ nhiều anh em thấy khá quen thuộc: khi bắt đầu một dự án, ta cần phân tích yêu cầu, rồi chọn công nghệ, thiết kế kiến trúc, tạo project skeleton ... Rồi từ đó, start implementation theo từng giai đoạn, từng sprint thôi. Đúng không nhỉ?

Bài viết này nêu lên quan điểm cá nhân của mình như một góc nhìn tham khảo.

Từ lúc mình là một junior developer cho đến khi đạt được kinh nghiệm tốt hơn, khi được giao cho một dự án, mình thường bắt đầu những bước dưới đây:

Hiểu bức tranh toàn cảnh

Rất nhiều lập trình viên cho rằng việc hiểu nghiệp vụ là công việc của Product Owner. Tuy nhiên, ở quan điểm của mình, việc hiểu được toàn bộ bức tranh nghiệp vụ là điều bắt buộc phải làm đối với mọi thành viên dự án. Khi hiểu được bức tranh tổng quát, mình sẽ đưa ra giải pháp tốt hơn, có giá trị hơn trong quá trình triển khai, coding, testing ... Hiểu được bức tranh toàn cảnh bao gồm:

  • Hiểu khách hàng mình là ai? Hoạt động trong lĩnh vực nào?
  • Đâu là nỗi đau / vấn đề mà họ cố gắng giải quyết
  • Yếu tố nào đối với họ là then chốt để xác định sản phẩm là thành công
  • Dự án mình đang làm đang cố gắng giải quyết điều gì? Có những đối tượng nào tham gia ...

Rất nhiều, rất nhiều những câu hỏi tương tự như vậy mình cần phải hiểu. Nắm được bức tranh của dự án chính là nắm được tấm bản đồ vậy. Làm dự án mà không nắm được bức tranh tổng thể thì giống như đi đêm không có đèn pin, đi vào rừng mà không có la bàn. Thất bại chỉ là sớm hay muộn thôi.

Hiểu bức tranh chi tiết

Đi vào chi tiết của dự án, mình thường phác thảo một sơ đồ khái niệm (Conceptual Model) để xác định miền nghiệp vụ và các đối tượng nghiệp vụ / quan hệ để hiểu rõ được nghiệp vụ chi tiết. Đây là một điều đối với mình cũng cực kì quan trọng không kém, bởi vì:

  • Việc có được một sơ đồ khái niệm giúp ta nhìn ra được các thực thể nghiệp vụ từ thực tế. Nó giúp ta hiểu rõ nghiệp vụ hơn, dễ sử dụng để xác định góc nhìn của mình về nghiệp vụ đó với business user hơn.
  • Sơ đồ khái niệm cũng là một ngôn ngữ chung để development team và business user cùng đóng góp để hoàn thiện và từ đó làm cho giao tiếp hiệu quả hơn. Khổng Tử nói: "danh có chính thì ngôn mới thuận" là vậy.
  • Từ conceptual model, giúp ta xác định được domain boundary. Điều này giúp ta module hóa và phân chia cấu trúc dự án một cách dễ dàng hơn.

Đối với các nghiệp vụ phức tạp, việc vẽ ra process flow về mặt business cũng cần thiết. Tuy nhiên, mọi thứ nên được xuất phát điểm từ việc ánh xạ các khái niệm business trong conceptual model.

Năm 2007 mình nhớ trong một buổi phỏng vấn, mình được hỏi: em hãy thiết kế một phần mềm quản lý thư viện, vẽ ra OOD. Mình trình bày tất cả các đối tượng: sách, thành viên, ... và thẻ mượn trả sách. Một anh TA hỏi mình: vì sao em lại nghĩ ra đối tượng thẻ mượn trả sách, mà không phải là một đối tượng quan hệ many-many bình thường? Mình trả lời: vì em cũng từng đi mượn sách thư viện, và em thấy rằng nghiệp vụ thực tế họ sẽ tạo ra một tờ giấy để ghi nhận ngày nhận, ngày trả mỗi khi có người mượn sách. Nếu chỉ nghĩ thuần túy về tech, thì thường mình sẽ không nghĩ ra được những khái niệm này.

Nắm được business chính là nắm được tinh thần của dự án. Nhờ tuân thủ ít nhất 2 bước đầu tiên này, từ lúc mình mới chập chững đi làm mình thường nắm dự án nhanh hơn và ra quyết định hiệu quả hơn. Từ đó cũng được promote nhanh hơn :)

Xác định domain boundary

Domain boundary chính là việc phân chia miền nghiệp vụ thành những vùng nhỏ hơn. Việc xác định domain boundary là một nghệ thuật vì nó là sự kết hợp giữa tech + business để align về mặt business process sao cho tối ưu, hiệu quả. Có khi nó phụ thuộc vào cấu trúc vận hành của business, có khi nó phụ thuộc vào chính domain knowledge đó, và cũng có khi nó được quyết định dựa trên kinh nghiệm và trực giác của bản thân. Domain boundary chính là một input quan trọng để thiết kế microservice hoặc phân chia cấu trúc module dự án.

Thật sự là từ lúc mình làm những công việc liên quan đến architecture thì mình mới được đụng vào loại task này nhiều. Tuy nhiên, việc càng quan tâm và hiểu được lý do đằng sau của việc phân chia kiến trúc dự án từ lúc là một developer sẽ giúp cho kinh nghiệm và kiến thức của các bạn tăng lên rất nhiều lần. Đừng chỉ làm và cho rằng nó đã được định nghĩa sẵn như vậy và nó vốn như thế.

Note: một trong những loại câu hỏi mà mình thường hỏi khi interview các bạn senior developer: tại sao dự án em làm lại được thiết kế như vậy? quyết định đằng sau đó là gì?

Thiết kế kiến trúc

Nghe tên cái task thấy hầm hố vậy thôi. Thực chất của việc thiết kế kiến trúc chính là xác định những giải pháp then chốt để giải quyết các vấn đề của dự án. Vậy thì, khoan nói tới việc lựa chọn kĩ thuật, bước đầu tiên là ta phải liệt kê ra được các vấn đề mà dự án đó cần giải quyết cả về functional requirement và non-functional requirement. Bạn xác định sai vấn đề cần giải, có nghĩa là bạn đã failed 80% dự án rồi.

Vì đây là một chủ đề cần nhiều giấy mực, nên mình mạn phép sẽ trình bày chi tiết hơn ở những bài viết khác. Mình chỉ muốn nhấn mạnh rằng: kiến trúc dự án thật ra chỉ là những giải pháp tổng thể, xây dựng những ràng buộc, nguyên tắc để đảm bảo giải quyết được yêu cầu dự án (cả về tính đúng đắn của chương trình và những yêu cầu về chất lượng).

Trong quá trình implementation, mình cho rằng bản thân mỗi lập trình viên chính là một kiến trúc sư để thiết kế ra giải pháp cho chính từng function mà bạn đang làm. Tất nhiên, nó cần được align với giải pháp tổng thể, nhưng mình tin rằng chính các bạn - chứ không phải ai khác - mới chính là một kiến trúc sư thực thụ trên từng dòng code. Cho nên, đừng bao giờ giới hạn vai trò của mình. Luôn đặt ra những câu hỏi, nắm chắc được bức tranh chung, sáng tạo và làm tốt nhất vai trò thiết kế của mình. Cách bạn đặt tên cho từng biến, thiết kế từng class, method, diễn đạt từng dòng logic, lựa chọn dùng thư viện A thay vì B, đưa dữ liệu vào cache thay vì đọc trực tiếp DB ... chính là thiết kế. Nếu ai đó nói rằng bạn không phải là một kiến trúc sư, người đó sai. Hoàn toàn sai!

Kiến trúc nó nằm trong hơi thở của từng dòng code. Mình tin là vậy!

Implementation

Việc triển khai dự án thường nên bắt đầu với việc test thử những giả định của mình về giải pháp trước. Trong những dự án mình làm thường có một iteration đầu tiên để xây dựng skeleton của dự án, và đồng thời test các giả định về implementation, integration, explore thêm về business. Cái gì khó và mơ hồ thì mình cần test trước - làm trước. Failed fast, thà phát hiện rủi ro ngay từ đầu và tìm cách fix nó thay vì để đến cuối dự án.

Điều này cũng nên áp dụng trong quá trình coding / testing. Mình nên bắt đầu với những điều mình nghĩ là rủi ro / quan trọng và test nó sớm thay vì ưu tiên những task dễ. Mà để làm được điều này, bạn phải nắm được cả bức tranh toàn cảnh và chi tiết dự án ở 2 bước đầu.

Note: khi mình nói về implementation, mình không giới hạn ở vai trò của developer hay QA, devops ... mà nó include tất cả những hoạt động cần thiết để tạo ra một sản phẩm.

Kết luận

Thật ra những điểm mình trình bày ở trên là triển khai chi tiết của một tiến trình từ phân tích yêu cầu, đến design và implementation. Mặc dù dự án phần mềm đưa ra sự chuyên biệt hóa ở từng những vai trò cụ thể, nhưng mình cho rằng để thật sự trở thành một nghệ nhân làm phần mềm thì chúng ta cần nhiều thứ hơn:

  • Hiểu bức tranh toàn cảnh của dự án
  • Hiểu thật rõ bài toán nghiệp vụ mình đang giải quyết.
  • Hiểu được những giải pháp của dự án và lý do đằng sau
  • Mỗi một người trong dự án chính là một kiến trúc sư vì hơn ai hết, chính bạn là người đưa ra thiết kế cho từng viên gạch của dự án trong mỗi hoạt động hàng ngày. Chính bạn quyết định nghệ thuật đằng sau của cái nghề lập trình này vậy.

Chuyện ngoài lề: mình có một người anh mà mình thật sự rất thần tượng. Ảnh nói một câu mà làm mình ấn tượng đến giờ:

Dự án failed là vì mình làm sai ở những chi tiết nhỏ. Nếu mình làm tốt những điều nhỏ nhất trong từng việc hàng ngày thì dự án không failed (hoặc ít failed hơn)

Đó là lý do mà dù trước đây dù làm Tech Director ở một công ty lớn, với quỹ thời gian rất hạn hẹp, nhưng anh vẫn dành thời gian để giúp review code cùng team trong những dự án quan trọng, chăm chút cho từng thiết kế, và giúp anh em dev học ra được nhiều điều từ những trao đổi về kĩ thuật, nhân sinh quan ... Anh chính là một nghệ nhân lập trình trong góc nhìn của mình vậy!