web-dev-qa-db-ja.com

オブジェクトのメソッドの呼び出しVS。オブジェクトをパラメーターとして渡す

一般的に受け入れられている慣行と見なされているのはどれですか?

class Image {
public void decode();
};
//main
Image image;
image.decode();

class ImageDecoder {
public Image run(Image image);
};
//main
Image image;
ImageDecoder decoder;
Image decoded = decoder.run(image);

言い換えれば、オブジェクトをパラメータとして受け入れるこれらの「ワーカークラス」は良い習慣なのでしょうか、それとも可能な限りオブジェクトに対してメソッドを直接呼び出す必要があるのでしょうか。これは単なる意見の問題ですか、それともどちらのデザインパターンが優れているかについての一般的な合意はありますか?これらのパターンはどのように呼ばれ、どこでもっと読むことができますか?

サイズ(幅、高さ)などの画像の重要なプロパティを操作したい場合、ImageResizerクラスの実装は意味をなさないため、Image :: resize()が間違いなく有効です。上記の例では、よくわかりません。結局のところ、さらに使用するためにイメージをデコードする(たとえば、イメージを別のタイプに変換する)ことは、イメージの固有の機能に近いものではありません。

上記のコードはほんの一例です。私の質問は、良いOOPデザインについてです。

1
Rydnappi

画像をデコードするためのよく知られた単一の方法はありますか?これは、画像の処理に関する重要な部分ですか?次に、その実装はImageクラス内に配置する必要があります。

画像をデコードする複数の可能な方法、または処理を変更するオプションはありますか?どちらが適切かという状況に依存しますか?同じデコードを画像以外のコンテンツに適用できますか?これらはすべて、別のデコーダークラスを持っていることを示すインジケーターになります。

いつものように、答えは真ん中のどこかにあり、コードベースの詳細に応じて、どちらか一方のソリューションがより理にかなっています。しかし、どちらも本質的に「良いOOP設計)」ではありません。

8
Kilian Foth

OOPの観点から「最良の」ソリューションを検討する場合-真の「最良の」方法はほとんどないことに留意してください [〜# 〜] solid [〜#〜] 原則、特にこの場合はSingle Responsibility Principle基本的に、オブジェクトは変更する理由が1つあるべきであると述べています(オブジェクトは1つのことを行う必要があるとも言われています)

したがって、この場合、Imageクラスの「単一の」最良の責任は、画像を構成するデータと、そのデータを使用する動作画像に固有。つまり、ImageクラスのSRPはImageです。

次に、その画像の内部状態を変更せず、むしろ入力としての画像に基づく別の何かを生成する画像に対する操作に従います。 (サイズ変更されたバージョン、圧縮/エンコードされたバージョンなど)は、ImageDecoderクラスなどの他のクラスの単一の責任として属します。

したがって、SOLIDガイドラインに従う場合、2番目のアプローチは「最善」です。しかし、他のアプローチが間違っていると言っているのではなく、たとえば、方法が1つしかない場合でも今すぐ画像をデコードし、そのコードをImageクラスに配置すると、将来、2番目のデコード方法が存在する場合、そもそもSRPに固執していた場合よりも、コードをリファクタリングしてサポートするのが難しくなります。

一見するとImageクラスに属すべきであるように見える、サイズ変更などの場合でも、そこにはいくつかの重要なロジックが含まれている可能性が高く、画像のサイズを変更する方法が複数ある可能性があります(アップサンプリング、幅/高さの比率の調整などに関して、どのようなトレードオフを行いたいか)。したがって、この機能を個別の責任とする方が理にかなっています。

1
Stephen Byrne