Không gian tên C # và quy ước đặt tên lớp cho các thư viện


26

Tôi đang xây dựng các thư viện với các hàm tiện ích nhỏ khác nhau trong C # và đang cố gắng quyết định quy ước đặt tên không gian và lớp. Tổ chức hiện tại của tôi là như thế này:

Company
Company.TextUtils
    public class TextUtils {...}
Company.MathsUtils
    public class MathsUtils {...}
    public class ArbitraryPrecisionNumber {...}
    public class MathsNotation {...}
Company.SIUnits
    public enum SISuffixes {...}
    public class SIUnits {...}

Đây có phải là một cách tốt để tổ chức không gian tên và các lớp, hoặc có cách nào tốt hơn không? Cụ thể, có vẻ như có cùng tên trong không gian tên và tên lớp (ví dụ: Company.TextUtilskhông gian tên và TextUtilslớp) chỉ là sự trùng lặp và gợi ý rằng lược đồ có thể tốt hơn.



5
Các hướng dẫn của Microsoft đề xuất tên số ít cho enums (vì vậy SISuffixthay vì SISuffixes) và tôi nghĩ rằng số ít đó đọc tốt hơn. Suffix.A đọc là "hậu tố A". Ngoài ra, tôi thường tránh lặp lại tên từ cấp lên trong hệ thống phân cấp. Đó là, thay vì Company.SIUnits.SISuffixes, tôi nghiêng về phía Company.SI.SuffixCompany.SI.Unit
Harrison Paine

Câu trả lời:


9

Rất khó để xác định mức độ hiệu quả của chiến lược đặt tên của bạn so với phần còn lại của mã.

Không gian tên sẽ đưa ra một số ý tưởng phù hợp với cấu trúc rộng của cơ sở mã của bạn và tên lớp thường mô tả loại chức năng hoặc khái niệm mà nó đại diện trong khu vực đó.

Bỏ qua một bên, trong ví dụ cụ thể của bạn, nếu bạn có khả năng có nhiều lớp loại 'Util' hơn, tôi sẽ xem xét đưa chúng vào, Company.Utils.Mathsv.v. Cách đó nếu bạn cần thêm chức năng phổ biến cho nhiều lĩnh vực tiện ích, bạn đã có một vị trí tự nhiên cho nó.


1
Có vẻ là một ý tưởng tốt. Đừng lo lắng quá nhiều, hãy chuyển tất cả vào "Company.Util".
người dùng

30

Có một tài liệu hay chứa rất nhiều quy tắc mà bạn nên tuân theo để phù hợp với Microsoft: Nguyên tắc thiết kế khung .

Một điều mà bạn nên thay đổi: Không đặt tên lớp là không gian tên của chúng. Điều đó sẽ dẫn đến hỗn hợp trình biên dịch. Chỉ cần không. Tìm một tên tốt hơn cho lớp của không gian tên.


3
Liên kết trực tiếp đến các hướng dẫn không gian tên: msdn.microsoft.com/en-us/l
Library / ms229026 (v = vs.110) .aspx

1
Dù trùng hợp hay không cũng là cùng một cuốn sách tuyệt vời về chủ đề này, cũng được viết bởi những người Microsoft đã tham gia vào việc tạo ra khuôn khổ DotNet, với một số nhận xét về những gì họ đã làm đúng và họ đã làm gì sai. Worth đọc: amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/...
Machado

@nvoigt, bạn có thể vui lòng chỉnh sửa câu trả lời của mình để thêm trích dẫn từ liên kết mà bạn bè của chúng tôi Pagotti đã cung cấp: " KHÔNG sử dụng cùng tên cho một không gian tên và một loại trong không gian tên đó. Ví dụ: không sử dụng Debug làm tên không gian tên và sau đó cũng cung cấp một lớp có tên Debug trong cùng một không gian tên. Một số trình biên dịch yêu cầu các kiểu như vậy phải đủ điều kiện. "
Machado

2
Hãy cẩn thận: Đôi khi một tên Sản phẩm tốt hơn là sử dụng tên Công ty. Đã ở trong một vài tình huống trong đó một công ty đã được mua lại và chúng tôi phải sản xuất các không gian tên mới trên bảng và phát hành lại. Tôi nghĩ rằng điều này là rất nhỏ nhưng muốn chỉ ra nó.
Jon Raynor

1
Các nguyên tắc thiết kế khung của Microsoft rất đáng nghi ngờ, chứa các tuyên bố sai về cách .NET hoạt động và thường không được Microsoft tuân theo. Hướng dẫn đặt tên của họ là tốt, nhưng tôi sẽ tránh liên kết các hướng dẫn chung với một tuyên bố rằng "bạn nên tuân theo" chúng.
Carl Leth

6

Đã được một thời gian kể từ khi tôi làm việc với C # hoặc hệ sinh thái .NET, vì vậy tôi không thể nói các thực tiễn tốt nhất được đề xuất hiện tại là gì. Tôi muốn đề nghị thay đổi tên của bạn như thế này:

