Làm thế nào để bạn quyết định nơi chức năng nên thuộc về một dự án quy mô lớn?


8

Trong tình hình phát triển hiện tại của tôi, chúng tôi có rất nhiều DLL, tệp thực thi và thư viện tĩnh. Làm thế nào để bạn quyết định những gì nên đi vào một DLL? Điều gì nên đi vào một thực thi? Tại sao có chức năng riêng biệt trong các tập tin thực thi khác nhau? Tôi hy vọng câu trả lời sẽ ngắn gọn, nhưng đây có vẻ là một chủ đề gây tranh cãi.

Làm thế nào để bạn quyết định nơi chức năng nằm trong một dự án quy mô lớn (nhiều hơn một tệp thực thi)? Tôi đang mong đợi các câu trả lời từ "Thiết kế tốt" đến "Tính mô đun" đến "Bất cứ quản lý nào đặt trong tài liệu yêu cầu".

Câu trả lời:


13

Việc lựa chọn giữa một thư viện và một tệp thực thi là tương đối đơn giản: nó có hợp lý để thực thi mã bạn muốn đưa vào một tệp thực thi như một chương trình độc lập không? Nếu không, nó có lẽ nên là một thư viện. Nói chung, tôi sẽ ưu tiên một lớp thực thi mỏng hơn nhiều thư viện khi cần, vì điều đó giúp việc tái sử dụng các thư viện phụ trợ này sau này dễ dàng hơn và chúng không bị ràng buộc với một chương trình cụ thể.

Khi quyết định cách phân chia mã của bạn giữa các thư viện, bạn có thể thấy bài viết của chú Bob Martin về độ chi tiết hữu ích.

Trong đó, ông nói về cấu trúc OO và định nghĩa một số nguyên tắc có thể giúp bạn đóng gói mã của mình một cách thích hợp. Những điều này cũng được đề cập chi tiết hơn trong cuốn sách của ông, Nguyên tắc, mô hình và thực tiễn Agile trong C # .

Tôi sẽ tóm tắt các nguyên tắc dưới đây:

Nguyên tắc tương đương tái sử dụng / phát hành (REP)

Hạt tái sử dụng là hạt phát hành. Chỉ các thành phần được phát hành thông qua hệ thống theo dõi có thể được sử dụng lại một cách hiệu quả. Hạt này là gói.

Chú Bob định nghĩa việc tái sử dụng là có thể liên kết tĩnh hoặc động thư viện được sử dụng lại với chương trình của mình và không bao giờ phải xem mã nguồn của nó. Khi một phiên bản mới của thư viện được phát hành, anh ta có thể tích hợp nó vào hệ thống của mình.

Đối xử với các thư viện theo cách này chỉ khiến các thứ liên quan trong cùng một gói. Mặt khác, người tiêu dùng của thư viện có thể phải nâng cấp lên phiên bản mới mà không có lý do hoặc tụt lại một vài phiên bản phía sau.

Nguyên tắc tái sử dụng chung (CRP)

Các lớp trong một gói được sử dụng lại với nhau. Nếu bạn sử dụng lại một trong các lớp trong một gói, bạn sử dụng lại tất cả chúng.

Nguyên tắc này hỗ trợ một ở trên. Nếu bạn có các lớp trong cùng một gói không liên quan đến nhau, bạn có thể buộc người dùng thư viện của mình nâng cấp không cần thiết.

Nguyên tắc đóng cửa chung (ĐCSTQ)

Các lớp trong một gói nên được đóng lại với các loại thay đổi tương tự. Một thay đổi ảnh hưởng đến một gói ảnh hưởng đến tất cả các lớp trong gói đó.

Nguyên tắc này nói về khả năng bảo trì. Ý tưởng ở đây là nhóm các lớp dựa trên cách họ có thể cần thay đổi. Bằng cách đó, các thay đổi của bạn có thể được bản địa hóa thành một phần của ứng dụng và không lan truyền khắp nơi.

Nguyên tắc phụ thuộc theo chu kỳ (ACP)

Cấu trúc phụ thuộc giữa các gói phải là Đồ thị chu kỳ có hướng (DAG). Đó là, không có chu kỳ trong cấu trúc phụ thuộc.

Không cho phép các phụ thuộc theo chu kỳ cho phép mỗi gói được phát triển độc lập và "phát hành" cho phần còn lại của công ty khi các thay đổi mới đã sẵn sàng. Bằng cách này, bạn không kết thúc với hai đội bế tắc, chờ đợi nhau để hoàn thành một số công việc.


2

