java中策略模式深入分析及示例
策略模式(Strategy Pattern)中体现了两个非常基本的面向对象设计的原则
–封装变化的概念
–编程中使用接口,而不是对接口的实现
策略模式的定义
–定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
–策略模式使这些算法在客户端调用它们的时候能够互不影响地变化
策略模式的编写步骤
–1.对策略对象定义一个公共接口。
–2.编写策略类,该类实现了上面的公共接口
–3.在使用策略对象的类中保存一个对策略对
象的引用。
–4.在使用策略对象的类中,实现对策略对象
的set和get方法(注入)或者使用构造方法完
成赋值
方案
把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就可以随意调用实现了这个接口的类的行为。
比如定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换,使得算法可独立于使用它的客户而变化。这就是策略模式。
适用情况
许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。
当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。
一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
优点
1、可以动态的改变对象的行为
缺点
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类
2、策略模式将造成产生很多策略类
组成
环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。
具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。
应用
场景如下,刘备要到江东娶老婆了,走之前诸葛亮给赵云三个锦囊妙计,说是按天机拆开能解决棘手问题。场景中出现三个要素:三个妙计(具体策略类)、一个锦囊(环境类)、赵云(调用者)。
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy8703')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy8703>
抽象策略类(Strategy)
public interface Strategy {
public void operate();
}
三个实现类(ConcreteStrategy):
妙计一:初到吴国
public class BackDoor implements IStrategy {
@Override
public void operate() {
System.out.println("找乔国老帮忙,让吴国太给孙权施加压力,使孙权不能杀刘备");
}
}妙计二:求吴国太开绿灯放行
public class GivenGreenLight implements IStrategy {
@Override
public void operate() {
System.out.println("求吴国太开个绿灯,放行");
}
}妙计三:孙夫人断后,挡住追兵
public class BlackEnemy implements IStrategy {
@Override
public void operate() {
System.out.println("孙夫人断后,挡住追兵");
}
}
环境类(Context)
public class Context {
private Strategy strategy;
//构造函数,要你使用哪个妙计
public Context(Strategy strategy){
this.strategy = strategy;
}
public void setStrategy(Strategy strategy){
this.strategy = strategy;
}
public void operate(){
this.strategy.operate();
}
}
例子
在使用图像处理软件处理图片后,需要选择一种格式进行保存。然而各种格式在底层实现的算法并不相同,这刚好适合策略模式。编写程序,演示如何使用策略模式与简单工厂模式组合进行开发
思路如下:
使用interface来定义一个接口,在该接口中定义save()方法;
根据图片格式定义不同的类,分别在这些类中使用关键字implements实现接口;
创建一个实现选择的类,在该类中定义实现选择的方法,该方法返回值为对应的图片保存类;
在主方法中实现接口。
代码如下:
public interface ImageSaver {
void save();//定义save()方法
}
public class GIFSaver implements ImageSaver {
@Override
public void save() {//实现save()方法
System.out.println("将图片保存成GIF格式");
}
}
public class JPEGSaver implements ImageSaver {
@Override
public void save() {
System.out.println("将图片保存成JPG格式");
}
}
public class PNGSaver implements ImageSaver {
@Override
public void save() {
System.out.println("将图片保存成PNG格式");
}
}
public class TypeChooser {
public static ImageSaver getSaver(String type) {
if (type.equalsIgnoreCase("GIF")) {//使用if else语句来判断图片的类型
return new GIFSaver();
} else if (type.equalsIgnoreCase("JPEG")) {
return new JPEGSaver();
} else if (type.equalsIgnoreCase("PNG")) {
return new PNGSaver();
} else {
return null;
}
}
}
public class User {
public static void main(String[] args) {
System.out.print("用户选择了GIF格式:");
ImageSaver saver = TypeChooser.getSaver("GIF");//获得保存图片为GIF类型的对象
saver.save();
System.out.print("用户选择了JPEG格式:");//获得保存图片为JPEG类型的对象
saver = TypeChooser.getSaver("JPEG");
saver.save();
System.out.print("用户选择了PNG格式:");//获得保存图片为PNG类型的对象
saver = TypeChooser.getSaver("PNG");
saver.save();
}
}
java排序策略模式实现:
有这样一个类:
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy8499')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy8499>public class Person {
private int id;
private String name;
private int age;
}
</td></tr></table>要求:假如有若干个类Person对象存在一个List当中,对他们进行排序,分别按照名字、
年龄、id 进行排序(要有正序与倒序两种排序方式)。假如年龄或者姓名重复,按照id的正序进行排序。
以下为实现源代码。
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy2354')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy2354>类Person
package com.jack.SortStrategy;
public class Person {
private int id;
private String name;
private int age;
public Person(int id,String name,int age){
this.id=id;
this.age=age;
this.name=name;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
}
类IdOrder
package com.jack.SortStrategy;
import java.util.Comparator;
public class IdOrder implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
return o1.getId()-o2.getId();
}
public String getMethodName()
{
return "按id正序";
}
}
类IdReverseOrder
package com.jack.SortStrategy;
import java.util.Comparator;
public class IdReverseOrder implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
return o2.getId()-o1.getId();
}
public String getMethodName()
{
return "按id逆序";
}
}
类AgeOrder
package com.jack.SortStrategy;
import java.util.Comparator;
public class AgeOrder implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
int result=o1.getAge()-(o2.getAge());
if(0==result){ //若年龄相同按id排
return o1.getId()-o2.getId();
}
return result;
}
public String getMethodName()
{
return "按年龄正序";
}
}
类AgeReverseOrder
package com.jack.SortStrategy;
import java.util.Comparator;
public class AgeReverseOrder implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
int result=o2.getAge()-(o1.getAge());
if(0==result){ //若年龄相同按id排
return o1.getId()-o2.getId();
}
return result;
}
public String getMethodName()
{
return "按年龄逆序";
}
}
类NameOrder
package com.jack.SortStrategy;
import java.util.Comparator;
public class NameOrder implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
int result=o1.getName().compareTo(o2.getName());
if(0==result){ //若姓名相同按id排
return o1.getId()-o2.getId();
}
return result;
}
public String getMethodName()
{
return "按姓名正序";
}
}
类NameReverseOrder
package com.jack.SortStrategy;
import java.util.Comparator;
public class NameReverseOrder implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
int result=o2.getName().compareTo(o1.getName());
if(0==result){ //若姓名相同按id排
return o1.getId()-o2.getId();
}
return result;
}
public String getMethodName()
{
return "按姓名逆序";
}
}
类Client
package com.jack.SortStrategy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Person> personList = new ArrayList<Person>();
personList.add(new Person(1, "zhangsan", 20));
personList.add(new Person(2, "lisi", 21));
personList.add(new Person(3, "wangwu", 25));
personList.add(new Person(4, "zhaoliu", 26));
personList.add(new Person(5, "chenqi", 28));
personList.add(new Person(6, "dongba", 10));
personList.add(new Person(7, "zhansan", 15));
personList.add(new Person(8, "liujiu", 26));
/*
* 可通过这里new不同的Comparator的实现从而实现不同的排序策略
* 分别有
* IdOrder:按Id正序
* IdReverseOrder:按Id逆序
* NameOrder:按姓名正序
* NameReverseOrder:按姓名逆序
* AgeOrder:按年龄正序
* AgeReverseOrder:按年龄逆序
*/
Comparator<Person> comp = new IdOrder();
Collections.sort(personList, comp);
System.out.println(((IdOrder)comp).getMethodName() " 排序后的序列是:");
System.out.println("-----------------------");
for (Iterator<Person> itor=personList.iterator();itor.hasNext();) {
Person p=itor.next();
System.out.println(p.getId() " " p.getName() " " p.getAge());
}
}
}
</td></tr></table>执行Client可以得到排序的结果
您可能感兴趣的文章:
java中策略模式深入分析及示例
secedit.exe本地安全策略命令的使用方法
Java 框架 Netty 实现原理分析
python常用的几种设计模式是什么
学php看什么书
什么是MVC模式
各版本MySQL并行复制的实现及优缺点
seo基础入门
PHP设计模式概述
玩Google有妙法:使用技巧十九招