2017-06-30 15 views
0

抽象クラスの抽象関数宣言の数が多すぎますか?抽象関数が多すぎます - OOPベストプラクティス

例えば、会員ベースの決済システムのために:

複数の支払モードがサポートされています。

  • クレジットカード
  • トークン(クレジットカードでのお支払いが、トークンを使用して)
  • リダイレクト(Paypal)
  • マニュアル(手動でユーザを管理する)

私は抽象クラスPaymentModeを持っています。上記の異なるモードがこのクラスに拡張されています。

これら

// each mode has own way of validating the customer data 
validate(); 

// own logic of cleaning customer data (e.g removing/adding/updating) 
preparePaymentData(); 

// returns a string for saving in database, subclass must implement so developers plan to extend the PaymentMode abstract will be forced to return the correct value 
getModeOfPayment(); 

// each mode has its own logic when determining payment gateways to attempt 
getGatewaysToAttempt(); 

// before sending the payment to gateway, each mode has its own logic when adding specific data 
addCustomDataSpecificForGateway(); 

// check if transaction has failed, different payment modes has different logic of determining a failed transaction 
isTransactionFailed() 

のために、各モードは以下のメソッドの独自のロジックを持っていると私はPaymentModeクラスで抽象メソッドを宣言する必要があり、各モードの6ユニークなロジック、私は、共通の共通化するために管理してきましたコードは既にPaymentModeクラスの中に置かれています。

この番号は、各モードに固有の新機能を実装するにつれて大きくなる場合があります。

将来の開発者がPaymentModeクラスを拡張した場合、すべての抽象関数宣言を実装する必要があると私は心配しています。

多くの抽象関数宣言には、という悪いデザインがありますか??どれくらいのものがいくらですか?

その悪いデザインならば、あなたはこの問題を解決する任意の技術やデザインパターンをお勧めすることができます

おかげ

+3

あなたの抽象クラスに実際に実装された機能がなく、それが期待されない場合は、代わりに_interface_を使用することもできます。振る舞いが何であるかを正確に指定することなく、支払いの_behavior_を記述したい場合、インターフェースは非常に適切なものになります。 –

+0

@TimBiegeleisenあなたの提案に感謝します。しかし、私の抽象クラスは、これらの異なる支払いモードが共通の機能を共有しているため、機能を持っています。 – Bogz

+2

抽象メソッドをほんの少ししか持たないということはありません。また、インタフェースと抽象クラスの両方の使用を検討することもできます。 –

答えて

0

膨大な数が可能であるがBADである抽象関数宣言のそのような数がありませんデザインに欠陥があることを意味します。単一責任の原則に注意してください。

あなたはすでに4つのモードがあると定義しています。あなたのケースでは各モードごとに4つのインターフェースを行うべきだと思います。これを実行すると、それらの4つすべてに共通するものを確認し、基本インターフェースを抽出することができます。あなたが...インターフェイスとしても、それらのすべてのために6つのユニークなロジックを抽出するために

1

を考慮することができるそれは細目なしに答えるのは難しいですが、:

は明らかインターフェイスや抽象抽象メソッド(メソッドにはハード制限はありませんクラス)がありますが、それほど明確ではなく理解しやすいものは少なくなります。

ですが、最適な設計ではないことを示していますが、新しいお支払い方法ごとにお支払い方法の抽象化を変更する必要があります。それは私には失敗した抽象を示しています。 OOPは、共通コードを引き出すことだけではなく、重複を避けることでもあり、抽象化についても同様です。

私は何になりますと、何とか支払方法に制御本当制御)を転送することです。支払い方法を信頼し、支払いを行うための作業を委任します。

は、お支払い方法にさまざまな具体的な方法で異なる部分を使用して、お支払い方法を尋ねるどこかの場所にあるを保持しています。手順はvalidate(),prepare...()です。また、あなたはそれがあなたに "ゲートウェイ"を与えることを期待しています。だから、(それがスーパークラスであっても)支払い方法の外にあるコードは、それが何であるか、それをどう処理するかを知っていなければなりません。

すべてを実行する代わりに、決済方法に全面的な制御を移すデザインを考えてください。特定のステップを前提にした外部コードなしで仕事をすることができます。例えば

public interface PaymentMethod { 
    Receipt payFor(Bill bill); 
} 

ここPaymentMethodすべて自分自身を行うための責任があります。ユーザーをリダイレクトし、必要なものをすべてデータベースに保存します。この「メイン」抽象概念(すべてのユースケースをカバーしている)に慣れたら、すべてのメソッドで同じであれば、データベースに保存するなどの詳細をカバーする小さな抽象概念を作成できます。

それに関連して、抽象的な親クラスをクラス間でコードを共有する方法として使用しないでください。これは、継承の目的とは完全に一致しません。さまざまな「コードの部分」に対して適切な抽象を作成し、それらを「より大きな」抽象(つまり合成)で使用させる。

関連する問題