设计模式----策略模式

一.策略模式定义

策略模式是指定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户,可以避免多重分支的if…else和switch语句

二.策略模式的应用场景

1.假如系统中有很多类,而他们的区别仅仅在于他们的行为不同.
2.一个系统需要动态地在几种算法中选择一种.

三.策略模式的优点

1.符合开闭原则
2.避免使用多重条件转移语句,如if…else…语句,switch语句
3.使用策略模式可以提高算法的保密性和安全性

四.策略模式的缺点

1.客户端必须知道所有的策略,并且自行决定使用哪一个策略类
2.代码中会产生非常多的策略类,增加维护难度

五.策略模式在jdk源码中的体现

1.Comparator接口中的compare()方法就是一个策略抽象实现

public interface Comparator<T> { int compare(T o1, T o2); ... }

Comparator抽象类下面有非常多的实现类,我们经常会把Comparator作为参数传入作为排序策略,例如Arrays类的parallelSort方法等

public class Arrays { 
... public static <T> void parallelSort(T[] a, int fromIndex, int toIndex, Comparator<? super T> cmp) { 
... 
}
... 
}

还有TreeMap的构造方法

 public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }

六.策略模式在Spring源码中的应用

1.Resource类

  public interface Resource extends InputStreamSource {
            boolean exists();

            default boolean isReadable() {
                return true;
            }

            default boolean isOpen() {
                return false;
            }

            default boolean isFile() {
                return false;
            }

            URL getURL() throws IOException;

            URI getURI() throws IOException;

            File getFile() throws IOException;

            default ReadableByteChannel readableChannel() throws IOException {
                return Channels.newChannel(this.getInputStream());
            }

            long contentLength() throws IOException;

            long lastModified() throws IOException;

            Resource createRelative(String var1) throws IOException;

            @Nullable
            String getFilename();

            String getDescription();
        }

我们虽然没有直接使用 Resource 类,但是我们经常使用它的子类,例如:
在这里插入图片描述

2.Spring的初始化,不同的类型的类采用不 同的初始化策略

首先有一个 InstantiationStrategy 接口,我们来看一下源码:

  public interface InstantiationStrategy {
            Object instantiate(RootBeanDefinition var1, @Nullable String var2, BeanFactory var3) throws BeansException;

            Object instantiate(RootBeanDefinition var1, @Nullable String var2, BeanFactory var3, Constructor<?> var4, @Nullable Object... var5) throws BeansException;

            Object instantiate(RootBeanDefinition var1, @Nullable String var2, BeanFactory var3, @Nullable Object var4, Method var5, @Nullable Object... var6) throws BeansException;
        }

顶层的策略抽象非常简单,但是它下面有两种策略 SimpleInstantiationStrategy 和 CglibSubclassingInstantiationStrategy,我们看一下类图:
在这里插入图片描述
打开类图我们还发现 CglibSubclassingInstantiationStrategy 策略类还继承了 SimpleInstantiationStrategy 类,说明在实际应用中多种策略之间还可以继承使用

二.代码实现思路

总体思路:

有这么一个场景,一个商场要做活动,活动有很多种策略,例如返优惠券策略,返现策略,送赠品策略,那我们就可以采用单例模式创建一个策略工厂,这个工厂里拥有一个策略的map,在静态代码块中初始化这个map,并提供一个根据key获取策略的方法,接着创建一个活动类.这个活动类中拥有一个策略接口的引用,利用构造方法传入,并在execute()方法中调用策略,在测试类中,创建一个活动类,传入对应的策略的key即可
再来一个场景,在支付过程中,我们可以选择用微信支付,支付宝支付,银联支付,京东支付等等,如果用户没有选择支付方式,那也会有一个默认的支付方式,实现思路如下:
1)创建一个支付的抽象类,定义每种支付方式的规范
2)创建各种支付方式,继承支付的抽象类
3)创建一个支付方式的管理类,里面拥有一个map,以及每个key的常量,在static中将所有的支付方式put进去
4)创建一个订单order类,在订单类中,拥有两个方法,一个是带参的pay(),一个是不带参的pay(),在带参的方法中,利用传入的payKey去支付方式管理类中获取对应的支付方式,在不带参的方法中采用默认的key去支付方式管理类中获取支付方式
5)测试

public class PayStrategyTest {
    public static void main(String[] args) {
        Order order = new Order("1","20180311001000009",324.45);
        PayState pay = order.pay(PayStrategy.JD_PAY);
        System.out.println(pay);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值