Cách xem xét khả năng bảo trì khi thiết kế giải pháp
- Khả năng bảo trì phải được chuyển thành yêu cầu thiết kế cụ thể
- Cấu trúc quyết định phạm vi mà một thay đổi có thể lan truyền
- Tài liệu phải giúp phân tích tác động, không chỉ mô tả giải pháp
- Khả năng kiểm thử quyết định liệu thay đổi có thể được thực hiện an toàn hay không
- Nên đánh giá khả năng bảo trì bằng kịch bản thay đổi trước khi chốt thiết kế
Với sản phẩm phần mềm và ICT, ISO/IEC 25010:2023 coi chất lượng sản phẩm là tập hợp các đặc tính có thể dùng để xác định yêu cầu, mục tiêu thiết kế, tiêu chí kiểm thử và tiêu chí đánh giá trong vòng đời sản phẩm. Maintainability vì thế không chỉ là vấn đề của đội bảo trì mà còn là một thuộc tính cần được phản ánh trong quyết định thiết kế.
Khả năng bảo trì phải được chuyển thành yêu cầu thiết kế cụ thể
Một giải pháp “dễ bảo trì” là mô tả quá rộng nếu không chỉ ra điều gì cần thay đổi và việc thay đổi đó phải đạt điều kiện nào. Cách hữu ích hơn là đặt ra các tình huống thay đổi có khả năng xảy ra: sửa một quy tắc nghiệp vụ, thay một dịch vụ bên ngoài, cập nhật giao diện tích hợp, xử lý một lỗi hoặc bổ sung một chức năng trong phạm vi hiện có.
Từ mỗi tình huống, cần xem xét ít nhất ba câu hỏi: phải hiểu những thành phần nào trước khi sửa, có bao nhiêu thành phần có nguy cơ bị tác động và bằng cách nào có thể xác nhận rằng thay đổi không làm hỏng hành vi hiện tại. Khi ba câu hỏi này khó trả lời, vấn đề thường nằm ở kiến trúc, sự phụ thuộc hoặc mức độ thiếu thông tin chứ không đơn thuần ở kỹ năng của người thực hiện.
Trong mô hình ISO/IEC 25010, maintainability được liên hệ với các thuộc tính như modularity, analysability, modifiability và testability. Chẳng hạn, modularity hướng tới việc thay đổi một thành phần với ảnh hưởng tối thiểu lên thành phần khác; analysability liên quan đến khả năng đánh giá tác động và xác định nơi cần sửa; modifiability phản ánh khả năng thực hiện thay đổi mà không gây lỗi mới hoặc làm suy giảm chất lượng.
Vì vậy, yêu cầu bảo trì nên được viết theo những tình huống có thể kiểm tra thay vì một câu chung như “hệ thống phải dễ bảo trì”. Carnegie Mellon Software Engineering Institute cũng tiếp cận maintainability ở cấp kiến trúc thông qua các yêu cầu dạng scenario, qua đó đánh giá rủi ro của quyết định kiến trúc trước những thay đổi dự kiến trong tương lai.