Điều gì sẽ làm cho việc duy trì mã dễ dàng hơn trong thời gian dài? Nếu bạn có các hàm không liên quan trong cùng một thành phần (nghĩa là dll, exe, đơn vị đã biên dịch) và bạn phải thay đổi một hàm, điều đó có bị phá vỡ không? Khi bạn thực hiện thay đổi trên một thành phần, bạn sẽ cần kiểm tra lại tất cả các thành phần hạ nguồn tùy thuộc vào TẤT CẢ các chức năng trong thành phần đó. Nếu bạn giới hạn chức năng trong từng thành phần, việc thay đổi từng thành phần sẽ ít rủi ro hơn.

Ngoài ra, bằng cách tập trung các thành phần vào một số lượng nhỏ chức năng liên quan chặt chẽ, bạn sẽ có thời gian dễ dàng hơn nhiều để chứng minh rằng một thành phần đó hoạt động theo cách cần thiết.


Luôn luôn nghĩ về kịch bản "DLL Hell". Đó là như ông Flynn đã nói, hãy nghĩ điều gì sẽ xảy ra khi có gì đó thay đổi. Luôn biết rất rõ các phụ thuộc của bạn và đảm bảo rằng bạn có thể bao quát các tình huống cài đặt mà không gây đau đớn cho người dùng cuối.
NoChance

2

Một cách đơn giản để tiếp cận câu trả lời là nhận ra rằng "DLL" là viết tắt của "thư viện liên kết động" và thuật ngữ chính là "thư viện".

Bạn muốn gì ở một thư viện bình thường? Những cuốn sách hay sẽ được chia sẻ bởi nhiều độc giả (người dùng); các vật phẩm hữu ích thu thập bụi cho đến khi được người đọc (người dùng) tham khảo để trả lời một câu hỏi quan trọng tại một thời điểm có lẽ tuyệt vọng; và các tài nguyên liên kết người đọc (người dùng) với các tài nguyên khác. Thư viện mã là tương tự. Chúng tôi giữ những thứ như mã được chia sẻ thường xuyên, các mô đun tham chiếu chuyên biệt hoặc có giá trị cao và tài nguyên khung kiến ​​trúc trong đó. Thư viện phần mềm có thể được biểu diễn trong một số loại tạo tác mã, chẳng hạn như tập lệnh, thư viện tĩnh, thư viện động, thành phần và tệp tài nguyên.

Nói chung, tôi khuyên bạn nên làm cho các mô-đun thực thi của bạn hoạt động giống như các tập lệnh. Họ phác thảo và quản lý rõ ràng cấu trúc và dòng chảy chính của hệ thống của bạn nhưng yêu cầu các tài nguyên từ thư viện của bạn để xử lý các chi tiết khó chịu. Tôi thấy cách tiếp cận này tốt hơn so với việc làm rối logic logic cấp cao với những lo ngại về triển khai cấp thấp và chuyên môn và kỹ thuật quá thấp.

Khi xem xét cách phân bổ mã của bạn giữa các tệp thực thi và thư viện, bạn cần xem xét cả thiết kế logic và thiết kế vật lý.

Ví dụ, trong các hệ thống hướng đối tượng, điều quan trọng là tổ chức một cách hợp lý mã của bạn để gán chính xác trách nhiệm cho các phương thức đúng trong các lớp bên phải. Đây là một phần của thiết kế giải pháp hợp lý. Thiết kế logic của bạn phải rõ ràng, rõ ràng và gọn gàng và nên được thể hiện bằng thuật ngữ có liên quan tốt đến miền của người dùng của bạn.

Khi bạn dự định thực sự cài đặt hệ thống của mình trên trang web của người dùng, bạn có thể quan tâm đến việc tạo ra một thiết kế vật lý chỉ định cách bạn sẽ gói mã của mình vào một tập hợp các đối tượng tài nguyên phần mềm có thể triển khai dễ dàng (thường là các tệp) cho nhu cầu của một hệ thống mục tiêu cụ thể. Việc xác định tài nguyên nào thuộc về gói triển khai nói chung có thể liên quan đến một số cân nhắc thiết kế vật lý cụ thể không liên quan trực tiếp đến thiết kế logic. Ví dụ: bạn có thể muốn trao đổi các thư viện xử lý tệp hình ảnh nhất định tùy thuộc vào khách hàng nào sẽ nhận được một bộ đối tượng triển khai nhất định.

Trong thực tế, bạn sẽ thấy rằng thiết kế logic tốt thường dẫn đến thiết kế vật lý tốt.

Tóm lại, nguyên tắc quan trọng nhất là bao bì thông minh. Bằng cách tổ chức các tài liệu mã của bạn vào các thư viện có liên quan mạnh mẽ, bạn sẽ có được các tạo phẩm mã có thể triển khai hữu ích mà bạn có thể dễ dàng sử dụng lại, di chuyển xung quanh hoặc cho đi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.