装饰模式职责

  • 动态地为一个对象增加新的功能
  • 装饰模式是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快读膨胀。


实现细节

  • Component抽象组件角色:真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互。
  • ConcreteComponent 具体组件角色(真实对象):如io流中的FileInputStream、FileOutputStream
  • Decorator装饰角色:持有一个抽象组件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象。这样,就能在真实对象调用前后增加新的功能。
  • ConcreteDecorator具体装饰角色:负责给构件对象增加新的责任。




简单案例说明




总结

装饰模式(Decorator)也叫包装器模式(Wrapper)

装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。


优点

  • 扩展对象功能,比继承灵活,不会导致类个数急剧增加
  • 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象
  • 具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类




抽象组件

IComponent.java

package 设计模式.装饰模式.抽象组件;

/**
* Component抽象组件角色:真实对象和装饰对象有相同的接口
*
* @author 陈霓清
*/
public interface IComponent {
/**
* 攻击
*/
void attack();
}

真实对象

古利特.java

package 设计模式.装饰模式.真实对象;

import 设计模式.装饰模式.抽象组件.IComponent;

/**
* 具体组件角色(真实对象)
*
* @author 陈霓清
*/
public class 古利特 implements IComponent {

@Override
public void attack() {
System.out.println("攻击");
}
}


装饰角色

Decorator.java

package 设计模式.装饰模式.装饰角色;

import 设计模式.装饰模式.抽象组件.IComponent;

/**
* 装饰角色:持有一个抽象组件的引用
*
* @author 陈霓清
*/
public class Decorator implements IComponent {

private IComponent component;

public Decorator(IComponent component) {
this.component = component;
}

@Override
public void attack() {
component.attack();
}

}

迅雷喷气机.java

package 设计模式.装饰模式.装饰角色;

import 设计模式.装饰模式.抽象组件.IComponent;

public class 迅雷喷气机 extends Decorator {

public 迅雷喷气机(IComponent component) {
super(component);
}

public void fly() {
System.out.println("飞行");
}

@Override
public void attack() {
super.attack();
fly();
}
}

双重钻孔机.java

package 设计模式.装饰模式.装饰角色;

import 设计模式.装饰模式.抽象组件.IComponent;

public class 双重钻孔机 extends Decorator {

public 双重钻孔机(IComponent component) {
super(component);
}

public void laser() {
System.out.println("双重镭射");
}

@Override
public void attack() {
super.attack();
laser();
}
}

客户端调用

Client.java

package 设计模式.装饰模式;

import 设计模式.装饰模式.真实对象.古利特;
import 设计模式.装饰模式.装饰角色.双重钻孔机;
import 设计模式.装饰模式.装饰角色.迅雷喷气机;

public class Client {

public static void main(String[] args) {
古利特 gridman = new 古利特();
gridman.attack();

System.out.println("增加新的功能,飞行----------");
迅雷喷气机 temp1 = new 迅雷喷气机(gridman);
temp1.attack();

System.out.println("增加新的功能,镭射攻击---------");
双重钻孔机 temp2 = new 双重钻孔机(gridman);
temp2.attack();
}
}


回到顶部