Java装饰者模式

亚瑟
• 阅读 159

装饰者模式目标
把许多要实现的功能,加载在子类上,类的继承,显得很臃肿,装饰着模式是在不改变原有类文件和使用继承的情况下,通过创建一个包装对象动态地扩展一个对象的功能,相比生成子类更为灵活
装饰模式的结构
在装饰模式中的角色有:
  ●  抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
  ●  具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
  ●  装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
  ●  具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任
源代码
抽象构件角色
[Java] 纯文本查看 复制代码
?
1
2
3
4
5
public interface Component {

 
public void sampleOperation();
 

}
具体构件角色
[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
public class ConcreteComponent implements Component {

@Override
public void sampleOperation() {
    // 写相关的业务代码
}

}
装饰角色
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
public class Decorator implements Component{

private Component component;
 
public Decorator(Component component){
    this.component = component;
}
@Override
public void sampleOperation() {
    // 委派给构件
    component.sampleOperation();
}
 

}
具体装饰角色
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
public class ConcreteDecoratorA extends Decorator {

public ConcreteDecoratorA(Component component) {
    super(component);
}
 
@Override
public void sampleOperation() {

     super.sampleOperation();

    // 写相关的业务代码
}

}
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
public class ConcreteDecoratorB extends Decorator {

public ConcreteDecoratorB(Component component) {
    super(component);
}
 
@Override
public void sampleOperation() {

     super.sampleOperation();

    // 写相关的业务代码
}

}
齐天大圣的例子
孙悟空有七十二般变化,他的每一种变化都给他带来一种附加的本领。他变成鱼儿时,就可以到水里游泳;他变成鸟儿时,就可以在天上飞行。
  本例中,Component的角色便由鼎鼎大名的齐天大圣扮演;ConcreteComponent的角色属于大圣的本尊,就是猢狲本人;Decorator的角色由大圣的七十二变扮演。而ConcreteDecorator的角色便是鱼儿、鸟儿等七十二般变化

源代码
抽象构件角色“齐天大圣”接口定义了一个move()方法,这是所有的具体构件类和装饰类必须实现的。
[Java] 纯文本查看 复制代码
?
1
2
3
4
5
//大圣的尊号
public interface TheGreatestSage {

 
public void move();

}
具体构件角色“大圣本尊”猢狲类
[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
7
public class Monkey implements TheGreatestSage {

@Override
public void move() {
    //代码
    System.out.println("Monkey Move");
}

}
抽象装饰角色“七十二变”
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
public class Change implements TheGreatestSage {

private TheGreatestSage sage;
 
public Change(TheGreatestSage sage){
    this.sage = sage;
}
@Override
public void move() {
    // 代码
    sage.move();
}

}
具体装饰角色“鱼儿”
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
public class Fish extends Change {

 
public Fish(TheGreatestSage sage) {
    super(sage);
}
@Override
public void move() {
    // 代码
    System.out.println("Fish Move");
}

}
具体装饰角色“鸟儿”
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
public class Bird extends Change {

 
public Bird(TheGreatestSage sage) {
    super(sage);
}
@Override
public void move() {
    // 代码
    System.out.println("Bird Move");
}

}
客户端类
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
public class Client {

public static void main(String[] args) {
    TheGreatestSage sage = new Monkey();
    // 第一种写法
    TheGreatestSage bird = new Bird(sage);
    TheGreatestSage fish = new Fish(bird);
    // 第二种写法
    //TheGreatestSage fish = new Fish(new Bird(sage));
    fish.move(); 
}

}
“大圣本尊”是ConcreteComponent类,而“鸟儿”、“鱼儿”是装饰类。要装饰的是“大圣本尊”,也即“猢狲”实例。
  上面的例子中,系统把大圣从一只猢狲装饰成了一只鸟儿(把鸟儿的功能加到了猢狲身上),然后又把鸟儿装饰成了一条鱼儿(把鱼儿的功能加到了猢狲+鸟儿身上,得到了猢狲+鸟儿+鱼儿)。

如上图所示,大圣的变化首先将鸟儿的功能附加到了猢狲身上,然后又将鱼儿的功能附加到猢狲+鸟儿身上。
设计模式在JAVA I/O库中的应用
装饰模式在Java语言中的最著名的应用莫过于Java I/O标准库的设计了。
  由于Java I/O库需要很多性能的各种组合,如果这些性能都是用继承的方法实现的,那么每一种组合都需要一个类,这样就会造成大量性能重复的类出现。而如果采用装饰模式,那么类的数目就会大大减少,性能的重复也可以减至最少。因此装饰模式是Java I/O库的基本模式。
  Java I/O库的对象结构图如下,由于Java I/O的对象众多,因此只画出InputStream的部分。

根据上图可以看出:
  ●  抽象构件(Component)角色:由InputStream扮演。这是一个抽象类,为各种子类型提供统一的接口。
  ●  具体构件(ConcreteComponent)角色:由ByteArrayInputStream、FileInputStream、PipedInputStream、StringBufferInputStream等类扮演。它们实现了抽象构件角色所规定的接口。
  ●  抽象装饰(Decorator)角色:由FilterInputStream扮演。它实现了InputStream所规定的接口。
  ●  具体装饰(ConcreteDecorator)角色:由几个类扮演,分别是BufferedInputStream、DataInputStream以及两个不常用到的类LineNumberInputStream、PushbackInputStream。

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
java 设计模式之模板模式
什么是模板模式模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。模板方法模式的结构抽象类(AbstractClass):
Karen110 Karen110
3年前
浅析装饰器的那些事儿
一、装饰器的简单定义外层函数返回里层函数的引用,里层函数引用外层函数的变量。二、装饰器的作用通俗来讲装饰器的作用就是在不改变已有函数代码前提下,为该函数增加新的功能。defrun():print('我会跑')fun()现在我想在原有函数的基础上新增一个功能:我会唱歌。这个时候利用装饰器则轻松可以帮我们实现这个功能。三、实例理解(1)不
Python进阶者 Python进阶者
4年前
浅析装饰器的那些事儿
一、装饰器的简单定义外层函数返回里层函数的引用,里层函数引用外层函数的变量。二、装饰器的作用通俗来讲装饰器的作用就是在不改变已有函数代码前提下,为该函数增加新的功能。defrun():print('我会跑')fun()现在我想在原有函数的基础上新增一个功能:我会唱歌。这个时候利用装饰器则轻松可以帮我们实现这个功能。三、实
Wesley13 Wesley13
3年前
JavaWeb实现文件上传与下载
1\.增强HttpServletResponse对象  1.实现一个增强的HttpServletResponse类,需要继承javax.servlet.http.HttpServletRequestWrapper类,通过重写自己需要增强的方法来实现(这种模式就叫做装饰者模式),使用该增强类在
Stella981 Stella981
3年前
Category 特性在 iOS 组件化中的应用与管控
背景iOSCategory功能简介Category是ObjectiveC2.0之后添加的语言特性。Category就是对装饰模式的一种具体实现。它的主要作用是在不改变原有类的前提下,动态地给这个类添加一些方法。在ObjectiveC(iOS的开发语言,下文用OC代替)中的具体体现为:实例(类)方法、属性和协
Stella981 Stella981
3年前
Python之设计模式
一、设计模式分类a、创建型模式简单工厂模式一、内容不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。二、角色工厂角色(Creator)抽象产品角色(Product)具体产品角色(ConcreteProduct)
Wesley13 Wesley13
3年前
Java Design Patterns
java的设计模式大体上分为三大类:创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模
Stella981 Stella981
3年前
Python 装饰器(Decorator)
Python 装饰器(Decorator)装饰模式有很多经典的使用场景,例如插入日志、性能测试、事务处理等等,有了装饰器,就可以提取大量函数中与本身功能无关的类似代码,从而达到代码重用的目的。下面就一步步看看Python中的装饰器。装饰器本身是一个Python函数,他可以让其他函数在不需要做任何代码变动
Wesley13 Wesley13
3年前
JavaWeb之动态代理解决request请求编码问题
动态代理解决编码问题1.设计模式出现原因:软件开发过程中,遇到相似问题,将问题的解决方法抽取模型(套路)常见设计模式:单例,工厂,适配器,装饰者,动态代理。2.装饰者模式简单介绍谷歌汽车开发场景1.Java定义了汽车开发约定interfaceICar{s
Wesley13 Wesley13
3年前
Java 设计模式系列(十三)模板方法
Java设计模式系列(十三)模板方法模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。一、模板方法的结构
3A网络 3A网络
2年前
Golang 常见设计模式之装饰模式
Golang常见设计模式之装饰模式想必只要是熟悉Python的同学对装饰模式一定不会陌生,这类Python从语法上原生支持的装饰器,大大提高了装饰模式在Python中的应用。尽管Go语言中装饰模式没有Python中应用的那么广泛,但是它也有其独到的地方。接下来就一起看下装饰模式在Go语言中的应用。简单装饰器我们通过一个简单的例子来