Cấu trúc quyết định phạm vi mà một thay đổi có thể lan truyền
Cấu trúc có lợi cho bảo trì không nhất thiết là cấu trúc có nhiều lớp hoặc nhiều mô-đun. Điểm quan trọng hơn là trách nhiệm của từng thành phần có rõ ràng hay không và quan hệ phụ thuộc giữa chúng có được kiểm soát hay không.
Khi một thành phần chứa nhiều trách nhiệm không liên quan, việc sửa một chức năng có thể buộc người thực hiện phải đọc và kiểm tra cả những phần không liên quan trực tiếp. Ngược lại, nếu các thành phần phụ thuộc chặt vào chi tiết triển khai của nhau, một thay đổi cục bộ dễ tạo hiệu ứng dây chuyền. Nghiên cứu của SEI về maintainability kiến trúc chỉ ra bốn thuộc tính thường được sử dụng khi xem xét khả năng bảo trì: kích thước, độ phức tạp, coupling và cohesion; coupling cao và cohesion thấp làm tăng khả năng một thay đổi bảo trì ảnh hưởng sang các thành phần khác.
Do đó, khi thiết kế cần kiểm tra ranh giới trách nhiệm, hướng phụ thuộc và các điểm giao tiếp giữa các thành phần. Encapsulation giúp che giấu chi tiết dễ thay đổi; lớp trung gian có thể ngăn một thay đổi ở nhà cung cấp hoặc giao thức lan trực tiếp vào logic lõi; giới hạn dependency làm giảm số nơi phải sửa đồng thời. Đây cũng là những nhóm tactic được SEI sử dụng khi phân tích maintainability và modifiability của kiến trúc.
Tuy nhiên, giảm coupling không có nghĩa là phải chia hệ thống thành càng nhiều phần càng tốt. Phân rã quá mức có thể làm tăng số interface, đường truyền dữ liệu và thành phần phải theo dõi. Tiêu chí đúng hơn là locality of change: một thay đổi thuộc một trách nhiệm nên được giữ trong một phạm vi hợp lý và không bắt người bảo trì hiểu toàn bộ giải pháp mới có thể sửa an toàn.
Tài liệu phải giúp phân tích tác động, không chỉ mô tả giải pháp
Tài liệu có giá trị đối với bảo trì khi nó rút ngắn quá trình trả lời các câu hỏi “thành phần này làm gì?”, “phụ thuộc vào đâu?”, “tại sao kiến trúc được chọn như vậy?” và “nếu thay đổi điểm này thì cần kiểm tra lại những gì?”.
Vì thế, tài liệu nên ưu tiên những thông tin khó suy ra chỉ bằng cách nhìn vào sản phẩm hoặc mã nguồn: ranh giới thành phần, luồng phụ thuộc, hợp đồng giao tiếp, giả định thiết kế, quyết định kiến trúc quan trọng, ràng buộc và lý do lựa chọn. Với các điểm dễ thay đổi, tài liệu còn cần chỉ ra phạm vi ảnh hưởng dự kiến và cơ chế kiểm chứng liên quan.
SEI lưu ý rằng việc phân tích maintainability phụ thuộc vào việc gói tài liệu kiến trúc có đủ thông tin để đánh giá các quyết định và rủi ro liên quan đến yêu cầu bảo trì hay không. Điều đó cho thấy tài liệu không phải phần bổ sung mang tính hành chính; nó là một phần của khả năng phân tích giải pháp khi cần thay đổi.
Tài liệu nhiều nhưng lỗi thời lại có thể gây tác dụng ngược. Khi sơ đồ, interface hoặc giả định trong tài liệu không còn khớp với hệ thống thực tế, người bảo trì phải xác minh lại mọi thông tin trước khi sử dụng. Vì vậy, nên ưu tiên một tập tài liệu nhỏ nhưng có chủ sở hữu, có điểm cập nhật rõ ràng và gắn trực tiếp với những quyết định có ảnh hưởng đến thay đổi.
Khả năng kiểm thử quyết định liệu thay đổi có thể được thực hiện an toàn hay không
Một cấu trúc dễ sửa nhưng khó xác nhận sau khi sửa vẫn chưa đạt khả năng bảo trì tốt. Testability là phần quan trọng vì người thực hiện cần biết thay đổi đã đáp ứng yêu cầu mới và không phá vỡ hành vi cũ.
Ngay trong thiết kế, cần xem liệu từng thành phần quan trọng có thể được quan sát và kiểm soát đủ để kiểm thử hay không. Nếu trạng thái nội bộ hoàn toàn khó quan sát, dependency không thể thay thế trong môi trường kiểm thử hoặc kết quả chỉ có thể được xác nhận bằng kiểm thử toàn hệ thống, chi phí xác minh mỗi thay đổi sẽ tăng đáng kể.
ISO/IEC 25010 mô tả testability theo khả năng thiết lập tiêu chí kiểm thử và thực hiện kiểm thử để xác định tiêu chí đó có được đáp ứng hay không. Vì vậy, quyết định kiến trúc nên được đánh giá đồng thời trên hai mặt: thay đổi có được cô lập không và phạm vi thay đổi đó có thể được kiểm chứng độc lập đến mức nào.
Điều này cũng tạo một ranh giới quan trọng: khả năng bảo trì không đồng nghĩa với việc mọi thay đổi đều phải rẻ hoặc không có rủi ro. Những thay đổi chạm vào mô hình dữ liệu cốt lõi, quy tắc xuyên suốt nhiều thành phần hoặc ràng buộc bên ngoài vẫn có thể có phạm vi lớn. Thiết kế tốt giúp phạm vi và nguyên nhân của tác động trở nên rõ ràng, thay vì tạo kỳ vọng rằng mọi thay đổi đều có thể được cô lập hoàn toàn.
Nên đánh giá khả năng bảo trì bằng kịch bản thay đổi trước khi chốt thiết kế
Một cách thực tế để kiểm tra thiết kế là chọn một số thay đổi có xác suất hoặc tác động cao rồi “đi thử” qua kiến trúc trước khi triển khai hoàn chỉnh.
Với mỗi kịch bản, nhóm thiết kế có thể xác định:
· Thành phần đầu tiên cần sửa
· Các dependency có khả năng bị ảnh hưởng
· Interface hoặc dữ liệu phải thay đổi
· Tài liệu cần dùng để hiểu tác động
· Kiểm thử cần chạy để xác nhận thay đổi
· Các điểm mà người thực hiện phải dựa vào kiến thức ngầm thay vì thông tin được ghi nhận
Nếu một thay đổi nhỏ đòi hỏi chỉnh sửa ở nhiều khu vực không cùng trách nhiệm, đó là tín hiệu cần xem lại ranh giới hoặc dependency. Nếu nhóm không thể xác định phạm vi tác động nếu thiếu một cá nhân cụ thể, cần xem lại tài liệu và cách biểu diễn quyết định. Nếu thay đổi có thể thực hiện nhưng chỉ được xác nhận ở cuối chuỗi tích hợp, testability là điểm cần xử lý.
Các tiêu chí định lượng cũng nên được thiết lập theo chính bối cảnh của giải pháp thay vì dùng một ngưỡng chung cho mọi hệ thống. Có thể đo số thành phần bị ảnh hưởng bởi một change scenario, thời gian cần để phân tích tác động, tỷ lệ thay đổi cần chỉnh sửa nhiều module, độ phức tạp hoặc coupling tại các khu vực thường xuyên thay đổi và phạm vi kiểm thử hồi quy cần thiết. Các chỉ số này có ý nghĩa nhất khi được dùng như baseline của chính hệ thống và theo dõi xu hướng qua các phiên bản, không phải như một con số “chuẩn” áp dụng máy móc.
Khả năng bảo trì của giải pháp phụ thuộc đồng thời vào cách thay đổi được cô lập trong cấu trúc và khả năng con người hiểu, đánh giá rồi kiểm chứng thay đổi đó. Cấu trúc tốt làm giảm phạm vi tác động; tài liệu tốt làm giảm sự phụ thuộc vào kiến thức ngầm; khả năng kiểm thử giúp xác nhận thay đổi mà không phải đánh cược vào toàn bộ hệ thống.
Vì vậy, khi thiết kế, câu hỏi quan trọng không phải chỉ là “giải pháp hiện tại có hoạt động không”, mà còn là: khi một yêu cầu hợp lý thay đổi, chúng ta có thể xác định nơi cần sửa, hiểu phạm vi ảnh hưởng và chứng minh rằng phần còn lại vẫn đúng hay không? Nếu câu trả lời có thể được đưa ra dựa trên kiến trúc, tài liệu và cơ chế kiểm thử thay vì kinh nghiệm cá nhân, khả năng bảo trì đã được đưa vào thiết kế theo đúng nghĩa.
