【Java入门提高篇】Day10 Java代理——静态代理
今天要介绍的是一个Java中一个很重要的概念——代理。
什么是代理?联系生活想想看,代理似乎并不陌生,最形象的代表便是经纪人,明星一般都有经纪人,经纪人作为中间人,负责代理明星的相关事宜,比如说,有人要请明星去唱歌表演,一般不会直接跟明星联系,而是联系他的经纪人,他的经纪人来负责安排行程,而真正唱歌表演的还是明星本人,经纪人仅仅作为一个附加物存在。
在Java中,代理也是这样的概念,来看个栗子:
先来创建一个明星类Stars:
public class Stars implements IStars{
private String name;
public Stars(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sing(){
System.out.println(getName() + " 唱了一首歌.");
}
public void dance(){
System.out.println(getName() + " 跳了一支舞.");
}
}
这是相应的接口:
public interface IStars {
void sing();
void dance();
}
现在创建一个代理类:
public class StarsProxy implements IStars{
//保存接收的代理对象
private IStars stars;
public StarsProxy(IStars stars){
this.stars = stars;
}
@Override
public void sing() {
System.out.println("我是代理,我收到了唱歌请求。");
stars.sing();
System.out.println("唱歌完毕");
}
@Override
public void dance() {
System.out.println("我是代理,我收到了跳舞请求。");
stars.dance();
System.out.println("跳舞完毕");
}
}
来测试一下:
public class Test {
public static void main(String[] args){
//创建目标对象
IStars stars = new Stars("Frank");//代理对象,把目标传给代理对象,建立关系
IStars starsProxy = new StarsProxy(stars);
starsProxy.sing();
starsProxy.dance();
}
}
运行结果:
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了跳舞请求。
Frank 跳了一支舞.
跳舞完毕
我们可以看到,实际上代理类只是保存了Stars类的一个实例,因为实现的是相同的接口,StarsProxy类必须实现需要代理的Stars类的方法,比如这里的dance和sing,而这个接口正是链接两者的关键,因为实现接口就代表必定存在接口中声明的方法。
那么,为什么要使用代理呢?
其实主要目的是为了扩展原有类的功能,想想看,如果那个Stars类不是你写的,而是别人写的,现在要将原有的sing或者dance方法进行改造,比如需要统计唱歌和跳舞的次数,次数大于10则不进行该操作直接返回,这时候用代理就很好实现了,来把代理类稍作修改:
public class StarsProxy implements IStars{
//保存接收的代理对象
private IStars stars;
//保存sing和dance的次数
private int num;
public StarsProxy(IStars stars){
this.stars = stars;
}
@Override
public void sing() {
if (!ifWork()) {
return;
}
System.out.println("我是代理,我收到了唱歌请求。");
stars.sing();
System.out.println("唱歌完毕");
}
@Override
public void dance() {
if (!ifWork()) {
return;
}
System.out.println("我是代理,我收到了跳舞请求。");
stars.dance();
System.out.println("跳舞完毕");
}
/**
* 是否继续工作
* @return 是返回true,否则返回false
*/
private boolean ifWork(){
if (num > 3){
System.out.println("明星今天已经很累了,明天再来吧。");
return false;
}else {
num++;
return true;
}
}
}
修改一下测试类:
public class Test {
public static void main(String[] args){
//创建目标对象
Stars stars = new Stars();
stars.setName("Frank");
//代理对象,把目标传给代理对象,建立关系
StarsProxy starsProxy = new StarsProxy(stars);
for (int i = 0;i < 5; i++){
starsProxy.sing();
}
}
}
测试结果如下:
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
明星今天已经很累了,明天再来吧。
看,简单粗暴。
但其实并没有多少干货,这里仅仅是一种代理的思想,用这种思想可以比较方便的在不直接修改原有类的前提下对原有类的方法进行扩展。为某个对象提供一个代理,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。可以使业务类只关注业务逻辑本身,保证了业务类的重用性,这也是代理的共有优点。
但是限制也显而易见:
1.代理类需要跟被代理类实现相同的接口,这样才能一起向上转型后实现多态。
2.当被代理的类需要进行的扩展增多时,管理会变得更加困难,之后对被代理类的修改,需要同时修改代理类,增加了修改成本。
所以不要为了使用而使用,应用在合适的场景才能发挥它真正的作用。
至此,本篇讲解完毕,欢迎大家继续关注!
【Java入门提高篇】Day10 Java代理——静态代理的更多相关文章
- 【Java入门提高篇】Java集合类详解(一)
今天来看看Java里的一个大家伙,那就是集合. 集合嘛,就跟它的名字那样,是一群人多势众的家伙,如果你学过高数,没错,就跟里面说的集合是一个概念,就是一堆对象的集合体.集合就是用来存放和管理其他类对象 ...
- 【Java入门提高篇】Day11 Java代理——JDK动态代理
今天来看看Java的另一种代理方式--JDK动态代理 我们之前所介绍的代理方式叫静态代理,也就是静态的生成代理对象,而动态代理则是在运行时创建代理对象.动态代理有更强大的拦截请求功能,因为可以获得类的 ...
- 【Java入门提高篇】Day12 Java代理——Cglib动态代理
今天来介绍另一种更为强大的代理——Cglib动态代理. 什么是Cglib动态代理? 我们先回顾一下上一篇的jdk动态代理,jdk动态代理是通过接口来在运行时动态创建委托类的代理对象,但是跟静态代理一样 ...
- 【Java入门提高篇】Day1 抽象类
基础部分内容差不多讲解完了,今天开始进入Java提高篇部分,这部分内容会比之前的内容复杂很多,希望大家做好心理准备,看不懂的部分可以多看两遍,仍不理解的部分那一定是我讲的不够生动,记得留言提醒我. 好 ...
- 【Java入门提高篇】Day13 Java中的反射机制
前一段时间一直忙,所以没什么时间写博客,拖了这么久,也该更新更新了.最近看到各种知识付费的推出,感觉是好事,也是坏事,好事是对知识沉淀的认可与推动,坏事是感觉很多人忙于把自己的知识变现,相对的在沉淀上 ...
- 【Java入门提高篇】Day21 Java容器类详解(四)ArrayList源码分析
今天要介绍的是List接口中最常用的实现类——ArrayList,本篇的源码分析基于JDK8,如果有不一致的地方,可先切换到JDK8后再进行操作. 本篇的内容主要包括这几块: 1.源码结构介绍 2.源 ...
- 【Java入门提高篇】Day16 Java异常处理(下)
今天继续讲解java中的异常处理机制,主要介绍Exception家族的主要成员,自定义异常,以及异常处理的正确姿势. Exception家族 一图胜千言,先来看一张图. Exception这是一个父类 ...
- 【Java入门提高篇】Day31 Java容器类详解(十三)TreeSet详解
上一篇很水的介绍完了TreeMap,这一篇来看看更水的TreeSet. 本文将从以下几个角度进行展开: 1.TreeSet简介和使用栗子 2.TreeSet源码分析 本篇大约需食用10分钟,各位看官请 ...
- 【Java入门提高篇】Day28 Java容器类详解(十)LinkedHashMap详解
今天来介绍一下容器类中的另一个哈希表———>LinkedHashMap.这是HashMap的关门弟子,直接继承了HashMap的衣钵,所以拥有HashMap的全部特性,并青出于蓝而胜于蓝,有着一 ...
- 【Java入门提高篇】Day27 Java容器类详解(九)LinkedList详解
这次介绍一下List接口的另一个践行者——LinkedList,这是一位集诸多技能于一身的List接口践行者,可谓十八般武艺,样样精通,栈.队列.双端队列.链表.双向链表都可以用它来模拟,话不多说,赶 ...
随机推荐
- LNMP架构部署
第1章 部署LNMP架构步骤 1.1 ①部署Linux系统(OK) 基本优化完成(ip地址设置 yum源更新 字符集设置) 安全优化完成(iptables关闭 selinux关闭 /tmp/ 1777 ...
- js同时使用多个分隔符分割字符串.
利用正则分割,str.split(/reg/);如果有这样一个字符串: "jb51.net,google.com,baidu.com_weibo.com_haotu.net", 我 ...
- 关于thinkphp控制器引用model里的方法的一点收获
有时候真的是很绕,为了这一点点收获,我几乎花了一天的时间.当我弄明白了的那一刻,我.........好吧,写到这里,我发现不能换行.好吧,就这样吧,开始说正题:要想在controler从model引用 ...
- 文本域、bootstrap-table显示以及MySQL三者间的换行符问题
首先,今天在做项目的时候遇到的一个问题,如何实现文本输入换行以及在前台Bootstrap-table中显示也能够换行. 也许你马上就会想到说,用富文本编辑器,然而我们需要实现的只是文本输入以及换行功能 ...
- 异步获取CMD命令行输出内容
当控制台命令使用process.Start(); 后可以直接显示输出内容,当然它是异步显示的不用等程序结束.代码如下: using System;using System.Collections.Ge ...
- C# 插入排序(数据结构与算法)
1 }
- python基础-------函数(三)
迭代器 一.迭代的概念 迭代:1 重复2 下一次重复是基于上一次的结果 l=['a','b','c','d'] count=0while count < len(l): print(l[coun ...
- MXNet之ps-lite及parameter server原理
MXNet之ps-lite及parameter server原理 ps-lite框架是DMLC组自行实现的parameter server通信框架,是DMLC其他项目的核心,例如其深度学习框架MXNE ...
- 使用webpack配置vue项目代理 (超简单)
我们都知道,前端开发跨域是一个很常见的问题,当然跨域的方法也有很多,现在我就给大家分享一个在vue项目中如何使用webpack做代理,步骤简单,操作方便,本人亲测,巨好使
- DLL的导出函数重定向机制
曾经,调试时跟进HeapAlloc,结果发现直接进入到ntdll的RtlAllocateHeap中,感到很有趣,就使用Dependency Walker查看kernel32.dll的导出函数,结果发现 ...