一、策略模式的定义

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

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

策略模式在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. ActiveMQ——activemq的使用java代码实例(精选)

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

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

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

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

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

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

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

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

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

  9. 设计模式之策略模式(strategy)

    策略模式原理:策略模式和简单工厂模式有点类似,只是简单工厂模式产生的是对象,策略模式产生的是根据对象产生的算法. 代码如下: #include <iostream> #include &l ...

随机推荐

  1. Linux0.11内核--加载可执行二进制文件之3.exec

    最后剩下最核心的函数do_execve了,由于这里为了简单起见我不分析shell命令的情况, /* * 'do_execve()'函数执行一个新程序. */ //// execve()系统中断调用函数 ...

  2. A book to recommend: The art of readable code

    我最喜欢的一本书 - 教我如何写可读的代码 Two month fan of the book, from August - Oct. 2014; and then, started to pract ...

  3. MysqlHelper 需要重写

    using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Text;u ...

  4. QTableView 一列添加两个按钮

    在QTableView的一列里添加两个按钮,之前添加一个按钮的思路是一样的,只是计算了一下按钮的宽,放两个按钮而已. 添加一个按钮的例子:QTableView 添加按钮 本例源代码:QtTowButt ...

  5. Python基础之【第一篇】

    Python简介: python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语 ...

  6. Eclipse背景颜色修改

    改变背景颜色(黑底背景的设置) windows->Preferences->General->Editor->Text Editors windows->Preferen ...

  7. [Reactive Programming] Async requests and responses in RxJS

    We will learn how to perform network requests to a backend using RxJS Observables. A example of basi ...

  8. android 30 下拉列表框:ArrayAdapter和Spinner.

    package com.sxt.day05_04; import android.os.Bundle; import android.app.Activity; import android.cont ...

  9. java返回数据工具类

    import com.qbskj.project.util.SpringUtils; /** * 消息 * */ public class Message { /** * 类型 */ public e ...

  10. QuickStart系列:docker部署之MariaDB

    Centos7里面没有Mysql 取而代之的是MariaDB,MariaDB是完全开源的.MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的 ...