Company
Company.Text
    public class TextUtils {...}
Company.Math
    public class MathUtils {...}
    public class ArbitraryPrecisionNumber {...}
    public class MathsNotation {...}
Company.SI
    public enum SISuffixes {...}
    public class SIUnits {...}

Những gì tôi đã làm ở đây là xóa "Utils" khỏi tên không gian tên. Tôi nghĩ rằng "Util" không nên ở trong một không gian tên, bởi vì Company.Textkhông gian tên một ngày nào đó có thể chứa các lớp không phải là các lớp tiện ích văn bản. Không Company.Mathgian tên đã chứa ArbitraryPrecisionNumbermà dường như không phải là một "tiện ích".

Xóa "Util" khỏi không gian tên cũng sẽ xóa mọi nhầm lẫn có thể phát sinh bằng cách có hai thứ có cùng tên (như được đề cập trong câu trả lời của Robert: https://softwareengineering.stackexchange.com/a/340440/13156 )

Một cách khác bạn có thể đã tổ chức mã:

Company
Company.Util
    public class TextUtils {...}
    public class MathUtils {...}
Company.Math
    public class ArbitraryPrecisionNumber {...}
    public class MathsNotation {...}
Company.SI
    public enum SISuffixes {...}
    public class SIUnits {...}

Trong trường hợp này, tất cả các lớp tiện ích nằm trong cùng một không gian tên. Không còn không Company.Textgian tên vì điều duy nhất có một lớp tiện ích.

Cá nhân, tôi thấy tùy chọn đầu tiên rõ ràng hơn một chút.


4

Sử dụng cùng tên cho không gian tên và lớp bên trong nó là vấn đề.

  • Nếu không gian tên chứa nhiều hơn một lớp, tại sao các lớp khác sẽ được đặt ở đó? điều đó không đúng, bởi vì mục tiêu của tên của không gian tên là để mô tả tất cả các lớp trong nó, không chỉ một. Ví dụ, nếu bạn có JsonSerialization, BinarySerializationXmlSerializationlớp học trong một không gian tên, nó sẽ làm cho tinh thần để tên namespace của bạn XmlSerialization?

    Điều thường xảy ra là do trích xuất một lớp từ một không gian tên tồn tại hoặc hợp nhất giữa nhiều lớp hoặc tổ chức lại khác, bạn thấy mình có một không gian tên chứa một lớp chính ; dần dần, các lớp nhỏ được đặt ở đó vì chúng hơi liên quan đến lớp gốc. Ví dụ, một không gian tên LogParsercó thể chứa một lớp duy nhất LogParservà sau đó ai đó đặt LogConverter, vì nó khá liên quan đến trình phân tích cú pháp LogSearcher, v.v. Vấn đề ở đây là tên của không gian tên đã không thay đổi: ngay khi LogConverterđược thêm vào, tên nên được thay đổi thành LogsProcessinghoặc, đơn giản , Logs.

  • Nếu không gian tên chỉ chứa một lớp, đó có thể là dấu hiệu của một vấn đề trong tổ chức mã.

    Mặc dù tôi đã thấy một vài lần các tình huống trong đó một lớp duy nhất với các nguyên tắc RẮN phù hợp rất khác với bất kỳ thứ gì khác trong cơ sở mã và do đó được đặt trong một không gian tên chuyên dụng, những trường hợp như vậy rất hiếm. Thường xuyên hơn, đây là dấu hiệu của một vấn đề. Tương tự, không có gì ngăn bạn có một lớp chứa một phương thức duy nhất, nhưng thường xuyên hơn không, các lớp như vậy sẽ chỉ ra một vấn đề.

    Ngay cả khi không gian tên của bạn chỉ chứa một lớp, thường có một cách cụ thể hơn khi đặt tên lớp và tổng quát hơn khi đặt tên không gian tên. Hãy tưởng tượng một ứng dụng, trong số những thứ khác, tại một thời điểm nhất định sẽ chuyển đổi các tệp được viết ở định dạng ABC sang định dạng DEF. Việc chuyển đổi không yêu cầu bất kỳ quá trình khử tuần tự hóa / tuần tự hóa đến / từ các đối tượng kinh doanh và được thực hiện bằng cách áp dụng một loạt các biểu thức chính quy đủ ngắn để đặt trong chính lớp chuyển đổi được gọiAbcToDefConverter. Tất cả logic chuyển đổi cần khoảng 80 LLOC trong khoảng mười phương thức phụ thuộc lẫn nhau, dường như là một tình huống trong đó hoàn toàn không cần phải phân tách lớp tồn tại cũng như không tạo các lớp bổ sung. Vì phần còn lại của ứng dụng không liên quan gì đến chuyển đổi, nên lớp có thể được nhóm với các lớp khác trong các không gian tên tồn tại. Vì vậy, người ta tạo ra một không gian tên được gọi AbcToDefConverter. Mặc dù không có gì sai về điều đó, người ta cũng có thể sử dụng một tên chung hơn, chẳng hạn như Converters. Trong các ngôn ngữ như Python, nơi các tên ngắn hơn được ưa thích và sự lặp lại được đưa ra, nó thậm chí có thể trở thành converters.Abc_To_Def.

Do đó, hãy sử dụng các tên khác nhau cho các không gian tên so với các lớp mà chúng chứa. Tên của một lớp sẽ cho biết lớp đang làm gì, trong khi tên của không gian tên sẽ làm nổi bật những gì phổ biến trong tất cả các lớp được đặt trong nó.


Nhân tiện , các lớp tiện ích bị sai về bản chất: thay vì chứa một cái gì đó cụ thể, chẳng hạn như số học chính xác tùy ý, chúng thay vào đó chứa mọi thứ chưa tìm thấy trong các lớp khác . Điều này chỉ đơn giản là đặt tên xấu, giống như một Miscellaneousthư mục trên máy tính để bàn, một cái gì đó cho thấy sự thiếu tổ chức.

Đặt tên tồn tại vì một lý do: để làm cho cuộc sống của bạn dễ dàng hơn khi bạn cần tìm công cụ sau này. Bạn biết rằng nếu bạn cần vẽ một biểu đồ, bạn có thể cố gắng tìm kiếm biểu đồ ở mức độ cao hay biểu đồ của trò chơi. Khi bạn cần thay đổi cách ứng dụng tạo hóa đơn, bạn sẽ tìm kiếm hóa đơn [e / ing] hóa đơn hoặc hóa đơn. Tương tự như vậy, hãy thử tưởng tượng một trường hợp mà bạn sẽ tự nói với mình: có thể tìm thấy tính năng này trong misc. Tôi không thể.

Nhìn vào .NET Framework. Không phải hầu hết các lớp đó là các lớp tiện ích? Ý tôi là, họ có vài điều phải làm với lĩnh vực kinh doanh. Nếu tôi làm việc trên một ứng dụng tài chính, hoặc một trang web thương mại điện tử hoặc nền tảng giáo dục gen tiếp theo, việc tuần tự hóa XML hoặc đọc các tệp hoặc thực hiện các truy vấn SQL hoặc thực hiện các giao dịch là tất cả các tiện ích. Tuy nhiên, chúng không được gọi UtilitySerializationhoặc UtilityTransaction, và chúng không nằm trong Utilitykhông gian tên. Họ có tên thích hợp, điều này giúp chúng tôi có thể (và dễ dàng, cảm ơn các nhà phát triển .NET!) Để tìm thấy chúng khi tôi cần.

Điều tương tự cũng xảy ra với các lớp học mà bạn thường sử dụng lại trong các ứng dụng của mình. Chúng không phải là các lớp tiện ích. Chúng là các lớp làm một số việc nhất định và những thứ chúng làm thực sự phải là tên của các lớp.

Hãy tưởng tượng bạn đã tạo một số mã liên quan đến các đơn vị và chuyển đổi các đơn vị. Bạn có thể đặt tên cho nó Utilityvà bị đồng nghiệp ghét bỏ; hoặc bạn có thể đặt tên cho nó UnitsUnitsConversion.


7
"Các lớp tiện ích là sai bản chất". Hấp dẫn. Giải pháp nào bạn đề xuất cho một cái gì đó như lớp tiện ích hàm Math? Một thể hiện của một đối tượng Math có thực sự cần thiết để sử dụng các hàm ngoài các toán tử số học cơ bản không?
Thất vọngWithFormsDesigner

1
Tôi đồng ý với bạn, nhưng bạn đề nghị gì thay thế?
người dùng


4
Tôi đã trì hoãn việc tạo một thư viện "utils" trong thời gian dài nhất nhưng cuối cùng bạn chỉ cần nhượng bộ. Thay thế là có các DLL bao gồm khoảng 3 dòng mã chỉ là cồng kềnh (và nhắc nhở tôi về mớ hỗn độn của phụ thuộc node.js là ) hoặc sao chép và dán các phương thức tiện ích của bạn tới mọi lớp duy nhất có thể cần chúng (để tránh có lớp "tập hợp các phương thức ngẫu nhiên" đó). IMO cuối cùng nó là một điều ác cần thiết.
Matti Virkkunen

3
@FrustratedWithFormsDesigner: đơn giản là ... Math? Tôi không thấy việc thêm Utilityhậu tố vào mọi thứ sẽ giúp cuộc sống của chúng ta dễ dàng hơn. Khi sử dụng System.Math.Min()phương pháp của .NET , bạn có thực sự thích viết hơn SystemUtility.MathUtility.Min()không? Trong mọi trường hợp, tôi đã chỉnh sửa rất nhiều câu trả lời của mình, vì vậy nó sẽ rõ ràng hơn bây giờ.
Arseni Mourzenko
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.