美文网首页
设计模式之策略模式(strategy)

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

作者: Insecurity | 来源:发表于2021-01-23 19:23 被阅读0次

    基础概念

    -定义:按套路先解释一下什么是策略模式:一个类的行为,能够在运行时,被更改,是行为模式的一种.(直接传传递一个对象不就好了)
    -场景: 排序工具类, 需要对任何对象进行排序,需要对任何对象进行比较.但有一个前提,你不能改变sort方法本身(设计原则:开闭原则)
    -实现方式:按功能,设计接口, Comparator ,定义了compare方法. (PS单方法体接口,可以用lambda表达式),定义ComparatorImpl 实现compare 接口,一种策略一种比较方式.在sort方法中,传入 Comparator 对象即可.这样就可以实现不改变sort本身,来实现增加策略的方式.
    -目的:思考这个问题,很简单,如果不用这种方式,你需要做到针对各种策略,按身高排序的sort1 按体重排序的sort2,破坏了原来色sort类.(目的只有一个,横向扩展,而不是垂直式的修改)

    源码应用

    • Comparator(比较器)
    int compare(T o1, T o2);
    
    • spring Resource ,Spring 会针对不同的底层资源,提供不同的 Resource 实现类
    * @see WritableResource
    * @see ContextResource
    * @see UrlResource
    * @see FileUrlResource
    * @see FileSystemResource
    * @see ClassPathResource
    * @see ByteArrayResource
    * @see InputStreamResource
    public interface Resource extends InputStreamSource {
        boolean exists();
        default boolean isReadable() {
            return exists();
        }
        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(getInputStream());
        }
        long contentLength() throws IOException;
       
        long lastModified() throws IOException;
       
        Resource createRelative(String relativePath) throws IOException;
       
        @Nullable
        String getFilename();
        String getDescription();
    }
    
    • InstantiationStrategy 负责使用 Bean 类的默认构造函数、带参构造函数或者工厂方法等来实例化 Bean,是一个策略模式的接口。InstantiationStrategy 接口源码如下。
    public interface InstantiationStrategy {
        Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
                throws BeansException;
        Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
                Constructor<?> ctor, Object... args) throws BeansException;
        Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
                @Nullable Object factoryBean, Method factoryMethod, Object... args)
                throws BeansException;
    }
    

    模式核心

    1. 对象:client(sort类) , N策略对象以及其对应的接口
    2. 组装方式, 可以直接以属性注入,也可以以方法参数传入.这种方式,就是直接以静态属性的方式注入.(可以对比一下comparable ,comparable只能固定一种实现,毕竟 是以接口实现方式,无法做到不同的实现.)
       private static Comparator YXTopComparator = new Comparator() {
            public int compare(Object var1, Object var2) {
                Curve var3 = ((Edge)var1).getCurve();
                Curve var4 = ((Edge)var2).getCurve();
                double var5;
                double var7;
                if ((var5 = var3.getYTop()) == (var7 = var4.getYTop()) && (var5 = var3.getXTop()) == (var7 = var4.getXTop())) {
                    return 0;
                } else {
                    return var5 < var7 ? -1 : 1;
                }
            }
        };
    

    3.优化了哪种代码?业务场景如下(优化if,else),这种写法的问题,如果业务有变化,需要增加 e,f,g 甚至更多的类型,每次都需要去更改调用类(这种方式是特别不友好的,),因此需要抽象一个策略接口,去做实体类,横向扩展,即可

     //根据类型不同,调用不同的物流接口(比如说顺丰,申通等等)
    if (type == "a") {
           
    } else if (type=="b") {
          
    } else  if (type=="c"){
            
    }
    //优化,抽象物流策略接口
    public interface ShipStrategy{
    //发运接口
    void ship();
    }
    
    //顺丰物流发运,策略实现类
    public class SFShipStrategy implement ShipStrategy {
    //发运接口
      void ship(){
      //发运
      .....
      }
    }
    
    //客户端调用(调用问题解决了,如何解决对象构造的if -else? ,根据 type = a  构建  a的策略)
    
    shipStrategy.ship();
    
    //1.维护 type 和class的映射关系. 2.通过spring获取策略对象(原理是反射.)
    Enum ShipType{
    SF("SF", "com.dzq.ship.SFShipStrategy "), ADD("ST",  "com.dzq.shipSTShipStrategy");
    }
    
    
    //2.通过反射获取到到对象
    Class.forName(clazz).newInstance()
    .....
    
    image.png

    相关文章

      网友评论

          本文标题:设计模式之策略模式(strategy)

          本文链接:https://www.haomeiwen.com/subject/xvyuzktx.html