設計模式——策略模式

設計模式——策略模式

1-  策略模式的定義

策略模式:定義了一個算法家族,分別封裝起來,讓算法可以相互替換,從而不會影響到使用算法的用戶。從概念上看,定義的所有的算法都只是完成相同的工作,只是實現不同,在具體使用時可以用相同的方式調用所有的算法,將算法類與使用算法的邏輯類解耦。

廢話不多說,Show Code!

 

2-  策略模式實現代碼

2-0準備工作

爲了更好的介紹策略模式,定義一個pojo:Person類,代碼如下:

package designPattern.test.strategy.pojo;

import java.io.Serializable;

/**
 * pojo
 */
public class Person implements Serializable {

    //姓名
    private String name;

    //年齡
    private Integer age;

    //性別
    private Byte gender;

    //體重
    private Double weight;

    //身高
    private Double height;

    //地址
    private String address;

    public Person(){}

    public Person(String name, Integer age, Byte gender, Double weight, Double height, String address) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.weight = weight;
        this.height = height;
        this.address = address;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Byte getGender() {
        return gender;
    }

    public void setGender(Byte gender) {
        this.gender = gender;
    }

    public Double getWeight() {
        return weight;
    }

    public void setWeight(Double weight) {
        this.weight = weight;
    }

    public Double getHeight() {
        return height;
    }

