2016-07-06 10 views
1

Ich habe eine Anwendung, wo ich mit mehreren Anbietern beschäftigen müssen - jeder mit ihrer unterschiedlichen Implementierung. Nehmen wir zum Beispiel Payment Systems, es gibt viele Anbieter und Banken.Reiniger Code in Laravel für Fabrik Muster

Es gibt ein paar Dinge gemeinsam, wie Implementierungsprozess. In jedem Fall muss ich ihnen eine Rückruf-URL geben, um mir eine Antwort zu geben.

Für jetzt habe ich zwei Anbieter - VendorPay und VendorA.

Ich werde zwei Routen haben:

payment/callback/vendorpay 
payment/callback/vendora 

jeder von ihnen in zwei Controller-Methoden aufrufen.

processVendorpay and processVendora 

Nun, wenn ich hinzufügen möchte, sagen wir mal, 15 weitere Anbieter wie diese, werde ich Methoden erstellen jedes Mal wenn ich neue Anbieter hinzu? Gibt es dafür eine sauberere Lösung?

Mein Controller rechts sieht nun wie folgt aus:

class PaymentController extends BaseController 
{ 
    protected $vendorpay_validator, $vendora_validator, $transaction, $transaction_log, $vendor_product, $vendor_transaction; 

    public function __construct(VendorpayValidator $vendorpay_validator, VendorAValidator $vendora_validator, Transaction $transaction, TransactionLog $transaction_log, VendorProduct $vendor_product, VendorTransaction $vendor_transaction) 
    { 
     $this->vendorpay_validator = $vendorpay_validator; 
     $this->vendora_validator = $vendora_validator; 
     $this->transaction = $transaction; 
     $this->transaction_log = $transaction_log; 
     $this->vendor_product = $vendor_product; 
     $this->vendor_transaction = $vendor_transaction; 
    } 
} 

Diese vier die Model Repository Objekte sind: $transaction, $transaction_log, $vendor_product, $vendor_transaction

Wenn ich mehr venodrs hinzufügen müssen, es hier auf das Hinzufügen Validator Objekt hält. Was wäre ein viel sauberer Weg, es zu tun?

Eine der Lösungen, die ich dachte, war - für mehrere Routen, ich nur eine Methode erstellen. Jetzt überprüfe ich die Route in dieser Methode und rufe die Factory-Object-Basis darauf auf.

Antwort

1

Sie sollten nur eine Route haben ...

payment/callback/{vendor} 

Dann, wenn Sie die Fabrik Weg gehen wollen (was ich denke, wäre eine gute Idee, in diesem Fall) ...

class VendorValidatorFactory 
{ 
    private function __construct() {} 

    public static function getValidator($vendor) 
    { 
     switch ($vendor) { 
      case 'vendorpay': 
       return new VendorPayValidator; 
      case 'vendora': 
       return new VendarAValidator; 
     } 
    } 
} 

entfernen Sie die nun unnötigen Injektionen von Ihrem Konstruktor und in der Methode, die auf der Route reagiert, verwenden Sie die Fabrik den richtigen Validator zu greifen ...

class SomeController extends Controller 
{ 
    public function __construct(Transaction $transaction, TransactionLog $transaction_log, VendorProduct $vendor_product, VendorTransaction $vendor_transaction) 
    { 
     $this->transaction = $transaction; 
     $this->transaction_log = $transaction_log; 
     $this->vendor_product = $vendor_product; 
     $this->vendor_transaction = $vendor_transaction; 
    } 

    public function processVendorResponse($vendor) 
    { 
     $validator = VendorValidatorFactory::getValidator($vendor); 
    } 
} 

Und nur ein Vorschlag, jedes Mal, wenn Sie Ihren Validator-Klassen, die Ihr Controller verwendet, eine neue Methode hinzufügen müssen, fügen Sie das zu einem ValidatorInterface hinzu und stellen Sie sicher, dass alle Ihre Validatoren das implementieren ValidatorInterface. Auf diese Weise müssen Sie, wenn Sie mehr hinzufügen müssen, nur diese Schnittstelle implementieren, und Sie sollten genau wissen, welche Funktionen Sie schreiben müssen. Dann aktualisieren Sie einfach Ihre Fabrikmethode, um die neue einzuschließen, und Sie sind fertig. Sie müssen Ihren Controller nicht mehr ändern, Routen hinzufügen oder Abhängigkeiten zu Ihrem Controller hinzufügen.

Verwandte Themen