设计模式之——策略(Strategy)模式

设计模式:

前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定。而是一套用来提高代码可复用性、可维护性、可读性、稳健性、以及安全性的解决方案

设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。

正确使用设计模式具有以下优点:

  • 可以提高程序员的思维能力、编程能力和设计能力。
  • 使程序设计更加标准化、代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。
  • 使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。

  策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式的变化独立于算法的使用者。具体的算法选择交由客户端决定 

策略模式的优点有:
    1.策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码。
    2.策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。 但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。
    3.使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
策略模式的缺点有:
    1:客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
    2.策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

下面是代码的实现

策略模式的重心,适应选择不同的策略进行相应的功能

import java.util.Comparator;

/**
 * @Descrintion:策略模式,进行排序的比较器
 * @version: 1.0
 */
public class Sorter {

    //这里使用冒泡排序
    public void sort(T[] arr, Comparator comparator){
        for (int i = 0; i < arr.length-1; i++) {
            int minPos = i;
            for (int j = i; j < arr.length; j++) {
                minPos = comparator.compare(arr[j],arr[minPos])==-1?j:minPos;
            }
            swap(arr,i,minPos);
        }
    }

    //进行交换
    private void swap(T[] arr, int i, int j){
        T temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

实体类——商店实体类,商店具有多种排序方式

/**
 * @Descrintion:商家,实体类:模拟店铺中商家的一些属性
 * @version: 1.0
 */
public class Store {
    private int storeId;//商家的Id
    private String name;//商品的名称
    private int sellNum;//商品卖出的数量
    private int reputation;//商家的信誉

    @Override
    public String toString() {
        return "Store{" +
                "storeId=" + storeId +
                ", name='" + name + '\'' +
                ", sellNum='" + sellNum + '\'' +
                ", reputation=" + reputation +
                "}";
    }

    public Store(int storeId, String name, int sellNum, int reputation) {
        this.storeId = storeId;
        this.name = name;
        this.sellNum = sellNum;
        this.reputation = reputation;
    }

    public int getStoreId() {
        return storeId;
    }

    public void setStoreId(int storeId) {
        this.storeId = storeId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSellNum() {
        return sellNum;
    }

    public void setSellNum(int sellNum) {
        this.sellNum = sellNum;
    }

    public int getReputation() {
        return reputation;
    }

    public void setReputation(int reputation) {
        this.reputation = reputation;
    }
}

客户端调用演示类

import java.util.Arrays;

/**
 * @Descrintion:策略模式的演示类
 * @version: 1.0
 */
public class Client {
    private static Store[] store;
    //一个购物网站,对店铺进行排名的时候,有多种排名方式
    public static void main(String[] args) {
        //初始化店铺
        init();
        //随机打乱初始化的店铺
        randomStore();
        //打乱后的店铺
        System.out.println(Arrays.toString(store));

        //进行排序调用
        Sorter storeSorter = new Sorter<>();
        //调用不同的排序方式,可以实现不同的排序,如果需要增加新的排序方式,可以直接添加相应的类,而不用去修改代码
        storeSorter.sort(store,new RankingById());
        storeSorter.sort(store,new RankingByName());
        storeSorter.sort(store,new RankingByReputation());
        storeSorter.sort(store,new RankingBySellNum());

        //输出排序后的数组
        System.out.println(Arrays.toString(store));
    }

    //初始化店铺
    private static void init(){
        store = new Store[]{
                new Store(1, "aa", 1, 1)
                ,new Store(2, "bb", 2, 2)
                ,new Store(3, "cc", 3, 3)
                ,new Store(4, "dd", 4, 4)
                ,new Store(5, "ee", 5, 5)
        };
    }

    //编写一个随机打乱的方法
    private static void randomStore(){
        int num = (int) (Math.random()*10);
        for (int i = 0; i < num; i++) {
            int mid = (int) (Math.random()*10)%store.length;
            swapStore(mid);
        }
    }
    //交换两个参数位置
    private static void swapStore(int mid){
        if (mid==0||mid>=store.length) return;
        Store s = store[0];
        store[0] = store[mid];
        store[mid] = s;
    }
}

下面是各种比较器,不同的属性进行不同的比较

import java.util.Comparator;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;

/**
 * @Descrintion:排名算法:按照店铺注册的ID进行排名
 *                      这里只实现,比较方法compare方法
 * @version: 1.0
 */
public class RankingById implements Comparator {
    @Override
    public int compare(Store o1, Store o2) {
        if (o1.getStoreId() > o2.getStoreId()) return 1;
        else if(o1.getStoreId() < o2.getStoreId()) return -1;
        return 0;
    }

    @Override
    public Comparator reversed() {
        return null;
    }

    @Override
    public Comparator thenComparing(Comparator other) {
        return null;
    }

    @Override
    public  Comparator thenComparing(Function keyExtractor, Comparator keyComparator) {
        return null;
    }

    @Override
    public > Comparator thenComparing(Function keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingInt(ToIntFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingLong(ToLongFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingDouble(ToDoubleFunction keyExtractor) {
        return null;
    }
}
import java.util.Comparator;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;

/**
 * @Descrintion:排名算法:按照店铺名称进行排名
 * @version: 1.0
 */
public class RankingByName implements Comparator {
    @Override
    public int compare(Store o1, Store o2) {
        if (o1.getName()==null||o2.getName()==null||o1.getName().equals(o2.getName()))
        return 0;
        return o1.getName().compareTo(o2.getName());
    }

    @Override
    public Comparator reversed() {
        return null;
    }

    @Override
    public Comparator thenComparing(Comparator other) {
        return null;
    }

    @Override
    public  Comparator thenComparing(Function keyExtractor, Comparator keyComparator) {
        return null;
    }

    @Override
    public > Comparator thenComparing(Function keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingInt(ToIntFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingLong(ToLongFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingDouble(ToDoubleFunction keyExtractor) {
        return null;
    }
}
import java.util.Comparator;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;

/**
 * @Descrintion:排名算法:按照店铺的信誉值进行排名
 * @version: 1.0
 */
public class RankingByReputation implements Comparator {
    @Override
    public int compare(Store o1, Store o2) {
        if (o1.getReputation()>o2.getReputation()) return 1;
        else if (o1.getReputation() reversed() {
        return null;
    }

    @Override
    public Comparator thenComparing(Comparator other) {
        return null;
    }

    @Override
    public  Comparator thenComparing(Function keyExtractor, Comparator keyComparator) {
        return null;
    }

    @Override
    public > Comparator thenComparing(Function keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingInt(ToIntFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingLong(ToLongFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingDouble(ToDoubleFunction keyExtractor) {
        return null;
    }
}
import java.util.Comparator;

/**
 * @Descrintion:排名算法:按照店铺出售商品数量进行排名
 * @version: 1.0
 */
public class RankingBySellNum implements Comparator {
    @Override
    public int compare(Store o1, Store o2) {
        if (o1.getSellNum()>o2.getSellNum()) return 1;
        else if (o1.getSellNum()

你可能感兴趣的:(设计模式(GOF,23),设计模式,java,算法)