1、定义:
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。
2、结构图:
3、协作角色
Component 定义一个对象的接口,可以给这些对象动态的增加职责。
ConcreteComponent 定义一个对象,可以给这些对象添加一些职责。
Decorator 维持一个Component对象的指针,并定义一个与Component 接口一致的接口。
Component向组件添加职责
4、适用性
在不影响其他对象的情况下,以动态,透明的方式给对象添加职责。
处理那些可以撤销的职责。
5、实例
linux串行子系统,其层次结构如下,
(1) 关注UART或者其他硬件的驱动
(2) tty驱动层,将上层驱动程序和硬件隔离
(3) 线路规程,以特殊方式格式化从客户或者硬件上得到的数据,有助于复用底层代码
这个子系统中,线路规程和装饰模式类似
每个具体的线路规程完成结构体:
struct tty_ldisc_ops {
int magic;
char *name;
int num;
int flags;
/*
* The following routines are called from above.
*/
int (*open)(struct tty_struct *);
void (*close)(struct tty_struct *);
void (*flush_buffer)(struct tty_struct *tty);
ssize_t (*chars_in_buffer)(struct tty_struct *tty);
ssize_t (*read)(struct tty_struct * tty, struct file * file,
unsigned char __user * buf, size_t nr);
ssize_t (*write)(struct tty_struct * tty, struct file * file,
const unsigned char * buf, size_t nr);
int (*ioctl)(struct tty_struct * tty, struct file * file,
unsigned int cmd, unsigned long arg);
long (*compat_ioctl)(struct tty_struct * tty, struct file * file,
unsigned int cmd, unsigned long arg);
void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
unsigned int (*poll)(struct tty_struct *, struct file *,
struct poll_table_struct *);
int (*hangup)(struct tty_struct *tty);
/*
* The following routines are called from below.
*/
void (*receive_buf)(struct tty_struct *, const unsigned char *cp,
char *fp, int count);
void (*write_wakeup)(struct tty_struct *);
struct module *owner;
int refcount;
};
通过tty_register_ldisc注册到tty_ldiscs中,在应用层动态绑定到设备上负责按照指定的协议格式化数据。