一、策略模式的定义

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

—— 策略模式使这些算法在客户端调用它们的时候能够相互不影响的变化,改变不同算法的实现方式不影响客户端的使用,即策略模式让算法独立于使用它的客户端而独立变化。

策略模式在Java中处处可以体现,TreeSet和TreeMap中均存在这样的构造方法:TreeSet(Comparator<? super E> comparator)TreeMap(Comparator<? superK> comparator),对它的描述为:构造一个空的TreeSet,它根据指定比较器进行排序。这里的指定比较器就是我们根据需要自己写的“算法”,这就是策略模式最基本的使用方式。

策略模式体现了两个非常基本的面向对象设计的原则:

1. 封装变化的概念。

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

二、策略模式的角色组成

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

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

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

四、编写策略模式的一般步骤:

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

2. 编写具体策略类,该类实现了上面的接口

3. 在使用策略对象的类(即:环境角色)中保存一个对策略对象的引用

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

5. 客户端进行调用

五、Java实现代码

要求:有这样一个类Class Person,包含id、name、age属性,有若干了Person对象存储在List中,要求对他们进行排序,分别按照名字、年龄、id进行排序(要有正序与倒序两种方式)。如果年龄或者姓名重复,则按照id的正序进行排列。要求使用策略模式进行。

思路分析:可以将若干Person类存放在ArrayList中,然后利用Collections中的 sort(List<T> list,Comparator<? super T> c)方法根据指定比较器产生的顺序对指定列表进行排序,我们要实现具体的比较规则,由于Comparator是一个接口,正好可以作为步骤一中的抽象策略角色。

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

省了一步,直接用接口Comparator即可

2. 编写具体策略类,该类实现了上面的接口

按name进行排序的具体策略类SortByName,其它SortById和SortByAge与之类似:

package com.StrategyJob;

import java.util.Comparator;

public class SortByName implements Comparator {

	private int sortType = 0 ;   // 定义标记位,默认是采用升序排列

	@Override
public int compare(Object arg0, Object arg1) { Person p0 = (Person)arg0 ;
Person p1 = (Person)arg1 ; String name0 = p0.name ;
String name1 = p1.name ; int id0 = p0.id ;
int id1 = p1.id ; if(name0.endsWith(name1)){ return id0 - id1 ;
} if(this.sortType != 0 ){
return name1.compareTo(name0);
}else{
return name0.compareTo(name1);
} } // 设置排序类型
public void setSortType(int sign)
{
this.sortType = sign ;
} }

3. 在使用策略对象的类(即:环境角色)中保存一个对策略对象的引用
;  在使用策略对象的类中,实现对策略对象的set和get方法(注入)或者使用构造方法完成赋值

这里3和4的步骤是在一起的

package com.StrategyJob;

import java.util.Comparator;

public class Environment {

	private Comparator comparator ;   // 私有的抽象策略角色的引用

	public Environment(Comparator comp)
{
this.comparator = comp ;
} public void setComparator(Comparator comp){
this.comparator = comp ;
} public Comparator getComparator(){
return this.comparator;
} }

5. 客户端进行调用

package com.StrategyJob;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator; public class Client { public static void main(String[] args){ // 按姓名name进行排序
SortByName sortbyname = new SortByName() ;
Environment environment = new Environment(sortbyname); Person p1 = new Person();
Person p2 = new Person();
Person p3 = new Person();
Person p4 = new Person(); ArrayList list = new ArrayList(); p1.setName("zhangsan");
p1.setId(1);
p1.setAge(20); p2.setName("lisi");
p2.setId(5);
p2.setAge(25); p3.setName("wangwu");
p3.setId(16);
p3.setAge(5); p4.setName("zhangsan");
p4.setId(6);
p4.setAge(5); list.add(p1);
list.add(p2);
list.add(p3);
list.add(p4); System.out.println("--------------------- 按照name升序排列 -----------------------");
// 按照name进行排序
Collections.sort(list, environment.getComparator()); for(Iterator iter = list.iterator() ; iter.hasNext() ; ){ Person p = (Person)iter.next();
String name = p.name ;
int id = p.id ;
System.out.println(name + " "+ id); } sortbyname.setSortType(1);
System.out.println("--------------------- 按照name降序排列start -----------------------");
// 按照name进行排序
Collections.sort(list, environment.getComparator()); for(Iterator iter = list.iterator() ; iter.hasNext() ; ){ Person p = (Person)iter.next();
String name = p.name ;
int id = p.id ;
System.out.println(name + " "+ id); } System.out.println("---------------------- 按照id升序排列 ----------------------"); SortById sortbyid = new SortById();
environment.setComparator(sortbyid);
Collections.sort(list, environment.getComparator()); for(Iterator iter = list.iterator() ; iter.hasNext() ; ){ Person p = (Person)iter.next();
int id = p.id ;
System.out.println(id + ""); } System.out.println("---------------------- 按照id降序排列 ----------------------"); sortbyid.setSortType(1);
Collections.sort(list, environment.getComparator()); for(Iterator iter = list.iterator() ; iter.hasNext() ; ){ Person p = (Person)iter.next();
int id = p.id ;
System.out.println(id + ""); } System.out.println("---------------------- 按照age升序排列 ----------------------"); SortByAge sortbyage = new SortByAge();
environment.setComparator(sortbyage);
Collections.sort(list, environment.getComparator()); for(Iterator iter = list.iterator() ; iter.hasNext() ; ){ Person p = (Person)iter.next();
int age = p.age ;
System.out.println(age + " " + p.id); } System.out.println("---------------------- 按照age降序排列 ----------------------"); sortbyage.setSortType(1);
Collections.sort(list, environment.getComparator()); for(Iterator iter = list.iterator() ; iter.hasNext() ; ){ Person p = (Person)iter.next();
int age = p.age ;
System.out.println(age + " " + p.id); } } }

