手撕装饰者模式(附源码+代码实现+UML)

一 装饰模式的应用分析
1.1 InputStream的类结构图:
在这里插入图片描述
public interface Cache {
String getId();
void putObject(Object varl,Object var2);
Object getObject(Object var1);
Object removeObject(Object var1);
void clear();
int getSize();
ReadWriteLock getReadWriteLock();
}
1.2 Spring 中TransactionAwareCacheDecorator事务缓存
private final Cache targetCache;
/**

  • Create a new TransactionAwareCache for the given target Cache.

  • @param targetCache the target Cache to decorate
    /
    public TransactionAwareCacheDecorator(Cache targetCache) {
    Assert.notNull(targetCache, “Target Cache must not be null”);
    this.targetCache = targetCache;
    }
    /
    *

  • Return the target Cache that this Cache should delegate to.
    */
    public Cache getTargetCache() {
    return this.targetCache;
    }
    TransactionAwareCacheDecorator 就是对Cache的一个包装。
    1.3 MVC中的装饰者模式HttpHeadResponseDecorator类
    public class HttpHeadResponseDecorator extends ServerHttpResponseDecorator {

    public HttpHeadResponseDecorator(ServerHttpResponse delegate) {
    super(delegate);
    }
    1.4
    Mybatis 中的 处理缓存的设计

在这里插入图片描述
二 定义
装饰者模式是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有的对象的功能),属于结构型模式。装饰者模式在我们的生活中应用也是比较多的,比如,买车子选配置,卖电脑增加配置等等。给对象扩展一些额外的功能。
适用场景
1 用于扩展一个类的功能或者给一个类添加附加职责。

2、动态的给一个对象添加功能,这些功能在动态的撤销。

装饰者模式最本质的特征是将原有的类的附加功能抽离出来,简化原有类的逻辑。通过这样的案例,我们可以得出结论,其实抽象的装饰者是可有可无的,具体可以根据业务模型来进行选择。
装饰者模式的优缺点

优点:
1、装饰者是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象扩展功能,即插即用

2、通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同的效果

3、装饰者完全遵循开闭原则

缺点:
1、会出现更多的代码,更多的类,增加程序的复杂性

2、动态装饰时,多层装饰时会更加复杂。
三 代码实现
需求——用装饰模式实现登录功能 (实现第三方登录)
3.1准备
a 用户类
public class User {
private String username;
private String password;
private String mid;
private String info;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMid() {
return mid;
}
public void setMid(String mid) {
this.mid = mid;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return “User [username=” + username + “, password=” + password + “, mid=” + mid + “, info=” + info + “]”;
}
}
返回信息类
public class ResultMsg {
private int code;
private String msg;
private Object data;
public ResultMsg(int code, String msg, Object data) {
super();
this.code = code;
this.msg = msg;
this.data = data;
}

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}

public String getMsg() {
return msg;
}

public void setMsg(String msg) {
this.msg = msg;
}

public Object getData() {
return data;
}

public void setData(Object data) {
this.data = data;
}

@Override
public String toString() {
return “ResultMsg [code=” + code + “, msg=” + msg + “, data=” + data + “]”;
}

}

3.2 登录基本实现
public interface loginService {
/**
* 注册接口
* @param name
* @param psw
* @return
*/
ResultMsg regist(String name, String psw);

/**

  • 登录接口
  • @param name
  • @param psw
  • @return
    */

ResultMsg login(String name, String psw);

}
登录实现类
public class loginServiceImpl implements loginService{

@Override
public ResultMsg regist(String name, String psw) {
	// TODO Auto-generated method stub
	return new ResultMsg(200, "注册成功", new User());
}

@Override
public ResultMsg login(String name, String psw) {
	// TODO Auto-generated method stub
	return null;
}

}
3.3 升级至第三方登录
public interface loginThirdService extends loginService{
//QQ登录
ResultMsg loginForQQ(String id);
//微信登录
ResultMsg loginForWeChat(String id);

//手机号登录
ResultMsg loginForPhone(String telephone,String code);

//token 登录
ResultMsg loginForToken(String id);

}
第三方登录实现类
public class loginForThirdServiceImpl implements loginThirdService{

private loginService loginService;


public loginForThirdServiceImpl(com.cy.decoractor.loginService loginService) {
	super();
	this.loginService = loginService;
}

@Override
public ResultMsg regist(String name, String psw) {
	// TODO Auto-generated method stub
	return loginService.regist(name, psw);
}

@Override
public ResultMsg login(String name, String psw) {
	// TODO Auto-generated method stub
	return loginService.login(name, psw);
}

@Override
public ResultMsg loginForQQ(String id) {
	// TODO Auto-generated method stub
	System.out.println("ID"+"的用户开始登录操作");
	return new ResultMsg(200, "QQ登录成功", new User());
}

@Override
public ResultMsg loginForWeChat(String id) {
	// TODO Auto-generated method stub
	System.out.println("ID"+"的用户开始登录操作");
	return new ResultMsg(200, "微信登录成功", new User());
}

@Override
public ResultMsg loginForPhone(String telephone, String code) {
	System.out.println("ID"+"的用户开始登录操作");
	return new ResultMsg(200, "手机登录成功", new User());
}

@Override
public ResultMsg loginForToken(String id) {
	// TODO Auto-generated method stub
	System.out.println("ID"+"的用户开始登录操作");
	return new ResultMsg(200, "Token登录成功", new User());
}

}
客户端测试:
public static void main(String[] args) {
loginThirdService loginForThirdService = new loginForThirdServiceImpl(new loginServiceImpl());

ResultMsg resultMsg = loginForThirdService.loginForQQ("1231233");

System.out.println(resultMsg.getMsg());

}
运行结果
在这里插入图片描述
装饰者模式和适配器模式对比

装饰者和适配者都是包装模式,装饰者也是一种特殊的代理模式。
装饰者模式 适配器模式
定义 装饰者和被装饰者都实现同一个 接口,主要目的是为了扩展之后依旧保留OOP关系 适配器和被适配者没有必然的联系,通常采用继承或者代理的形式进行包装
形式 是一种非常特殊的适配器模式 没有层级关系,装饰者模式有层级关系
关系 满足 is-a 的关系 满足has -a的关系
功能 注重覆盖和扩展 注重兼容和转换
设计 前置考虑 后置考虑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值