美文网首页
Strategy Pattern(策略模式)

Strategy Pattern(策略模式)

作者: 那只大象 | 来源:发表于2015-01-26 17:31 被阅读88次

前言:

类TreeSet的构造方法

TreeSet构造出一个对象之后,给它传什么比较器,它就按照什么样的比较器去运行。给它传一个升序的,就按照升序的方式运行,给它传一个降序的,就按照降序的方式运行。而TreeSet本身是没有任何变化的,唯一变化的是传递给它的比较器。

• 策略模式(Strategy Pattern)中体现了两个非常基本的面向对象设计的原则

– 封装变化的概念

– 编程中使用接口,而不是对接口的实现

• 面向接口的编程

• 策略模式的定义

– 定义一组算法,将每个算法都封装起来,并且使它们之间可以互换

– 策略模式使这些算法在客户端调用它们的时候能够互不影响地变化

• 策略模式的意义

– 策略模式使开发人员能够开发出由许多可替换的部分组成的软件,并且各个部分之间是弱连接的关系

– 弱连接的特性使软件具有更强的可扩展性,易于维护;更重要的是,它大大提高了软件的可重用

• 策略模式的组成

– 抽象策略角色:策略类,通常由一个接口或者抽象类实现

– 具体策略角色:包装了相关的算法和行为

– 环境角色持有一个策略类的引用,最终给客户端调用的

• 策略模式的实现

– 策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。

– 策略模式使得算法可以在不影响到客户端的情况下发生变化。使用策略模式可以把行为和环境分割开来。

– 环境类负责维持和查询行为类,各种算法则在具体策略中提供。由于算法和环境独立开来, 算法的修改都不会影响环境和客户端。

• 策略模式的编写步骤

– 1.对策略对象定义一个公共接口

– 2.编写策略类,该类实现了上面的公共接口

– 3.在使用策略对象的类中保存一个对策略对象的引用

– 4.在使用策略对象的类中,实现对策略对象的set和get方法(注入)或者使用构造方法完成赋值

•参看JDK Collections类的源代码

该方法接收待排序的列表,按照Comparator具体的实现类的规则来排序

对于Collections来说,它本身并没有提供自己的排序规则,它调用了数组的辅助类Arrays的sort()方法来完成排序,这个时候转到Arrays.sort()这个方法

Arrays.sort()

调用私有方法mergeSort(),外部无法调用,这个时候转到Arrays.mergeSort()这个方法

Arrays.mergeSort()

源码之前,了无秘密:最终判断怎么排序还是用我们所提供的排序规则来进行排序的。通过Collections的源代码,可以知道Collections也使用了策略模式,只不过它是借助于数组的辅助类Arrays完成了排序的具体实现,具体实现的源代码里面会用到我们在程序里所提供的排序规则

• 实现自己的策略模式

– 抽象策略角色:

抽象接口Strategy

– 具体策略角色:

加法策略类AddStrategy 减法策略类SubtractStrategy 乘法策略类MultiplyStrategy 除法策略类DivideStrategy

– 环境角色:

环境角色类Environment

客户端调用,将具体策略类传递给环境角色类中的策略类引用:

客户端调用

•参看TreeMap类的源代码

因TreeSet底层是用TreeMap实现的,故TreeSet的任何操作都是通过TreeMap来实现的。参看TreeMap类的源代码,就能解读前言所述内容。

在使用策略对象的类TreeMap(环境角色)中持有一个对策略对象(比较器)的引用:

保存一个对策略对象的引用

在使用策略对象的类中,使用构造方法完成对策略对象的赋值:

完成对策略对象的赋值

具体的比较器则是我们在程序里所提供的比较器:

使用我们在程序里提供的比较器

• 策略模式的缺点

– 1.客户端必须知道所有的策略类,并自行决定使用哪一个策略类

– 2.造成很多的策略类

• 解决方案

– 采用工厂方法


(完)

相关文章

网友评论

      本文标题:Strategy Pattern(策略模式)

      本文链接:https://www.haomeiwen.com/subject/xilkxttx.html