Паттерн стратегии является одним из паттернов поведенческого дизайна . Шаблон стратегии используется, когда у нас есть несколько алгоритмов для конкретной задачи, и клиент решает, какую фактическую реализацию использовать во время выполнения.
Шаблон стратегии также известен как шаблон политики . Мы определяем несколько алгоритмов и позволяем клиентскому приложению передавать алгоритм, который будет использоваться в качестве параметра. Одним из лучших примеров этого шаблона является метод Collections.sort()
который принимает параметр Comparator. Основываясь на различных реализациях интерфейсов Comparator, Объекты сортируются по-разному, проверьте этот пост для сортировки объектов в Java, используя Java Comparable и Comparator .
В нашем примере мы попытаемся реализовать простую корзину покупок, в которой у нас есть две стратегии оплаты — с помощью кредитной карты или PayPal.
Прежде всего мы создадим интерфейс для нашей стратегии, в нашем случае, чтобы заплатить сумму, переданную в качестве аргумента.
1
2
3
4
5
6
|
package com.journaldev.design.strategy; public interface PaymentStrategy { public void pay( int amount); } |
Теперь нам нужно будет создать конкретные реализации алгоритмов оплаты с помощью кредитной / дебетовой карты или через PayPal.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
package com.journaldev.design.strategy; 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" ); } } |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
package com.journaldev.design.strategy; 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." ); } } |
Теперь наши алгоритмы готовы, и мы можем реализовать корзину покупок, а способ оплаты потребует ввода в качестве стратегии оплаты.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
package com.journaldev.design.strategy; 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; } } |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
package com.journaldev.design.strategy; 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); } } |
Обратите внимание, что метод оплаты корзины покупок требует алгоритм оплаты в качестве аргумента и нигде не сохраняет его как переменную экземпляра.
Давайте проверим нашу установку с помощью простой программы.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
package com.journaldev.design.strategy; 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 //pay by credit card cart.pay( new CreditCardStrategy( "Pankaj Kumar" , "1234567890123456" , "786" , "12/15" )); } } |
Вывод вышеуказанной программы:
1
2
|
50 paid using Paypal. 50 paid with credit /debit card |
Диаграмма классов шаблонов стратегий
Важные точки
- Мы могли бы использовать композицию для создания переменной экземпляра для стратегий, но мы должны избегать этого, поскольку мы хотим, чтобы конкретная стратегия применялась для конкретной задачи, то же самое следует в методах Collections.sort () и Arrays.sort (), которые принимают компаратор как аргумент.
- Стратегия Pattern очень похожа на State Pattern . Одно из отличий состоит в том, что Context содержит состояние в качестве переменной экземпляра, и может быть несколько задач, реализация которых может зависеть от состояния, тогда как в шаблоне стратегии стратегия передается как аргумент методу, а у объекта context нет никакой переменной для его хранения. ,
- Шаблон стратегии полезен, когда у нас есть несколько алгоритмов для конкретной задачи, и мы хотим, чтобы наше приложение могло гибко выбирать любой алгоритм во время выполнения для конкретной задачи.
Это все для стратегии Pattern в Java, надеюсь, вам понравилось.