接下去我们要介绍结构型模式,它描述如何将类或者对象结合在一起形成更大的结构,就像搭积木,可以通过简单积木的组合形成复杂的、功能更为强大的结构。
结构型模式可以分为类结构型模式和对象结构型模式:
- 类结构型模式关心类的组合,由多个类可以组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系。
对象结构型模式关心类与对象的组合,通过关联关系使得在一 个类中定义另一个类的实例对象,然后通过该对象调用其方法。 根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式。
定义
王者荣耀是目前很热门的一款游戏,号称国民游戏,而我是一个菜逼玩家,这时候我就想怎么才能快速上星变成百星王者,于是我就想到了找代练玩家,让他们帮忙上百星,而这里的百星玩家就是一个代理,整个流程就是代理模式的大白话。
代理模式(Proxy Pattern) :为其他对象提供一种代理以控制对这个对象的访问。代理模式也叫做委托模式,它是一项基本设计技巧。许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式,而且在日常的应用中,代理模式可以提供非常好的访问控制。
类图
● Subject抽象主题角色
抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。
● RealSubject具体主题角色
也叫做被委托角色、被代理角色。它才是冤大头,是业务逻辑的具体执行者。
● Proxy代理主题角色
也叫做委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
优缺点
优点
职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰。
高扩展性
具体主题角色是随时都会发生变化的,只要它实现了接口,甭管它如何变化,那我们的代理类完全就可以在不做任何修改的情况下使用。
智能化
参考动态代理。
缺点
- 由于在客户端和真实主题之间增加了代理对象,因此 有些类型的代理模式可能会造成请求的处理速度变慢。
- 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
实现
这里我们就以王者荣耀代练作为示例实现:
先定义一个王者荣耀玩家接口,玩家有排位方法:
public interface HonorOfKingsPlayer {
void rank();
}
再定义一个小陈这样的菜逼玩家实现王者荣耀玩家接口:
public class CaibiPlayer implements HonorOfKingsPlayer {
private String name;
public CaibiPlayer(String name) {
this.name = name;
}
@Override
public void rank() {
System.out.println(name + "账号开始5V5排位");
}
}
再定义一个代练:
public class PowerLeveling implements HonorOfKingsPlayer {
private final HonorOfKingsPlayer honorOfKingsPlayer;
public PowerLeveling(HonorOfKingsPlayer honorOfKingsPlayer) {
this.honorOfKingsPlayer = honorOfKingsPlayer;
}
@Override
public void rank() {
System.out.println("代练开始工作");
this.honorOfKingsPlayer.rank();
}
}
定义客户端类:
public class Client {
public static void main(String[] args) {
CaibiPlayer caibiPlayer=new CaibiPlayer("小陈");
PowerLeveling powerLeveling=new PowerLeveling(caibiPlayer);
powerLeveling.rank();
}
}
输出:
代练开始工作
小陈账号开始5V5排位
这里的例子其实十分简单,但是实际运用很广泛,远不止这么简单,但是原理是一样的,例如我们学习Spring最常听到的AOP其实就是一个动态代理。
下一篇就研究一下动态代理吧!