策略模式中体现了两个非常基本的面向对象设计的原则:
1.封装变化的概念。
2.编程中使用接口,而不是对接口的实现。

策略模式的定义:
定义一组算法,将每个算法都封装起来,并使它们之间可以互换。策略模式使这些算法在客户端调用它们的时候能够互不影响地变化。

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

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

策略模式的组成
1.抽象策略角色:策略类,通常由一个接口或者抽象类实现。
2.具体策略角色:包装了相关的算法和行为。
3.环境角色:持有一个策略类的引用,最终给客户端调用的。

策略模式的实现
1.策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使它们可以相互替换。
2.策略模式使得算法可以在不影响到客户端的情况下发生变化。使用策略模式可以把行为和环境分割开来。

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

策略模式的编写步骤

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

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

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

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

策略模式的优点
1.策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
2.使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。

策略模式的缺点
1.客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
2.由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。

下面举个例子来说明一下

有一个Person类,属性有id,name,age,分别按照id,name,age进行正序和倒序的排列。

package com.zhouyu.strategy;

public class Person
{
private int id;
private String name;
private int age; public Person()
{ } public Person(int id,String name,int age)
{
this.id = id;
this.name = name;
this.age = age;
} public int getId()
{
return id;
} public String getName()
{
return name;
} public int getAge()
{
return age;
} public void setId(int id)
{
this.id = id;
} public void setName(String name)
{
this.name = name;
} public void setAge(int age)
{
this.age = age;
}
}

这个是抽象策略角色,一个名为Strategy的接口

package com.zhouyu.strategy;

import java.util.List;

public interface Strategy
{
public void sort(List<Person> list);
}

还有几个具体策略角色,他们都继承了Strategy接口

package com.zhouyu.strategy;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; public class ForIdUp implements Strategy,Comparator<Person>
{
@Override
public void sort(List<Person> list)
{
Collections.sort(list,this);
} @Override
public int compare(Person o1, Person o2)
{
return o1.getId()-o2.getId();
}
}
package com.zhouyu.strategy;

import java.util.Collections;
import java.util.Comparator;
import java.util.List; public class ForIdDown implements Strategy,Comparator<Person>
{
@Override
public void sort(List<Person> list)
{
Collections.sort(list,this);
} @Override
public int compare(Person o1, Person o2)
{
return o2.getId() - o1.getId();
}
}

这里只给出了按照Id的正序和倒序,其他的请下载代码吧,这里就不重复写出了。

这个是环境角色

package com.zhouyu.strategy;

import java.util.List;

public class Environment
{
private Strategy strategy; public void setStrategy(Strategy strategy)
{
this.strategy = strategy;
} public void sort(List<Person> list)
{
this.strategy.sort(list);
}
}

最后是测试用的类

package com.zhouyu.strategy;

import java.util.ArrayList;
import java.util.List; public class Client
{
private Environment environment = new Environment(); public static void main(String[] args)
{
List<Person> list = new ArrayList<Person>();
list.add(new Person(1,"刘备",30));
list.add(new Person(2,"关羽",29));
list.add(new Person(3,"张飞",28));
list.add(new Person(4,"赵云",26)); Client client = new Client();
Environment environment = new Environment(); //按照Id正序排序
ForIdUp idUp = new ForIdUp();
client.print(idUp,list); //按照Id倒序排序
ForIdDown idDown = new ForIdDown();
client.print(idDown,list); //按照name正序排序
ForNameUp nameUp = new ForNameUp();
client.print(nameUp,list); //按照name倒序排序
ForNameDown nameDown = new ForNameDown();
client.print(nameDown,list); //按照age正序排序
ForAgeUp ageUp = new ForAgeUp();
client.print(ageUp,list); //按照age倒序排序
ForAgeDown ageDown = new ForAgeDown();
client.print(ageDown,list);
} public void print(Strategy strategy,List<Person> list)
{
environment.setStrategy(strategy);
environment.sort(list);
for(int i=0;i<list.size();i++)
{
Person person = list.get(i);
System.out.println("序号:"+ person.getId() + ",姓名:" + person.getName() + ",年龄:" +person.getAge());
}
System.out.println("--------------------------------------------------------------");
} }

