[解決済み] 単一のメソッドを持つクラス -- 最適なアプローチ?
質問
一つの関数を実行するためのクラスがあるとします。関数を実行した後、そのクラスは破棄することができます。これらのアプローチのうち、どちらかを選ぶ理由はあるのでしょうか?
// Initialize arguments in constructor
MyClass myObject = new MyClass(arg1, arg2, arg3);
myObject.myMethod();
// Pass arguments to method
MyClass myObject = new MyClass();
myObject.myMethod(arg1, arg2, arg3);
// Pass arguments to static method
MyClass.myMethod(arg1, arg2, arg3);
細かいことはわざと曖昧にして、様々な状況に対するガイドラインを得ようとしたのです。しかし、Math.random()のような単純なライブラリ関数を念頭に置いていたわけではありません。私が考えているのは、もっと具体的で複雑なタスクを実行するクラスで、それを行うには1つの(パブリック)メソッドしか必要ないものなのです。
どのように解決するのか?
私は以前、静的メソッドで満たされたユーティリティクラスが大好きでした。そうしなければ冗長性とメンテナンス地獄を引き起こしてしまうようなヘルパーメソッドを、見事に統合してくれたのです。インスタンス化することもなく、廃棄することもなく、ただ火をつけるだけで、とても簡単に使うことができます。これは、私がサービス指向アーキテクチャを作る上で、初めて無意識に行った試みだったと思います。つまり、たくさんのステートレス・サービスが、ただ自分の仕事をするだけで、それ以外のことは何もしないのです。しかし、システムが成長するにつれて、ドラゴンがやってくるようになりました。
ポリモーフィズム
例えば、UtilityClass.SomeMethodというメソッドがあり、楽しげに動作しているとします。突然、その機能を少し変更する必要が出てきました。ほとんどの機能は同じですが、それでもいくつかの部分を変更する必要があります。もしこれが静的メソッドでなかったら、派生クラスを作って必要に応じてメソッドの内容を変更することができます。スタティック・メソッドである以上、それはできない。確かに、古いメソッドの前後に機能を追加するだけなら、新しいクラスを作成して、その中で古いメソッドを呼び出せばいいのですが、それは単に気持ち悪いだけです。
インターフェイスの悩み
静的メソッドは、論理的な理由からインターフェースを通して定義することができません。また、スタティックメソッドをオーバーライドできないので、スタティッククラスをインターフェースで受け渡しする必要がある場合、スタティッククラスは役に立ちません。このため、strategyパターンの一部として静的クラスを使用することはできません。この問題を解決するために
インターフェースの代わりにデリゲートを渡す
.
テスト
これは基本的に、上記のインターフェイスの問題と密接に関係しています。実装を交換する能力は非常に限られているので、プロダクションコードをテストコードに置き換えることも困難です。繰り返しになりますが、ラップすることは可能ですが、実際のオブジェクトの代わりにラッパーを受け入れることができるようにするために、コードの大部分を変更する必要があります。
ブロブ(塊)の育成
静的メソッドは通常ユーティリティメソッドとして使われ、ユーティリティメソッドは通常異なる目的を持つので、すぐにまとまりのない機能でいっぱいの大きなクラスになってしまいます。理想的には、各クラスはシステムの中で単一の目的を持つべきです。目的がきちんと定義されているのであれば、むしろ5倍くらいのクラスがあってもいいと思います。
パラメータクリープ
最初は、その小さなかわいい、無邪気な静的メソッドが1つのパラメータを取るかもしれません。機能が大きくなるにつれて、いくつかの新しいパラメータが追加されます。やがて、さらにオプションのパラメータが追加されるので、メソッドのオーバーロードを作成します(または、サポートしている言語ではデフォルト値を追加するだけです)。やがて、10個のパラメータを受け取るメソッドができあがります。本当に必要なのは最初の3つだけで、4から7はオプションである。しかし、パラメータ6を指定すると、7-9も入力する必要がある...。この静的メソッドと同じことをするためだけにクラスを作るのであれば、コンストラクタで必要なパラメータを取り込み、ユーザーがプロパティやメソッドで任意の値を設定し、相互に依存する複数の値を同時に設定できるようにすれば解決するはずです。また、メソッドがこれほど複雑になってしまった場合、どうせなら独自のクラスにする必要がある場合がほとんどです。
理由もなくクラスのインスタンスを作成するようコンシューマに要求する。
最も一般的な議論の1つは、なぜクラスの消費者がこのメソッドを呼び出すためにインスタンスを作成することを要求し、その後インスタンスを使用しないのでしょうか?クラスのインスタンスを生成するのは、ほとんどの言語において非常に安価な処理なので、スピードは問題ではありません。コンシューマに一行のコードを追加することは、将来的により保守性の高いソリューションの基礎を築くための低コストと言えます。最後に、インスタンスの作成を避けたい場合は、クラスのシングルトンラッパーを作成すれば、簡単に再利用することができます。ただし、この場合、クラスがステートレスであることが条件となります。もしステートレスでない場合でも、静的なラッパーメソッドを作成することで、すべてを処理することができ、長期的にはすべての利点を得ることができます。最後に、シングルトンであるかのようにインスタンス化を隠すクラスを作ることもできます。MyWrapper.Instance] はプロパティで、単に [new MyClass()]を返すだけです。
シスだけが絶対的なものを扱える
もちろん、私がスタティック・メソッドを嫌うのには例外があります。肥大化の心配のない真のユーティリティクラスは、静的メソッドの優れたケースです。例えば、System.Convert。もし、あなたのプロジェクトが、将来のメンテナンスの必要性のない一過性のものであれば、全体のアーキテクチャはあまり重要ではありません。
標準、標準、標準!
インスタンスメソッドを使うことは、スタティックメソッドを使うことを阻害するものではありませんし、その逆もまた然りです。差別化の背後に理由があり、それが標準化されている限りは。ビジネスレイヤーに様々な実装方法が散らばっているのを見るのは、何にも勝る苦痛です。
関連
-
[解決済み】WebForms UnobtrusiveValidationModeは、jqueryのScriptResourceMappingを必要とする
-
[解決済み] プライベートメソッド、フィールド、インナークラスを持つクラスをテストするにはどうすればよいですか?
-
[解決済み] Mavenを使用して、依存関係を持つ実行可能なJARを作成するにはどうすればよいですか?
-
[解決済み] Pythonで静的なクラス変数は可能ですか?
-
[解決済み] C#のオートプロパティに初期値を与える最良の方法は何ですか?
-
[解決済み] Java内部クラスと静的ネストされたクラス
-
[解決済み] インターフェースと抽象クラスの違いは何ですか?
-
[解決済み] 抽象メソッドと仮想メソッドの違いは何ですか?
-
[解決済み] オブジェクト名の前のシングルアンダーコアとダブルアンダーコアの意味は何ですか?
-
[解決済み] インターフェースと抽象クラス(一般的なOO)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Solved] 1つ以上のエンティティで検証に失敗しました。詳細は'EntityValidationErrors'プロパティを参照してください [重複]。
-
[解決済み】GDI+、JPEG画像をMemoryStreamに変換する際にジェネリックエラーが発生しました。
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】パディングが無効で、削除できない?
-
[解決済み】WPFでXamlファイルにコメントを追加する方法は?
-
[解決済み】なぜこのコードはInvalidOperationExceptionを投げるのですか?
-
[解決済み】EF 5 Enable-Migrations : アセンブリにコンテキストタイプが見つかりませんでした
-
[解決済み】値をNULLにすることはできません。パラメータ名:source
-
[解決済み】ランダムなブーリアンを生成する最速の方法
-
[解決済み] C#で静的クラスを使用する場合【重複】について