ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

装饰器模式

2021-05-02 14:05:19  阅读:195  来源: 互联网

标签:int price 模式 装饰 蛋糕 getPrice public


写法:
1, 定义一个抽象的类 抽象类里面定义抽象方法
2, 定义装饰器 装饰器继承抽象类,引入抽象类属性,构造方法注入,重写抽象类方法,方法执行调用注入的实例重写的方法,装饰器作为一个抽象类存在
3, 定义基础模型,与装饰器没有关系,但是继承了最上层的抽象类,写自身业务逻辑
4, 定义需要装饰的类,继承装饰类,构造方法直接使用super,重写的方法直接调用super+自身业务逻辑(此处有违里式替换原则).
5, 使用方法,定义基础模型实力,然后作为构造入参,定义需要装饰的类实例,便达到了透明的功能拓展的效果。

原理:
通过实例结构可以看到,除去基础实例外,因为继承了装饰器,所有被装饰的类都被注入了顶层抽象类的子类实例,成嵌套结构。调用被装饰类实例重写的抽象类方法,因为写成了直接调用了super.method()+业务逻辑,而装饰器类重写的抽象方法内部调用的是注入的实例重写的抽象方法,所以得到的最终结果就是调用了前一个实例方法结果+当前实例方法结果。
例如价格计算场景:普通蛋糕是100元,加水果50,加巧克力100 这种场景下,一定存在一个抽象蛋糕,只有价格抽象方法,普通蛋糕直接继承了抽象蛋糕,重写了抽象方法,定义价格为100,再存在一个蛋糕装饰器,也继承了抽象蛋糕,需要重新抽象蛋糕的价格方法,不同的是蛋糕装饰器有一个属性,就是抽象蛋糕,并且通过构造方法注入,且重写的方法内,调用的是注入实例重写的方法。
价格计算逻辑:普通蛋糕100,将普通蛋糕通过蛋糕装饰器加入水果,此刻的水果蛋糕,可以理解一个蛋糕装饰器,期内存在一个普通蛋糕+水果,便是存在一个普通蛋糕的属性,和自身价格的属性。调用价格方法,期内是直接使用了super.method(),也就是蛋糕装饰器的方法,蛋糕装饰器调用的是普通蛋糕的价格,然后再加上水果蛋糕的价格。后面加入巧克力一样效果,总价就是先是50+100 = 150,再150+100 = 250。(是的,只有二百五才会这样写)

思考:与继承相比,装饰器模式更灵活,符合开闭原则,不改变原有对象的情况下动态拓展对象功能,即插即用。

 


可以把装饰器看成一种静态代理,不同的是装饰器是自身功能的增强,但是代理模式是代理过程中的增强,更具有aop的切面思想,突出方法调用前后的处理,装饰器模式是突出本身的功能
继承的类会写的比较多,但是不用装饰器模式的话,那根本没办法写,例如ABC三个功能排列组合,就得写6各类,装饰器模式的话,只用写一个功能一个即可,功能越多,效果越明显

InputStream,Logger都是使用了这种装饰器模式,对Logger功能做拓展,装饰器模式就非常的适合。

//抽象蛋糕
public abstract class Cake {

protected abstract int getPrice();

}

//普通蛋糕
public class BaseCake extends Cake {

private int price;

public void setPrice(int price) {
    this.price = price;
}

@Override
protected int getPrice() {
    return this.price;
}

}

//蛋糕装饰器
public class CakeDecorator extends Cake{

private Cake cake;

protected int price;

public void setPrice(int price) {
    this.price = price;
}

public CakeDecorator(Cake cake) {
    this.cake = cake;
}

@Override
protected int getPrice() {
    return this.cake.getPrice();
}

}

//通过蛋糕装饰器加上冰淇淋
public class CreamCake extends CakeDecorator {

public CreamCake(Cake cake) {
    super(cake);
}

public void setPrice(int price){
    this.price = price;
}

@Override
protected int getPrice() {
    return super.getPrice()+this.price;
}

}

//通过蛋糕装饰器加上水果
public class FruitsCake extends CakeDecorator {

public FruitsCake(Cake cake) {
    super(cake);
}

public void setPrice(int price){
    this.price = price;
}

@Override
protected int getPrice() {
    return super.getPrice()+this.price;
}

}

//通过蛋糕装饰器加上nomal
public class NomalCake extends CakeDecorator {

public NomalCake(Cake cake) {
    super(cake);
}

public void setPrice(int price){
    this.price = price;
}

@Override
protected int getPrice() {
    return super.getPrice()+this.price;
}

}

//计算出搭配总价
public class Test {

public static void main(String[] args) {
    BaseCake baseCake = new BaseCake();
    baseCake.setPrice(100);
    NomalCake nomalCake = new NomalCake(baseCake);
    nomalCake.setPrice(200);
    FruitsCake fruitsCake = new FruitsCake(nomalCake);
    fruitsCake.setPrice(300);
    CreamCake creamCake = new CreamCake(fruitsCake);
    creamCake.setPrice(400);
    System.out.println(creamCake.getPrice());
}

}

标签:int,price,模式,装饰,蛋糕,getPrice,public
来源: https://www.cnblogs.com/xianyi/p/14725616.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有