1.装饰者模式的简介
装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰者到相比子类更加灵活
装饰着的特点:装饰器和被装饰器都实现同一个接口
, 主要目的装饰器和被装饰器都实现同一个接口, 主要目的是为了扩展之后依旧保留 OOP 关系(同宗同源)
应用场景:IO 流包装、 数据源包装、 简历包装
为什么说是动态的将责任附加到对象身上,因为装饰者模式有了装饰角色,就可以根据需要动态的装饰不同的具体构件角色和具体装饰角色,这个具体构件和装饰角色是可以动态的切换的
在spring中的引用: Spring 的 ApplicationContext 中配置所有的 DataSource
。 这些 DataSource 可能是各种不同类型的, 比如不同的数据库: Oracle、 SQL Server、 MySQL 等, 也可能是不同的数据源: 比如Apache 提 供 的 org.apache.commons.dbcp.BasicDataSource 、 Spring 提 供 的org.springframework.jndi.JndiObjectFactoryBean 等。 然后 SessionFactory 根据客户的每次请求, 将 DataSource 属性设置成不同的数据源, 以到达切换数据源的目的。
在spring的命名体现:Spring 中用到的包装器模式在类名上有两种表现: 一种是类名中含有 Wrapper
, 另一种是类名中含有Decorator
。 基本上都是动态地给一个对象添加一些额外的职责
2.装饰者模式的结构
装饰者模式以对客户透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰者模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。
装饰者模式的类图如下
在装饰模式中的角色有:
抽象构件(Component)角色
:给出一个抽象接口,以规范准备接收附加责任的对象。具体构件(ConcreteComponent)角色
:定义一个将要接收附加责任的类。装饰(Decorator)角色
:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。具体装饰(ConcreteDecorator)角色
:负责给构件对象“贴上”附加的责任。
3.装饰者模式的实例演示
实例介绍:
在原有的登录的接口的情况下,动态的增加了发送短信的功能
抽象构件角色 定义登录的接口
/**
* @Project: spring
* @description: 抽象构件角色 登录的接口业务
* @author: sunkang
* @create: 2018-09-05 20:51
* @ModificationHistory who when What
**/
public interface ISiginSerevice {
ResultMsg login(String username, String password);
}
具体构件角色 ,登录的具体实现
/***
* @Description:
* @Param: 具体构件角色 登录的具体实现
* @return:
* @Author: sunkang
* @Date: 2018/9/5
*/
public class SiginService implements ISiginSerevice {
/**
* 登录的方法
* @param username
* @param password
* @return
*/
public ResultMsg login(String username,String password){
return new ResultMsg("200","登录成功",new Object());
}
}
装饰角色,拓展了发送短信的功能
/**
* @Project: spring
* @description: 装饰角色 拓展了发送短信的功能
* @author: sunkang
* @create: 2018-09-05 21:41
* @ModificationHistory who when What
**/
public interface ISiginForThirdService extends ISiginSerevice {
/**
* 原有登录的方法
* @param username
* @param password
* @return
*/
ResultMsg login(String username, String password);
/**
* 发送短信
* @param msg
* @return
*/
ResultMsg sendShortMessage(String msg);
}
具体的装饰角色,原有的登录功能动态增加了发送短信的功能
/**
* @Project: spring
* @description: 具体的装饰角色 原有的登录功能增加了发送短信的功能
* @author: sunkang
* @create: 2018-09-06 09:14
* @ModificationHistory who when What
**/
public class SiginForThirdService implements ISiginForThirdService {
private ISiginSerevice siginSerevice ;
public SiginForThirdService(ISiginSerevice siginSerevice) {
this.siginSerevice = siginSerevice;
}
@Override
public ResultMsg login(String username, String password) {
ResultMsg msg = siginSerevice.login(username,password);
//注册成功发送短信的功能
if(msg.getCode().equals("200")){
System.out.println("用户登录成功");
msg = sendShortMessage(username);
}
return msg;
}
/**
* 发送短信的功能 这个是装饰器 增加的额外的功能,在登录成功之后发送短信通知
* @param username
* @return
*/
@Override
public ResultMsg sendShortMessage(String username) {
System.out.println("恭喜用户:"+username+"发送短信成功");
return new ResultMsg("200","发送短信成功",new Object());
}
}
测试案例
/**
* @Project: spring
* @description: 装饰者测试
* @author: sunkang
* @create: 2018-09-06 09:23
* @ModificationHistory who when What
**/
public class SiginTest {
public static void main(String[] args) {
ISiginSerevice siginSerevice = new SiginService();
ISiginSerevice siginForThirdService = new SiginForThirdService(siginSerevice);
siginForThirdService.login("sunkang","4324");
}
}
测试结果