装饰策略落在具体的代码实现效果上其实与代理模式的静态实现没有什么区别,都可以做到对原实现方法进行前置/后置/干预及方法替换,不必太纠结于此。
两者的差别是代理模式实际上是对被代理对象生成了一个身份一样但实现不同的对象。比如小红爱穿裙子,生成的代理对象是小粉红,她爱穿长裙子。而装饰模式相当于小红爱穿裙子,而装饰模式给她的裙子上缀了只小蝴蝶。这是两者之间的差别
装饰模式通过对顶层接口通过顶层接口进行实现后其实就走了原实现类的旁支,它实现了原来的功能,但又进行了修改。
以下仍以拣货业务进行描述
有些仓库要求在生成拣货列表的同时要打印拣货单据(无纸化仓库将拣货列表发送到手持,但小仓库可能仍需要打印拣货单据)
那么就对现有的拣货实现调整,附加一个打印单据的功能
本例中没有自己单独的顶层接口,顶层接口使用拣货任务本身的顶层接口(在建造者模式举例中的实现)
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 decorator;
import java.util.List;
import bean.PickDoc;
import bean.PickList;
import bean.PickTask;
import builder.IPickTask;
import strategy.IPickStrategy;
/**
- 拣货装饰类
- @author zhousjmas@hotmail.com
-
*/
public abstract class PickTaskDecorator implements IPickTask {private IPickTask pickTask;
private IPickStrategy pickStrategy;
//构造方法,传入所要装饰的拣货对象
public PickTaskDecorator(IPickTask pickTask) {
this.pickTask = pickTask;
}@Override
//被装饰对象的原生方法
public List<PickList> getPickList(List<PickDoc> list) {
return pickTask.getPickList(list);
}@Override
//被装饰对象的原生方法
public List<PickTask> getPickTask(List<PickList> list) {
return pickTask.getPickTask(list);
}@Override
//被装饰对象的原生方法
public void setPickStrategy(IPickStrategy pickStrategy) {pickTask.setPickStrategy(pickStrategy);;
}
}
进行实际的装饰操作,在这里我们增加一个打印拣货单的操作(这个不是每个仓库必须的,需要对指定仓库进行装饰)
package decorator;
import java.util.List;
import bean.PickDoc;
import bean.PickList;
import bean.PickTask;
import builder.IPickTask;
import strategy.IPickStrategy;
public class SinglePickTaskDecorator extends PickTaskDecorator{
public SinglePickTaskDecorator(IPickTask pickTask) {
super(pickTask);
}
//打印拣货列表
private void printPickList() {
System.out.println("打印拣货任务列表");
}
@Override
//被装饰对象的原生方法
public List<PickList> getPickList(List<PickDoc> list) {
List<PickList> pickList = super.getPickList(list);
//打印拣货列表
printPickList();
return pickList;
}
@Override
//被装饰对象的原生方法
public List<PickTask> getPickTask(List<PickList> list) {
return super.getPickTask(list);
}
@Override
//被装饰对象的原生方法
public void setPickStrategy(IPickStrategy pickStrategy) {
super.setPickStrategy(pickStrategy);;
}
}
//实际调用
package decorator;
import java.util.ArrayList;
import java.util.List;
import bean.PickDoc;
import builder.IPickTask;
import builder.SinglePickTask;
import strategy.DigitalPickStrategy;
import strategy.IPickStrategy;
public class PickTaskDecoratorMain {
public static void main(String[] args) {
IPickTask pickTask = new SinglePickTask();
List<PickDoc> list = new ArrayList<PickDoc>();
//进行装饰
PickTaskDecorator pickTaskDecorator = new SinglePickTaskDecorator(pickTask);
//假设当前是电子仓,要用电子仓的拣货策略
IPickStrategy pickStrategy = new DigitalPickStrategy();
//为装饰器类设置拣货策略
pickTaskDecorator.setPickStrategy(pickStrategy);
//运行装饰后的
pickTaskDecorator.getPickList(list);
}
}
调用的效果
来源:51CTO
作者:mas199980
链接:https://blog.51cto.com/4890631/2485098