web-dev-qa-db-ja.com

クラスと同じ名前の単一の静的メソッドが1つだけある多くのクラス-コードのにおい?

私のアプリケーションでは、単一責任原則(SRP)に準拠しようとしています。私はxxxxxManagerという名前のCRUDクラスをたくさん持っています。

SRPに続いて、私はそれぞれに4つのクラスを作りました:

xxxxxCreator、xxxxxGetter、xxxxxDeleter、xxxxxUpdater

静的メソッドは1つしかありません:xxxxxCreator :: create(Model $ model)、xxxxUpdater :: update(Model $ model)など。

これは私にとってコードの匂いです。 SRPを押しすぎていますか?

3
Lukmo

単一の責任は、データアクセス、の作成、読み取り、更新、削除ではありません。そのレベルでは、粒度が小さすぎます。

SRPは、クラスが1つのことだけを実行する必要があることを意味しません。これは、クラスが変更する理由を1つだけ持つべきであることを意味します。ウィキペディアの記事 は次のように説明しています

すべてのクラスは単一の責任を持つ必要があり、その責任はクラスによって完全にカプセル化される必要があります。すべてのサービスは、その責任と密接に連携している必要があります。

14
Robert Harvey

あなたがやっていることは、クラスではなく関数を書くことです。すべての言語でスタンドアロン関数が許可されているわけではありませんが、その言語で許可されている場合は、それらを関数として記述する方が理にかなっています。

これは必ずしも悪いことではありません。多くの人々は「すべてがオブジェクトである」と独断的に言いたがりますが、それは間違っています。あなたが書いているこれらのオブジェクトは、オブジェクトではなく、オブジェクトの服を着ていても機能です。関数に問題はありません。

SRPはOOP=特定の用語ですが、手続き型プログラミングまたは関数型プログラミングでも機能します。オブジェクトまたはクラスが単一の責任を持つ代わりに、関数は単一の処理を行います。これらの関数は単一の処理を実行します。事。

ただし、ModelがOOクラスまたはオブジェクトの場合(たまたま、使用している言語の型システムの「オブジェクト」または「クラス」であるデータ構造だけではありません)、他のコードのスタイルとうまく一致しない可能性があります。

より多くのOOの方法で物事をやりたい場合は、これらをModelクラスに置くことができると思います。両方に指定する2つの例は、Modelを唯一の引数として取るためです。次に、 、Modelがまだ巨大ではない、膨らんでいない、扱いにくいと想定すると、SRPと一致する可能性があります。

6
Michael Shaw

私はSRPのどこにも、各クラスに単一のmethod ...があると言っているとは思いません。また、多くの依存関係を持つ4つのクラスを作成しました。 xxxxUpdater。

CRUDは間違いなく単一の依存関係の領域に含まれると思います。

1
Uri Agassi

そうだと思います。私はその日、Javaを再設計してすべてのクラスに1つのメソッドrun()のみが存在するようにした。あなたはそれで本当に多くをすることができなかったので、これは本当にどこにも行きませんし、他のどこにも牽引力を拾いませんでした。

この時点で遭遇し始めるのは、非常に基本的な制御構造を実装するのが非常に困難なことです。 ifステートメントがどのようなものかを考えると、

_if (condition)
{
    // do this
}
else
{
    // do that
}
_

それはただ一つのことをしているのですか?それは単にrunning()ですか?いいえ、それは2つのことを行っており、毎回1つまたは2つではありません。場合によってはdoesThis()、場合によってはdoesThat()です。したがって、else句を含む事実上すべてのifステートメントで、そこにあるのは選択肢です。

  1. クラスやモジュールなどで複数の関数を使用します。

  2. 関数は1つだけ使用しますが、異なる場所では動作が明らかに異なるため、それぞれを別の関数に簡単に変換できます。

1は2よりもクリーンですか、それとも2は1よりもクリーンですか? ...はい。それはあなたがどちらに行きたいかに関して、本当に状況に依存します。 しないでくださいしたいことは、ifステートメントを取り除くことです。そして、自動的にほとんど分解されないすべての非無限ループは、ifステートメントを意味します。

更新、削除、作成、取得ごとに別々のクラスを作成するのはなぜですか?道のどこかで、あなたはまだこれをしなければならないでしょう:

_if (condition1)
{
    xxxxxCreator.Create();
}
else if (condition2)
{
    xxxxxGetter.Get();
}
else if (condition3)
{
    xxxxxUpdater.Update();
}
else
{
    xxxxxDeleter.Delete();
}
_

私はすべて同じクラスで行われている1つ、2つ、3つ、4つの異なることを数えます。これをより小さなifステートメントに分割しても、たとえマシンコード内であっても、条件がどこかに存在します。 ...そして、これは、1つだけを実行する必要がある関数/クラスの必要性のこのような厳密な解釈に違反します。

プログラミングで条件文を忘れることはできないので、そのような厳密な解釈に固執しないでください。先に進み、メソッドGet()Update()Create()、およびDelete()を使用してxxxxxManagerクラスを作成します。

1
Panzercrisis

単一の責任原則の存在の主な理由は次のとおりです。

  • あなたが全体で混乱してすべてを行うクラスを作るのを防ぐために
  • 十分に別の問題でコードを分離するように強制します。

したがって、基本的には、エンティティで4つのCRUDアクションを処理するクラスを作成する場合、私には問題ありません。さらに、あなたの方法もSRPの原則を尊重すべきだと付け加えます。たとえば、更新アクションはエンティティを返すべきではありません。それは更新ではなく読み取りアクションの役割です!

1
eka808