ライブラリのC#名前空間とクラスの命名規則


26

C#でさまざまな小さなユーティリティ関数を使用してライブラリを構築し、名前空間とクラスの命名規則を決定しようとしています。私の現在の組織は次のようなものです。

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 {...}

これは名前空間とクラスを整理するのに良い方法ですか、それとももっと良い方法がありますか?特に、名前空間とクラス名(Company.TextUtils名前空間とTextUtilsクラスなど)に同じ名前を付けることは単なる重複であり、スキームがより良い可能性を示唆しています。



5
Microsoftのガイドラインでは、列挙型の単数名を推奨しているため(SISuffixではなくSISuffixes)、単数形の方が読みやすいと思います。 「サフィックスA」Suffix.A として読み取ります。また、一般的に、階層の1レベル上の名前を繰り返すことは避けます。代わりに、つまりCompany.SIUnits.SISuffixes私が傾くだろう、Company.SI.SuffixCompany.SI.Unit
ハリソンペイン

回答:


9

命名戦略が他のコードからどれだけ効果的であるかを判断することは非常に困難です。

名前空間は、コードベースの広範な構造のどこに収まるかのアイデアを提供する必要があり、クラス名は通常、その領域内でどのような機能または概念を表すかを説明します。

脇に注意してください、あなたの特定の例では、もっと多くの「Util」型クラスがある可能性がある場合、それらを下に置くことを検討しますCompany.Utils.Maths。複数のユーティリティ領域に共通の機能を追加する必要がある場合は、すでにそれのための自然な場所。


1
良い提案ですね。心配しすぎないように、すべてを「Company.Util」にロブするだけです。
ユーザー

30

Microsoft:Framework Design Guidelinesに準拠するために従うべき多くのルールを含む素晴らしいドキュメントがあります。

変更する必要があることの1つは、名前空間としてクラスに名前を付けないでくださいこれは、コンパイラーの混乱を招きます。しないでください。名前空間のいずれかのクラスのより適切な名前を見つけます。


3
名前空間のガイドラインへの直接リンク:msdn.microsoft.com/en-us/library/ms229026
v

1
これは偶然にも、このテーマに関する素晴らしい本の同じ名前でもあり、DotNetフレームワークの作成に参加したMicrosoftの人々によって書かれたものです。読む価値がある:amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/…–
マチャド

@nvoigtは、あなたがリンクから私たちの友人Pagottiを引用符を追加するにはあなたの答えが用意編集してくださいことができます: " しないでください。名前空間とその名前空間の種類に同じ名前を使用するたとえば、名前空間名としてデバッグを使用していないと次に、同じ名前空間にDebugという名前のクラスも提供します。いくつかのコンパイラでは、そのような型を完全に修飾する必要があります。
マチャド

2
警告:製品名は会社名を使用するよりも良い場合があります。会社が買収され、全面的に新しい名前空間を作成して再リリースする必要があったいくつかのシナリオに参加しました。これは非常に小さいと思いますが、指摘したかったのです。
ジョンレイナー

1
Microsoftのフレームワーク設計ガイドラインは非常に疑わしく、.NETがどのように機能するかについての虚偽の声明を含んでおり、Microsoft自体が従わないことが非常に多いです。それらの命名ガイドラインは優れていますが、全体的なガイドラインを「従うべき」という声明とリンクさせないようにします。
カールレス

6

C#または.NETエコシステムで作業してからしばらく経ちましたので、現在推奨されているベストプラクティスが何であるかは言えません。次のように名前を変更することをお勧めします。

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 {...}

ここで行ったことは、名前空間名から「Utils」を削除することです。名前空間にテキストユーティリティクラスCompany.Textではないクラスが含まれることがあるので、「Util」は名前空間にあるべきではないと思います。Company.Math名前空間がすでに含まれているArbitraryPrecisionNumber「ユーティリティ」であるように思いません。

