最近、私はあなたのデザインにたくさんのマネージャークラスがあることは悪いことだと考え始めました。私は説得力のある議論をするのに十分なほど成熟していないが、ここにいくつかの一般的なポイントがある:
「マネージャー」に大きく依存しているシステムを理解するのは、私にとってはるかに難しいことがわかりました。これは、実際のプログラムコンポーネントに加えて、マネージャーの使用方法と理由も理解する必要があるためです。
多くの場合、マネージャーは、プログラマーがプログラムを正しく機能させる方法を見つけられなかったときなど、デザインの問題を軽減するために使用されているようですTM そして、すべてが正しく動作するようにマネージャークラスに依存する必要がありました。
もちろん、飼い葉桶は良いことができます。明白な例はEventManager
で、これは私のお気に入りの構成要素の1つです。 :P私の要点は、マネージャは多くの場合、過度に使用されているように思われ、プログラムアーキテクチャの問題を隠す以外に理由はありません。
マネージャークラスは本当に悪いアーキテクチャの兆候ですか?
マネージャークラスは、いくつかの理由で、アーキテクチャが不適切であることを示している可能性があります。
無意味な識別子
FooManager
という名前は、クラスが実際にが何をするかについては何も言いませんが、Foo
インスタンスが含まれている点が異なります。クラスにわかりやすい名前を付けると、その真の目的が明確になり、リファクタリングにつながる可能性があります。
分数責任
単一責任の原則によれば、各コード単位は正確に1つの目的を果たす必要があります。マネージャを使用すると、その責任を人為的に分割している可能性があります。
ResourceManager
インスタンスの存続期間とアクセスを調整するResource
を検討してください。アプリケーションには、ResourceManager
インスタンスを取得するための単一のResource
があります。この場合、ResourceManager
クラスの静的メソッドでResource
インスタンスの機能を提供できないという本当の理由はありません。
非構造化抽象化
多くの場合、マネージャーは、管理するオブジェクトの潜在的な問題を抽象化するために導入されます。このため、管理者は設計が不十分なシステムの応急処置として虐待する傾向があります。抽象化は複雑なシステムを単純化する良い方法ですが、「マネージャー」という名前は、それが表す抽象化の構造についての手掛かりを提供しません。それは本当に工場なのか、プロキシなのか、それとも他の何かなのか?
もちろん、同じ理由で、マネージャーは悪よりも多くの目的で使用できます。 EventManager
(実際にはDispatcher
)は、イベントをソースからキューに入れ、関心のあるターゲットにディスパッチします。この場合、個々のEvent
は、出所や宛先の概念のない単なるメッセージであるため、イベントの受信と送信の責任を分離することは理にかなっています。
Dispatcher
またはEvent
を書くのと同じ理由で、GarbageCollector
of Factory
インスタンスを書きます:
マネージャは、ペイロードが知る必要のないものを知っています。
それは、マネージャーのようなクラスを作成するための最善の正当化だと思います。値のように動作する「ペイロード」オブジェクトがある場合、システム全体の柔軟性を維持するために、オブジェクトはできるだけ愚かである必要があります。個々のインスタンスに意味を提供するには、それらのインスタンスを意味のある方法で調整するマネージャーを作成します。その他の状況では、マネージャーは不要です。
マネージャーcanは、アーキテクチャが悪いことを示すものですが、多くの場合、デザイナーに代わって、オブジェクトのより適切な名前を付けられない、または単に単なる反射を示しているにすぎません。英語(およびそのことについては人間の言語)は日常の実用的な概念を伝えるのに適していて、抽象度が高く技術的な概念を伝えるのには適していません。
私のポイントを説明する簡単な例:Factory Patternが命名される前は、人々はそれを使用していましたが、それを呼び出す方法がわかりませんでした。したがって、Foo
クラスのファクトリを作成する必要があった人は、それをFooAllocationManager
と呼んだ可能性があります。それは悪いデザインではありません、それは単に想像力の欠如です。
そして、誰かが多くのファクトリーを維持し、それらを要求するさまざまなオブジェクトにそれらを渡すクラスを実装する必要があります。そして、彼は自分のクラスをFactoryManager
と呼んでいます。というのは、Word Industry
が彼に決して起こらなかったからです。もう一度、想像力の欠如の場合。
多くの「マネージャー」クラスを持つことは、多くの場合 貧血ドメインモデル の兆候です。ドメインロジックはドメインモデルから引き上げられ、代わりにマネージャークラスに配置されます。 トランザクションスクリプト 。ここでの危険は、基本的には手続き型プログラミングに戻ることです-それ自体はプロジェクトによっては良いこともそうでないこともありますが、考慮または意図されていなかったというのが本当の問題です。
"情報エキスパート" の原則に従って、論理演算は必要なデータのできるだけ近くに配置する必要があります。これは、ドメインロジックをドメインモデルに戻すことを意味します。これにより、「マネージャー」がドメインモデルの状態を外部から変更するのではなく、これらの論理演算がドメインモデルの状態に観察可能な影響を及ぼします。
短い答え:それは依存します。
「マネージャークラス」にはいくつかの異なる形式があり、それらのいくつかは良いものであり、他のものは悪いものであり、それらのほとんどにとって、マネージャークラスを導入することが正しいかどうかはコンテキストに大きく依存します。それらを正しくするための良い出発点は 単一責任の原則 に従うことです-あなたのマネージャークラスのそれぞれが何を担当しているのか(そして何をしていないのか)を正確に知っていれば、それらを理解する問題ははるかに少なくなります。
または、直接質問に答えてください。これは、不適切なアーキテクチャを示すマネージャークラスの数ではなく、責任が不明確なマネージャークラスが多すぎる、または懸念が多すぎます。
それらは本質的に悪い設計を示していると言うのは簡単かもしれませんが、それらは多くの良いものをもたらし、単一のタスクと責任を普遍的に包含することにより、プロジェクト全体でコードの複雑さと他の定型コードを減らすのに役立ちます。
マネージャーの普及は設計の判断が不十分なためである可能性がありますが、コンポーネント化された設計やサードパーティのUIコンポーネント、または奇妙なインターフェイスを持つサードパーティのWebサービスで、設計の決定が不十分だったり、非互換性の問題を処理したりすることもあります。例として。
これらの例は、全体的な複雑さを軽減し、「醜いコード」を1か所にカプセル化することによってさまざまなコンポーネントとレイヤー間の疎結合を促進する特定の状況で非常に役立つ場合を示しています。しかし、1つの落とし穴は、マネージャをシングルトンにするのが魅力的であると人々が感じることです。私はこれに反対します。もちろん、他の人が単一責任の原則に従うことは常に推奨されます。
マネージャークラスは、アーキテクチャが悪い兆候である可能性がありますか?
あなたはあなたの質問に答えました:彼らは悪いデザインの兆候である必要はありません。
EventManagerでの質問の例を除いて、別の例があります: [〜#〜] mvc [〜#〜] 設計パターンでは、プレゼンターはモデルのマネージャーと見なすことができます/ viewクラス。
ただし、コンセプトを誤用している場合は、設計が不適切であり、おそらくアーキテクチャの兆候です。
マネージャークラス-ほぼ同様 "-er"で終わるすべてのクラス -は悪であり、OOPとは関係ありません。私にとっては、それは悪いアーキテクチャの兆候です。
どうして? 「-er」という名前は、コード設計者が何らかのアクションを実行してクラスに変換したことを意味します。その結果、具体的な概念を反映しない人工的なエンティティができましたが、何らかのアクションがあります。これは非常に手続き的に聞こえます。
その上、通常、このようなクラスはいくつかのデータを受け取り、それを操作します。これは パッシブデータとアクティブプロシージャ の哲学であり、手続き型プログラミングでその場所を見つけました。気づいたら、Managerクラスに悪いことはありませんが、OOPではありません。
オブジェクト思考は、オブジェクトが自分自身に対して何かを行うことを意味します。 ドメインの発見 、ビルド セマンティックネット 、オブジェクトを生きた有機体、スマートで責任ある人間にしましょう。
このようなオブジェクトを制御する必要はありません。彼らは何をすべきか、そしてどのようにすべきかを知っています。したがって、マネージャクラスはOOP原則を2回破壊します。「-er」クラスであることに加えて、他のオブジェクトを制御します。しかし、それはマネージャに依存します。彼が制御します-彼は悪いマネージャです。もし彼はコーディネートします-彼は良いマネージャーです-- [〜#〜] mvc [〜#〜] の "C"の文字は "コーディネーター"と綴られるべきです。
この質問に対する正しい答えは次のとおりです。
ソフトウェアの作成中に遭遇するすべての状況は異なります。たぶんあなたは、マネージャークラスが内部でどのように機能するかを誰もが知っているチームにいるのでしょうか?その設計を使用しないのは完全に狂気です。または、マネージャーの設計を他の人にプッシュしようとしている場合、それは悪い考えかもしれません。しかし、それは正確な詳細に依存します。