设计模式——装饰者模式
2016-03-03 20:19
357 查看
好几天没出博客了,在学习Android的一些新控件的时候,用到了一个模式,叫装饰者模式,所以在此讲讲这个模式。
装饰者模式,又名包装(Wrapper)模式,包含以下四个角色:
1、抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
2、具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
3、装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
4、具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。
UML关系图(图是我用画图工具画的,实在有点丑,不要介意):
装饰者模式UML
比喻:小明想去买手机,去了手机店,看到智能机,想要一部智能机,选择Android手机,但看到的一部Android机,Android手机只能玩Android游戏,目前还想要带音乐的安卓机,服务员过来,按照着音乐手机把音乐功能加进去了(当然现在Android机都带音乐,只是假设没带音乐功能)。
1)抽象构件角色IPhone,可以是接口或抽象类,这里比喻做手机(这里定义为IPhone,前面的I是接口的意思,并不是苹果手机):
/**
* 手机(抽象构件角色)
*/
public interface IPhone {
void function();
}
2)具体构件角色MusicPhone,这里比喻做音乐手机:
/**
* 音乐手机(具体构件角色)
*/
public class MusicPhone implements IPhone {
@Override
public void function() {
Log.i("MusicPhone","可以听音乐!");
}
}
3)装饰角色SmartPhone,并创建一个抽象方法,把处理的事情延迟到子类中处理,这里比喻为智能机:
/**
* 智能机(装饰角色)
*/
public abstract class SmartPhone implements IPhone{
IPhone iPhone;
public SmartPhone(IPhone iPhone) {
this.iPhone=iPhone;
}
@Override
public void function() {
iPhone.function();
}
abstract void advancedFunction();
}
4)具体装饰角色AndroidPhone,这里比喻为安卓机:
/**
* 安卓机(具体装饰角色)
*/
public class AndroidPhone extends SmartPhone{
public AndroidPhone(IPhone iPhone) {
super(iPhone);
}
@Override
public void function() {
super.function();
advancedFunction();
}
@Override
void advancedFunction() {
Log.i("AndroidPhone","可以玩android游戏!");
}
}
5)调用如下:
private void initDecorator() {
IPhone musicPhone=new MusicPhone();
IPhone androidPhone=new AndroidPhone(musicPhone);
androidPhone.function();
}
优点:
1、比继承更加的灵活。
2、可以动态扩展一个对象功能。
缺点:
1、会产生很多的小对象,增加了代码的复杂性。
2、出错排查比较的麻烦。
使用场合:
1、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
2、需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
装饰者模式,又名包装(Wrapper)模式,包含以下四个角色:
1、抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
2、具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
3、装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
4、具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。
UML关系图(图是我用画图工具画的,实在有点丑,不要介意):
装饰者模式UML
比喻:小明想去买手机,去了手机店,看到智能机,想要一部智能机,选择Android手机,但看到的一部Android机,Android手机只能玩Android游戏,目前还想要带音乐的安卓机,服务员过来,按照着音乐手机把音乐功能加进去了(当然现在Android机都带音乐,只是假设没带音乐功能)。
1)抽象构件角色IPhone,可以是接口或抽象类,这里比喻做手机(这里定义为IPhone,前面的I是接口的意思,并不是苹果手机):
/**
* 手机(抽象构件角色)
*/
public interface IPhone {
void function();
}
2)具体构件角色MusicPhone,这里比喻做音乐手机:
/**
* 音乐手机(具体构件角色)
*/
public class MusicPhone implements IPhone {
@Override
public void function() {
Log.i("MusicPhone","可以听音乐!");
}
}
3)装饰角色SmartPhone,并创建一个抽象方法,把处理的事情延迟到子类中处理,这里比喻为智能机:
/**
* 智能机(装饰角色)
*/
public abstract class SmartPhone implements IPhone{
IPhone iPhone;
public SmartPhone(IPhone iPhone) {
this.iPhone=iPhone;
}
@Override
public void function() {
iPhone.function();
}
abstract void advancedFunction();
}
4)具体装饰角色AndroidPhone,这里比喻为安卓机:
/**
* 安卓机(具体装饰角色)
*/
public class AndroidPhone extends SmartPhone{
public AndroidPhone(IPhone iPhone) {
super(iPhone);
}
@Override
public void function() {
super.function();
advancedFunction();
}
@Override
void advancedFunction() {
Log.i("AndroidPhone","可以玩android游戏!");
}
}
5)调用如下:
private void initDecorator() {
IPhone musicPhone=new MusicPhone();
IPhone androidPhone=new AndroidPhone(musicPhone);
androidPhone.function();
}
优点:
1、比继承更加的灵活。
2、可以动态扩展一个对象功能。
缺点:
1、会产生很多的小对象,增加了代码的复杂性。
2、出错排查比较的麻烦。
使用场合:
1、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
2、需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
相关文章推荐
- NLTK学习笔记——Classify模块(2)
- 蓝桥杯六7牌型种类
- 安卓类似于微信朋友圈功能,集合了Gson,PhotoView,android-universal-image-loader这些用法
- 多阶段决策模板(2059)
- c语言常出错误
- 使用wireshark常用的过滤命令
- granfan inflxDB zabbix
- kaptcha验证码
- Masonry自动布局学习博客网址
- 一个经典的字母排列算法
- 区间DP LightOJ 1422 Halloween Costumes
- c++通过类名动态创建对象
- uva725 Division
- codeforces 633C. Spy Syndrome 2 trie + dp
- JAR包
- svn更新出现冲突的解决方法
- Handler机制总结
- bzoj1799 self 同类分布 数位Dp
- NLTK学习笔记——Classify模块(1)
- 利用IIS和花生壳在校园网IP下搭建简单网站超详细教程