設計模式——策略模式
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了。