抽象クラスの一般的な名前を避ける方法は?


10

一般に、ファイルハンドルやUNIXプロセスなどを扱っていない限り、ルーチン名やクラス名の一部として「ハンドル」や「プロセス」などの単語を使用しないことをお勧めします。しかし、抽象クラスは、処理などの他に何かをどうしようとしているのか、実際には分からないことがよくあります。私の現在の状況では、ユーザーの受信ボックスにログインして、そこからのメッセージを処理する「EmailProcessor」があります。次のスタイルの問題が発生することに気づきましたが、これをより正確な名前にする方法は本当にわかりません。

  • 派生クラスをクライアントとして扱い、実装する機能の一部によって基本クラスに名前を付けた方が良いですか?より意味を与えますが、is-aに違反します。たとえば、EmailAcquirerは、派生クラスのために取得しているため、適切な名前になりますが、派生クラスは誰のためにも取得しません。
  • あるいは、派生クラスが何をするのか誰が知っているので、本当にあいまいな名前です。ただし、「Processor」は、ログインやIMAPの使用など、関連する多くの操作を実行しているため、まだ一般的すぎます。

このジレンマから抜け出す方法はありますか?

問題は、「これは何をするのか」という質問に実際に答えることができない抽象メソッドの場合により明白になります。答えは単に「クライアントが望むものは何でも」だからです。


その「一般的な」主張の出典(およびいくつかの文脈)はありますか?また、リストの追加の命名規則-おそらく存在しない完全な名前を探すのに時間を無駄にしないでください。疑わしい場合は、できる限り最高の名前を付け、必要に応じて定義されたコメントとして長い説明を追加しますが、誰かがあなたの選択を気に入らない場合や、あなたが完璧な名前を突然見つけた場合は、後でいつでもリファクタリングできます別のことをしている。
Steve314

3
@ Steve314-はい、スティーブマッコネル、コードコンプリート、第1版、ルーチンに関する第4章または第5章。これらの章でのネーミングに関する広範な議論。基本的に、適切な名前がない場合は、適切な機能がないと結論付けます。
djechlin 2012

良い名前を見つけられないことは悪い兆候のように見えるかもしれませんが、IMOは関数自体に基づいて関数が悪いかどうかを知る必要があります。英語がプロジェクト用にカスタム設計されていなかったという理由だけでリファクタリングを行うのは少し手間がかかります。いいえ、それは日常的な問題ではありませんが、すでに問題があると判断しました。
Steve314

1
@ Steve314プログラミングは完全に複雑さを管理することであり、あなたの脳が何かのための言葉を思い付くことができない場合、それがそれを使用するようなことをしなければならないようなことをしなければならないとき、それはその複雑さを管理することができないかなりの可能性がありますより大きな文章またはより大きなシステムの一部として。良い名前を見つけることができないことが懸念のために立ち止まる大きな原因であると言うのは、実際には大胆な主張ではありません。しかし、これはマクコンネルで広く議論されています、私は本全体がカバーツーカバーで読む価値があるけれども、私はそれらの2つの章を読むことを勧めます。
djechlin 2012

Code Completeの主張は必ずしも信頼されるべきではありません。私は本の評判を知っていますが、これも知っています。そのうえ、私は古くから完全にうまく複雑さを管理してきました-間違いが発生する、原因は何かがうまくいかない場合、問題は時々単純な機能であり、明らかに間違っていることはありませんが、とにかくです
Steve314

回答:


10

問題は名前ではなく、1つのクラスに入れすぎていることです。

あなたの例のクラスでは、いくつかの部分は非常に具体的です(メールが取得される方法)。その他の部分は非常に抽象的です(メールで行うこと)。

継承よりも、別個のクラスを使用する方が適切です。

私は提案します:

  • POPMailBoxDownloaderによってサブクラス化された抽象MessageIterator

  • POPMailBoxDownloaderを所有し、メッセージを処理する別のクラス。


これは正確に聞こえます。何か「processEvent」または「MessageProcessor」という名前を付けていることに気づいたら、派生ではなく構成よりも設計しやすい可能性があります。この場合、それはトレードオフです。メンテナーの柔軟性は有用ですが、クライアントは各機能が何をするのか(メンテナーよりも)正確に不思議に思うことでイライラします。
djechlin 2012

6

