Spring设计模式(配饰器模式)

博客用于学习记录:方便以后回顾

本来的学习计划是先梳理一下Java的知识点,在看Go语言的,慢慢的走近区块链的方向。没想到公司今天就区块链部门就成立了,还以为是在明年年初才会组建团队。自己待在自己的舒适区里,自认为外界都没有变化,其实只是固封在自己的深井。

这个模式还是我被面试的时候问一个设计模式,问的时候我还没有答好?

模式的定义:

配饰器模式的定义:

动态地为一个对象添加一些额外的职责,若要扩展一个对象的功能,装饰者提供了比继承更有弹性的替代方案。

模式的结构图 :

类适配器(UML):适配器核心Adapter直接继承自Adaptee

Java中那些类是装饰器模式_设计模式

对象适配器(UML):(核心Adapter和Adaptee是关联关系)

Java中那些类是装饰器模式_Java中那些类是装饰器模式_02

模式包含角色 :

**目标(Target):**这就是所期待得到的接口。注意:由于这里讨论的是类适配器模式,因此目标不可以是类。

**源(Adapee):**现在需要适配的接口。

**适配器(Adaper):**适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不可以是接口,而必须是具体类。

使用场景 :

Spring AOP 模块对 BeforeAdvice、AfterAdvice、ThrowsAdvice 三种通知类型的支持实际上是借
助适配器模式来实现的,这样的好处是使得框架允许用户向框架中加入自己想要支持的任何一种通知类

模式具体实现 :

配饰器有两种实现方式,一种是直接继承一种是组合方式。

初始化bean
@AllArgsConstructor
@Data
@Builder
public class ResultMsg {
    private String code;
    private String msg;
    private Object data;
}
一 :创建源
public interface RegistService {
    /**
     * 注册方法
     * @param username 用户名
     * @param password 手机号
     * @return
     */
    public ResultMsg regist(String username, String password);

}
二 :创建目标
public class SiginForThirdService {
    public ResultMsg regist(String openId){
        ResultMsg resultMsg = new ResultMsg("200","注册成功",openId+"成功");
        System.out.println(resultMsg.toString());
        return resultMsg;
    }

}
三 :创建继承模式适配器
public class RegistForQQ  extends SiginForThirdService implements RegistService {
    public ResultMsg regist(String username, String password) {
        String openId =  password + username;
        return super.regist(openId);
    }
}
四 :创建组合模式适配器
public class RegistForWeChat  implements RegistService {

    SiginForThirdService siginForThirdService;

    public RegistForWeChat(SiginForThirdService siginForThirdService) {
        this.siginForThirdService = siginForThirdService;
    }

    public ResultMsg regist(String username, String password) {
        String openId = username + password;
        return siginForThirdService.regist(openId);
    }
}
五 测试
public class AdapterTest {
    @Test
    public void test_refistForQQ(){
        RegistService registService = new RegistForQQ();
        registService.regist("userName","passWord");
    }

    @Test
    public void test_refistForWeChat(){
        RegistService registService = new RegistForWeChat(new SiginForThirdService());
        registService.regist("userName","passWord");
    }
}