接下去我们要介绍结构型模式,它描述如何将类或者对象结合在一起形成更大的结构,就像搭积木,可以通过简单积木的组合形成复杂的、功能更为强大的结构。

结构型模式可以分为类结构型模式和对象结构型模式:

  • 类结构型模式关心类的组合,由多个类可以组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系。

对象结构型模式关心类与对象的组合,通过关联关系使得在一 个类中定义另一个类的实例对象,然后通过该对象调用其方法。 根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式。

定义

王者荣耀是目前很热门的一款游戏,号称国民游戏,而我是一个菜逼玩家,这时候我就想怎么才能快速上星变成百星王者,于是我就想到了找代练玩家,让他们帮忙上百星,而这里的百星玩家就是一个代理,整个流程就是代理模式的大白话。

代理模式(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其实就是一个动态代理。
下一篇就研究一下动态代理吧!