一.策略模式定义
定义一系列算法,把他们封装起来,并且他们可以相互替换。本模式使得算法可独立于使用他的客户而变化
二.策略模式结构说明
1.Strategy :策略接口,用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略实现定义的算法。
2.ConcreteStrategy:具体的策略实现,也就是具体的算法实现。
3.Context:上下文,负责和具体的策略类交互。通常上下文会持有一个真正的策略实现,上下文还可以让具体的策略类来获取上下文的数据,甚至可以让具体的策略类来回调上下文的方法。
三.策略模式的示例代码
package com.interfaces;
//策略接口
public interface Strategy {
double arithmeticInterface();
}
package com.model;
import com.interfaces.Strategy;
//负责和策略接口交互的上下文类
public class Context {
private Strategy strategy=null;
public Context(Strategy strategy) {
super();
this.strategy = strategy;
}
public double quote(){//能实现调用不同的算法
return strategy.arithmeticInterface();
}
}
package com.model;
import com.interfaces.Strategy;
public class ConcreteStrategy implements Strategy {
@Override
public double arithmeticInterface() {
//具体的算法实现
return 0.0;
}
}
四.策略模式的实例应用--商场价格打折
/**
* @author 紫竹
* @function 策略模式实例
* 演示商场打折: a.对于普通客户或者是新客户报全价
* b.对于老客户报的价格,统一折扣5%
* c.对于大客户报的价格,统一折扣10%
*/
package com.model;
import com.interfaces.Strategy;
//计算价格类
public class Price {
private Strategy strategy=null;
public Price(){
}
public Price(Strategy strategy) {
super();
this.strategy = strategy;
}
//根据不同的具体实现的策略,得到不同的价格
public double getCustomPrice(double goodsPrice){
return strategy.discountPrice(goodsPrice);
}
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
}
package com.interfaces;
public interface Strategy {
double discountPrice(double goodsPrice);
}
package com.model;
import com.interfaces.Strategy;
//大客户打折的策略具体实现
public class LargeCustomStrategy implements Strategy {
@Override
public double discountPrice(double goodsPrice) {
return goodsPrice*(1-0.1);
}
}
package com.model;
import com.interfaces.Strategy;
//老客户打折的策略具体实现
public class OldCustomStrategy implements Strategy {
@Override
public double discountPrice(double goodsPrice) {
return goodsPrice*(1-0.05);
}
}
package com.test;
import com.model.*;
import com.model.Price;
//客户端测试
public class Client {
public static void main(String args[]){
double goodsPrice=302.23;
Price price=new Price(new LargeCustomStrategy());
System.out.println("大客户购买商品的价格为:"+price.getCustomPrice(goodsPrice));
//不需要修改原来的Price 和 Strategy组合,只需要增加具体的策略即可,正好符合 开-闭的原则
price.setStrategy(new OldCustomStrategy());
System.out.println("老客户购买商品的价格为:"+price.getCustomPrice(goodsPrice));
}
}
输出结果:
大客户购买商品的价格为:272.007
老客户购买商品的价格为:287.1185
五.模拟JDK中的策略模式实现(comparable&comparator接口)
package com.interfaces;
//comparable接口
public interface Comparable {
int compareTo(Object obj);
}
package com.interfaces;
//comparator接口
public interface Comparator {
int compare(Object obj1,Object o2);
}
package com.exercise.model;
import com.interfaces.Comparable;
import com.interfaces.Comparator;
//猫类,实现了Comparable接口
public class Cat implements Comparable{
private int height;
private int weight;
private Comparator comparator=new CatWeightComparator();
public Cat(int height,int weight) {
super();
this.height = height;
this.weight=weight;
}
public void setHeight(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Comparator getComparator() {
return comparator;
}
public void setComparator(Comparator comparator) {
this.comparator = comparator;
}
@Override
public String toString(){
return this.getWeight()+"|"+this.getWeight();
}
@Override
public int compareTo(Object obj) {
return comparator.compare(this, obj);//使用我指定的方式比较
}
}
package com.exercise.model;
import com.interfaces.Comparator;
//猫高度的比较器,比较器的具体实现
public class CatHeightComparator implements Comparator{
@Override
public int compare(Object obj1, Object obj2) {
Cat c1=(Cat)obj1;
Cat c2=(Cat)obj2;
if(c1.getWeight()>c2.getWeight())return 1;
else if(c1.getWeight()<c2.getWeight())return -1;
else return 0;
}
}
package com.exercise.model;
import com.interfaces.Comparator;
//猫重量的比较器
public class CatWeightComparator implements Comparator{
@Override
public int compare(Object obj1, Object obj2) {
Cat c1=(Cat)obj1;
Cat c2=(Cat)obj2;
if(c1.getWeight()>c2.getWeight())return 1;
else if(c1.getWeight()<c2.getWeight())return -1;
else return 0;
}
}
package com.exercise.model;
import com.interfaces.Comparable;
//数据排序
public class DataSort{
//冒泡排序,整数排序
public static void sort(int [] a) {
for(int i=0;i<a.length-1;i++){
for(int j=0;j<a.length-i-1;j++){
if(a[j]>a[j+1]){
swap(a,j,j+1);
}
}
}
}
//交换
private static void swap(int[] a, int j, int i) {
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
public static void show(int [] a){
for(int value:a){
System.out.print(value+"\t");
}
}
//冒泡排序,使用comparable接口实现对任意对象排序(这个对象必须实现Comparable接口)
public static void sort(Object [] a) {
for(int i=0;i<a.length-1;i++){
for(int j=0;j<a.length-i-1;j++){
if(((Comparable)a[j]).compareTo((Comparable)a[j+1])==1){//大于
swap(a,j,j+1);
}
}
}
}
//交换
private static void swap(Object[] a, int j, int i) {
Object temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
//显示
public static void show(Object [] a){
for(Object value:a){
System.out.print(value+"\t");
}
}
}
package com.exercise.test;
import com.exercise.model.Cat;
import com.exercise.model.DataSort;
//测试类
public class Test {
public static void main(String[] args) {
// int []a ={3,2,1,45,32,6};
Cat cat[]={new Cat(2,2),new Cat(3,3),new Cat(8,8),new Cat(5,5),new Cat(4,4)};
DataSort.sort(cat);
DataSort.show(cat);
}
}
输出结果:
2|2 3|3 4|4 5|5 8|8
本文参考了《研磨设计模式》一书,以及马士兵老师的视频,特此声明!