【策略模式-strategy】
来源:互联网 发布:网络连接错误代码118 编辑:程序博客网 时间:2024/05/23 19:02
1:定义:
在《head first Design Pattern》中的定义是:策略模式定义了算法族,分别分装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
2:设计原则
1) 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
2) 针对接口编程,而不是针对实现编程。
3) 多用组合,少用继承。
3策略模式的编写步骤
1) 对策略对象定义一个公共接口。
2) 编写策略类,该类实现了上面的公共接口。
3) 在使用策略对象的类中保存一个对策略对象的引用。
4) 在使用策略对象的类中,实现对策略对象的set和get方法(注入)或者使用构造方法完成赋值。
4,实际例子:
《head first <span lang="EN-US" style="" font-size:10.5pt;"="">Design Pattern》的例子(简化后):模拟一个鸭子游戏,游戏中有三种鸭子(绿头鸭MallardDuck, 红头鸭RedheadDuck,橡皮鸭RubberDuck,诱饵鸭DecoyDuck),鸭子们都会游泳,外表各不相同,同类型鸭子叫声相同,绿头鸭和红头鸭会飞会叫,橡皮鸭不会飞但会叫,诱饵鸭不会飞不会叫,请设计这个游戏。1,我们可能这么设计:
该设计的缺陷是:绿头鸭和红头鸭叫声相同,但是quack()却无法复用,如果该行为要修改,那么修改该行为非常麻烦,你必须得往下追踪并在每一个定义此行为的类中修改它,这将是可怕的。
解决方法:分开变化的与不会变化的部分;体现(设计原则1)Duck类内的fly()和quack()会随着鸭子的不同而改变,将这两个行为从Duck类中分开,形成“算法族”。整体类结构如下所示:详细代码:飞行的接口:
- interface FlyBehavior{
- public void fly();
- }
两个飞行类的实现:
- class FlyWithwings implements FlyBehavior{
- public void fly(){
- System.out.println("can fly");
- }
- }
- class FlyNoWay implements FlyBehavior{
- public void fly(){
- System.out.println("can not fly");
- }
- }
叫声的接口:
- interface QuackBehavior{
- public void quack();
- }
三个叫声行为的实现:
- class Quack implements QuackBehavior{
- public void quack(){
- System.out.println("guagua");
- }
- }
- class Squeak implements QuackBehavior{
- public void quack(){
- System.out.println("zhizhi");
- }
- }
- class MuteQuack implements QuackBehavior{
- public void quack(){
- System.out.println("can not fly");
- }
- }
鸭子的基类:
- abstract class Duck {
- FlyBehavior flyBehavior;
- QuackBehavior quackBehavior;
- public abstract void display();
- public void performFly(){
- flyBehavior.fly();
- }
- public void performQuack(){
- quackBehavior.quack();
- }
- public void swim(){
- System.out.println("All ducks can swim");
- }
- }
在java的 Comparator使用的就是该设计模式,就是不改变对象本身,而是用一个策略对象改变它的行为;以下模拟下它的实现过程。题目:人有年龄和身高两种属性,现在要对不同的人排序,可以按年龄也可以按身高。
人物类定义:
- class perSon {
- int Age;
- int weigth;
- perSon(int Age, int weigth) {
- this.Age = Age;
- this.weigth = weigth;
- }
- public void printinfo(){
- System.out.println("age:"+Age+" weight:"+ weigth);
- }
- }
MyComparator接口:
- interface MyComparator<T> {
- public int compare(T o1, T o2);
- }
接下来是两种比较策略,继承了接口MyComparator
- class perSonSortWithweigth implements MyComparator<perSon> {
- @Override
- public int compare(perSon o1, perSon o2) {
- // TODO Auto-generated method stub
- // TODO Auto-generated method stub
- if (o1.weigth > o2.weigth) {
- return 1;
- } else if (o1.weigth == o2.weigth) {
- return 0;
- } else {
- return -1;
- }
- }
- }
- class perSonSortWithAge implements MyComparator<perSon> {
- @Override
- public int compare(perSon o1, perSon o2) {
- // TODO Auto-generated method stub
- if (o1.Age > o2.Age) {
- return 1;
- } else if (o1.Age == o2.Age) {
- return 0;
- } else {
- return -1;
- }
- }
- }
接下来模拟arrays类(api中的arrays要复杂的多);
- class myArrays {
- public static <T> void sort(T[] arr, MyComparator<? super T> c) {
- T temp;
- // 简单的冒泡排序
- // 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- // 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。最后的元素应该会是最大的数。
- // 针对所有的元素重复以上的步骤,除了最后一个。
- for (int i = 0; i < arr.length - 1; i++) {
- for (int j = 0; j < arr.length - i - 1; j++) {
- if (c.compare(arr[j + 1], arr[j]) >= 0) {
- temp = arr[j];
- arr[j] = arr[j + 1];
- arr[j + 1] = temp;
- }
- }
- }
- }
- }
测试如下:
- public class test {
- public static void main(String[] args) {
- perSon[] persons=new perSon[]{new perSon(1,2),new perSon(2,3),new perSon(3,0)};
- myArrays.sort(persons,new perSonSortWithAge());
- for(int i=0;i<persons.length;i++){
- persons[i].printinfo();
- }
- myArrays.sort(persons, new perSonSortWithweigth());
- for(int i=0;i<persons.length;i++){
- persons[i].printinfo();
- }
- }
- }
既然提到了Comparator,那么顺便介绍下Comparable接口吧;对于上边的题目,如果用Comparable接口该这么实现:MyComparable接口定义如下:
- interface MyComparable<T> {
- int compareTo(T o);
- }
人物类继承接口:
- class person implements MyComparable {
- int Age;
- int weigth;
- person(int Age, int weigth) {
- this.Age = Age;
- this.weigth = weigth;
- }
- public void printinfo() {
- System.out.println("age:" + Age + " weight:" + weigth);
- }
- @Override
- public int compareTo(Object o) {
- // TODO Auto-generated method stub
- if(Age > ((person)o).Age){
- return 1;
- }else if(Age == ((person)o).Age){
- return 0;
- }else{
- return -1;
- }
- }
- }
类arrays
- class MyArrays{
- public static void sort(Object[] arr){
- Object temp;
- for (int i = 0; i < arr.length - 1; i++) {
- for (int j = 0; j < arr.length - i - 1; j++) {
- if (((MyComparable)arr[j + 1]).compareTo(arr[j]) >= 0) {
- temp = arr[j];
- arr[j] = arr[j + 1];
- arr[j + 1] = temp;
- }
- }
- }
- }
- }
测试代码为:
- public class test1 {
- public static void main(String[] args) {
- person[] persons=new person[]{new person(1,2),new person(2,3),new person(3,0)};
- MyArrays.sort(persons);
- for(int i=0;i<persons.length;i++){
- persons[i].printinfo();
- }
- }
- }
那么他们的区别如下所示:Comparable 和 Comparator 都是用来实现集合中元素的比较、排序的。
只是 Comparable 是在集合内部定义的方法实现的排序,而Comparator 是在集合外部实现的排序,
所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。
Comparator位于包java.util下,而Comparable位于包 java.lang下
一.Comparable 是一个对象,本身就已经支持自比较所需要实现的接口(如 String、Integer 自己就可以完成比较大小操作,已经实现了Comparable接口)
自定义的类要在加入list容器中后能够排序,可以实现Comparable接口,在用Collections类的sort方法排序时,如果不指定Comparator,那么就以自然顺序排序,这里的自然顺序就是实现Comparable接口设定的排序方式。
二.Comparator 是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。
可以说一个是自已完成比较,一个是外部程序实现比较的差别而已。
- 策略模式 Strategy模式
- Strategy模式 策略模式
- 策略模式(Strategy模式)
- 策略模式(Strategy Pattern)
- Strategy策略模式
- 策略(Strategy)模式
- Strategy策略模式
- 策略(Strategy)模式
- 策略模式(Strategy Pattern)
- 策略模式 Strategy Pattern
- 策略模式(Strategy Pattern)
- 策略模式(Strategy)
- HeadFirst Strategy策略模式
- 策略模式(Strategy Pattern)
- Strategy Pattern (策略模式)
- 泛化策略模式(Strategy)
- Strategy 策略模式
- Strategy 策略模式
- PowerDesigner使用教程 —— 概念数据模型 (转)
- [哈希]PAT1039 Course List for Student
- linux下使用JMX监控tomcat
- 不习惯的时候就是成长的时候
- 为什么用CDC定义指针绘图,而不用对象
- 【策略模式-strategy】
- gcc -D:gcc的预定义功能
- 跟我一起写Makefile(四):书写命令
- JDK版本的发布时间表
- 设置中在fragment中启动fragment流程及log输出
- jQuery hover(over, out)事件函数
- Windows下完整下载Android源代码
- 一句话小结
- 胖子第二版