设计模式学习

看破设计模式之策略模式(strategy)

2018-12-12  本文已影响0人  松松木tell

一、策略模式概述

模式定义: 定义算法族,分别封装一起,让它们可以相互替换;此模式让算法的变化独立于使用它的客户
使用场景: 针对一个问题有多种解决方法,而区别仅仅在于算法(行为)不同
模式结构:
1.抽象策略类
定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
2.具体策略类
实现了抽象策略定义的接口,提供具体的算法实现。
3.环境类
持有一个抽象策略类的引用,最终给客户端调用。

UML图:

image.png

二、标准策略代码实现

/**
 * 抽象策略类
 */
public interface IStrategy {
    int calculate(int num1, int num2);
}

/**
 * 具体实现类A
 */
public class AddStrategy implements IStrategy {
    @Override
    public int calculate(int num1, int num2) {
        System.out.println("加法");
        return num1 + num2;
    }
}
/**
 * 具体实现类B
 */
public class MinusStrategy implements IStrategy {
    @Override
    public int calculate(int num1, int num2) {
        System.out.println("减法");
        return num1 - num2;
    }
}
/**
 * 环境类(持有策略抽象类)
 */
public class Context {
    private IStrategy cal;

    public Context(IStrategy cal) {
        this.cal = cal;
    }
    public int excuteCalculate(int num1, int num2) {
        return cal.calculate(num1, num2);
    }
}

测试结果

public class ClientMain {
    public static void main(String[] args) {
        Context context = new Context(new AddStrategy());
        int result = context.excuteCalculate(30, 20);
        System.out.println(result);
    }
}

三、模式理解重点

策略模式的重心不是如何实现算法,而是如何组织这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。
判断是不是策略模式,只要看一个类里是否持有了抽象对象的关联或者依赖,且当客户使用这个类使用实例化了这个属性。

四、策略模式java用例

1.Comparator的使用

java中比较的使用就是典型的策略模式,我们实例化了Comparator(抽象策略类)接口传递给TreeSet(环境类)。

        TreeSet<Person> treeSet=new TreeSet<>(new Comparator<Person>(){
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge()-o2.getAge();
            }
        });

查看源码可以发现TreeSet间接持有了Comparator对象

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{
    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }
}

public class TreeMap<K,V> extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{
    private final Comparator<? super K> comparator;
    public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }
}

2.Arrays.sort()中Comparator的使用

        Arrays.sort(null, new Comparator<Person>() {
            @Override
             public int compare(Person o1, Person o2) {
                return o1.getAge()-o2.getAge();
            }
        });

查看源码可以发现Arrays虽然没有持有Comparator对象,而是通过静态方法执行,但是思想上还是使用策略模式

public static <T> void sort(T[] a, Comparator<? super T> c) {
        if (c == null) {
            sort(a);
        } else {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a, c);
            else
                TimSort.sort(a, 0, a.length, c, null, 0, 0);
        }
    }

五、变通

根据实际使用策略模式也并非一成不变,只要是使用了策略思想都可以归为该模式;下面这种方式是环境类持有抽象类的依赖。

/**
 * 环境类(持有策略抽象类)
 */
public class Context {
    public static int excuteCal(IStrategy cal,int num1,int num2){
        return cal.calculate(num1,num2);
    }
}
**测试结果**
public class ClientMain {
    public static void main(String[] args) {
        int result = Context.excuteCal(new AddStrategy(),30,20);
        System.out.println(result);
    }
}

//TODO

六、心得参考

http://c.biancheng.net/view/1378.html
https://blog.csdn.net/u012124438/article/details/70039943/
HeadFirst设计模式

上一篇 下一篇

猜你喜欢

热点阅读