通俗易懂系列 | 设计模式(五):策略模式

介绍#

策略设计模式是行为设计模式之一。当我们为特定任务使用多个算法时,使用策略模式,客户端决定在运行时使用的实际实现。

策略模式的最佳示例之一是Collections.sort()采用Comparator参数的方法。基于Comparator接口的不同实现,对象将以不同的方式进行排序。

实例#

对于我们的示例,我们将尝试实施一个简单的购物车,我们有两种付款策略 - 使用信用卡或使用PayPal。

首先,我们将为我们的策略模式示例创建接口,在我们的例子中,支付金额作为参数传递。
支付方式:PaymentStrategy.java

package com.journaldev.design.strategy;public interface PaymentStrategy {public void pay(int amount);}

现在我们将不得不使用信用卡/借记卡或通过PayPal为支付创建具体的算法实现。

信用卡付款:CreditCardStrategy.java

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;}@Overridepublic void pay(int amount) {System.out.println(amount +" paid with credit/debit card");}}

Paypal付款:PaypalStrategy.java

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;}@Overridepublic void pay(int amount) {System.out.println(amount + " paid using Paypal.");}}

现在我们的策略模式示例算法准备好了。我们可以实施购物车和付款方式将需要输入作为付款策略。

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;}}

ShoppingCart.java

package com.journaldev.design.strategy;import java.text.DecimalFormat;import java.util.ArrayList;import java.util.List;public class ShoppingCart {//List of itemsList<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);}}

请注意,购物车的付款方式需要付款算法作为参数,并且不会将其作为实例变量存储在任何位置。

让我们用一个简单的程序测试我们的策略模式示例设置。

ShoppingCartTest.java

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 paypalcart.pay(new PaypalStrategy("myemail@example.com", "mypwd"));//pay by credit cardcart.pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15"));}}

上述程序的输出是:

50 paid using Paypal.50 paid with credit/debit card

类图#

总结#

  • 我们可以使用组合为策略创建实例变量,但我们应该避免这种情况,因为我们希望将特定策略应用于特定任务。在Collections.sort()和Arrays.sort()方法中遵循相同的方法,将比较器作为参数。
  • 策略模式与状态模式(State Pattern)非常相似。其中一个区别是Context包含状态作为实例变量,并且可以有多个任务,其实现可以依赖于状态,而策略模式策略作为参数传递给方法,上下文对象没有任何变量来存储它。
  • 当我们为特定任务提供多个算法时,策略模式很有用,我们希望我们的应用程序可以灵活地在运行时为特定任务选择任何算法。
  • 优点:1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
  • 缺点:1、策略类会增多。 2、所有策略类都需要对外暴露。
  • 主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
  • 何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
  • 如何解决:将这些算法封装成一个一个的类,任意地替换。
  • 关键代码:实现同一个接口。
  • 使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
  • 注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

这就是java中的Strategy Pattern,我希望你喜欢它。
翻译于:strategy-design-pattern-in-java

(0)

相关推荐

  • java学习——88.菜单(二)

    上篇仅介绍了菜单,大部分情况下,菜单是有二级菜单的,也即菜单项. 1.  菜单项 菜单项为菜单的最小单位,不能再分解了.一股情况下,菜单项都代表着某一种功能. 其类名为JMenuItem,其类声明如下 ...

  • 策略模式

    有道无术,术可求 有术无道,止于术 一.策略模式的定义 先举一个例子来说:在网上购物的时候,有的时候会有一些打折的活动,可能会给你5元的优惠券,也有可能会给一张满减的优惠券,而无论给怎样的优惠券,到了 ...

  • 点外卖,让我想起了 策略模式【原创】

    回复"000"获取大量电子书 本篇文章是设计模式系列的第三篇: 模板模式 单例模式 今天给大家分享的是策略模式,具体内容大纲如下: 生活案例 在这互联网时代,尤其是在城市中,有一帮 ...

  • 大话设计模式笔记(二)の策略模式

    举个栗子 问题描述 商场收银软件,营业员根据客户所购买的商品单价和数量,向客户收费. 简单实现 /** * 普通实现 * Created by callmeDevil on 2019/6/1. */ ...

  • 通俗易懂系列 | 设计模式(八):建造者模式

    介绍# 今天我们将研究java中的Builder模式.Builder 设计模式是一种创造性的设计模式,如工厂模式和抽象工厂模式. 当Object包含许多属性时,引入了Builder模式来解决Facto ...

  • 通俗易懂系列 | 设计模式(六):责任链模式

    责任链设计模式是行为设计模式之一. 责任链模式用于在软件设计中实现松散耦合,其中来自客户端的请求被传递到对象链以处理它们.然后链中的对象将自己决定谁将处理请求以及是否需要将请求发送到链中的下一个对象. ...

  • 通俗易懂系列 | 设计模式(一):模板模式

    实际开发中常常会遇到,代码骨架类似甚至相同,只是具体的实现不一样的场景.例如:流程都有开启.编辑.驳回.结束.每个流程都包含这几个步骤,不同的是不同的流程实例它们的内容不一样.共享单车都是先开锁.骑行 ...

  • PHP设计模式之策略模式

    PHP设计模式之策略模式 策略模式,又称为政策模式,属于行为型的设计模式. Gof类图及解释 GoF定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换.本模式使得算法可独立于使用它的 ...

  • [PHP小课堂]PHP设计模式之策略模式

    [PHP小课堂]PHP设计模式之策略模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • 设计模式之策略模式

    策略模式 Strategy Intro 策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的 Context. 策略模式是一种定 ...

  • 设计模式(22) 策略模式

    在策略模式中,一个类的行为或算法可以在运行时动态更改. GOF对策略模式的描述为: Define a family of algorithms, encapsulate each one, and m ...

  • 设计模式:策略模式,Java集合定制排序的核心思想

    前言 前阵子面试的时候,有个面试官问我了解哪些设计模式吗?我说了策略模式.接着他问有哪些场景应用,我又回答他jdk的集合工具类有个排序方法就用到了策略模式,也就是java.util包下的Collect ...

  • 设计模式之策略模式和状态模式(strategy pattern & state pattern)

    本文来讲解一下两个结构比较相似的行为设计模式:策略模式和状态模式.两者单独的理解和学习都是比较直观简单的,但是实际使用的时候却并不好实践,算是易学难用的设计模式吧.这也是把两者放在一起介绍的原因,经过 ...