Cấu trúc lại thành phần

Hãy tưởng tượng bạn được chỉ định làm việc với một cơ sở mã cũ mà không có cấu trúc thành phần hợp lý hoặc bất kỳ cấu trúc nào. Một quả bóng bùn lớn! Gì bây giờ?! Làm cách nào để chuyển từ đó đến các thành phần đẹp, có thể tái sử dụng mà bạn thích làm việc?
Quả bóng bùn
Với mục đích của bài viết này, quả bóng bùn sẽ là Nền tảng viết blog của tôi như còn lại sau phần bốn . Tất cả các lớp bị dồn vào một gói mặc dù trách nhiệm của họ rất khác nhau. Đây là cách nó nhìn từ góc độ IDE:
Suy ra các thành phần
Trong trường hợp không có cấu trúc nào cả hoặc nó không có ý nghĩa gì, bước đầu tiên hợp lý là tìm kiếm cấu trúc ẩn trong mã và làm cho nó rõ ràng. Trừ khi cơ sở mã là một lớp Chúa duy nhất, phải có một số cách để nhóm các lớp lại với nhau, ngay cả khi cấu trúc kết quả là dưới mức tối ưu. Nếu đã có cấu trúc không hoàn hảo, nhưng có thể sử dụng được thì có thể bỏ qua bước này.
Trong ví dụ đã cho, rõ ràng là chúng ta có ba lớp liên quan trực tiếp đến các bài đăng, 1 lớp chủ yếu liên quan đến markdown, hai lớp chủ yếu liên quan đến git, một lớp tiện ích và một lớp "chính". MarkdownPostFactory
và GitPostReader
trông giống như triển khai của các giao diện PostReader
và không tồn tại PostFactory
, ít nhất là đánh giá theo tên. Như đã nói trước đây, chúng ta không quan tâm rằng cấu trúc được suy ra là không tối ưu, chúng ta chỉ cần một cái gì đó để làm việc với. Hãy làm cho nó rõ ràng:
Công nhận mức tối ưu
Với một cấu trúc thành phần, chúng tôi có thể bắt đầu tìm kiếm những cải tiến tiềm năng. Vì các thành phần chỉ là một nhóm các lớp hợp tác với nhau cho một mục đích chung, tất cả các chất lượng thiết kế tiêu chuẩn áp dụng cho chúng - tính liên kết cao, ghép nối thấp, SOLID, v.v. Chúng ta cũng có thể sử dụng các kỹ thuật ngôn ngữ để xác định các sai sót trong thành phần của chúng ta. Đây là một trong những:
Đặt tên cho từng thành phần, trách nhiệm của nó và các cộng tác viên. Tìm kiếm sự lúng túng và rò rỉ trách nhiệm.
Hãy áp dụng nó vào cấu trúc thành phần nền tảng blog được suy luận của chúng tôi:
- Thành phần bài đăng chịu trách nhiệm trình bày các bài đăng được cung cấp bởi việc triển khai
PostReader
- Thành phần Git chịu trách nhiệm sao chép và cập nhật một kho lưu trữ nhất định và đọc các bài đăng từ kho lưu trữ và chuyển đổi chúng thành
Post
các đối tượng bằng cách sử dụng triển khaiPostFactory
, cho mục đích của Thành phần Đăng - Thành phần Markdown chịu trách nhiệm tạo
Post
các đối tượng từ các tệp đánh dấu cho mục đích của thành phần Đăng
Đối với tôi, tất cả điều này chỉ là kỳ lạ. Thành phần bài đăng không làm bất cứ điều gì về việc đọc và tạo bài đăng - mọi thứ đều được trừu tượng hóa bằng cách sử dụng các giao diện. Thành phần Git thực hiện rất nhiều công việc liên quan đến git và công việc liên quan đến hậu kỳ. Nó cũng sử dụng thành phần Markdown gián tiếp bởi một giao diện liên quan đến bài đăng. Thành phần Markdown có trách nhiệm rất hẹp và chỉ bao gồm 1 lớp.
Tối ưu hóa cấu trúc
Biết chính xác những gì sai với các thành phần của chúng tôi, chúng tôi sẽ có thể cải thiện những điều này. Chúng ta sẽ bắt đầu bằng cách mô tả bức tranh mục tiêu và sau đó dần dần tiến tới nó. Điều này ngụ ý một loạt các lần tái cấu trúc, vì vậy tốt hơn hãy chuẩn bị các bài kiểm tra của bạn để xác nhận rằng bạn không vi phạm bất cứ điều gì!
Xem xét các điểm yếu được đề cập ở trên, tôi đã chọn cấu trúc mục tiêu sau:
- Thành phần bài đăng sẽ chịu trách nhiệm đọc và trình bày các bài đăng nằm trong kho lưu trữ do thành phần Git duy trì. Việc chuyển đổi các tệp đánh dấu thành
Post
các đối tượng sẽ là một chi tiết nội bộ của thành phần Bài đăng, nằm trong mộtPostFactory
đối tượng. - Thành phần Git sẽ sao chép và cập nhật (theo yêu cầu) một kho lưu trữ git nhất định.
Sau khi thực hiện các thay đổi trong codebase, chúng tôi nhận được cấu trúc như sau:
Đóng gói các thành phần
Sau khi cắt ra các thành phần thích hợp, tốt hơn là bạn nên đóng gói bên trong của chúng bằng các công cụ sửa đổi khả năng hiển thị và giao diện. Tôi đã viết toàn bộ một bài báo về tính đóng gói, mà bạn có thể (thậm chí nên!) Xem tại đây .
Như bạn có thể thấy trong hình trên, tôi đã đóng gói GitSupport
giao diện sử dụng hành vi của thành phần Git . Bằng cách này, tất cả sự phức tạp của GitSupportImpl
nó được ẩn sau một cái gì đó thành công và vô tội như:
public interface GitSupport {
File getWorkTree();
}
Thật đẹp phải không?
Tóm lược
A Ball of Mud không phải là ngày tận thế. Bạn cũng không cần phải viết lại mọi thứ vào microservices để đạt được mức độ mô-đun tốt và khả năng phát triển độc lập của các tính năng. Bắt đầu bằng cách phân tích cấu trúc hiện tại và suy ra thành phần tiềm ẩn do những người tiền nhiệm của bạn để lại cho bạn. Sử dụng các quy tắc thiết kế tốt và các kỹ thuật khác để nhận ra tính tối ưu trong cấu trúc được suy ra. Cải thiện các sai sót đã nhận ra bằng cách thiết lập một bức tranh mục tiêu và dần dần tái cấu trúc theo hướng đó. Sau khi các thành phần được cắt nhỏ, hãy đóng gói chúng để không có chi tiết hoặc trách nhiệm triển khai nào bị rò rỉ ra ngoài nữa. Thưởng thức!
Bài đăng này được lấy cảm hứng từ bài báo cùng tên của Tim. Bạn có thể kiểm tra nó ở đây .
Có thể bạn quan tâm
