2021-07-28

策略模式(学习笔记)

  1. 意图

  3. 适用性

  • 许多相关的类仅仅是行为有异。"策略"提供了一种用多个行为中的一个行为来配置一个类的方法
  • 需要使用一个算法的不同变体
  • 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构
  • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句

  4. 结构

           

  5. 效果

  1. 可以在运行时切换对象内的算法

  2. 一个替代继承的方法       如果直接生成一个Context类的子类,从而给它以不同的行为。这会将行为硬性编制到Context中,将算法的实现与Context的实现混合起来,从而使Context难以理解、维护和扩展,而且还不能动态的改变算法

  3. 消除了一些条件语句   

  4. Strategy可以提供相同行为的不同实现

  5. 客户必须了解不同的Strategy以选择合适的算法

  6. 许多现代编程语言支持函数类型功能,允许你在一组匿名函数中实现不同版本的算法。使用这些函数的方式就和使用策略对象时完全相同,无需借助额外的类和接口来保持代码简洁

  7. 增加了对象的数目

  8. Strategy和Context之间的通信开销      无论各个ConcreteStrategy实现的算法是简单还是复杂,它们都共享Strategy定义的接口。因此很可能某些ConcreteStrategy不会用到所有通过这个接口传递给它们的信息,简单的ConcreteStrategy可能不使用其中的任何信息!这就意味着有时Context会创建和初始化一些永远不会用到的参数。如果存在这个问题,需要在Strategy和Context之间进行更紧密的耦合

  6. 代码实现  

  在本例中,策略模式被用于在电子商务应用中实现各种支付方法。客户选中希望购买的商品后需要选择一种支付方式:Paypal 或者信用卡。具体策略不仅会完成实际的支付工作,还会改变支付表单的行为,并在表单中提供相应的字段来记录支付信息

  strategies/PayStrategy.java: 通用的支付方法接口

package strategy.strategies;/** * @author GaoMing * @date 2021/7/26 - 20:57 * Common interface for all strategies. */public interface PayStrategy { boolean pay(int paymentAmount); void collectPaymentDetails();}

  strategies/PayByPayPal.java: 使用 PayPal 支付

package strategy.strategies;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashMap;import java.util.Map;/** * @author GaoMing * @date 2021/7/26 - 20:57 */public class PayByPayPal implements PayStrategy{ private static final Map<String, String> DATA_BASE = new HashMap<>(); private final BufferedReader READER = new BufferedReader(new InputStreamReader(System.in)); private String email; private String password; private boolean signedIn; static {  DATA_BASE.put("amanda1985", "amanda@ya.com");  DATA_BASE.put("qwerty", "john@amazon.eu"); } /**  * Collect customer's data.  */ @Override public void collectPaymentDetails() {  try {   while (!signedIn) {    System.out.print("Enter the user's email: ");    email = READER.readLine();    System.out.print("Enter the password: ");    password = READER.readLine();    if (verify()) {     System.out.println("Data verification has been successful.");    } else {     System.out.println("Wrong email or password!");    }   }  } catch (IOException ex) {   ex.printStackTrace();  } } private boolean verify() {  setSignedIn(email.equals(DATA_BASE.get(password)));  return signedIn; } /**  * Save customer data for future shopping attempts.  */ @Override public boolean pay(int paymentAmount) {  if (signedIn) {   System.out.println("Paying " + paymentAmount + " using PayPal.");   return true;  } else {   return false;  } } private void setSignedIn(boolean signedIn) {  this.signedIn = signedIn; }}

  strategies/PayByCreditCard.java: 使用信用卡支付

