策略模式简单来说就是将业务和实现业务的具体方法剥离开来
依然以仓库拣货来说,合并拣货分单拣货是一种模式,但具体根据所出库单中的品是什么类型,从哪种类型仓库出,还是要有具体的拣货策略来生成拣货列表
比如 服装仓按动线进行拣货,快消仓分整拣散拣,数码仓的品要扫码标记SN与单据关系出库
那么就要根据各种不同的仓库划分出不同的拣货列表创建方式,这样就把拣货这个业务本身,和具体拣货列表的生成进行剥离。不写死在具体业务中
首先建立策略模式的顶层接口
package strategy;
import java.util.List;
import bean.PickDoc;
import bean.PickList;
/**
- 拣货策略顶层接口
- @author zhousjmas@hotmail.com
-
*/
public interface IPickStrategy {public List<PickList> pickStrategy(List<PickDoc> list) ;
}
然后依次建立服装,数码,快消3种仓库的具体拣货列表策略
package strategy;
import java.util.List;
import bean.PickDoc;
import bean.PickList;
/**
- 服装仓拣货策略
- @author zhousjmas@hotmail.com
-
*/
public class ClothPickStrategy implements IPickStrategy {@Override
public List<PickList> pickStrategy(List<PickDoc> list) {// TODO Auto-generated method stub System.out.println("根据单据展开服装仓拣货策略"); return null;
}
}
package strategy;
import java.util.List;
import bean.PickDoc;
import bean.PickList;
/**
- 数码仓拣货策略
- @author zhousjmas@hotmail.com
-
*/
public class DigitalPickStrategy implements IPickStrategy{@Override
public List<PickList> pickStrategy(List<PickDoc> list) {// TODO Auto-generated method stub System.out.println("根据单据展开数码仓拣货策略"); return null;
}
}
package strategy;
import java.util.List;
import bean.PickDoc;
import bean.PickList;
/**
- 快消仓拣货策略
- @author zhousjmas@hotmail.com
-
*/
public class FmcgPickStrategy implements IPickStrategy{@Override
public List<PickList> pickStrategy(List<PickDoc> pickDoc) {// TODO Auto-generated method stub System.out.println("根据单据展开快消仓拣货策略"); return null;
}
}
然后对以前定义的拣货接口进行修改,引入设置拣货策略的方法,依次修改合并拣货与分单拣货的实现
package builder;
import java.util.List;
import bean.PickDoc;
import bean.PickList;
import bean.PickTask;
import strategy.IPickStrategy;
/**
- 定义要完成的动作
- @author mas
-
*/
public interface IPickTask {//计算要拣货的SKU列表
public List<PickList> getPickList(List<PickDoc> list);//计算拆分的拣货任务
public List<PickTask> getPickTask(List<PickList> list);//设置拣货策略
public void setPickStrategy(IPickStrategy pickStrategy);
}
然后进行示例调用
package strategy;
import java.util.ArrayList;
import java.util.List;
import bean.PickDoc;
import builder.IPickTask;
import builder.UnionPickTask;
public class PickStrategyMain {
public static void main(String[] args) {
//拣货单据列表
List<PickDoc> list = new ArrayList<PickDoc>();
//假设当前是电子仓,要用电子仓的拣货策略
IPickStrategy pickStrategy = new DigitalPickStrategy();
//拣货模式为合并拣货
IPickTask pickTask = new UnionPickTask();
//设置拣货策略
pickTask.setPickStrategy(pickStrategy);
//获取拣货列表
pickTask.getPickList(list);
}
}
调用效果
这里会看到有个做静态代理演示代码的StaticPickTaskProxy.java报错。
这是因为这个静态代理类是要实现IPickTask这个顶层接口的所有方法,
这里就发现静态代理的缺点了。
另外也可以看到面向接口开发的优势,可以快速观察到所涉及业务子类的影响。如果不面向接口编程,那么可能会在大的业务调整时导致某些也涉及到业务的类被我们忽略修改,同时因为业务测试的分支难以覆盖而造成潜在隐患
来源:51CTO
作者:mas199980
链接:https://blog.51cto.com/4890631/2485087