Skip to content

Strategy

Amir edited this page Jul 19, 2022 · 1 revision

الگوی طراحی استراتژی

الگوی استراتژی یک الگوی طراحی رفتاری (behavioral) است که امکان انتخاب یک الگوریتم را در زمان اجرا فراهم می کند

ویژگی اصلی این الگو این است که کلاینت مجموعه ای از الگوریتم ها را دارد که در آنها الگوریتم خاصی برای استفاده در زمان اجرا انتخاب می شود. این الگوریتم ها بین استراتژی ها قابل تعویض هستند.

مزایا و معایب الگوی استراتژی

الگوی استراتژی چندین مزیت دارد:

  • جابجایی بین الگوریتم های مختلف (استراتژی ها) در زمان اجرا آسان است زیرا از چند شکلی (polymorphism) در رابط ها استفاده می شود.
  • کد تمیز، زیرا از کدهای پر از شرط (غیر پیچیده) اجتناب می شود.
  • کدهای تمیز بیشتر، زیرا نگرانی ها را به کلاس ها (یک کلاس برای هر استراتژی) انتقال داده می شود.
  • آنها را می توان بدون تغییر نهاد زمینه تغییر داد.

معایب

  • کاربران کد یا توسعه دهندگان باید وجود استراتژی های مختلف را بدانند و مشتری باید بفهمد که استراتژی ها چگونه متفاوت هستند
  • تعداد اشیاء در برنامه را افزایش می دهد.

مثال در java

interface استراتژی

public interface PaymentStrategy {
	public void pay(int amount);
}
public class CreditCardStrategy implements PaymentStrategy {
	private String name;
	private String cardNumber;
	private String cvv;
	private String dateOfExpiry;
	public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate){
		this.name=nm;
		this.cardNumber=ccNum;
		this.cvv=cvv;
		this.dateOfExpiry=expiryDate;
	}
	@Override
	public void pay(int amount) {
		System.out.println(amount +" paid with credit/debit card");
	}
}
public class PaypalStrategy implements PaymentStrategy {
	private String emailId;
	private String password;	
	public PaypalStrategy(String email, String pwd){
		this.emailId=email;
		this.password=pwd;
	}	
	@Override
	public void pay(int amount) {
		System.out.println(amount + " paid using Paypal.");
	}
}
public class Item {
	private String upcCode;
	private int price;	
	public Item(String upc, int cost){
		this.upcCode=upc;
		this.price=cost;
	}
	public String getUpcCode() {
		return upcCode;
	}
	public int getPrice() {
		return price;
	}
}
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class ShoppingCart {

	//List of items
	List<Item> items;
	
	public ShoppingCart(){
		this.items=new ArrayList<Item>();
	}
	
	public void addItem(Item item){
		this.items.add(item);
	}
	
	public void removeItem(Item item){
		this.items.remove(item);
	}
	
	public int calculateTotal(){
		int sum = 0;
		for(Item item : items){
			sum += item.getPrice();
		}
		return sum;
	}
	
	public void pay(PaymentStrategy paymentMethod){
		int amount = calculateTotal();
		paymentMethod.pay(amount);
	}
}
public class ShoppingCartTest {

	public static void main(String[] args) {
		ShoppingCart cart = new ShoppingCart();
		
		Item item1 = new Item("1234",10);
		Item item2 = new Item("5678",40);
		
		cart.addItem(item1);
		cart.addItem(item2);
		
		//pay by paypal
		cart.pay(new PaypalStrategy("myemail@example.com", "mypwd"));
		
		//pay by credit card
		cart.pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15"));
	}

}

استرتژی در javascript

image image image image image

استراتژی در پایتون

from __future__ import annotations
from abc import ABC, abstractmethod
from typing import List


class Context():
    """
    The Context defines the interface of interest to clients.
    """

    def __init__(self, strategy: Strategy) -> None:
        """
        Usually, the Context accepts a strategy through the constructor, but
        also provides a setter to change it at runtime.
        """

        self._strategy = strategy

    @property
    def strategy(self) -> Strategy:
        """
        The Context maintains a reference to one of the Strategy objects. The
        Context does not know the concrete class of a strategy. It should work
        with all strategies via the Strategy interface.
        """

        return self._strategy

    @strategy.setter
    def strategy(self, strategy: Strategy) -> None:
        """
        Usually, the Context allows replacing a Strategy object at runtime.
        """

        self._strategy = strategy

    def do_some_business_logic(self) -> None:
        """
        The Context delegates some work to the Strategy object instead of
        implementing multiple versions of the algorithm on its own.
        """

        # ...

        print("Context: Sorting data using the strategy (not sure how it'll do it)")
        result = self._strategy.do_algorithm(["a", "b", "c", "d", "e"])
        print(",".join(result))

        # ...


class Strategy(ABC):
    """
    The Strategy interface declares operations common to all supported versions
    of some algorithm.

    The Context uses this interface to call the algorithm defined by Concrete
    Strategies.
    """

    @abstractmethod
    def do_algorithm(self, data: List):
        pass


"""
Concrete Strategies implement the algorithm while following the base Strategy
interface. The interface makes them interchangeable in the Context.
"""


class ConcreteStrategyA(Strategy):
    def do_algorithm(self, data: List) -> List:
        return sorted(data)


class ConcreteStrategyB(Strategy):
    def do_algorithm(self, data: List) -> List:
        return reversed(sorted(data))


if __name__ == "__main__":
    # The client code picks a concrete strategy and passes it to the context.
    # The client should be aware of the differences between strategies in order
    # to make the right choice.

    context = Context(ConcreteStrategyA())
    print("Client: Strategy is set to normal sorting.")
    context.do_some_business_logic()
    print()

    print("Client: Strategy is set to reverse sorting.")
    context.strategy = ConcreteStrategyB()
    context.do_some_business_logic()

نتیجه

Client: Strategy is set to normal sorting.
Context: Sorting data using the strategy (not sure how it'll do it)
a,b,c,d,e

Client: Strategy is set to reverse sorting.
Context: Sorting data using the strategy (not sure how it'll do it)
e,d,c,b,a

Is necessary

Design Pattern

Creational

Structural

Behavioral

Template

Clone this wiki locally