package strategy.strategies;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;/** * @author GaoMing * @date 2021/7/26 - 20:58 */public class PayByCreditCard implements PayStrategy{ private final BufferedReader READER = new BufferedReader(new InputStreamReader(System.in)); private CreditCard card; /**  * Collect credit card data.  */ @Override public void collectPaymentDetails() {  try {   System.out.print("Enter the card number: ");   String number = READER.readLine();   System.out.print("Enter the card expiration date 'mm/yy': ");   String date = READER.readLine();   System.out.print("Enter the CVV code: ");   String cvv = READER.readLine();   card = new CreditCard(number, date, cvv);   // Validate credit card number...  } catch (IOException ex) {   ex.printStackTrace();  } } /**  * After card validation we can charge customer's credit card.  */ @Override public boolean pay(int paymentAmount) {  if (cardIsPresent()) {   System.out.println("Paying " + paymentAmount + " using Credit Card.");   card.setAmount(card.getAmount() - paymentAmount);   return true;  } else {   return false;  } } private boolean cardIsPresent() {  return card != null; }}

  strategies/CreditCard.java: 信用卡类

package strategy.strategies;/** * @author GaoMing * @date 2021/7/26 - 20:58 */public class CreditCard { private int amount; private String number; private String date; private String cvv; CreditCard(String number, String date, String cvv) {  this.amount = 100_000;  this.number = number;  this.date = date;  this.cvv = cvv; } public void setAmount(int amount) {  this.amount = amount; } public int getAmount() {  return amount; }}

  context/Order.java: 订单类

package strategy.context;import strategy.strategies.PayStrategy;/** * @author GaoMing * @date 2021/7/26 - 20:59 * Order class. Doesn't know the concrete payment method (strategy) user has * picked. It uses common strategy interface to delegate collecting payment data * to strategy object. It can be used to save order to database. * */public class Order { private int totalCost = 0; private boolean isClosed = false; public void processOrder(PayStrategy strategy) {  strategy.collectPaymentDetails();  // Here we could collect and store payment data from the strategy. } public void setTotalCost(int cost) {  this.totalCost += cost; } public int getTotalCost() {  return totalCost; } public boolean isClosed() {  return isClosed; } public void setClosed() {  isClosed = true; }}

  Demo.java: 客户端代码

package strategy;import strategy.context.Order;import strategy.strategies.PayByCreditCard;import strategy.strategies.PayByPayPal;import strategy.strategies.PayStrategy;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashMap;import java.util.Map;/** * @author GaoMing * @date 2021/7/26 - 20:56 */public class Demo { private static Map<Integer, Integer> priceOnProducts = new HashMap<>(); private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); private static Order order = new Order(); private static PayStrategy strategy; static {  priceOnProducts.put(1, 2200);  priceOnProducts.put(2, 1850);  priceOnProducts.put(3, 1100);  priceOnProducts.put(4, 890); } public static void main(String[] args) throws IOException {  while (!order.isClosed()) {   int cost;   String continueChoice;   do {    System.out.print("Please, select a product:" + "\n" +      "1 - Mother board" + "\n" +      "2 - CPU" + "\n" +      "3 - HDD" + "\n" +      "4 - Memory" + "\n");    int choice = Integer.parseInt(reader.readLine());    cost = priceOnProducts.get(choice);    System.out.print("Count: ");    int count = Integer.parseInt(reader.readLine());    order.setTotalCost(cost * count);    System.out.print("Do you wish to continue selecting products? Y/N: ");    continueChoice = reader.readLine();   } while (continueChoice.equalsIgnoreCase("Y"));   if (strategy == null) {    System.out.println("Please, select a payment method:" + "\n" +      "1 - PalPay" + "\n" +      "2 - Credit Card");    String paymentMethod = reader.readLine();    // Client creates different strategies based on input from user,    // application configurat......

原文转载:http://www.shaoqun.com/a/902604.html

跨境电商:https://www.ikjzd.com/

skyee:https://www.ikjzd.com/w/290

airwallex:https://www.ikjzd.com/w/1011

bsci 认证:https://www.ikjzd.com/w/2339


1.意图  3.适用性许多相关的类仅仅是行为有异。"策略"提供了一种用多个行为中的一个行为来配置一个类的方法需要使用一个算法的不同变体算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句  4.结构  5.效果  1.可以在运
prime:https://www.ikjzd.com/w/129
promotion:https://www.ikjzd.com/w/127
急速:https://www.ikjzd.com/w/1861
这就是中华第一高瀑,网红都来打卡,震撼二个字写在镜头里_文成:http://www.30bags.com/a/221142.html
这口井有四个眼,是郑旦和西施媲美的地方:http://www.30bags.com/a/221569.html
这款越南版的"紫禁城"风韵还不错哟:http://www.30bags.com/a/241764.html
这里,藏着贵州最美的色彩和风景:http://www.30bags.com/a/277417.html
口述实录:这般挑逗:瞬间性欲大涨:http://www.30bags.com/m/a/249954.html
经常过性生活的夫妻会怎样 警惕4个危害 :http://lady.shaoqun.com/a/439515.html
男人怎么提高性生活质量 4个强大性能力的技巧 :http://lady.shaoqun.com/a/439516.html
和谐房事有什么好处 夫妻性爱美满的4个益处 :http://lady.shaoqun.com/a/439517.html
如何找到一个有钱的女孩,让她对自己感兴趣:http://lady.shaoqun.com/a/439518.html

No comments:

Post a Comment