设计模式之代理模式

Proxyr设计模式之代理模式

Demo地址

https://github.com/rocky123shine/ProxyDemo

概念

Proxy模式,也称代理模式,其定义是为其他对象提供一种代理以控制对这个对象的访问,简单的说就是在访问和被访问对象中间加上的一个间接层,以隔离访问者和被访问者的实现细节。

代理的作用

为其他对象提供一种代理,控制这个对象的访问

代理的分类
虚代理( Remote Proxy )

代理一些开销很大的对象,这样便能迅速返回,进行其它操作,只有在真正需要时才实例化

远程代理( Remote Proxy )

为一个对象在不同的地址空间提供局部代表。

保护代理(Protection Proxy)

控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。

智能指引(Smart Reference)

他取代了简单的指针,它在访问对象时执行一些附加操作。

对应代理使用的场景

当客户端对象需要访问远程主机中的对象时可以使用远程代理。
当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理,例如一个对象需要很长时间才能完成加载时。
当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理。
通过使用缓冲代理,系统无须在客户端每一次访问时都重新执行操作,只需直接从临时缓冲区获取操作结果即可。
当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时可以使用保护代理。
当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理。

代理模式角色
抽象对象(目标接口)

声明了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。

目标对象

定义了代理对象所代表的目标对象。

代理对象

代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。 代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象。
代理对象的特点:
1. 实现目标接口(可有可无,标准有)
2. 持有目标对象引用

代理模式分类
静态代理

代理类有程序员生成的为静态代理

动态代理

代理类有系统生成的为动态代理(在运行时刻动态生成代理类)

静态代理简单举例

案例情景:买一部最新苹果手机,大陆买不到,需要在台湾找人代理购买

目标接口
//目标接口
public interface IShopPhone {
    //买手机
    void shopPhone(String phoneName);   
}
目标对象
//目标对象 目标对象实现目标接口
public class SunnyShopPhone implements IShopPhone {
    @Override
    public void shopPhone(String phoneName) {
        System.out.println("手机名称:" + phoneName);
    }
}
代理对象
//代理对象 此处为标准代理模式 实现了目标接口(变种可不实现)
public class ProxyShopPhone implements IShopPhone {
    private IShopPhone shopPhone;
    public ProxyShopPhone(IShopPhone shopPhone){
        this.shopPhone = shopPhone;
    }
    //代理对象实现购买的动作
    @Override
    public void shopPhone(String phoneName) {
        this.shopPhone.shopPhone(phoneName);
    }

}

使用:
 IShopPhone phone = new SunnyShopPhone();
 IShopPhone proxy = new ProxyShopPhone(phone);
 proxy.shopPhone("iPhoneX");//购买IphoneX
动态代理简单举例

案例情景:商家工作人员查询订单信息,不同人员权限不同,有的可以修改价格,有的不可以

目标接口
//目标接口
public interface IOrder {

    public String getOrderId();

    public void setOrderId(String orderId);

    public String getOrderName();

    public void setOrderName(String orderName);

    public String getOrderPrice();

    public void setOrderPrice(String orderPrice);

    public String getOrderUserName();

    public void setOrderUserName(String orderUserName);

}
目标对象
//目标对象 实现目标接口
public class OrderBean implements IOrder {

    private String orderId;
    private String orderName;
    private String orderPrice;
    private String orderUserName;

    public OrderBean() {

    }

    public OrderBean(String orderId, String orderName, String orderPrice,
            String orderUserName) {
        super();
        this.orderId = orderId;
        this.orderName = orderName;
        this.orderPrice = orderPrice;
        this.orderUserName = orderUserName;
    }

    @Override
    public String getOrderId() {
        return orderId;
    }

    @Override
    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    @Override
    public String getOrderName() {
        return orderName;
    }

    @Override
    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    @Override
    public String getOrderPrice() {
        return orderPrice;
    }

    @Override
    public void setOrderPrice(String orderPrice) {
        this.orderPrice = orderPrice;
    }

    @Override
    public String getOrderUserName() {
        return orderUserName;
    }

    @Override
    public void setOrderUserName(String orderUserName) {
        this.orderUserName = orderUserName;
    }

    @Override
    public String toString() {
        return "OrderBean [orderId=" + orderId + ", orderName=" + orderName
                + ", orderPrice=" + orderPrice + ", orderUserName="
                + orderUserName + "]";
    }
}
反射获取目标接口
Class<?>[] interfaces = orderBean.getClass().getInterfaces();
生成代理对象
//参数1 目标对象类,
//参数2 目标接口
//参数3 InvocationHandler 对象
IOrder proxyOrder = (IOrder) Proxy.newProxyInstance(orderBean.getClass().getClassLoader(), interfaces,newOrderInvocationHandler(orderBean));
自定义 InvocationHandler(动态代理中的重点)
public class OrderInvocationHandler implements InvocationHandler {

    private IOrder order;

    public OrderInvocationHandler(IOrder order){
        this.order = order;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //反射机制处理->(动态访问属性和方法)
        if("getOrderPrice".equals(method.getName())){
            //权限处理
            if (!"AAAA".equals(this.order.getOrderUserName())){
                try {
                    throw new SecurityException("没有权限访问,请确定你是否是管理员用户...");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                String price = OrderService.queryPrice(order.getOrderId());
                order.setOrderPrice(price);
            }
        }
        return method.invoke(order, args);
    }

}

使用:
// 首先查询所有数据
        List<OrderBean> orderList = OrderService.getOrderList();
        // 目标对象
        OrderBean orderBean = orderList.get(0);
        // 目标接口
        Class<?>[] interfaces = orderBean.getClass().getInterfaces();
        // 代理对象
        //OrderInvocationHandler作用:监听proxyOrder方法调用
        IOrder proxyOrder = (IOrder) Proxy.newProxyInstance(orderBean
                .getClass().getClassLoader(), interfaces,
                new OrderInvocationHandler(orderBean));

        System.out.println("订单ID: " + proxyOrder.getOrderId());
        System.out.println("订单名称: " + proxyOrder.getOrderName());
        System.out.println("订单用户名: " + proxyOrder.getOrderUserName());
        System.out.println("订单价格: " + proxyOrder.getOrderPrice());
代理模式是一种结构型设计模式,它提供一个代理对象来代表另一个对象。在代理模式中,有一个被称为实际对象(Subject)和一个被称为代理对象(Proxy)的中介,代理对象持有实际对象的引用,并且可以控制对实际对象的访问。代理模式的主要目的是在不修改原始对象的情况下,为原始对象添加额外的逻辑处理。 代理模式分为多种类型,如远程代理、虚拟代理、保护代理等,它们各自有不同的应用场景: - 远程代理:为远程对象提供一个本地代表。 - 虚拟代理:根据需要创建开销大的对象,通过虚拟代理控制访问这些对象的过程。 - 保护代理:控制对原始对象的访问权限,例如进行权限检查。 代理模式的优点包括: 1. 能够控制对真实对象的访问,并在访问前后添加额外的逻辑。 2. 可以通过代理对象实现延迟加载,即在实际需要时才创建真实对象。 3. 增强了对真实对象的封装,并且可以避免对真实对象的重复引用。 在C#中实现代理模式通常涉及以下步骤: 1. 定义一个接口或抽象类,声明真实对象和代理对象需要实现的方法。 2. 实现真实对象的类,按照接口或抽象类的要求实现具体方法。 3. 实现代理类,它同样实现接口或抽象类,并在方法中持有真实对象的引用,通过调用真实对象的方法来执行所需的操作,同时可以添加额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值