下面讲解策略模式:
策略模式(Strategy Pattern)中体现了两个非常基本的面向面向对象涉及的原则:
--封装变化的概念
--编程中使用接口,而不是对接口的实现
策略模式的定义:
--定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
--策略模式使这些算法在客户端调用它们的时候能够互不影响地变化
策略模式的组成:
--抽象策略角色:策略类,通常由一个接口或者抽象类实现(例如Comporator接口)
--具体策略角色:包装了相关的算法和行为(例如Comporator接口的实现类)
--环境角色:持有策略类的引用,最终给客户端调用的(例如TreeSet或TreeMap,构造方法中接收了Comporator实现类的对象的一个引用)
策略模式的实现:
--策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口独立的类中,从而使得它们可以互相替换。
--策略模式使得算可以在不影响到客户端的情况下发生变化。使用策略模式可以把行为和环境分割开来。
--环境类负责维持和查询行为类,各种算法则在具体策略中提供。由于算法和环境独立开来,算法的修改都不会影响环境和客户端。
策略模式的编写步骤:
1、对策略对象定义一个公共接口。
2、编写策略类,该类实现了上面的公共接口
3、在使用策略对象的类中保存一个对策略对象的引用。
4、在使用策略对象的类中,实现对策略对象的set和get方法(注入)或者使用构造方法完成赋值。
策略模式的缺点:
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
2、造成很多的策略类。
解决上述问题的方法是:采用工厂方法(这个现在还不讲)
以下是示例代码:
最后留的一个用策略模式实现的作业(此作业进行了详细讲解,同时自己也做出来了,经常回忆性的看看):
1. 有这样一个类:
public class Person {
private int id;
private String name;
private int age;
}
// getter and setter
要求:假如有若干个类Person对象存在一个List当中,对他们进行排序,分别按照名字、
年龄、id 进行排序(要有正序与倒序两种排序方式)。假如年龄或者姓名重复,按照id
的正序进行排序。要求使用策略模式进行。
作业答案见附件
策略模式(Strategy Pattern)中体现了两个非常基本的面向面向对象涉及的原则:
--封装变化的概念
--编程中使用接口,而不是对接口的实现
策略模式的定义:
--定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
--策略模式使这些算法在客户端调用它们的时候能够互不影响地变化
策略模式的组成:
--抽象策略角色:策略类,通常由一个接口或者抽象类实现(例如Comporator接口)
--具体策略角色:包装了相关的算法和行为(例如Comporator接口的实现类)
--环境角色:持有策略类的引用,最终给客户端调用的(例如TreeSet或TreeMap,构造方法中接收了Comporator实现类的对象的一个引用)
策略模式的实现:
--策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口独立的类中,从而使得它们可以互相替换。
--策略模式使得算可以在不影响到客户端的情况下发生变化。使用策略模式可以把行为和环境分割开来。
--环境类负责维持和查询行为类,各种算法则在具体策略中提供。由于算法和环境独立开来,算法的修改都不会影响环境和客户端。
策略模式的编写步骤:
1、对策略对象定义一个公共接口。
2、编写策略类,该类实现了上面的公共接口
3、在使用策略对象的类中保存一个对策略对象的引用。
4、在使用策略对象的类中,实现对策略对象的set和get方法(注入)或者使用构造方法完成赋值。
策略模式的缺点:
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
2、造成很多的策略类。
解决上述问题的方法是:采用工厂方法(这个现在还不讲)
以下是示例代码:
package com.shengshiyuan;
/**
* 抽象策略角色
* 类: Strategy <br>
* 描述: TODO <br>
* 作者: fangguanhong fangguanhong@163.com <br>
* 时间: Oct 17, 2013 11:30:24 AM
*/
public interface Strategy {
/**
* 完成两个整型数字的运算(加、减、乘、除)
* 方法: calculate <br>
* 描述: TODO <br>
* 作者: fangguanhong fangguanhong@163.com <br>
* 时间: Oct 17, 2013 11:30:35 AM
* @param a
* @param b
* @return
*/
public int calculate(int a, int b);
}
package com.shengshiyuan;
/**
* 具体策略角色
* 类: AddStrategy <br>
* 描述: TODO <br>
* 作者: fangguanhong fangguanhong@163.com <br>
* 时间: Oct 17, 2013 11:32:11 AM
*/
public class AddStrategy implements Strategy {
/**
* 完成假发操作
* 方法: calculate <br>
* 描述: TODO
* @param a
* @param b
* @return
* @see com.shengshiyuan.Strategy#calculate(int, int)
*/
public int calculate(int a, int b) {
return a + b;
}
}
package com.shengshiyuan;
/**
* 具体策略角色
* 类: SubtractStrategy <br>
* 描述: TODO <br>
* 作者: fangguanhong fangguanhong@163.com <br>
* 时间: Oct 17, 2013 11:33:30 AM
*/
public class SubtractStrategy implements Strategy {
/**
* 完成减法操作
* 方法: calculate <br>
* 描述: TODO
* @param a
* @param b
* @return
* @see com.shengshiyuan.Strategy#calculate(int, int)
*/
public int calculate(int a, int b) {
return a - b;
}
}
package com.shengshiyuan;
/**
* 具体策略类
* 类: MultiplyStrategy <br>
* 描述: TODO <br>
* 作者: fangguanhong fangguanhong@163.com <br>
* 时间: Oct 17, 2013 11:34:55 AM
*/
public class MultiplyStrategy implements Strategy {
/**
* 完成乘法操作
* 方法: calculate <br>
* 描述: TODO
* @param a
* @param b
* @return
* @see com.shengshiyuan.Strategy#calculate(int, int)
*/
public int calculate(int a, int b) {
return a * b;
}
}
package com.shengshiyuan;
/**
* 具体策略角色
* 类: DivideStrategy <br>
* 描述: TODO <br>
* 作者: fangguanhong fangguanhong@163.com <br>
* 时间: Oct 17, 2013 11:35:41 AM
*/
public class DivideStrategy implements Strategy {
/**
* 完成除法操作
* 方法: calculate <br>
* 描述: TODO
* @param a
* @param b
* @return
* @see com.shengshiyuan.Strategy#calculate(int, int)
*/
public int calculate(int a, int b) {
return a / b;
}
}
package com.shengshiyuan;
/**
* 环境角色
* 类: Environment <br>
* 描述: TODO <br>
* 作者: fangguanhong fangguanhong@163.com <br>
* 时间: Oct 17, 2013 11:37:24 AM
*/
public class Environment {
private Strategy strategy;
/**
* 在构造方法中初始化策略类的引用
* 标题: 构造器 <br>
* 描述: TODO <br>
* 作者: fangguanhong fangguanhong@163.com <br>
* 时间: Oct 17, 2013 11:49:35 AM
* @param strategy
*/
public Environment(Strategy strategy) {
this.strategy = strategy;
}
public int calculate(int a, int b) {
return strategy.calculate(a, b);
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public Strategy getStrategy() {
return this.strategy;
}
}
package com.shengshiyuan;
public class Client {
public static void main(String[] args) {
AddStrategy addStrategy = new AddStrategy();
// 加
Environment environment = new Environment(addStrategy);
System.out.println(environment.calculate(3, 4));
// 减
SubtractStrategy subtractStrategy = new SubtractStrategy();
environment.setStrategy(subtractStrategy);
System.out.println(environment.calculate(3, 4));
// 乘
MultiplyStrategy multiplyStrategy = new MultiplyStrategy();
environment.setStrategy(multiplyStrategy);
System.out.println(environment.calculate(3, 4));
// 除
DivideStrategy divideStrategy = new DivideStrategy();
environment.setStrategy(divideStrategy);
System.out.println(environment.calculate(3, 4));
}
}
最后留的一个用策略模式实现的作业(此作业进行了详细讲解,同时自己也做出来了,经常回忆性的看看):
1. 有这样一个类:
public class Person {
private int id;
private String name;
private int age;
}
// getter and setter
要求:假如有若干个类Person对象存在一个List当中,对他们进行排序,分别按照名字、
年龄、id 进行排序(要有正序与倒序两种排序方式)。假如年龄或者姓名重复,按照id
的正序进行排序。要求使用策略模式进行。
作业答案见附件