java23种设计模式之代理模式

上一节说到装饰器模式: https://blog.csdn.net/zhanglei082319/article/details/88592661

装饰器模式概念:为一个业务实现,添加该业务内一些其他的职责,称之为装饰器模式。

      今天说另一种设计模式:代理模式

      代理模式: 生活中的中介,中间商等等都是代理,java中的代理的概念也差不多。代理者拥有委托人的部分权限,代理者也可以在代理的同时加上自己的部分业务。

      java中代理模式分为两种:静态代理和动态代理。

      静态代理:在程序启动前将接口,实现类,代理类全部手动实现完成。就手机销售代理商问题的静态代理实现如下:

     1、先定义一个商家接口

/**
 * 商家
 */
public interface Business {

    /**
     * 零售
     */
    void  retail();


    /**
     * 批发
     */
    void  wholesale();
}

     2、定义一个苹果手机商家实现类

/**
 * 苹果商家
 */
public class IPhoneBusiness implements Business {


    @Override
    public void retail() {
        System.out.println("成功卖出一个苹果手机!");
    }

    @Override
    public void wholesale() {
        System.out.println("成功卖出多台苹果手机!");
    }
}

    3、定义静态代理实现类

/**
 * 代理商家
 */
public class ProxyBusiness {

    private  Business business = new IPhoneBusiness();

    public void sell(){
        System.out.println("代理销售!");
        business.retail();
    }

}

   4、测试一下静态代理

 public static void main(String[] args) {
        ProxyBusiness proxyBusiness = new ProxyBusiness();
        proxyBusiness.sell();
    }

   

       打印结果测试完成,代理商成功销售出一台手机。

       从接口实现中可以看到,目前代理商能够销售苹果手机。

       我们假设代理商在销售苹果手机时,需要在商品包装上需要贴上自己的独家代理商标签。随着代理商业务逐渐扩大,我们的代理商需要代理很多种款式的手机,而且每一种款式的手机都需要贴上自己的标签。

       这种情况下,如果还是继续使用静态代理的方式进行,那么不可避免的会存在很多冗余的功能代码实现。我们希望将这些统一的功能可以放在一个地方实现。怎么办呢?

       动态代理: 运行时生成的代理实现类和实例,我们称之为动态代理。

       使用动态代理实现多种手机代理商贴标签的功能如下:

       1、为了实现多个款式的手机,这里添加一个手机代理商

/**
 * 华为手机
 */
public class HuaweiPhoneBusiness implements Business{

    @Override
    public void retail() {
        System.out.println("成功销售一台华为手机");
    }

    @Override
    public void wholesale() {
        System.out.println("成功销售多台华为手机");
    }

    @Override
    public String name() {
        return "华为手机";
    }
}

     2、动态代理商实例创建器


public class ProxyFactory {

    private static void  before(Business business){
        System.out.println(business.name()+": 贴上代理商标签");
    }


    private static void  after(Business business){
        System.out.println(business.name()+": 销售成功");
    }


    private static Business  getProxy(Business business) {
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                before(business);
                method.invoke(business, args);
                after(business);
                return null;
            }
        };
        return (Business) Proxy.newProxyInstance(Business.class.getClassLoader(),
                new Class[]{Business.class}, handler);
    }


}

      测试一下

 public static void main(String[] args) {
        Business iphone = ProxyFactory.getProxy(new IPhoneBusiness());
        Business huawei = ProxyFactory.getProxy(new HuaweiPhoneBusiness());
        iphone.retail();
        iphone.wholesale();
        huawei.retail();
        huawei.wholesale();
 }

     

      这样我们就可以将贴标签这个业务功能,单独放在一个地方进行实现了,当然只要是一些公共的功能我们都可以放置在统一的地方实现。在实例化代理商的时候,判断这个代理商是否有公共的功能需要实现,如果有就实例化代理对象,如果没有就普通实例化自身。

       代理模式的使用场景

        静态代理模式:  一般在一个类,针对于不同的调用者会赋予不同的权限时,我们可以使用静态代理模式。还有当我们需要对一个类进行某些功能的修改,但是又不能直接去内部修改,这时可以使用静态代理。

        动态代理模式:  这个一般比较侧重于方法上,当一个方法执行前后或者中间需要使用到一些公共的功能,可以使用动态代理。 还有jdk动态代理是面向接口的,当遇到一些固定的只需要定义接口,不许要实现类的情况,我们可以动态代理生成固定功能的实现类。

        实际项目中代理模式使用也非常频繁,特别是动态代理,我们熟知的springAop  mybatis中的mapper  connection  log  等等都使用了动态代理。

     

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值