1

定期的な支払いプロファイルを取得して「失敗」としてマークするなど、機能のごく一部のみを実行するクラスを何と呼びますか?

名前を付けるのは正しいRecurringPaymentProfileMarkAsFailedServiceですか?単なる名前であることはわかっていますが、標準/慣習を遵守したいと思います。これは「サービス」クラスがすべきことですか、それとも別の設計パターンですか? 私は SRP の原則に沿ってフォローアップしようとしています。したがって、私が正しければ、それぞれが 1 つのタスクに特化した多数の小さなクラスになることになります。正しい命名基準を定義したいと思います。

4

3 に答える 3

0

私は SRP の「精神」を理解していると思いますが、個人的には、RecurringPaymentProfileService のメソッド (MarkAsFailed) であるはずの別のクラスを作成する必要があると結論付けるのはやりすぎだと思います (このロジックを説明している場合) 「機能の非常に小さな部分」として)。

多くの場合、このような長くて扱いにくい名前に苦労することになるのは、コード構造に関して競合する原則の間で適切なバランスをとっていないことを示していると思います。

私の指針となる原則は、サービスは、特定のビジネス エンティティまたはプロセス (PaymentProfiles など) の処理 (返品/処理) に可能な限り排他的に関連するという意味で、SRP に準拠するように努める必要があるということです。しかし、私の考えでは、サービスの内部構造を n 度まで分割しようとすると、おそらく他の多くの原則に違反することになるでしょう。

于 2012-10-24T09:25:00.743 に答える
0

まあ、価値があるのは、あなたの説明から、コマンド デザイン パターンを使用しているように聞こえます。

通常、クラス名が長すぎることに気付いた場合は、代わりにパッケージまたはパス階層を使用します。この場合、次のようになります。

パッケージ: commands.recurringPaymentProfile

クラス: MarkAsFailed

したがって、「サービス」の代わりに「コマンド」を使用し、recurringPaymentProfile に適用されるものを 1 つのパッケージにグループ化します。

于 2012-10-24T09:10:59.200 に答える
0

厳密に文書化されているのを見たことはありませんが、通常、「サービス」という言葉を使用して、関連するエンド ユーザー機能のサブセットを処理するクラスを示します。

たとえば、銀行口座システムがあるとします。次のサービスがあるとします。

public class AccountService
{
  public boolean transfer(Account src, Account dest, double amt) // ....

  public Account create(User user, double initAmt) // ...

  public void close(Account account) // ...
}

したがって、ユーザーが実行できる「高レベル」の機能は、私のサービスにカプセル化されています。サービスはデータベースにアクセスし、ヘルパーをインスタンス化し、必要な計算を行います。しかし、私が言ったように、これは私が業界で過ごした時間から観察してきたことです.

SRP に関する限り: SRP は、実行したい機能ごとにまったく新しいクラスが必要だという意味ではありません。プロファイルを失敗としてマークするためのクラス、成功としてマークするためのクラス、およびプロファイルの名前を変更するための別のクラスは必要ありません。

SRP は、各クラスが「1 つのこと」を処理することを意味しますが、その「1 つのこと」は密接に関連する機能のセットになる可能性があります。考慮すべきもう 1 つの重要な OO 設計原則は、カプセル化です。つまり、クラスはクライアントに公開するものを最小限に抑え、他のユーザーが必要とするものだけを公開する必要があります。PaymentProfile の内部状態を管理する小さなクラスがたくさんある場合は、PaymentProfile のすべての詳細を公開していることになります。小さな例を挙げましょう:

PaymentProfile オブジェクトにブール値の isSuccess があるとします。次に、クラス RecurringPaymentProfileMarkAsFailedService は次のようになります。

 public class RecurringPaymentProfileMarkAsFailedService {
   public void mark(PaymentProfile profile)
   {
     profile.setSuccess(false);
   }
 }

クール - すべてうまくいっています。PaymentProfile に「成功」​​と「失敗」のステータスを設定できるだけでなく、更新中に一部の内部システムがクラッシュしたことを意味する「InternalError」をサポートする必要があるという機能リクエストを受け取りました。ブール値を使用できなくなったため、ブール値の isSuccess を、成功、失敗、エラーのいずれかになる列挙型に変更します。ここで、MarkAsFailedService をリファクタリングする必要があります。

これは単純なリファクタリングです。これは 1 つのクラスにすぎませんが、複雑なクラス ツリーの場合、これらのリファクタリングはシステム全体に反映される可能性があります。これは、PaymentProfile に関する実装の詳細を明らかにしすぎている兆候です。クラスはカプセル化する必要があるため、クラスの実装を変更してもクライアントにはほとんどまたはまったく影響がありません。

于 2012-10-26T23:15:11.417 に答える