6. 运行结果

注:一般一个类中的private成员变量都会跟着setXXX和getXXX方法进行赋值和改变值的,只在类的内部使用该成员变量。

坚持每天的学习,加油!!!

策略模式原理及Java代码实例的更多相关文章

  1. 使用策略模式重构switch case 代码

    目录 1.背景 2.案例 3.switch…case…方式实现 4.switch…case…带来的问题 5.使用策略模式重构switch…case…代码 6.总结 1.背景 之前在看<重构    ...

  2. JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)

    转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...

  3. 最短路径A*算法原理及java代码实现(看不懂是我的失败)

    算法仅仅要懂原理了,代码都是小问题,先看以下理论,尤其是红色标注的(要源代码请留下邮箱,有測试用例,直接执行就可以) A*算法 百度上的解释: A*[1](A-Star)算法是一种静态路网中求解最短路 ...

  4. 策略模式在PHP业务代码的实践

    [大话设计模式]-- 策略者模式(Strategy):它定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变法,不会影响到使用算法的客户. 策略模式的核心就是屏蔽内部策略算法,内部的 ...

  5. ActiveMQ——activemq的使用java代码实例(精选)

    ActiveMQ 在java中的使用,通过单例模式.工厂实现 Jms规范里的两种message传输方式Topic和Queue,两者的对比如下表():   Topic Queue 概要 Publish  ...

  6. 策略模式+注解 干掉业务代码中冗余的if else...

    前言: 之前写过一个工作中常见升级模式-策略模式 的文章,里面讲了具体是怎样使用策略模式去抽象现实中的业务代码,今天来拿出实际代码来写个demo,这里做个整理来加深自己对策略模式的理解.   一.业务 ...

  7. 干货 | 10分钟带你彻底了解column generation(列生成)算法的原理附java代码

    OUTLINE 前言 预备知识预警 什么是column generation 相关概念科普 Cutting Stock Problem CG求解Cutting Stock Problem 列生成代码 ...

  8. 【java设计模式】(7)---策略模式(案例解析)

    策略模式 一.概念 1.理解策略模式 策略模式是一种行为型模式,它将对象和行为分开,将行为定义为 一个行为接口 和 具体行为的实现.策略模式最大的特点是行为的变化,行为之间可以相互替换. 每个if判断 ...

  9. 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查

    原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...

随机推荐

  1. 存储过程中得到新增数据的ID

    数据库中有自增字段UID 存储过程如下: CREATE     PROCEDURE   AddUser   (   @Username           nvarchar(50),   @Email ...

  2. Eclipse 中 Debug 模式跳转到 exitCurrentThread 的问题解决

    问题描述: Debug 模式启动项目,断点跳转到exitCurrentThread 解决方法: 修改Eclipse 配置 [window]->[Preferences]->[Java]-& ...

  3. HttpGet params not being sent httpget.setParams(params)不好使

    错误的代码 HttpClient httpclient = new DefaultHttpClient(); HttpUriRequest request = new HttpGet(uri); Ht ...

  4. Ext 的一些常用方法

    一.Ext 1.1 Ext.isEmpty(v, allowBlank) //是否为空[链接] 1.2 Ext.isArray(v) //是否为数组集合 1.3 Ext.isPrimitive(v) ...

  5. Java类对象数组声明和初始化

    Java是纯面向对象语言.类是其重要构成单位. 然后,在实际编程中,我们会自己定义一些类,如Point <span style="font-size:14px;">pu ...

  6. java-jdbc循环设置sql参数

    PreparedStatement sta=null; Connection conn=null; @Test public void Test2() { //获取连接池 ComboPooledDat ...

  7. openfire User Service 和删除分组的方法

    z4PstKlN 服务器-> 系统属性 plugin.userservice.enabled 值为 true 增加用户 9090/plugins/userService/userservice? ...

  8. 第二百八十八节,MySQL数据库-索引、limit分页、执行计划、慢日志查询

    MySQL数据库-索引.limit分页.执行计划.慢日志查询 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获 ...

  9. 介绍Unity中相机的投影矩阵与剪切图像、投影概念

    这篇作为上一篇的补充介绍,主要讲Unity里面的投影矩阵的问题: 上篇的链接写给VR手游开发小白的教程:(三)UnityVR插件CardboardSDKForUnity解析(二) 关于Unity中的C ...

  10. ubuntu-12.04.5-desktop-amd64.iso:ubuntu-12.04.5-desktop-amd64:安装Oracle11gR2

    ubuntu 桌面版的安装不介绍. 如何安装oracle:核心步骤和关键点. ln -sf /bin/bash /bin/sh ln -sf /usr/bin/basename /bin/basena ...