名前空間から「Util」を削除すると、同じ名前の2つのものが存在することによって生じる可能性のある混乱も解消されます(Robertの回答:https : //softwareengineering.stackexchange.com/a/340440/13156を参照

コードを整理する別の方法:

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 {...}

この場合、ユーティリティクラスはすべて同じネームスペースに存在します。Company.Textユーティリティクラスしかなかったため、これ以上名前空間はありません。

個人的には、最初のオプションがもう少し明確だと思います。


4

名前空間とその内部のクラスに同じ名前を使用すると問題が発生します。

  • 名前空間に複数のクラスが含まれている場合、他のクラスがそこに配置されるのはなぜですか?名前空間の名前の目標は、1つだけでなく、その中のすべてのクラスを記述することであるため、正しくないと感じます。あなたが持っている場合たとえば、JsonSerializationBinarySerializationおよびXmlSerialization名前空間のクラス、それはあなたの名前空間に名前を付けるために理にかなってXmlSerialization

    通常起こることは、既存の名前空間からのクラスの抽出、または複数のクラス間のマージまたは他の再編成のために、あなたは主要なクラスを含む名前空間を見つけます。マイナークラスは、元のクラスとわずかに関連しているため、徐々に配置されます。たとえば、名前空間がLogParser単一のクラスを含むことができLogParser、その後、誰かプットLogConverterそれはかなりパーサに関連しているため、その後、LogSearcherすぐによう:などをここでの問題は、名前空間の名前が変更されていなかったということですLogConverter、追加されました名前は、LogsProcessingまたは単に変更する必要がありますLogs

  • 名前空間に含まれるクラスが1つだけの場合は、コード編成内の問題の兆候である可能性があります。

    適切なSOLID原則を持つ単一のクラスがコードベースの他のものとは非常に異なり、したがって専用の名前空間に置かれる状況を数回見ましたが、そのようなケースはまれです。多くの場合、これは問題を示しています。同様に、単一のメソッドを含むクラスを持つことを妨げるものは何もありませんが、多くの場合、そのようなクラスは問題を示します。

    名前空間に含まれるクラスが1つだけの場合でも、通常、クラスに名前を付けるときはより具体的に、名前空間に名前を付けるときはより一般的な方法があります。ある特定の瞬間に、ABC形式で記述されたファイルをDEF形式に変換するアプリケーションを想像してください。変換には、ビジネスオブジェクトへの、またはビジネスオブジェクトからの逆シリアル化/シリアル化は必要ありません。また、変換クラス自体の中に配置するのに十分短い一連の正規表現を適用することにより行われます。AbcToDefConverter。変換ロジックはすべて、約10の相互依存メソッドで約80 LLOCかかります。既存のクラスを分割したり、追加のクラスを作成したりする必要がない状況のようです。アプリケーションの残りの部分は変換とは関係がないため、クラスを既存のネームスペース内の他のクラスとグループ化することはできません。したがって、という名前空間を作成しますAbcToDefConverter。その点で本質的に問題はありませんが、などのより一般的な名前を使用することもできConvertersます。より短い名前が優先され、繰り返しがスローされるPythonなどの言語では、になることさえありconverters.Abc_To_Defます。

したがって、名前空間に含まれるクラスとは異なる名前を使用してください。クラスの名前はクラスが何をしているかを示す必要がありますが、名前空間の名前はその中に置かれているすべてのクラスに共通することを強調する必要があります。


ちなみに、ユーティリティクラスは本質的に間違っています。任意精度の演算など、特定の何かを含む代わりに、他のクラスでは見つけられなかったすべてのものを含んでいます。これはMiscellaneous、デスクトップ上のディレクトリのように、単に名前が間違っているだけです。これは、組織の欠如を示しています。

命名には理由があります:後で物を見つける必要があるときにあなたの人生を楽にするため。チャートを描画する必要がある場合は、「チャート」または「プロット」を検索してみてください。アプリが請求書を生成する方法を変更する必要がある場合は、「invoic [e / ing]」または「bill」を検索します。同様に、「ええと、この機能はおそらくその他にもあるはずです」と自分自身に言うケースを想像してみてください。できません。

.NET Frameworkを見てください。これらのクラスのほとんどはユーティリティクラスではありませんか?つまり、彼らはビジネスドメインとはほとんど関係がありません。金融アプリ、eコマースWebサイト、または次世代の教育プラットフォームで作業している場合、XMLのシリアル化やファイルの読み取り、SQLクエリの実行、トランザクションの実行などがすべてユーティリティです。ただし、これらは、UtilitySerializationまたはと呼ばれるUtilityTransactionことはなく、Utility名前空間にはありません。それらは適切な名前を持っているので、必要なときに見つけることができます(簡単に、.NET開発者に感謝します!)。

アプリでよく再利用するクラスについても同じことが言えます。これらはユーティリティクラスではありません。それらは特定のことを行うクラスであり、実際に行うことはクラスの名前であるべきです。

ユニットとユニットの変換を処理するコードを作成したとします。名前を付けてUtility同僚に嫌われるかもしれません。またはあなたはそれに名前を付けることUnitsUnitsConversion


7
「ユーティリティクラスは本来間違っています」。面白い。数学関数ユーティリティクラスなどのソリューションを提案しますか?必要があるインスタンス Mathオブジェクトのは、本当に基本的な算術演算子を超えて機能を使用する必要が?
FrustratedWithFormsDesigner

1
私はあなたに同意しますが、代替案として何を提案しますか?
ユーザー


4
私は「utils」ライブラリの作成を最も長い時間遅らせましたが、最終的にはあなたがやらなければなりません。 )、またはユーティリティメソッドをコピーして、それらを必要とする可能性のあるすべてのクラスに貼り付けます(「ランダムメソッドのコレクション」クラスを避けるため)。IMOは最終的には必要な悪です。
マッティバークネン

3
@FrustratedWithFormsDesigner:単純に... MathUtilityすべてに接尾辞を追加すると、私たちの生活が楽になるとは思いません。.NETのSystem.Math.Min()メソッドを使用する場合、SystemUtility.MathUtility.Min()代わりに書くことを本当に好むでしょうか?いずれの場合も、回答を大幅に編集したので、今では明確になっているはずです。
Arseni Mourzenko
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.