14 tháng 03, 2017 – 1535 lượt xem
Trong Java, package là một tính năng ít được nhắc đến nhất (phải chăng vì nó … quá cơ bản ?).
Rõ ràng chúng ta thường chia các package theo một hướng tư duy nhất định và sau đó mọi thứ cứ thế tiếp diễn. Việc sắp xếp và đặt tên package không gây quá nhiều trở ngại, thậm chí là đối với những người mới nhập team. Kể cả khi đặt tên package sai hoặc không đúng với quy chuẩn của team, các IDE sẽ giúp bạn refactor trong nháy mắt.
Tuy vậy, việc tổ chức package một cách khoa học sẽ đem lại nhiều lợi ích bất ngờ cho lập trình viên, hôm nay, tôi sẽ giúp bạn làm được điều đó.
Tóm Tắt
#1 Sự nhất quán khi đặt tên
Việc duy trì sự nhất quán khi lập trình là vô cùng cần thiết. Trong quá trình tổ chức package, đây cũng không phải là một yêu cầu ngoại lệ. Một application có thể chứa 1001 package nhưng tôi cá rằng đồng nghiệp của bạn và bạn-ở-thì-tương-lai đều không mong chờ 1001 kiểu đặt tên package khác nhau.
Nếu bạn vẫn còn nghi ngờ về vai trò của sự nhất quán khi lập trình, hãy đọc bài viết này.
#2 Cân nhắc khi đặt tên package liên quan tới Object type
Rõ ràng trong một package chứa các class Controller, bạn sẽ có xu hướng đặt tên cả package đó là “controller”. Tôi không phản đối việc này nhưng hãy nghĩ xem, liệu đặt tất cả các Controller vào package controller có giúp gì được cho bạn không? Nhìn thì có vẻ rất ổn nhưng việc đó là không cần thiết bởi tên các class Controller của bạn vốn đã được đặt tên rất cụ thể rồi.
#3 Mô tả được kiến trúc của Application
Cấu trúc của các packages cần có mối liên hệ mật thiết với kiến trúc của ứng dụng. Giả sử ứng dụng của tôi có 3 tầng: resource layer, business layer và database access layer, tôi sẽ chia 3 package tương ứng là resoure, business và database. Đây là bước đầu tiên để đảm bảo kiến trúc ứng dụng đang dần đi sâu vào từng dòng code của bạn thay vì chỉ nằm trên bản vẽ.
Lấy luôn một ví dụ liên quan đến biểu đồ thiết kế tôi lấy từ Testing Stragety in Microservice.
Cần tổ chức các packages cho ứng dụng này như thế nào nhỉ? Đây rồi, rõ ràng là tôi phải có resource, domain, database và services. Chắc chắn là như thế. Sau đó, tùy thuộc vào nơi tôi muốn chứa interface, tôi có thể sinh thêm repositories hoặc gateways.
Làm quen và triển khai các kiến trúc xây dựng ứng dụng trong khóa thực tập NodeJS Full Stack
#4 Áp dụng nguyên lý Single Responsibility
Các class có chung mục đích sử dụng sẽ được xếp chung package. Quy tắc này giúp ta nắm được logic của application nhanh hơn.
#5 Nguyên lý Interface Segregation
Quá trình tổ chức packages không phải lúc nào cũng đáp ứng được nguyên tắc này. Chúng ta không muốn các yếu tố bên ngoài tác động lên một vài class nào đó, hãy cố gắng đặt các class có tính “public” vào chung một chỗ, phần còn lại dành cho một số thứ “riêng tư” (các phần của ứng dụng mà lập trình viên không muốn người ngoài truy cập tự do vào đó). Project Jigsaw của Java 9 sẽ là công cụ đắc lực trong phần này.
#7 Nguyên lý Dependency Inversion
Chúng ta thường nói package A phụ thuộc vào package B nếu bất kỳ class nào thuộc A có import ít nhất một class từ package B. Và điều quan trọng ở đây là chúng ta muốn “kiểm soát” sự phụ thuộc đó. Để các package tuân thủ nguyên tắc này thì mỗi class trong nó phải tuân thủ DIP trước (Dependency Inversion).
Tính năng analyzing dependency của IntelliJ sẽ hỗ trợ bạn tìm các điểm vi phạm DIP.
Triển khai các nguyên lý thiết kế hướng đối tượng OOD tại lớp Node JS Fullstack
Tổng kết
Tổ chức package một cách kém chuyên nghiệp không dẫn project của bạn đến bờ vực thẳm. Nó chỉ ngăn cản bạn và đồng nghiệp nắm được các yếu tố cốt lõi của project(một cách nhanh nhất) và tạo ra những sự khó chịu nhất định khi bảo trì project. Dù sao đi nữa, nếu bạn muốn trở thành lập trình viên chuyên nghiệp, bạn phải làm mọi thứ thật chuyên nghiệp.
Techmaster via TidyJava