2009-03-13 58 views
5

Sự phức tạp rất phổ biến đối với kiến ​​trúc sư kỹ thuật là chia ứng dụng trong các vùng lắp ráp và không gian tên.Mẹo chiến lược về phân vùng và không gian tên phân vùng

  • Các hội đồng có thể được phân đoạn theo: ranh giới triển khai, hiệu suất và bảo mật.
  • Không gian tên có thể được phân đoạn theo ranh giới ứng dụng logic.

Ngoài ra: không gian tên có thể mở rộng nhiều cụm.

Tôi đã có trải nghiệm không tốt trong dự án khi chúng tôi chia các hội đồng theo đơn vị lôgic của ứng dụng. Quyết định này đã kết thúc với các tệp giải pháp với 30 hoặc 40 dự án! Thời gian tải tệp giải pháp chính là xấp xỉ. 5 phút!!! Điều này đã kết thúc trong một sự lãng phí thời gian, ...

Kịch bản ngược lại là giữ tất cả mã trong 1 assembly và phân vùng khi nó thực sự cần thiết.

Bạn có thêm mẹo hay phương pháp hay nhất nào về vấn đề này không?

Trả lời

1

Tôi chia mã thành các hội đồng riêng biệt chỉ khi tôi cần sử dụng lại nó cho hai ứng dụng khác nhau (khá nhiều). Vì vậy, tôi bắt đầu với mọi thứ trong một dự án, và khi cần sử dụng lại mã trở nên rõ ràng, tôi tạo một assembly mới và chuyển mã (đôi khi nó hiển nhiên ngay từ đầu, ví dụ khi bạn cần có một ứng dụng web và giành các biểu mẫu Điều).

Re. Không gian tên, tôi muốn có nó khá tốt phân vùng trong một hội đồng, do đó, nó là rõ ràng, nơi mỗi lớp thuộc về và những gì nó nên được sử dụng cho.

+0

Đây cũng là cách hiện tại của tôi làm việc. Thường thì tôi thấy các nhà phát triển chia nhỏ ứng dụng trong 3 hội đồng vì hầu hết họ nghĩ rằng một lớp 3 trong 3 hội đồng là một điều tốt để làm; nhưng điều này cũng có thể đạt được bằng cách phân vùng không gian tên và giữ toàn bộ trong 1 assembly. Chỉ khi bảo mật và hiệu suất là những người chơi chính, thì hãy bắt đầu điều tra cách phân chia thể chất cho ứng dụng của bạn. –

0

Bạn có thể phân vùng lớp bằng Không gian tên và sử dụng thư mục nếu bạn muốn nhóm các tệp nguồn cùng nhau để bảo trì dễ dàng hơn. Nếu bạn có yêu cầu bảo mật và một số hội đồng nhất định cần phải trải qua quá trình xử lý đặc biệt như Obfuscation chẳng hạn, thì bạn có thể cần phải tách riêng chúng ra thành một dự án riêng biệt.

Khả năng sử dụng lại cũng là một yếu tố mà bạn có thể cần cân nhắc khi suy nghĩ về việc liệu một đơn vị logic có cần có dự án riêng của mình hay không vì bạn có thể cần dự án này trong một giải pháp khác.

0

Điều gì đã làm việc tốt cho tôi là nhóm cấp độ lớn theo loại mã, nhưng nhiều cấp độ macro hơn các đơn vị lôgic mà bạn đã chia nhỏ. Ví dụ:

  • Động cơ - mọi thứ không trực quan. Các lớp hỗ trợ, mã cơ sở hạ tầng cơ sở. Tất cả mọi thứ đề cập đến điều này.
  • EngineUI - Dựa trên Engine và được sử dụng rõ ràng cho giao diện người dùng nhưng không có gì cụ thể cho bất kỳ ứng dụng nào.
  • EngineServer - Dựa trên công cụ, được sử dụng bởi (thường là web) máy chủ xây dựng.
  • AppCore - Chức năng cốt lõi của ứng dụng cụ thể, không có giao diện người dùng.
  • AppUI - Giao diện người dùng ứng dụng cụ thể
  • AppClient - Sử dụng AppUI, AppCore, EngineUI, Engine. Ứng dụng khách thực tế.
  • AppServer - Sử dụng AppServer, EngineServer, Engine. Ứng dụng máy chủ.

Mỗi dự án có một hệ thống phân cấp các không gian tên và thỉnh thoảng tôi thấy hữu ích khi chia nhỏ một mã lớn thành một assembly khác nhưng thường giữ mọi thứ hợp lý và dễ quản lý, ngay cả khi có hàng trăm các tệp liên quan. Quá nhiều dự án chắc chắn là điều tôi cố tránh. Một phần thưởng của việc giữ các dự án này ở mức tối thiểu là nó làm cho việc sử dụng lại các thư viện này trở nên dễ dàng hơn nhiều trong các dự án tiếp theo (chẳng hạn như các bản dựng thử nghiệm tự động).

Tôi không lo lắng quá nhiều về mã không sử dụng đang được triển khai từ các thư viện này vì tôi có thể sử dụng utility để loại bỏ các chức năng không sử dụng cho bản xây dựng cuối cùng, giữ kích thước tệp xuống mức tối thiểu.

0

Tôi thấy hữu ích khi tổ chức không gian tên thành phân cấp và làm cho tên lắp ráp khớp với tên phụ họ đóng góp. Ví dụ, một dự án có tên Womble sẽ có một không gian tên top-level Womble, và sau đó có thể có hội gọi là:

