策略模式

概述

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

UML

实现

Strategy.java,策略类,定义算法的公共接口。

public abstract class Strategy {   // 算法方法   public abstract void algorithmInterface();}

ConcreteStrategyA.java,算法A,封装了具体算法,继承Strategy。

public class ConcreteStrategyA extends Strategy {   @Override   public void algorithmInterface() {      System.out.println("算法A实现");   }}

ConcreteStrategyB.java,算法B。

public class ConcreteStrategyB extends Strategy {   @Override   public void algorithmInterface() {      System.out.println("算法B实现");   }}

ConcreteStrategyC.java,算法C。

public class ConcreteStrategyC extends Strategy {   @Override   public void algorithmInterface() {      System.out.println("算法C实现");   }}

Context.java,上下文环境,维护Strategy引用。

public class Context {   private Strategy strategy;   public Context(Strategy strategy) {      this.strategy = strategy;   }   public void contextInterface() {      strategy.algorithmInterface();   }}

StrategyTest.java,客户端代码。

public class StrategyTest {   public static void main(String[] args) {      Context context;      context = new Context(new ConcreteStrategyA());      context.contextInterface();      context = new Context(new ConcreteStrategyB());      context.contextInterface();      context = new Context(new ConcreteStrategyC());      context.contextInterface();   }}

优缺点

优点

1、   提供了一种替代继承的方法,而且既保持了继承的优点(代码重用),还比继承更灵活(算法独立,可以任意扩展);

2、   避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展;

3、   遵守大部分GRASP原则和常用设计原则,高内聚、低偶合;

4、   易于进行单元测试,各个算法区分开,可以针对每个算法进行单元测试;

5、   ……

缺点

1、   因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量;

2、   选择何种算法需要客户端来创建对象,增加了耦合,这里可以通过与工厂模式结合解决该问题;

3、   程序复杂化。

实例

需求

商场收银系统,实现对不同情况(正常收费、折扣收费、返利收费等)的收费。

实现

CashSuper.java,现金收费父类。

/* 现金收费父类 */public abstract class CashSuper {   /* 收取现金方法,参数为商品原价,返回值为当前价 */   public abstract double acceptCash(double money);}

CashNormal.java,正常收费。

/* 正常收费 */public class CashNormal extends CashSuper {   @Override   public double acceptCash(double money) {      return money;   }}

CashRebate.java,打折收费。

/* 打折收费 */public class CashRebate extends CashSuper {   /* 折扣率 */   private double moneyRebate;      public CashRebate(double moneyRebate) {      this.moneyRebate = moneyRebate;   }    @Override   public double acceptCash(double money) {      return money * moneyRebate;   }}

CashReturn.java,返利收费。

/* 返利收费 */public class CashReturn extends CashSuper {   /* 返利满足条件 */   private double moneyCondition;   /* 满足条件后返回值 */   private double moneyReturn;      public CashReturn(double moneyCondition, double moneyReturn) {      this.moneyCondition = moneyCondition;      this.moneyReturn = moneyReturn;   }    @Override   public double acceptCash(double money) {      double result = 0;      result = money - Math.floor(money / moneyCondition) * moneyReturn;      return result;   }}

CashContext.java,维护CashSuper对象。

public class CashContext {    private CashSuper cs;      public CashContext(CashSuper cs) {      this.cs = cs;   }      public double getResult(double money) {      return cs.acceptCash(money);   }}

CashTest.java,客户端。

public class CashTest {   public static void main(String[] args) {      double money = 500;      CashContext context;      context = new CashContext(new CashNormal());      double normal = context.getResult(money);      System.out.println("正常收费:" + normal);      context = new CashContext(new CashRebate(0.8));      double rebate = context.getResult(money);      System.out.println("八折收费:" + rebate);      context = new CashContext(new CashReturn(200, 100));      double retur = context.getResult(money);      System.out.println("满200返100:" + retur);   }}

总结

策略模式和简单工厂模式的区别

相同点

1、   都是用到了封装、继承、多态;

2、   都抽出一个接口或者抽象类,针对不同的情况,有不同的实现类。

不同点

1、   使用方式不同,工厂是静态的,策略的上下文是需要创建对象的;

2、   工厂产生的是对象,不同情况下产生不同的对象;

3、   策略产生的是策略,或者说是算法,不同情况下使用不同的算法。

结论

无论何种设计模式,都是基于面相对象的三大特性,即封装、继承、多态。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我是攻城师

理解Java7和8里面HashMap+ConcurrentHashMap的扩容策略

(2)在(1)的基础上,理解ConcurrentHashMap的并发安全的设计和实现思路

1094
来自专栏Golang语言社区

Go程序GC优化经验分享

最近一段时间对《仙侠道》的服务端进行了一系列针对GC的调优,这里跟各位分享一下调优的经验。

1374
来自专栏精讲JAVA

Java 8 和 Java 9 中并发工具的改变

Java 8 和 Java 9中 concurrent 包有了一些改变, 本文对这些改变做了汇总。

1122
来自专栏余林丰

8.并发容器ConcurrentHashMap#put方法解析

jdk1.7.0_79   HashMap可以说是每个Java程序员用的最多的数据结构之一了,无处不见它的身影。关于HashMap,通常也能说出它不是线程安全的...

2776
来自专栏進无尽的文章

面向对象设计中类的关系

所谓的设计正是采用恰当的方式组织类关。因此谈设计我认为首先要从类之间的关系开始说起.

1115
来自专栏京东技术

京东资深架构师代码评审歪诗

1333
来自专栏向上的小草

设计模式(-)-工厂模式介绍

>今天介绍的几个设计模式是前一段时间看《大话设计模式》这本书中介绍的,做个笔记记录下看完的前几章节的内容。不足之处欢迎指正。

1540
来自专栏精讲JAVA

Java 8 和 Java 9 中并发工具的改变

Java 8 和 Java 9中 concurrent 包有了一些改变, 本文对这些改变做了汇总。

752
来自专栏JAVA高级架构

Java设计模式-责任链模式

作者:Jet啟思 链接:https://juejin.im/post/5a126b146fb9a0450c490201 今天来说说程序员小猿和产品就关于需求发生...

33611
来自专栏博岩Java大讲堂

Java集合--ConcurrentHashMap原理

3235

扫码关注云+社区