    public void setHeight(Double height) {
        this.height = height;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

2-1策略接口

package designPattern.test.strategy;

import designPattern.test.strategy.pojo.Person;
import java.util.List;

/**
 * 策略接口
 */
public interface Strategy {
    /**
     * 根據Person的具體信息推薦商品集合
     */
    List<String> recommendGoodsList(Person person);
}

2-2具體的推薦商品的策略算法

這裏是策略模式算法實現的核心,算法的具體實現都寫在這裏!

根據年齡推薦商品:

package designPattern.test.strategy.pojo;

import com.google.common.base.Preconditions;
import designPattern.test.strategy.Strategy;

import java.util.ArrayList;
import java.util.List;

/**
 * 根據年齡推薦
 */
public class AgeStrategy implements Strategy {

    /**
     * 根據不同的年齡推薦不同的商品
     */
    @Override
    public List<String> recommendGoodsList(Person person) {
        Preconditions.checkNotNull(person);
        List<String> goodsList = new ArrayList<>();
        Integer age = person.getAge();
        if (age <= 10) {
            goodsList.add("棒棒糖");
        } else if (age > 10 && age <= 20) {
            goodsList.add("四大名著");
        } else if (age > 20 && age <= 30) {
            goodsList.add("NorthFace");
        } else if (age > 30 && age <= 40) {
            goodsList.add("章光101");
        } else if (age > 40 && age <= 50) {
            goodsList.add("老人按摩機");
        } else {
            goodsList.add("老人機,字超大的");
        }
        return goodsList;
    }
}

根據性別推薦商品:

package designPattern.test.strategy.pojo;

import com.google.common.base.Preconditions;
import designPattern.test.strategy.Strategy;

import java.util.ArrayList;
import java.util.List;

/**
 * 根據性別推薦
 */
public class GenderStrategy implements Strategy {

    /**
     * 具體的推薦邏輯,根據性別推薦不同的商品
     */
    @Override
    public List<String> recommendGoodsList(Person person) {
        List<String> goodsList = new ArrayList<>();
        Preconditions.checkNotNull(person);
        //男孩都有吉他,女孩都有舞鞋
        if (person.getGender() == 1) {
            goodsList.add("吉他");
        } else {
            goodsList.add("舞鞋");
        }
        return goodsList;
    }
}

根據身高推薦商品:

package designPattern.test.strategy.pojo;

import com.google.common.base.Preconditions;
import designPattern.test.strategy.Strategy;

import java.util.ArrayList;
import java.util.List;

/**
 * 身高推薦策略
 */
public class HeightStrategy implements Strategy {

    /**
     * 根據身高推薦不同的商品
     */
    @Override
    public List<String> recommendGoodsList(Person person) {
        List<String> goodsList = new ArrayList<>();
        Preconditions.checkNotNull(person);
        Double height = person.getHeight();
        if (height > 150.0 && height <= 160.0) {
            goodsList.add("內增高");
        } else if (height > 160.0 && height <= 170.0) {
            goodsList.add("厚板鞋");
        } else if (height > 170.0 && height <= 180.0) {
            goodsList.add("大風衣");
        } else {
            goodsList.add("Air Jordan");
        }
        return goodsList;
    }
}

根據體重推薦商品:

package designPattern.test.strategy.pojo;

import com.google.common.base.Preconditions;
import designPattern.test.strategy.Strategy;

import java.util.ArrayList;
import java.util.List;

/**
 * 體重推薦策略
 */
public class WeightStrategy implements Strategy {

    /**
     * 根據不同的體重推薦不同的商品
     */
    @Override
    public List<String> recommendGoodsList(Person person) {
        List<String> goodsList = new ArrayList<>();
        Preconditions.checkNotNull(person);
        Double weight = person.getWeight();
        if (weight > 40.0 && weight <= 50.0) {
            goodsList.add("金華火腿");
        } else if (weight > 50.0 && weight <= 60.0) {
            goodsList.add("蛋白粉");
        } else if (weight > 60.0 && weight <= 70.0) {
            goodsList.add("滷肉火燒");
        } else if (weight > 70.0 && weight <= 80.0) {
            goodsList.add("紅富士大蘋果");
        } else if (weight > 80.0 && weight <= 90.0) {
            goodsList.add("跑步機");
        } else {
            goodsList.add("特大號椅子");
        }
        return goodsList;
    }
}

根據地址推薦商品:

package designPattern.test.strategy.pojo;

import com.google.common.base.Preconditions;
import designPattern.test.strategy.Strategy;

import java.util.ArrayList;
import java.util.List;

/**
 * 地址推薦策略
 */
public class AddressStrategy implements Strategy {

    /**
     * 根據不同的地址推薦不同商品
     */
    @Override
    public List<String> recommendGoodsList(Person person) {
        List<String> goodsList = new ArrayList<>();
        Preconditions.checkNotNull(person);
        String address = person.getAddress();
        if(address.startsWith("北京")){
            goodsList.add("大前門");
        } else if(address.startsWith("湖北")){
            goodsList.add("黃鶴樓");
        } else if(address.startsWith("河南")){
            goodsList.add("紅旗渠");
        } else if(address.startsWith("雲南")){
            goodsList.add("紅塔山");
        } else if(address.startsWith("安徽")){
            goodsList.add("一品黃山");
        } else {
            goodsList.add("中華");
        }
        return goodsList;
    }
}

3-  測試類

package designPattern.test.strategy;

import designPattern.test.strategy.pojo.*;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * 策略模式測試
 */
public class StrategyTest {

    /**
     * 新建不同的策略,實際項目中一般採用Spring注入的方式
     * 將所有的策略都放在容器中,實際使用時注入不同的策略即可
     */
    private Strategy ageStrategy = new AgeStrategy();
    private Strategy genderStrategy = new GenderStrategy();
    private Strategy heightStrategy = new HeightStrategy();
    private Strategy weightStrategy = new WeightStrategy();
    private Strategy addressStrategy = new AddressStrategy();

    /**
     * 測試數據
     */
    private Person person = new Person("yudaijing", 27, (byte) 0, 56.0, 168.0, "安徽合肥");

    /**
     * 測試策略模式
     */
    @Test
    public void testStrategy() {
        List<String> goodsList = new ArrayList<>();
        List<String> ageRecommendGoodsList = ageStrategy.recommendGoodsList(person);
        List<String> genderRecommendGoodsList = genderStrategy.recommendGoodsList(person);
        List<String> heightRecommendGoodsList = heightStrategy.recommendGoodsList(person);
        List<String> weightRecommendGoodsList = weightStrategy.recommendGoodsList(person);
        List<String> addressRecommendGoodsList = addressStrategy.recommendGoodsList(person);
        goodsList.addAll(ageRecommendGoodsList);
        goodsList.addAll(genderRecommendGoodsList);
        goodsList.addAll(heightRecommendGoodsList);
        goodsList.addAll(weightRecommendGoodsList);
        goodsList.addAll(addressRecommendGoodsList);
        goodsList.stream().forEach(System.out::println);
    }
}

總結:策略模式將不同的算法或者行爲抽象出來,形成算法類,可以將業務邏輯與算法解耦。同時使用的算法需要變更的時候可以只修改配置文件就OK了。


發佈了31 篇原創文章 · 獲贊 41 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章