Android開発者はおそらく Ceja's Clean Architecture に精通しており、ユースケースは Command Pattern を実装するクラスです。
Shvetsは、パターンインテントを次のように定義します。
私はコードの可読性とテスト容易性を向上させるためにそのアプローチを使用しています。しかし、Shvetsの Anti-Patternsコース を読んだ後、私は彼の Functional Decomposition Anti-Pattern 定義と混同しました:
Command Pattern の代わりに Functional Decomposition Anti-Pattern を使用している場合、どうすればわかりますか?
ここでの主な問題はShvetsのアンチパターンの説明に欠陥があると思います。それが、コマンドパターンと区別するのに問題がある理由です。
この名前は、属性「アンチパターン」とともに古い既存の用語「機能分解」を使用しているため、欠陥があります。
この用語は、以前は「パターン」または「アンチパターン」の概念に関連付けられていなかったAFAIKでしたが、彼のトピックのためにそれを選択することにより、Shvetsはそれに新しい、混乱する意味を与えました。プログラミングにおける本来の意味は「 複雑なプロセスを取り、それをより単純な部分に分解する 」であり、それが今日でもこの用語を使用する方法です。 ( Wikipediaの定義 は数学におけるより一般的な用語についてですが、これはおそらく私たちのプログラミングのコンテキストではあまり役に立たないと思います。)参照 この以前のSEの投稿 、他の人がアンチパターン名で既に問題を抱えていた場合、上の答えは代わりに「手続き分解」という名前を提案していますが、その名前は同様の問題を引き起こす可能性があります。
パターンの説明から引用した最初の3つの症状は、実際にはコマンドオブジェクトに適していますが、他の適切に設計されたクラスにも適しています。それがまさに、彼らが私見である理由です(= /// =)Shvetsが説明するこの種の「縮退したアーキテクチャ」の良い指標ではありません。たとえば、「 関数として単一のアクションを持つクラス 」に関するこの以前のSEの投稿を参照してください。
Shvetsがおそらく頭に浮かんだのは、人々が手続き型コードをクラスにシューホーンしようとする状況でした。これは、ほとんどの場合、典型的なコマンドオブジェクトのスケールとは完全に異なるスケール( "アプリケーションスケール"について言及)で発生します。インスタンス化された「オブジェクト」は「モジュール」または「サブ」以外の抽象化ではないため、これは、SOLIDではないコードを生成し、クラスが大きすぎ、適切な抽象化が欠落し、ほとんどの場合すべてが静的である可能性があるクラスになります。 -program」、一度だけ存在し、アプリケーションプロセス全体と同じ存続期間を持ちます。
ただし、コマンドオブジェクトは、プログラミング言語が高次関数またはクロージャの組み込みメカニズムを提供しない状況では、よりオブジェクト指向の回避策です。 「コマンドパターン」という用語は、C++とJava=が支配的であった時代であり、これらの言語の両方がそのようなメカニズムを提供していなかった時代である1995年のGOFの「デザインパターン」の本にその起源がありますそのため、独自の抽象化としてプログラム内で関数を渡す必要がある場合は、おそらくコマンドパターンを使用するのが最善の選択でした。
現在、これらの両方の言語(および他の最新の言語)は、データ型に関数をカプセル化するための追加のメカニズムを提供しているため、(元のOO = form)more。それでも、「コマンド」がカプセル化する「アクション」または「関数」だけでなく、より複雑なインターフェースが必要な場合にも役立ちます。
あなたが違いを言う方法は、機能分解アンチパターンの男がそれを使っている無差別にに対し、クリーンアーキテクチャの男はそれを使っている- 実際に役立つ目的がある場合:
コマンドパターンは、オブジェクトを使用してアクションを実行したり、後でイベントをトリガーしたりするために必要なすべての情報をカプセル化する動作設計パターンです。この情報には、メソッド名、メソッドを所有するオブジェクト、およびメソッドパラメータの値が含まれます。
関数分解の担当者は、関数を含める以外の目的ではないクラスコンテナーで関数を呼び出すことを優先して、オブジェクトのすべての利点を破棄しました。
IComparable Interface も見てください。これには 単一のメソッド もあります。
コマンドパターンを適切に使用すると、コマンドを選択したときと実行するときの時間または場所が異なります。キュー、コールバック、元に戻すスタックなどに入れられます。
基本的に他に選択の余地がないため、機能分解アンチパターンはメソッドをクラスに配置するだけです。言語またはコードレビューによって強制されますが、コマンドを選択して実行する時間と場所の分離を最小限に抑えたいと考えています。関数を配置するボックスが必要なかった場合は、クラスをまったく使用しません。
コマンドパターンは、Shvetsの機能分解アンチパターン(FDAP)にも、FDAPに提案されたより優れた方法(抽象化)にもないものをエンコードしています。
コマンドは、CalculateInterest
やDisplayTable
のような1つの特定のアクションだけでなく、アクションの一般的な、アクションのabstractionについても推論する手段です。それはプレイ時の具現化です。アクションは、実行できるオブジェクトになるだけでなく、実行スタックに渡して、実行する意味があり、どこかに保存し、メタアクション(undo
、redo
、trace
)など.
多くのFDAP症状(継承/ポリモーフィズムの活用なし、再利用なし)になりにくいことに加えて、コマンドはとにかくそれを打ち負かします。なぜなら、それは通常、そのアンチパターンによってターゲットとされるクラスの種類とはまったく異なる抽象化レベルだからです。
メタファーは本質的に漏れやすい抽象化ですが、私の思考スタイルは本質的にメタファー主導なので、この質問に対する私のアプローチを次に示します。
メタファー1-複数部門組織の各部門の担当者(または「プロジェクトリーダー」)。
説明
分析
メタファー2-有名な「入力、処理、出力」ブラックボックス。
説明
分析
(警告:動物虐待の警告)
Metaphor 3-いきつくり
説明
分析
メタファー4-臓器に損傷がない生き物
説明
分析
(免責事項:この比喩のリストを作成する過程でいきいきは発生しません。)
パターンとアンチパターンの間には客観的な区別がないことに注意してください。アンチパターンは、コードを改善しない状況で適用される単なるパターンです。
「機能分解」は、協調オブジェクトとしてではなく、一連の関数呼び出しとして設計されたアーキテクチャを表します。これは、単一の関数をカプセル化するコマンドクラスにつながる可能性があります(それらはオブジェクトではなく関数と見なされ、凝集と結合を適切に考慮せずにクラスにラップされるだけです)、または適切な分離なしに100万の関数を持つ神クラスにつながる可能性があります懸念の。
コマンドパターンを、実際にはコマンドパターンを必要としないコンテキストで使用すると、関数分解アンチパターンに陥る可能性があります。
(アンチパターンは悪いコードを意味しないことにも注意してください。それは単に悪いオブジェクト指向設計を意味します。関数型言語は、関数分解が非常に強力なパラダイムであることを示しています。それはオブジェクト指向設計。)