仿写RxJava中的装饰器模式:
整个例子的背景:用户选择商品、下单、店家发货、快递、拿到商品。
交易类:Delivery
public abstract class Delivery {
public abstract void transport(Product product);
public void arrive(Product product){
transport(product);
}
// 创建订单与收获地址
public static Delivery create(String name,Order order){
// 创建收获地址
DeliveryCreate deliveryCreate=new DeliveryCreate(order);
// 创建快递
return new DeliveryProcess(deliveryCreate,name);
}
// 设置商品传递流程
public Delivery sendOrderToLocation(String name){
return new DeliveryProcess(this,name);
}
// 设置商品传递流程,且做些事
public Delivery sendOrderToLocation(String name,String thing){
return new DeliveryProcess(this,name,thing);
}
// 转换商品
public Delivery map(String name,Exchange<?,?> p){
return new DeliveryProcess(this,name,p);
}
}
创建订单和收获地址类:
public class DeliveryCreate extends Delivery{
// 订单
private Order order;
public DeliveryCreate(Order order){
this.order = order;
}
// 收获地址
@Override
public void transport(Product product) {
System.out.println("用户拿到了商品");
order.apply(product);
}
}
订单类:Order
public interface Order {
void apply(Product dothing);
}
快递传递类:DeliveryProcess
public class DeliveryProcess extends Delivery{
private Exchange exchange;
private String name;
private String otherThing;
private Delivery parent;
public DeliveryProcess(Delivery nextNode, String name){
System.out.println("LogOut:订单到达-----"+name);
this.parent= nextNode;
this.name= name;
}
public DeliveryProcess(Delivery nextNode,String name,Exchange exchange){
System.out.println("LogOut:订单到达-----"+name);
this.name=name;
this.parent= nextNode;
this.exchange= exchange;
}
public DeliveryProcess(Delivery nextNode, String name,String otherThing){
System.out.println("LogOut:订单到达-----"+name);
this.parent= nextNode;
this.name= name;
this.otherThing=otherThing;
}
// 传递快递
@Override
public void transport(Product product) {
if(name!=null){
System.out.println("LogOut:商品已发货,目前到达-----"+name);
}
if(otherThing!=null){
System.out.println("LogOut:商品检查:-----"+otherThing);
}
Product newProduct=product;
if (exchange!=null){
newProduct=exchange.change(product);
}
// 将快递给下一个快递站
parent.transport(newProduct);
}
}
商品类:Product
public interface Product<T> {
void size(int d);
void number(int t);
void color(String e);
void content(T info);
}
商品转换类:
public interface Exchange<R,T> {
Product<T> change(Product<R> product);
}
main:
Delivery.create("用户下单地点",new Order() {
@Override
public void apply(Product dothing) {
dothing.color("Red");
dothing.size(100);
dothing.number(10);
dothing.content("三只松鼠");
}
})
.sendOrderToLocation("广东","检查下是否过期了")
.sendOrderToLocation("四川","看看好不好吃???")
.sendOrderToLocation("三只松鼠旗舰店")
.arrive(new Product<String>() {
@Override
public void number(int d) {
System.out.println("商品的个数:"+d);
}
@Override
public void size(int big) {
System.out.println("商品的大小:"+big);
}
@Override
public void color(String col) {
System.out.println("商品的颜色:"+col);
}
@Override
public void content(String str) {
System.out.println("商品的类型:"+str);
}
});
}
执行结果:
LogOut:订单到达-----用户下单地点
LogOut:订单到达-----广东
LogOut:订单到达-----四川
LogOut:订单到达-----三只松鼠旗舰店
LogOut:商品已发货,目前到达-----三只松鼠旗舰店
LogOut:商品已发货,目前到达-----四川
LogOut:商品检查:-----看看好不好吃???
LogOut:商品已发货,目前到达-----广东
LogOut:商品检查:-----检查下是否过期了
LogOut:商品已发货,目前到达-----用户下单地点
用户拿到了商品,三只松鼠
商品的颜色:Red
商品的大小:100
商品的个数:10
商品的类型:三只松鼠
添加商品转换:
Delivery.create("用户下单地点",new Order() {
@Override
public void apply(Product dothing) {
dothing.color("Red");
dothing.size(100);
dothing.number(10);
dothing.content(12);
}
})
.sendOrderToLocation("广东","检查下是否过期了")
.map("重庆", new Exchange<Integer, String>() {
@Override
public Product<Integer> change(Product food) {
return new Product<Integer>() {
@Override
public void number(int d) {
System.out.println("商品被掉包:number");
food.number(5);
}
@Override
public void size(int big) {
System.out.println("商品被掉包:size");
food.size(big);
}
@Override
public void color(String cor) {
System.out.println("商品被掉包:color");
food.color("绿色");
}
@Override
public void content(Integer str) {
System.out.println("商品被掉包:info");
food.content("重庆火锅");
}
};
}
})
.sendOrderToLocation("四川","看看好不好吃???")
.sendOrderToLocation("三只松鼠旗舰店")
.arrive(new Product<String>() {
@Override
public void number(int d) {
System.out.println("商品的个数:"+d);
}
@Override
public void size(int big) {
System.out.println("商品的大小:"+big);
}
@Override
public void color(String col) {
System.out.println("商品的颜色:"+col);
}
@Override
public void content(String str) {
System.out.println("商品的类型:"+str);
}
});
}
打印结果:
LogOut:订单到达-----用户下单地点
LogOut:订单到达-----广东
LogOut:订单到达-----重庆
LogOut:订单到达-----四川
LogOut:订单到达-----三只松鼠旗舰店
LogOut:商品已发货,目前到达-----三只松鼠旗舰店
LogOut:商品已发货,目前到达-----四川
LogOut:商品检查:-----看看好不好吃???
LogOut:商品已发货,目前到达-----重庆
LogOut:商品已发货,目前到达-----广东
LogOut:商品检查:-----检查下是否过期了
LogOut:商品已发货,目前到达-----用户下单地点
用户拿到了商品
商品被掉包:color
商品的颜色:绿色
商品被掉包:size
商品的大小:100
商品被掉包:number
商品的个数:5
商品被掉包:info
商品的类型:重庆火锅
上面的仿写,其实就做了两件事:在拿到商品前,不停的装饰自己(即添加额外操作),拿到商品后,不停的卸装(执行额外操作,然后将商品传给下一层)。
这种设计模式是一种垂直方向添加功能,上一层需要持有下一层的对象。
缺点: 多层装饰比较复杂