装饰模式
1 前言
O(∩_∩)O 首先呢,在这先祝各位湿兄湿姐圣诞节快乐,多多吃苹果。
今天呢,我们来讲讲装饰模式,装饰模式就是包装模式,简单的说就是通过一种对客户端透明的方式来拓展对象的功能,是继承关系的一种替代方案。
就拿我们经常吃的的苹果来说吧,在平安夜之前,苹果就是苹果,但到了平安夜之际,苹果就摇身一变成为平安果,这就是装饰的力量,不论是从外观还是内在的含义,经过装饰后都将大大的改变。
在jdk中,装饰模式使用的也是很频繁的,比如常见的I/O流,我们可以把一个简单的字节流转换成一个字节流,再将字节流转换成缓冲流等。
接着呢,我们先来看看传统的继承关系来实现转换过程。
2 继承转换
首先,我们先实现一个普通苹果
实现
<!--苹果接口--!>
public interface Apple {
public void show();
public void func();
}
<!--普通苹果实现--!>
public class CommonApple implements Apple{
@Override
public void show() {
this.func();
}
@Override
public void func() {
System.out.println("普通苹果");
}
}
普通苹果
这样我们的普通苹果就出来了,先吃着。平安夜来了,我们要一个刻字的苹果该怎么办呢?
刻字苹果实现
public class LetterApple implements Apple{
@Override
public void show() {
this.func();
}
@Override
public void func() {
System.out.println("刻字苹果");
}
}
刻字苹果
可以看到实现一个刻字苹果只需要在创建一个类去实现苹果就可以了,但我们不可能拿着一个没有包装盒的苹果去送对象吧,所以呢,我们还需要实现一个包装好的刻字苹果。
包装好的刻字苹果
public class PackingAndLetterApple implements Apple{
@Override
public void show() {
this.func();
}
@Override
public void func() {
System.out.println("包装苹果");
System.out.println("刻字苹果");
}
}
这样我们虽然是得到了包装好的刻字苹果,但是我们可以发现这种实现方式过于粗暴,代码过于冗余,每当我们需要一个复杂的功能时都需要重新去实现一个类。
** 而装饰模式就全完可以解决这个问题,当我们需要一个包装好的刻字苹果时,我们只需要先将普通苹果装饰成刻字苹果再装饰成包装苹果**就可以了。
3 装饰模式
装饰模式的几个角色
- 抽象组件角色:一个抽象接口,是装饰者和被装饰者的父接口。
- 抽象装饰角色:包含一个组件的应用,并定义与抽象组件一样的方法。
- 具体组件角色:为抽象组件的实现类。
- 具体装饰角色:为抽象装饰角色的实现类,负责具体的装饰。
具体的实现:
实现一个包装的刻字苹果
抽象组件角色:Apple.class
public interface Apple {
public void show();
public void func();
}
抽象装饰角色:AppleDecorator.class
public abstract class AppleDecorator implements Apple{
private Apple apple;
public AppleDecorator(Apple apple) {
this.apple = apple;
}
public Apple getApple() {
return apple;
}
具体组件角色:LetterAppleDecorator.class / PackingAppleDecorator.class
public class LetterAppleDecorator extends AppleDecorator{
private Apple apple;
public LetterAppleDecorator(Apple apple) {
super(apple);
}
@Override
public void show() {
this.getApple().show();
this.func();
}
@Override
public void func() {
System.out.println("刻字苹果");
}
}
public class PackingAppleDecorator extends AppleDecorator{
private Apple apple;
public PackingAppleDecorator(Apple apple) {
super(apple);
// TODO Auto-generated constructor stub
}
@Override
public void show() {
this.getApple().func();
this.func();
}
@Override
public void func() {
System.out.println("高档包装苹果");
}
}
具体装饰角色:CommonApple.class
public class CommonApple implements Apple{
@Override
public void show() {
this.func();
}
@Override
public void func() {
System.out.println("苹果");
}
}
测试:MainClass.clas
public class MainClass {
public static void main(String[] args) {
Apple apple = new CommonApple();
apple.func();
System.out.println("`````````````````````````````````````````");
apple = new LetterAppleDecorator(apple);
apple.func();
System.out.println("`````````````````````````````````````````");
apple = new PackingAppleDecorator(apple);
apple.func();
System.out.println("`````````````````````````````````````````");
}
}
运行结果
4 优缺点
优点
- Decorator模式和继承都是为了拓展对象的功能,但是很明显Decorator模式更加灵活。
- 当对一个对象有多种装饰时,那么开发者也同时可以实现不同的行为组合。
缺点:
- 装饰模式会导致类的增多,会使程序变复杂,虽然变的比较灵活,但是响应的操作也会变复杂。
最后呢,还是祝大家圣诞节快乐,都能收到自己喜欢的礼物<a>(❤ ω ❤)</a>。
喜欢的话戳一下喜欢呗。
有什么建议的话希望大家能在下方回复(●'◡'●),
上一篇:建造者模式
下一篇:策略模式(待更)