Java设计模式 ---- 装饰者模式

一,装饰者模式

    装饰者模式,举一个简单的例子,JDK中的IO就充分使用了装饰者模式,IO中有两个顶层接口:InputStream和OutputStream。其他所有相关的字符流和字节流都是实现自该类,并且在全部实现类中,存在部分类的功能是对其他实现类功能增强,例如输入输入流和对应的Buffered输入输出流。

    所以,简单来说,装饰者模式是对原有功能的增强。在不改变原有结构的基础上,创造出类结构的强一致性,增强类或者也可以称为包装类,持有原有原有类的引用,对原有类的部分数据结构进行打开重构。装饰者模式装饰的是原有类的类型而不是原有类的行为

二,UML类图


    * Componment : 装饰行为的顶层接口,用来保证装饰对象的强一致性;

    * ContreteComponment : 原有实现类,整体包装是对该类进行包装;

    * Decorator : 包装类的顶层接口,并继承整个行为的顶层接口,保证强一致性;

    * ConcreteDecoratorA : 具体的包装类,用来对原有类进行类型包装;

三,代码实现

1,实体类

public class Order {
    private String orderId;

    private Double cost;

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public Double getCost() {
        return cost;
    }

    public void setCost(Double cost) {
        this.cost = cost;
    }

    @Override
    public String toString() {
        return "Order{" +
                "orderId='" + orderId + '\'' +
                ", cost=" + cost +
                '}';
    }
}

2,顶层接口

public interface IMarketCost {

    public void cost();

    public Order getOrder();
}

3,原有类

public class StandardCost implements IMarketCost {

    private Order order;

    public StandardCost(Order order) {
        this.order = order;
    }

    @Override
    public void cost() {
        System.out.println("---------原订单---------");
        System.out.println(order);
    }

    @Override
    public Order getOrder() {
        return order;
    }
}

    可以看出原有类没有任何的折扣优惠

4,包装类

    现在超市搞活动,存在普通用户的优惠活动和VIP用户的优惠活动两种方式,需要根据优惠用户类型和花费金额不同采取不同的优惠方式,这时候就需要对原有类进行包装处理;

    * 包装类顶层接口

public interface ICountMarketCost extends  IMarketCost {

}

    * 折扣包装类

public class DiscountCost implements ICountMarketCost {

    private IMarketCost marketCost;

    public DiscountCost(IMarketCost marketCost) {
        this.marketCost = marketCost;
    }

    @Override
    public Order getOrder() {
        return marketCost.getOrder();
    }

    @Override
    public void cost() {
        Order order = marketCost.getOrder();
        Double cost = order.getCost();
        if (cost > 200) {
            order.setCost(cost * 0.9);
        }
        System.out.println("----------折扣销售----------");
        System.out.println(order);
    }

}

    * VIP包装类

public class VIPCost implements ICountMarketCost {

    private IMarketCost marketCost;

    public VIPCost(IMarketCost marketCost) {
        this.marketCost = marketCost;
    }

    @Override
    public Order getOrder() {
        return marketCost.getOrder();
    }

    @Override
    public void cost() {
        Order order = marketCost.getOrder();
        Double cost = order.getCost();
        if (cost < 100) {
            cost *= 0.9;
        } else if (cost < 200) {
            cost *= 0.8;
        } else {
            cost *= 0.7;
        }
        order.setCost(cost);
        System.out.println("---------VIP订单--------");
        System.out.println(order);
    }
}

5,测试类

public class DecorateTest {
    public static void main(String[] args) {
        Order order = new Order();
        order.setOrderId(UUID.randomUUID().toString());
        order.setCost(300.00);
        // 原订单
        IMarketCost standCost = new StandardCost(order);
        standCost.cost();
        // 折扣订单
        ICountMarketCost discountCost = new DiscountCost(standCost);
        discountCost.cost();
        // VIP订单
        standCost.getOrder().setCost(300.00);
        ICountMarketCost vipCost = new VIPCost(standCost);
        vipCost.cost();
    }
}

    这样包装之后,如果该超市以后针对不同的时期要举办不同的活动,只需要新建包装类实现包装接口,在该实现类中定义优惠详情,就可以完成整体活动的添加和变更, 而不需要对原有代码进行转换;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值