1.裝飾者模式的簡介
裝飾模式:動態(tài)的給一個對象添加一些額外的職責预明,就增加功能來說瞬项,裝飾者到相比子類更加靈活
裝飾著的特點:裝飾器和被裝飾器都實現(xiàn)同一個接口
羔巢, 主要目的裝飾器和被裝飾器都實現(xiàn)同一個接口, 主要目的是為了擴展之后依舊保留 OOP 關(guān)系(同宗同源)
應用場景:IO 流包裝浅妆、 數(shù)據(jù)源包裝墅诡、 簡歷包裝
為什么說是動態(tài)的將責任附加到對象身上壳嚎,因為裝飾者模式有了裝飾角色,就可以根據(jù)需要動態(tài)的裝飾不同的具體構(gòu)件角色和具體裝飾角色末早,這個具體構(gòu)件和裝飾角色是可以動態(tài)的切換的
在spring中的引用: Spring 的 ApplicationContext 中配置所有的 DataSource
烟馅。 這些 DataSource 可能是各種不同類型的, 比如不同的數(shù)據(jù)庫: Oracle然磷、 SQL Server郑趁、 MySQL 等, 也可能是不同的數(shù)據(jù)源: 比如Apache 提 供 的 org.apache.commons.dbcp.BasicDataSource 姿搜、 Spring 提 供 的org.springframework.jndi.JndiObjectFactoryBean 等寡润。 然后 SessionFactory 根據(jù)客戶的每次請求, 將 DataSource 屬性設(shè)置成不同的數(shù)據(jù)源舅柜, 以到達切換數(shù)據(jù)源的目的梭纹。
在spring的命名體現(xiàn):Spring 中用到的包裝器模式在類名上有兩種表現(xiàn): 一種是類名中含有 Wrapper
, 另一種是類名中含有Decorator
致份。 基本上都是動態(tài)地給一個對象添加一些額外的職責
2.裝飾者模式的結(jié)構(gòu)
裝飾者模式以對客戶透明的方式動態(tài)地給一個對象附加上更多的責任变抽。換言之,客戶端并不會覺得對象在裝飾前和裝飾后有什么不同氮块。裝飾者模式可以在不使用創(chuàng)造更多子類的情況下绍载,將對象的功能加以擴展。
裝飾者模式的類圖如下
在裝飾模式中的角色有:
抽象構(gòu)件(Component)角色
:給出一個抽象接口滔蝉,以規(guī)范準備接收附加責任的對象击儡。具體構(gòu)件(ConcreteComponent)角色
:定義一個將要接收附加責任的類。裝飾(Decorator)角色
:持有一個構(gòu)件(Component)對象的實例锰提,并定義一個與抽象構(gòu)件接口一致的接口曙痘。具體裝飾(ConcreteDecorator)角色
:負責給構(gòu)件對象“貼上”附加的責任。
3.裝飾者模式的實例演示
實例介紹:
在原有的登錄的接口的情況下立肘,動態(tài)的增加了發(fā)送短信的功能
抽象構(gòu)件角色 定義登錄的接口
/**
* @Project: spring
* @description: 抽象構(gòu)件角色 登錄的接口業(yè)務
* @author: sunkang
* @create: 2018-09-05 20:51
* @ModificationHistory who when What
**/
public interface ISiginSerevice {
ResultMsg login(String username, String password);
}
具體構(gòu)件角色 ,登錄的具體實現(xiàn)
/***
* @Description:
* @Param: 具體構(gòu)件角色 登錄的具體實現(xiàn)
* @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());
}
}
裝飾角色边坤,拓展了發(fā)送短信的功能
/**
* @Project: spring
* @description: 裝飾角色 拓展了發(fā)送短信的功能
* @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);
/**
* 發(fā)送短信
* @param msg
* @return
*/
ResultMsg sendShortMessage(String msg);
}
具體的裝飾角色,原有的登錄功能動態(tài)增加了發(fā)送短信的功能
/**
* @Project: spring
* @description: 具體的裝飾角色 原有的登錄功能增加了發(fā)送短信的功能
* @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);
//注冊成功發(fā)送短信的功能
if(msg.getCode().equals("200")){
System.out.println("用戶登錄成功");
msg = sendShortMessage(username);
}
return msg;
}
/**
* 發(fā)送短信的功能 這個是裝飾器 增加的額外的功能,在登錄成功之后發(fā)送短信通知
* @param username
* @return
*/
@Override
public ResultMsg sendShortMessage(String username) {
System.out.println("恭喜用戶:"+username+"發(fā)送短信成功");
return new ResultMsg("200","發(fā)送短信成功",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");
}
}
測試結(jié)果