设计模式之代理模式

代理模式

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

优点: 1、职责清晰。 2、高扩展性。 3、智能化。

缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

使用场景:按职责来划分,通常有以下使用场景: 1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。 5、Cache代理。 6、防火墙(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理。

注意事项: 1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。 2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

实例:

1.静态代理

提供一个公共接口,目标对象跟代理对象都必须实现这个接口

public interface IUserDao  {

    void eat();
}

目标对象

public class UserDao implements IUserDao {
    @Override
    public void eat() {
        Log.e("android","Hello kitty");
    }
}

代理对象

public class ProxyDao implements IUserDao {

    private UserDao userDao;

    public ProxyDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void eat() {
        Log.e("android","Hello 代理");
        userDao.eat();
        Log.e("android","Hello 代理");
    }
}

测试

//        目标对象
        UserDao userDao = new UserDao();
//        代理对象
        ProxyDao proxyDao = new ProxyDao(userDao);
//        执行代理方法
        proxyDao.eat();

 

2.动态代理(jdk代理)

在动态代理中,代理对象不需要实现公共接口,而是利用JDK的API,动态的在内存中构建代理对象

public class ProxyFactory {
    //维护一个目标对象
    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    public Object getInstance(){

        return Proxy.newProxyInstance(
                //指定当前目标对象使用类加载器,获取加载器的方法是固定的
                target.getClass().getClassLoader(),
                //目标对象实现的接口的类型,使用泛型方式确认类型
                target.getClass().getInterfaces(),
                //事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Log.e("android","动态 代理");
                        //执行目标方法
                        Object invoke = method.invoke(target, args);
                        Log.e("android","动态 代理");
                        return invoke;
                    }
                }
        );
    }
}

测试

 //目标对象
        IUserDao userDao = new UserDao();
        IUserDao proxyDao = (IUserDao) new ProxyFactory(userDao).getInstance();
        //执行代理方法
        proxyDao.eat();

其实还有第三种代理cglib,不过因为不能直接在android中使用,所以暂时不讨论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值