一、策略模式的定义

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

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

策略模式在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. linu 把文件中的字母小写转换为大写,大写转换为小写awk toupper tolower

    cat aa.txt|tr "[a-z]" "A-Z" [root@ob2 mytmp]# awk '{print toupper($0)}' aa2.txt ...

  2. Laravel Debugbar

    Installation Require this package with composer: composer require barryvdh/laravel-debugbar After up ...

  3. selenium测试(Java)--多表单切换(十二)

    采用下面的例子来编写用例 <!DOCTYPE html> <html> <head> <meta http-equiv="content-type& ...

  4. selenium测试(Java)-- 验证信息(八)

    package com.test.validationinfor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.f ...

  5. 机器学习之梯度提升决策树GBDT

    集成学习总结 简单易学的机器学习算法——梯度提升决策树GBDT GBDT(Gradient Boosting Decision Tree) Boosted Tree:一篇很有见识的文章 https:/ ...

  6. Android代码的几点小技巧

     1)View的状态保存与恢复dispatchRestoreInstanceStateonRestoreInstanceStateonSaveInstanceState 2)Service的前台服务使 ...

  7. 用C结构体来实现面向对象编程,ti xDAIS标准算法就这么搞的(1)

    用C结构体来实现面向对象编程,ti xDAIS标准算法就这么搞的. 测试代码如下: #include <stdio.h> #include <stdlib.h> #includ ...

  8. JS中document对象详解

    转自:http://www.cnblogs.com/andycai/archive/2010/06/29/1767351.html 对象属性 document.title //设置文档标题等价于HTM ...

  9. erlang二进制的难理解的地方,有点神奇

    40> <<A:16>> = <<1,2>>.<<1,2>>41> <<B:16/bits>> ...

  10. OpenGL介绍

    OpenGL是一个开放的三维图形软件包,它独立于窗口系统和操作系统,以它为基础开发的应用程序可以十分方便地在各种平台间移植:OpenGL可以与Visual C++紧密接口,便于实现机械手的有关计算和图 ...