クラスの適切な名前が見つからない場合は、クラスのインラインコードドキュメントを作成します。クラスの目的を一文で説明しています。通常、この説明からクラスの適切な名前を取得できます。これは、抽象クラスにも役立ちます。

クラスの説明が「ユーザーの受信トレイにログインし、そこからのメッセージを処理する」である場合、クラス名として「InboxProcessor」をお勧めします。派生クラスに「ユーザーの受信トレイにログインし、スパムメールをスパムフォルダーに移動する」という説明がある場合、名前として「InboxSpamMover」を選択します。

「プロセッサ」のような総称名を使用しても、抽象クラスの総称的な目的を反映していれば、問題は発生しません。

1つまたは2つのセンテンスでクラスの目的を説明することに問題がある場合は、デザインに問題がある可能性があります。たぶん、クラスはあまりにも多くを行っており、単一責任原則に違反しています。これは抽象クラスにも適用されます。


2

フランク・ザッパを言い換えれば、それはそれであり、そのように命名されるべきです。あなたの例では、どのような処理が行われているかを十分に掘り下げていません。それはEmailToTroubleTicketProcessorEmailGrammarCorrectorEmailSpamDetector

問題は、「これは何をするのか」という質問に実際に答えることができない抽象メソッドの場合により明白になります。答えは単に「クライアントが望むものは何でも」だからです。

それは正確には当てはまりません。あなたが抽象的なものに答えることができない質問は、「それはそれが何をするのですか?」です。それは実装固有であるためです。EmailSenderクラスにDeliveryStatus deliver(Email e)メソッドがある場合、実装が電子メールを受け取り、それを配信して、それがどのように行われたかについてステータスを返すという暗黙の契約があります。SMTPサーバーに接続するか、印刷してホーミングハトに縛られるかは関係ありません。アブストラクトはその約束を数値化するだけなので、実装は「そうです、私はそうします」と言うことができます。


end関数が何らかの意味でターミナルである場合、抽象クラスは「これで、これで、何でもやりたいことができる」と言っている場合はどうでしょうか?たとえば、メソッドは状態、戻り値の型void、スローなしにアクセスできません。
djechlin 2012

それはまだ同じことです。メソッドがvoid doWhatYouDoWith(Email e)である場合でも、クラスをと呼ぶことができますEmailDisposer。これは、クラスが何をするかを示すのに十分具体的ですが、実装までは十分に一般的です。私は@KrisVanBaelがそれを釘付けにしたと思いますが、曖昧なものに頼った場合、1つの屋根の下に多すぎる可能性があります。
Blrfl 2012

0

なぜそのような言葉を使うのが悪いの考えてください。それらは説明的ですか?クラスを説明する言葉はありますか?EmailBaseClass?それは、EmailManagerや類似のものを言うよりも説明的でしょうか?重要なのは、問題のクラスについての洞察を得ることです。したがって、適切な動詞または名詞を見つけます。コードを詩のように扱います。


「EmailBaseClass」は「ageInteger」という名前のようなものint ageですが、プレーンテキストのメールやMIMEメールなどをそこから取得することを期待しているため、さらに悪いことです。abstractそもそも単語の前にあるものを説明する必要はありません(これはJavaです)。このクラスの基本部分について、特別な洞察はありますか?そして、より多くの洞察は、is-aの関係を越えようとしているものに名前を付ける問題をまだ解決していません、私は何かが曖昧すぎるか、または一般的すぎる可能性があります。より多くの洞察を持つことへのより多くの洞察。
djechlin

@djechlin-まれに、ageInteger実際に適切な場合があります。ハンガリー語表記は、頻繁に発生する状況からの省略形です。確かに、あなたはの線に沿って何かが必要な場合があり時間があるageNumericageString名前が明確にする最も簡単かつ明確な方法であることにタイプの表示で、同じスコープでは。
Steve314

@djechlin個人的には、理解を深めるために覗くことができるコードを操作するのが最も簡単だと思います。つまり、名前は私が何を扱っているかを教えてくれます。systemController抽象基本クラスか、巨大な階層のリーフかを知る必要はありません。もちろん、これはIDE(ほとんどのJava開発ではそうだと思いますが)で改善できます。クラスの内容と構造についてすぐにユーザーに通知できるため、実際に洞察富んだ名前を同様に正当化することはできません。
zxcdw
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.