一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

java中策略模式深入分析及示例

时间:2016-07-13 编辑:简简单单 来源:一聚教程网

策略模式(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):
妙计一:初到吴国
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排序策略模式实现:

有这样一个类:

 代码如下 复制代码

public class Person {

private int id;

private String name;

private int age;

}

要求:假如有若干个类Person对象存在一个List当中,对他们进行排序,分别按照名字、

年龄、id 进行排序(要有正序与倒序两种排序方式)。假如年龄或者姓名重复,按照id的正序进行排序。

以下为实现源代码。

 代码如下 复制代码

类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 {

 @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 {
 
 @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 {


 @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 {
 
 @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 {

 @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 {
 @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 personList = new ArrayList();
  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 comp = new IdOrder();                       

  Collections.sort(personList, comp);

  System.out.println(((IdOrder)comp).getMethodName()+"  排序后的序列是:");
  
  System.out.println("-----------------------");

  for (Iterator itor=personList.iterator();itor.hasNext();) {
   
   Person p=itor.next();
   System.out.println(p.getId() + "  " +p.getName()+ "  " + p.getAge());
  }

 }

}

执行Client可以得到排序的结果

热门栏目