Heim  >  Artikel  >  Backend-Entwicklung  >  Strategiemuster: eines der Designmuster

Strategiemuster: eines der Designmuster

PHPz
PHPzOriginal
2023-08-28 17:53:061034Durchsuche

Strategiemuster: eines der Designmuster

Bisher haben wir in dieser Serie drei Designmuster behandelt. Wir definieren vier verschiedene Kategorien von Designmustern. In diesem Artikel erkläre ich das Strategy Design Pattern, das zu den Behavioral Design Patterns gehört.

Möglicherweise haben Sie eine Frage: Wann sollten Sie dieses Designmuster verwenden? Ich würde sagen, wenn wir mehrere Methoden (Algorithmen) haben, um denselben Vorgang auszuführen, und wir möchten, dass die Anwendung basierend auf den Parametern, die Sie haben, eine bestimmte Methode auswählt. Dieser Modus wird auch Strategiemodus genannt.

Ein ganz einfaches Beispiel aus diesem Artikel ist die Sortierfunktion. Wir haben zum Beispiel mehrere Algorithmen zum Sortieren von Arrays, aber abhängig von der Anzahl der Array-Elemente sollten wir wählen, welchen Algorithmus wir verwenden möchten, um die beste Leistung zu erzielen.

Dieser Modus wird auch Strategiemodus genannt.

Frage

Ich werde ein Beispiel einer E-Commerce-Website geben, die mehrere Zahlungsgateways integriert. Obwohl die Website über mehrere Zahlungsgateways verfügt, werden auf Anfrage nicht alle im Frontend angezeigt. Stattdessen muss das passende Zahlungsgateway basierend auf dem Warenkorbbetrag spontan ausgewählt werden.

Als einfaches Beispiel: Wenn der Warenkorbwert weniger als 500 $ beträgt, sollte die Zahlung mithilfe der PayPal-Standards abgewickelt werden. Beträgt der Betrag jedoch 500 $ oder mehr, sollte die Zahlung mithilfe der gespeicherten Kreditkartendaten abgewickelt werden (vorausgesetzt, die Daten sind bereits gespeichert). ).

Wenn die richtige Strategie nicht implementiert ist, sieht unser Code so aus:

Zuerst stellen wir die Hauptkurse für die Zahlung per Paypal und die Zahlung per Kreditkarte bereit, die weiter unten hinzugefügt werden.

// Class to pay using Credit Card
class payByCC {

    private $ccNum = '';
	private $ccType = '';
	private $cvvNum = '';
	private $ccExpMonth = '';
	private $ccExpYear = '';
	
	public function pay($amount = 0) {
		echo "Paying ". $amount. " using Credit Card";
	}
	
}

// Class to pay using PayPal
class payByPayPal {

	private $payPalEmail = '';
	
	public function pay($amount = 0) {
		echo "Paying ". $amount. " using PayPal";
	}

}

// This code needs to be repeated every place where ever needed.
$amount  = 5000;
if($amount >= 500) {
	$pay = new payByCC();
	$pay->pay($amount);
} else {
	$pay = new payByPayPal();
	$pay->pay($amount);
}

Hier könnte man sagen, dass wir bedingte Anweisungen platzieren müssen, damit unser Code ordnungsgemäß funktioniert. Stellen Sie sich vor, wie viele Änderungen Sie vornehmen müssen, wenn wir neue Änderungen an dieser Logik vornehmen müssen oder Sie einen Fehler in dieser Logik finden. Wir müssen an allen Stellen, an denen dieser Code verwendet wird, Patches hinzufügen.

Lösung

Wir werden die gleiche Anforderung umsetzen, jedoch mit dem Strategiemuster, das es uns ermöglicht, unseren Code klarer, leichter verständlich und erweiterbar zu machen.

Schnittstelle

Zunächst implementieren wir die Schnittstellen, die alle verschiedenen Zahlungs-Gateway-Klassen verwenden werden. Letztlich sind das unsere Strategien.

interface payStrategy {
    public function pay($amount);
}

class payByCC implements payStrategy {
	
	
	private $ccNum = '';
	private $ccType = '';
	private $cvvNum = '';
	private $ccExpMonth = '';
	private $ccExpYear = '';
	
	public function pay($amount = 0) {
		echo "Paying ". $amount. " using Credit Card";
	}
	
}

class payByPayPal implements payStrategy {

	private $payPalEmail = '';
	
	public function pay($amount = 0) {
		echo "Paying ". $amount. " using PayPal";
	}

}

