Java多线程编程——静态代理模式

代理(Proxy)是一种设计模式,它提供了对目标对象另外的访问方式,即通过代理对象访问目标对象。这样做的好处是,可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。

本文我们介绍静态代理。静态代理在使用时,需要定义接口或者父类,目标对象与代理对象一起实现相同的接口或者是继承相同父类。

例如,现在我们想举办一场演唱会,邀请一名歌星前来助阵。一种方案是,我们去寻找演艺经纪公司,让他们帮我们联系歌手出演节目。这里,歌手是目标对象,他只负责在演唱会上唱歌;而演艺公司则是代理对象,他们还要负责除了歌手唱歌之外其它的琐事。使用Java程序实现如下:

public class Main {
    public static void main(String[] args) {
        // can be simplified as
        //      new Agency(new Singer()).sing();
        Singer singer = new Singer();
        Agency agency = new Agency(singer);
        agency.sing();
    }
}

interface Concert {
    void sing();
}

class Singer implements Concert {
    @Override
    public void sing() {
        System.out.println("Do La Mi");
    }
}

class Agency implements Concert {
    private Concert target;

    public Agency(Concert target) {
        this.target = target;
    }

    @Override
    public void sing() {
        System.out.println("Before concert: Announcement");
        target.sing();
        System.out.println("After concert: Payment");
    }
}

代码中,类Singer(歌手)和Agency(演艺经纪公司)都实现了Concert接口(演唱会),只是Singer类里重写的sing方法只有“唱歌”这一件事,而Agency类里重写的sing方法除了调用target对象的sing方法外,还要做其它事情(如会前宣传、会后收账)。不难看出,Agency类里的sing方法增强了Singer类里的sing方法,完成了Singer类所不能完成的任务。

回顾先前介绍的实现Runnable接口的线程创建方式:

public class Main {
    public static void main(String[] args) {
        Task task = new Task();
        Thread thread = new Thread(task);
        thread.start();
    }
}

class Task implements Runnable {
    @Override
    public void run() {
        System.out.println("Working");
    }
}

代码中main方法里,第一句创建的Task类对象实现了Runnable接口,是我们的目标对象(类比于上个例子中的歌手);第二句,我们将task对象丢入Thread类的构造方法中创建了一个线程对象thread,它是我们的代理对象(类比于上个例子中的经纪公司);第三句,我们调用thread的start方法开启线程,事实上就是由代理对象完成线程的开启及运行的(在Thread类的start方法的源码中,程序让JVM调用run方法,而run方法就是直接调用目标对象的run方法)。

总结起来,静态代理可以做到在不修改目标对象的功能前提下,对目标功能扩展。但是,因为代理对象需要与目标对象实现一样的接口/继承同一个父类,所以会产生很多代理类,使得类太多;同时,一旦接口增加方法,目标对象与代理对象都要维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值