名前空間を持つスマーフ命名クラスの回避に関する問題


39

ここからsmurf命名という用語を取りました(21番)。トラブルに慣れていない人を救うために、Smurfの命名は、関連するクラス、変数などの束に共通の接頭辞を付ける行為であるため、「a SmurfAccountViewpass SmurfAccountDTOto to SmurfAccountController」などになります。

私がこれに対して一般的に聞いた解決策は、smurf名前空間を作成し、smurfプレフィックスを削除することです。これは一般的に私に役立ちましたが、私は2つの問題に直面しています。

  1. 私はConfigurationクラスを持つライブラリで作業しています。呼び出すこともできましたがWartmongerConfiguration、Wartmonger名前空間にあるため、単に呼び出されConfigurationます。同様Configurationに呼び出すことができるクラスもありますSmurfConfigurationが、それはSmurf名前空間にあるため、冗長になります。私のコードにSmurf.Configurationは横に表示される場所があり、Wartmonger.Configuration完全修飾名を入力するのは面倒で、コードが読みにくくなります。SmurfConfigurationand(ライブラリではなく私のコードである場合)を扱う方が良いでしょうWartmongerConfiguration

  2. 私はServiceSmurf名前空間で呼び出されたクラスを呼び出しましたSmurfService。Smurfジョブを実行する複雑なSmurfライブラリの上にServiceあるファサードです。Smurf接頭辞がなければ非常に一般的なSmurfServiceため、より良い名前のようServiceです。それSmurfServiceはすでに一般的で役に立たない名前であり、スマーフを取り除くことはこれをより明白にしただけだと認めることができます。しかし、、などと命名することもできますがRunnerLauncherそれでも「気分が良くなる」SmurfLauncherLauncherは、a が何をするのかわからないからですが、a SmurfLauncherが何をするのかは知っているからです。あなたは、a Smurf.Launcherがすることはa と同じように明白であるべきだと主張することができますSmurf.SmurfLauncher、しかし、 `Smurf.Launcherは、smurfsを起動するクラスではなく、セットアップに関連する何らかのクラスであることがわかりました。

これらのいずれかに対処するためのオープンな方法と閉じた方法があれば、それは素晴らしいことです。そうでない場合、彼らの迷惑を軽減するための一般的な慣行は何ですか?


3
Smurf.Launchersmurfsを起動しますか、それともsmurfsを起動しSmurfJobますか?おそらくそれを呼び出すことができますSmurf.JobLauncherか?
Blorgbeard

2
クラスにXService、XManagerなどの名前を付けるのはコード臭です。これらは何の意味もありません。Utilのようなものです。ファイル名をざっと読んでいると、そこに何かあったり、そこからなくなったりする可能性があります。あなたが中を覗かない限り、知る方法はありません。名前をSmurfServiceから別の名前に完全に変更します。
ダニエルカプラン

1
実際にSmurfJobsを起動するか、技術的に実行してSmurfドキュメントの言語と一致させます。それと他の答えを踏まえて、私はに名前SmurfServiceを変更しSmurfJobRunnerます。私が予想したように、ナンバー1には言語にとらわれない最適な解像度がないようです。行くのがSmurfConfiguration適切な場合がありますが、私の場合Configurationは面倒でも最高だと思いますWartmonger.Configuration
ダニエルコバーマン

6
WartmongersとSmurfsの両方を設定することに関心がある単一のクラスがある理由を理解しようとしています。
ドナルドフェローズ

なぜ違いSmurf.ConfigurationSmurfConfiguration感じるのですか?確かにそれは余分な文字ではありませんよね?(Config長さが問題である場合は短縮されます。)Smurf.Configuration問題はありSmurfConfigurationませんか?
パブロH

回答:


16

良い点をいくつか挙げます。

  1. クラスの重複に関しては、C#でクラスをエイリアスできます。たとえば、StackOverflowのこの投稿をusing ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;参照してください。あなたはあなたのプログラミング言語を示していませんが、私はあなたが書いたものからそれを推測しました。だから、あなたはエイリアスがように、2つの異なるプロジェクトでそれらをすることができ扱っているところと両方のクラスを消費するときには、あいまいさを解放します。SmurfConfigurationWartmongerConfiguration

  2. サービスは外部アプリケーションに公開されるため、アプリケーション名でサービスにブランドを設定しても問題はありません。したがって、この場合SmurfServiceは、実際に消費側アプリケーションのサービスのグループを明確にするため有効です。

このスタイルの命名を回避するには、名前空間を使用する必要があると思います。MyCompanyMyProductMyAreaClassNameを読み取らないと、コードを調べて、額面でクラスが何であるかを確認するのが難しくなります。エイリアシング手法を使用すると、必要に応じてあいまいさを軽減できます。#2で指摘したように、人々がサービスを消費するのは、命名に複雑さを取り入れるべきだと思うときだけです。消費者がさまざまなサービスを利用している場合、曖昧さが混乱する可能性があるため、このスタイルの命名が完全に理にかなっています。


5
エイリアスは物事を混乱させるだけです。Smurf.Serviceの代わりに、SmurfService = Smurf.Serviceになりました。ですから、そもそも物の名前としてSmurfServiceを持っているかもしれません。それらには場所がありますが、この特定の問題のためではありません。ただし、おそらく答えのない問題に対する最善の答えです:)
gbjbaanb

私のC#は私の質問で出てきましたが、実際には現在Javaとorg.apache.smurfville.wartmonger.configuration。残念ながらエイリアスは除外されます。2は確かなポイントなので、私はサービスのSmurfブランドを維持します。
ダニエルコバーマン

25

名前空間のポイントは、衝突することなく異なるライブラリから同じ名前のクラスを持つことができるようにすることです。両方から同じ名前のクラスを使用する必要がある場合は、一方または両方にその名前空間スコープをプレフィックスとして付けることにより、あいまいさを排除する必要があります。

そうは言っても、Smurfがクラスについて具体的なことを教えてくれれば、Smurfのクラスがたくさんあることはそれほど悪くはありません。クラス名は、クラスが何をするかについての情報を提供するのに十分な説明的なものでなければなりません。

      Session
       ^   ^
      /     \
DBSession   HttpSession

同様に、DBSessionDBRequestオブジェクトを返すオブジェクトを取る場合がありDBResponseます。また、オブジェクトでHttpSession動作する場合がHttpRequestありHttpResponseます。

これらは目的のあるSmurfクラスです。

それらはMyCompany名前空間に存在する可能性がMyCompanyHttpSessionありますが、MyCompanyDBSession以前よりも多くの情報を提供しません。この場合、Smurfをドロップして名前空間にします。

MyCompany.HttpSession

3

私は以前にこの同じ混乱のポイントに立ち向かったことがありますが、それは通常、それがその名前の一部としてある種のものを含めるかどうかの本当に問題です。

潜在的な種類の構成として言及SmurfConfigurationWartmongerConfigurationます。名前空間の形容詞(その種類)を削除したことを示すため、残っているのは単なるバニラConfigurationです。私はそれを避けます。

ストロベリーアイスクリームはストロベリーネームスペースのアイスクリームであり、チョコレートと同様であると判断するようなものですが、起こったことは、物自体からアイデンティティを与える形容詞を離婚したということです。イチゴのカテゴリーではアイスクリームではありません。ストロベリーアイスクリーム-アイスクリームの一種です。

アプリで、Strawberry.IceCreamクラスをインポートし、から直接インスタンス化を開始すると想像してみましょうIceCream

var ic = new IceCream(); //actually I'm strawberry ice cream

これは、別のIceCreamクラスをインポートする瞬間まで、うまくいくように思えるかもしれません。今、あなたは元の問題に戻り、それらを何らかの形で区別する必要がありますが、これは問題です。あなたがずっと欲しかったのは:

var sic = new StrawberryIceCream();
var cic = new ChocolateIceCream();

名前空間は、ライブラリで同じ概念を偶発的に表す可能性のあるサードパーティ間の潜在的な競合を避けるために残しておく方が適切です。ただし、ある開発者がライブラリまたはプロジェクトを作成する場合、各コンセプトに一意の名前を付け、名前空間を組織のフォルダーとしてのみ使用する必要があります。多くの場合、フォルダの名前は、そのフォルダが整理する概念の名前に含まれていますが、それでも構いません。


2

クラスの束に共通のプレフィックスがある場合、おそらく独自の名前空間に移動するに値するというのは、間違いなく良い経験則です。この問題に対処するために、2つの名前空間から同様の名前のクラスを使用する必要がある場合:

1)名前空間をエイリアスしますが、私はそれを短くし、ポイントまで、任意の自然な省略形、おそらく1文字だけにすることもできます。

using Sm = Smurf;
using W = Wartmonger;

次に、使用場所に常にプレフィックスを付け、インスタンスに適切な名前を付けます。

Sm::Configuration smConf; 
W::Configuration wConf;

2)他の回答で示唆されているように、クラスをエイリアスします。

using SmConf = Smurf.Configuration;

3)制御できるライブラリは、「構成」という用語を使用しないことを検討してください。シソーラスを使用します。例:「設定」、「モデル」、「パラメータ」。とにかくコンテキストにとって意味があるかもしれません:たとえば、Smurfが数値解析モジュールのようなものである場合、おそらく「パラメーター」と記述した方がその構成には適しているでしょう。モジュールのコンテキストに関連付けられた特定のボキャブラリーを使用して、他の名前空間に混在している場合でも一意性を保持する一意の名前を考え出します。これはOPの質問2に対する一種の答えかもしれないと感じています。

4)コードをリファクタリングして、2つの異なる場所からの構成の使用を混在させる必要がないようにします。詳細はあなた次第です。

5)クラスに渡す前に、2つの構成を1つに結合します。組み合わせたconfクラスを使用して、以下を表します。

struct Conf {
    SmurfConfiguration smurf;
    WartmongerConfiguation wart;
}

短いメンバー変数名は、クラス/名前空間のエイリアスと同じことを実現しています。


0

名前に1つのポイントを追加するのが面倒なのは奇妙に思えます。

Wartmonger.Configuration configuration = Wartmonger.Configuration .new();

// vs

WartmongerConfiguration configuration = WartmongerConfiguration.new();

両方SmurfWartmonger構成が1つの場所で一緒に使用されているが、別々に複数の場所で使用されている場合-名前空間は間違いなく良いアプローチです。

名前空間を持つことは接頭辞で、あなたが使用して終了ところ、内部コードに「クリーン」の名前を使用する可能性与えるSmurfConfiguration内部のSmurfServiceあなたがそのコードを開きます迷惑毎回になることができるの内部コードを、。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.