写的不好,请大家多多指出错误。

不知道代码传到哪里,只好传到CSDN上了,有需要的自行下载

设计模式原来如此-策略模式(Strategy Pattern)的更多相关文章

  1. 乐在其中设计模式(C#) - 策略模式(Strategy Pattern)

    原文:乐在其中设计模式(C#) - 策略模式(Strategy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 策略模式(Strategy Pattern) 作者:webabc ...

  2. 反馈法学习设计模式(一)——策略模式Strategy Pattern

    简介(Introduction) 之前学习Java8实战时,遇到一个很好的策略模式示例.便想着借着这个示例结合反馈式的方法来,学习策略设计模式,也以便后面反复琢磨学习. 首先我们通过练习,逐步写出符合 ...

  3. 8.6 GOF设计模式四: 策略模式… Strategy Pattern

    策略模式… Strategy Pattern  在POS系统中,有时需要实行价格优惠, 该如何处理?  对普通客户或新客户报全价  对老客户统一折扣5%  对大客户统一折扣10%  注:课件 ...

  4. 二十四种设计模式:策略模式(Strategy Pattern)

    策略模式(Strategy Pattern) 介绍定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法的变化可独立于使用它的客户. 示例有一个Message实体类,对它的操作有 ...

  5. 【UE4 设计模式】策略模式 Strategy Pattern

    概述 描述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法的变化不会影响到使用算法的客户. 套路 Context(环境类) 负责使用算法策略,其中维持了一 ...

  6. 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)

    在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了“工厂模式”.“策略模式”.“状态模式”等.当然在重构时,有的地 ...

  7. 设计模式 - 策略模式(Strategy Pattern) 具体解释

    策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全 ...

  8. HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern)

    策略模式(Strategy Pattern): 定义了了算法簇,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户端. 第一个设计原则:找出应用中可能需要变化之处,把他们独立 ...

  9. JAVA设计模式之策略模式 - Strategy

    在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 ...

随机推荐

  1. linux的一些权限的操作 chmod

    u ---属主 g ---用户组 o ---其他组 + ----赋予权限 - ----取消权限 = ----赋予权限并取消以前的权限 r = 4   //读 w =2   //写 x =1   //执 ...

  2. 采用Atlas+Keepalived实现MySQL读写分离、读负载均衡

    ========================================================================================== 一.基础介绍 == ...

  3. graph-SCC

    strongly connected component(SCC): 里面的任一对顶点都是互相可达的. 一个有向图,将每个SCC缩成一个点,那么这个图就变成了DAG(有向无环图). 原图进行DFS之后 ...

  4. Python之code对象与pyc文件(一)

    Python程序的执行过程 我们都知道,C语言在执行之前需要将源代码编译成可执行的二进制文件,也就是将源代码翻译成机器代码,这种二进制文件一旦生成,即可用于执行.但是,Python是否一样呢?或许很多 ...

  5. luogu3193 [HNOI2008]GT考试

    there #include <iostream> #include <cstdio> using namespace std; int n, m, mod, nxt[25], ...

  6. luogu3178 [HAOI2015]树上操作

    裸题 #include <iostream> #include <cstdio> using namespace std; typedef long long ll; int ...

  7. 如何打造一个"逼格"的web前端项目

    最近利用空余的时间(坐公交车看教程视频),重新了解了前后端分离,前端工程化等概念学习,思考如何打造一个“逼格”的web前端项目. 前端准备篇 前端代码规范:制定前端开发代码规范文档. PS:重中之中, ...

  8. python week08 并发编程之多线程--实践部分

    一. threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 官网链接:https://docs.pytho ...

  9. Python 开启线程的2中方式,线程VS进程(守护线程、互斥锁)

    知识点一: 进程:资源单位 线程:才是CPU的执行单位 进程的运行: 开一个进程就意味着开一个内存空间,存数据用,产生的数据往里面丢 线程的运行: 代码的运行过程就相当于运行了一个线程 辅助理解:一座 ...

  10. [python学习篇][廖雪峰][2]函数式编程

    函数名也是变量: >>> f = abs >>> f(-10) 10 然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就 ...