【设计模式】----- 策略模式
什么是策略模式
策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式的变化独立于使用算法的客户。--《Head First 设计模式》。
例子说明
这里举的例子是本人给出的一个简单实现,如果有错误请大家指出。在一个商城系统中,商品列表的排序是多变的,可能按价格升序,可能按热门程度降序,本文例子将使用策略模式解决这种变化。
具体实现
ProductService类说明:类包含Sort接口,Product指的是需要被排序的数据,sortProduct方法开始排序。Sort是策略模式不同算法的一个抽象,利用多态实现价格升序(MoneySort)、热门程度降序(HotSort)等多种排序方式达到互相替换的目的。
import java.util.List;
public class ProductService {
private Sort sort;
private List<Product> products;
/**
* 对商品排序
*/
public void sortProduct() {
sort.doSort(this.products);
}
public ProductService(List<Product> products) {
this.products = products;
}
public void setSort(Sort sort) {
this.sort = sort;
}
public Sort getSort() {
return sort;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
}
import java.util.Comparator;
import java.util.List;
/**
* 按照名称降序
*/
public class HotSort implements Sort {
@Override
public void doSort(List<Product> products) {
products.sort(new Comparator<Product>() {
@Override
public int compare(Product o1, Product o2) {
return -(o1.getHot() - o2.getHot());
}
});
}
}
import java.util.Comparator;
import java.util.List;
/**
* 价格升序
*/
public class MoneySort implements Sort{
@Override
public void doSort(List<Product> products) {
products.sort(new Comparator<Product>() {
@Override
public int compare(Product o1, Product o2) {
return (int) (o1.getMoney() - o2.getMoney());
}
});
}
}
public class Product {
/**
* 商品名称
*/
private String productName;
/**
* 商品金额
*/
private Double money;
/**
* 热门程度
*/
private Integer hot;
public Product(String productName, Double money, Integer hot) {
this.productName = productName;
this.money = money;
this.hot = hot;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
public Integer getHot() {
return hot;
}
public void setHot(Integer hot) {
this.hot = hot;
}
@Override
public String toString() {
return "Product{" +
"productName='" + productName + '\'' +
", money=" + money +
", hot=" + hot +
'}';
}
}
测试类
/**
* 策略模式:定义了算法族,分别封装起来,让它们之间可以互相转换,此模式让算法的变化独立于使用算法的客户。
*/
public class StrategyTest {
public static void main(String[] args) throws Exception {
List<Product> products = new ArrayList<>();
products.add(new Product("苹果",10D,1));
products.add(new Product("荔枝",20D,41234));
products.add(new Product("香蕉",30D,11));
products.add(new Product("猕猴桃",40D,9));
ProductService productService = new ProductService(products);
// 按热门程度降序
hotSort(productService);
// 按价格升序
moneySort(productService);
}
/**
* 按价格升序
* @param productService
*/
private static void moneySort(ProductService productService) {
productService.setSort(new MoneySort());
System.out.println("价格升序前:" +productService.getProducts());
productService.sortProduct();
System.out.println("价格升序后:" +productService.getProducts());
}
/**
* 按热门程度降序
* @param productService
*/
private static void hotSort(ProductService productService) {
// 按热门程度降序
productService.setSort(new HotSort());
System.out.println("热门程度降序前:" +productService.getProducts());
productService.sortProduct();
System.out.println("热门程度降序后:" +productService.getProducts());
}
执行结果:
策略模式总结:
同一业务如果有不同的计算方式的话使用策略模式可以把变化隔离起来,在不改动已有的代码下通过新增实现类就可以切换算法,但开发者必须知道具体的算法,比如上面的HotSort,MoneySort。