Womble.ClientLibrary.dll 
Womble.Controls.dll 
Womble.Util.dll 
Womble.Interop.dll 

Ở đây, không gian tên Womble ngoài kéo dài nhiều hội, nhưng mỗi lắp ráp có subnamespace độc ​​đáo mà chỉ có nó có thể đóng góp, mà bạn tìm thấy bằng cách loại bỏ .dll từ cuối. Nó làm cho nó dễ dàng hơn nhiều để nhớ những gì bạn cần để tham khảo và tìm thấy mọi thứ.

Đối với số lượng rất lớn các hội đồng, cuối cùng bạn không cần phải giữ tất cả chúng trong một giải pháp. Trong việc phát triển quy mô lớn, nó giúp chia nhỏ một sản phẩm lớn thành các hệ thống con, có thể bao gồm nhiều hội đồng, và mỗi hệ thống con có thể được duy trì bởi các nhóm riêng biệt và có thể có các tệp giải pháp riêng của chúng. Các nhóm khác nhau "phát hành" phiên bản mới cho nhau thông qua kiểm soát nguồn, coi nhau là thư viện của bên thứ ba.

Tôi không nghĩ rằng có một cách khó khăn và nhanh chóng để quyết định cách chia nhỏ phần mềm thành dạng vô trùng. Có một nguyên tắc chung ở đây: những thứ thay đổi vì những lý do khác nhau nên được tách ra.

Các dự án rất lớn có thể đạt được từ thực tế là bằng cách đặt mọi thứ vào các hội đồng riêng biệt, bạn có thể vá chúng riêng biệt. Bạn có thể tạo hotfix cho một vấn đề trong Womble.Interop.dll, và sau đó sản xuất riêng hotfix cho một vấn đề trong Womble.Controls.dll, và đưa cả hai cho cùng một khách hàng, do đó trong lý thuyết, hai assembly đó có thể hoàn toàn được duy trì và hỗ trợ bởi các nhóm riêng biệt, mà không cần phải phối hợp hoạt động của họ trực tiếp.

Các hội đồng riêng biệt cũng tạo sự rõ ràng trong các phụ thuộc giữa mã. Bạn có thể thấy ở mức rất cao (chỉ cần nhìn vào danh sách tham khảo) cách một đoạn mã phụ thuộc vào mã khác và cách nó có thể được sử dụng lại. Nếu bạn đặt tất cả mọi thứ trong một hội đồng, nó có thể là một mớ hỗn độn rối rắm lớn không có mô hình hợp lý với nó.

0

Động lực

Lý do tại sao tôi gửi bài trả lời cuối này là tất cả câu trả lời trước có nhiều khuyến nghị thực hành tốt nhất chứ không phải sau đó nhất quán.

Vì nhiều năm tôi đang làm việc trong một dự án .NET rất lớn và chỉ thực hành tốt nhất quán phù hợp với cả chiến lược và kỹ thuật tốt là đề xuất của nhóm NDepend.

Tóm lại

khuyến nghị NDepend nói chung là inline với kinh nghiệm của bạn không cơ cấu lắp ráp theo kiến ​​trúc.Nó cũng có những cân nhắc khi có các hội đồng riêng biệt và tại sao. Quy tắc của ngón tay cái là sử dụng cấu trúc bởi cụm vì lý do vật lý, sử dụng không gian tên vì lý do logic.

NDepend tóm tắt thực hành tốt nhất:

Đối với hội đồng và các dự án

  • Giảm đáng kể số lượng lắp ráp của cơ sở mã của bạn.
  • Tạo một hội đồng mới chỉ khi điều này được chứng minh bằng một yêu cầu cụ thể cho việc tách vật lý.
  • Trong dự án Visual Studio, hãy sử dụng ‘tham chiếu theo assembly’ thay vì ‘tham chiếu bởi dự án Visual Studio’.
  • Không bao giờ sử dụng tùy chọn tham chiếu Visual Studio ‘Sao chép địa phương = True’.
  • Đặt tất cả các giải pháp VS và Xây dựng các tệp hành động .bat trong thư mục $ rootDir $.
  • Biên dịch tất cả các hội đồng trong thư mục: $ rootDir $ \ bin \ Debug và $ rootDir $ \ bin \ Release
  • Sử dụng thư mục $ rootDir $ \ bin để lưu trữ các bài kiểm tra.

Đối với không gian tên

  • Sử dụng các khái niệm về không gian tên để xác định ranh giới của các thành phần.
  • Không gian tên thường chứa từ một đến hai chục loại và có kích thước hợp lý phù hợp trong phạm vi 500 đến 2.000 LoC.
  • Dành thời gian để cân bằng các thành phần cơ sở mã của bạn, đó chắc chắn là một nhiệm vụ rẻ hơn dự kiến, do đó, Lợi tức đầu tư sẽ cao.
  • Kiểm tra liên tục biểu đồ phụ thuộc của các thành phần bên trong một hội đồng là theo chu kỳ.
  • Nếu một thành phần quá lớn (> 2.000 LoC), thì hãy sử dụng các không gian tên phụ để phân chia thành một nhóm nhỏ hơn các thành phần liên quan.
  • Ở mọi quy mô, phân loại các thành phần giữa các trình dàn xếp cấp cao, các tính năng độc lập ở mức trung bình, cơ sở/miền cấp thấp.
  • Việc có bộ cấu phần 'được điều chỉnh mức' sẽ loại bỏ nhu cầu về hầu hết các quyết định thiết kế.

đọc chi tiết

Partitioning code base through .NET assemblies and Visual Studio projects

Defining .NET Components with Namespaces