策略模式(Strategy Pattern)中体现了两个非常基本的面向对象设计的原则
–封装变化的概念
–编程中使用接口,而不是对接口的实现
策略模式的定义
–定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
–策略模式使这些算法在客户端调用它们的时候能够互不影响地变化
策略模式的编写步骤
–1.对策略对象定义一个公共接口。
–2.编写策略类,该类实现了上面的公共接口
–3.在使用策略对象的类中保存一个对策略对
象的引用。
–4.在使用策略对象的类中,实现对策略对象
的set和get方法(注入)或者使用构造方法完
成赋值
方案
把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就可以随意调用实现了这个接口的类的行为。
比如定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换,使得算法可独立于使用它的客户而变化。这就是策略模式。
适用情况
许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。
当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。
一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
优点
1、可以动态的改变对象的行为
缺点
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类
2、策略模式将造成产生很多策略类
组成
环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。
具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。
应用
场景如下,刘备要到江东娶老婆了,走之前诸葛亮给赵云三个锦囊妙计,说是按天机拆开能解决棘手问题。场景中出现三个要素:三个妙计(具体策略类)、一个锦囊(环境类)、赵云(调用者)。
代码如下 | 复制代码 |
抽象策略类(Strategy) public interface Strategy { public void operate(); } 三个实现类(ConcreteStrategy): |
例子
在使用图像处理软件处理图片后,需要选择一种格式进行保存。然而各种格式在底层实现的算法并不相同,这刚好适合策略模式。编写程序,演示如何使用策略模式与简单工厂模式组合进行开发
思路如下:
使用interface来定义一个接口,在该接口中定义save()方法;
根据图片格式定义不同的类,分别在这些类中使用关键字implements实现接口;
创建一个实现选择的类,在该类中定义实现选择的方法,该方法返回值为对应的图片保存类;
在主方法中实现接口。
代码如下:
代码如下 | 复制代码 |
public interface ImageSaver { void save();//定义save()方法 } public class GIFSaver implements ImageSaver { public class JPEGSaver implements ImageSaver { @Override public class PNGSaver implements ImageSaver { @Override } public class TypeChooser { public class User { |
java排序策略模式实现:
有这样一个类:
代码如下 | 复制代码 |
public class Person { private int id; private String name; private int age; } |
要求:假如有若干个类Person对象存在一个List当中,对他们进行排序,分别按照名字、
年龄、id 进行排序(要有正序与倒序两种排序方式)。假如年龄或者姓名重复,按照id的正序进行排序。
以下为实现源代码。
代码如下 | 复制代码 |
类Person package com.jack.SortStrategy; public class Person { package com.jack.SortStrategy; import java.util.Comparator; public class IdOrder implements Comparator<Person> { @Override } package com.jack.SortStrategy; import java.util.Comparator; public class IdReverseOrder implements Comparator<Person> { package com.jack.SortStrategy; import java.util.Comparator; public class AgeOrder implements Comparator<Person> { @Override package com.jack.SortStrategy; import java.util.Comparator; public class AgeReverseOrder implements Comparator<Person> { package com.jack.SortStrategy; import java.util.Comparator; public class NameOrder implements Comparator<Person> { @Override package com.jack.SortStrategy; import java.util.Comparator; public class NameReverseOrder implements Comparator<Person> { package com.jack.SortStrategy; import java.util.ArrayList; public class Client { /** Collections.sort(personList, comp); System.out.println(((IdOrder)comp).getMethodName()+" 排序后的序列是:"); for (Iterator<Person> itor=personList.iterator();itor.hasNext();) { } } |
执行Client可以得到排序的结果