Als nächstes erstellen wir unsere Hauptklasse, die andere Strategien als die bisher implementierten verwenden kann.

class shoppingCart {
    	
	public $amount = 0;
	
	public function __construct($amount = 0) {
		$this->amount = $amount;
	}
	
	public function getAmount() {
		return $this->amount;
	}
	
	public function setAmount($amount = 0) {
		$this->amount = $amount;
	}

	public function payAmount() {
		if($this->amount >= 500) {
			$payment = new payByCC();
		} else {
			$payment = new payByPayPal();
		}
		
		$payment->pay($this->amount);
		
	}
}

Hier sehen wir, dass das bedingte Laden unserer Zahlungsmethode in der Methode payAmount erfolgt. Lassen Sie uns alles zusammenpacken und sehen, wie wir es weiter verwenden können.

interface payStrategy {
    public function pay($amount);
}

class payByCC implements payStrategy {
	
	private $ccNum = '';
	private $ccType = '';
	private $cvvNum = '';
	private $ccExpMonth = '';
	private $ccExpYear = '';
	
	public function pay($amount = 0) {
		echo "Paying ". $amount. " using Credit Card";
	}
	
}

class payByPayPal implements payStrategy {

	private $payPalEmail = '';
	
	public function pay($amount = 0) {
		echo "Paying ". $amount. " using PayPal";
	}

}

class shoppingCart {
	
	public $amount = 0;
	
	public function __construct($amount = 0) {
		$this->amount = $amount;
	}
	
	public function getAmount() {
		return $this->amount;
	}
	
	public function setAmount($amount = 0) {
		$this->amount = $amount;
	}

	public function payAmount() {
		if($this->amount >= 500) {
			$payment = new payByCC();
		} else {
			$payment = new payByPayPal();
		}
		
		$payment->pay($this->amount);
	}
}

$cart = new shoppingCart(499);
$cart->payAmount();

// Output
Paying 499 using PayPal

$cart = new shoppingCart(501);
$cart->payAmount();

//Output 
Paying 501 using Credit Card

Wir können sehen, dass der Rollover des Zahlungsgateways für die Anwendung nicht transparent ist. Abhängig von den Parametern steht ihm das passende Zahlungsgateway zur Abwicklung der Transaktion zur Verfügung.

Neue Strategie hinzufügen

Wenn der Benutzer zu einem späteren Zeitpunkt eine neue Strategie mit anderer Logik hinzufügen muss (hier ein neues Zahlungsgateway), ist dies in diesem Fall sehr einfach. Nehmen wir an, wir möchten ein neues Zahlungsgateway, Moneybooker, hinzufügen und Geldbeträge verarbeiten, wenn der Warenkorbbetrag 500 $ übersteigt, aber unter 1.000 $ fällt.

Alles, was wir tun müssen, ist eine neue Strategieklasse zu erstellen, die unsere Schnittstelle implementiert, und schon kann es losgehen.

class payByMB implements payStrategy {

    private $mbEmail = '';
	
	public function pay($amount = 0) {
		echo "Paying ". $amount. " using Money Booker";
	}

}

Wir haben jetzt unsere neue Strategieklasse fertig, alles was wir ändern müssen, ist die Hauptmethode payAmount. Muss wie folgt geändert werden:

public function payAmount() {
    
	if($this->amount > 500 && $this->amount < 1000) {
		$payment = new payByMB();
	} else if($this->amount >= 500) {
		$payment = new payByCC();
	} else {
		$payment = new payByPayPal();
	}
	
	$payment->pay($this->amount);
}

Hier sehen Sie, dass wir nur Änderungen an der payAmount-Methode vorgenommen haben, nicht am Client-Code, der die Methode aufruft.

Fazit

Abschließend lässt sich sagen, dass wir die Implementierung des Strategiemusters in Betracht ziehen sollten, wenn wir mehrere Möglichkeiten haben, dieselbe Aufgabe auszuführen (in Softwaresprachen, wenn wir mehrere Algorithmen haben, um dieselbe Operation auszuführen).

In diesem Modus können wir Algorithmen frei hinzufügen/entfernen, da der Wechsel dieser Algorithmen für die Anwendung nicht transparent ist.

Ich habe mein Bestes gegeben, um ein einfaches, aber nützliches Beispiel zur Veranschaulichung des Strategieentwurfsmusters bereitzustellen. Wenn Sie jedoch weitere Kommentare oder Fragen haben, können Sie diese gerne dem Feed unten hinzufügen.

Das obige ist der detaillierte Inhalt vonStrategiemuster: eines der Designmuster. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn