zoukankan      html  css  js  c++  java
  • 设计模式之策略模式

    1. 策略模式的作用

      在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。

    2. 为什么要使用策略模式?

      我们想象一下最常见的场景:排序。排序无非两种选择,升序或降序。如果我们要封装一个类要自由的切换两种排序要怎么做呢?

      最常见的做法是这样的:

       

    public class Demo {
        public void sort(boolean asc) { 
            if (asc) {   //判断是否要升序
                //实现升序的算法
            } else {
                //实现降序的算法
            }
        }
    }

      

      我们可以发现这要的代码极不美观,而且这还是只有两种情况的时候,加入有N中情况那岂不是要写很多的判断。甚至可能大多数时候我们并不能提前想好所有的类型,如果临时要加入新的算法只能再次修改原来的代码。维护很困难。这时候我们就可以使用策略模式来实现。

    3. 怎么使用策略模式?

      以上述排序为例,在java中我们需要实现自己的比较器。

      

    public static void main(String[] args) {
            List<Integer> list = new ArrayList<>();
            Collections.sort(list, new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o1 - o2;
                }
            });
        }

      如此,当我们在需要定义新的排序规则(因为排序的对象可能是多种多样的),当我们需要一个新的规则时,我们不需要去修改Collections.sort()方法的内容,而是实现一个自己的比较器,这样就可以实现新的排序。

    4. 分析一下策略模式是怎么构成的?

      我们同样以上述排序为例:

      (1)策略接口

    @FunctionalInterface
    public interface Comparator<T> {  这是策略接口

    int compare(T o1, T o2); 这是实现不同策略的接口函数


      (2)不同的实现

    class MyComparator4Integer implements Comparator{   //为了比较Integer类型而实现的类
    
        @Override
        public int compare(Object o1, Object o2) {
            return 0;
        }
    }


    class MyComparator4String implements Comparator{ //为了比较String类型而实现的类

    @Override
    public int compare(Object o1, Object o2) {
    return 0;
    }
    }
     

      (3)调用者中(其中一个

    private static <T> void binarySort(T[] a, int lo, int hi, int start,
                                           Comparator<? super T> c) {
            assert lo <= start && start <= hi;
            if (start == lo)
                start++;
            for ( ; start < hi; start++) {
                T pivot = a[start];
    
                // Set left (and right) to the index where a[start] (pivot) belongs
                int left = lo;
                int right = start;
                assert left <= right;
                /*
                 * Invariants:
                 *   pivot >= all in [lo, left).
                 *   pivot <  all in [right, start).
                 */
                while (left < right) {
                    int mid = (left + right) >>> 1;
                    if (c.compare(pivot, a[mid]) < 0)   //在调用者中会调用策略函数,当传入的比较器不同时,比较的规则也会随之改变
                        right = mid;
                    else
                        left = mid + 1;
                }
                assert left == right;
    
                /*
                 * The invariants still hold: pivot >= all in [lo, left) and
                 * pivot < all in [left, start), so pivot belongs at left.  Note
                 * that if there are elements equal to pivot, left points to the
                 * first slot after them -- that's why this sort is stable.
                 * Slide elements over to make room for pivot.
                 */
                int n = start - left;  // The number of elements to move
                // Switch is just an optimization for arraycopy in default case
                switch (n) {
                    case 2:  a[left + 2] = a[left + 1];
                    case 1:  a[left + 1] = a[left];
                             break;
                    default: System.arraycopy(a, left, a, left + 1, n);
                }
                a[left] = pivot;
            }
        }

      

      

  • 相关阅读:
    BP神经网络基本原理
    天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,增益其所不能
    LSH算法原理
    数据库索引的作用和长处缺点
    开机黑屏 仅仅显示鼠标 电脑黑屏 仅仅有鼠标 移动 [已成功解决]
    Linux makefile 教程 很具体,且易懂
    银行家算法
    HDU 1757 A Simple Math Problem(矩阵高速幂)
    js中substr与substring的差别
    BackTrack5 (BT5)无线password破解教程之WPA/WPA2-PSK型无线password破解
  • 原文地址:https://www.cnblogs.com/liwangcai/p/11872874.html
Copyright © 2011-2022 走看看