23种设计模式----代理模式----结构型模式

代理模式

  • 1.什么是代理模式
  • 2.代理模式的角色
  • 3.例子
    • 3.1 背景
    • 3.2 例子结构
    • 3.3 抽象的共同的方法
    • 3.4 导购
    • 3.5 买家
    • 3.6 调用者
    • 3.7 结果
  • 4.总结

23种设计模式

1.什么是代理模式

代理这个词在生活中也很多。
最经典的一个就是在香港的警匪片中,反派老大被抓到警察局,然后反派老大说,我什么都不会交代,和我的律师说吧。
此时,律师就是反派老大在与警察交涉过程中的代理人。
还有一种情况就是反派老大管理的地盘太大,有些管理不过来,于是就设立了一个个的代理人。
不过,不管怎么样,当其他的反派老大拜访时,老大还是需要亲自招待的。
总结一下:代理就是一方面是补充本体不足,另一方面分担本体工作。
而有些事情只能由本体完成。

2.代理模式的角色

抽象的共同的操作
本体
代理人
调用者

3.例子

3.1 背景

相信每一个人都去过超市,或者商场等等。
所以呢,每一个人都会购物。
那么购物的步骤是怎么样的?
看到商品,先看看是不是自己需要的东西,然后看下商品的价格,与卖家砍砍价,最后成交。

大型的商场都有导购员,当你在看某件商品时,导购员就会介绍商品的有关信息。如果你接受导购员的服务,那么在这一时间内,导购员只会为你服务,不过,不管导购员如何诱惑,买不买还是买家的决定。

情况比较紧急或者商品不允许挑选(类似药品等特殊品)时,买家只需要付款就行。(还没见过砍价砍到药店的人才。。。。)

3.2 例子结构

《23种设计模式----代理模式----结构型模式》

3.3 抽象的共同的方法

package proxyable;

/**
 * 
 * 到超时买东西必备的技能
 * 1.东西的名称
 * 2.买家的名称
 * 3.问价格
 * 4.砍价
 * 5.成交
 * 
 * 
 */
public interface BuySomething {

    String getThingName();
    
    String getBuyerName();
    
    void setBuyerName(String buyerName);
    
    int getThingPrice(String thingName);
    
    int bargainirg(String thingName,String buyerName);
    
    void deal(String thingName,String buyerName);
    
}

3.4 导购

package proxy;

import proxyable.BuySomething;

/**
 * 
 * 从某种程度上来说,导购就是买家的一个代理人
 * 
 */
public class Guide implements BuySomething{

    private String buyerName;
    
    private BuySomething buySomething;
    
    public Guide(String buyName) {
        this.buyerName = buyName;
    }
    
    @Override
    public String getThingName() {
        System.out.println("导购熟悉超市环境,获取商品名称的速度比买家快");
        return "thingName";
    }

    @Override
    public void setBuyerName(String buyerName) {
        System.out.println("导购需要明确的知道,自己服务的买家是谁"+buyerName);
        if(buySomething == null){
            try{
                buySomething = create(buyerName);
            } catch (Exception e){
                e.printStackTrace();
            }
        }
        buySomething.setBuyerName(buyerName);
        this.buyerName = buyerName;
    }

    @Override
    public int getThingPrice(String thingName) {
        System.out.println("导购询问价格一般都比较贵");
        return 100;
    }

    @Override
    public int bargainirg(String thingName, String buyerName) {
        System.out.println("导购砍价几乎是象征性的砍价");
        return 0;
    }

    /**
     * 被代理者无法替代的工作
     */
    @Override
    public void deal(String thingName, String buyerName) {
        System.out.println("不管导购多么的努力,决定权还是在买家身上");
        if(buySomething == null){
            try {
                buySomething = create(buyerName);
            } catch (Exception e){
                e.printStackTrace();
            }
        }
        buySomething.deal(thingName, buyerName);
    }
    
    private synchronized BuySomething create(String buyerName) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
        return (BuySomething) Class.forName("real."+buyerName).newInstance();
    }

    @Override
    public String getBuyerName() {
        return this.buyerName;
    }

}

3.5 买家

package real;

import proxyable.BuySomething;

public class Buyer implements BuySomething{

    private String name;
    
    @Override
    public String getThingName() {
        System.out.println("买家不熟悉超市的环境,所以获取商品的名称比较慢");
        return "thingName";
    }

    @Override
    public int getThingPrice(String thingName) {
        System.out.println("买家询问价格同样贵");
        return 100;
    }

    @Override
    public int bargainirg(String thingName, String buyerName) {
        System.out.println("买家砍价比较狠");
        return 10;
    }

    @Override
    public void deal(String thingName, String buyerName) {
        System.out.println("买家经过长时间的考虑,最终决定买下来");
    }

    @Override
    public void setBuyerName(String buyerName) {
        System.out.println("现在的操作人"+buyerName);
        this.name = buyerName;
    }

    @Override
    public String getBuyerName() {
        return this.name;
    }

}

3.6 调用者

package client;

import proxy.Guide;
import proxyable.BuySomething;

public class Main {

    public static void main(String[] args) {
        
        System.out.println("逛超市吧");
        System.out.println("导购全权购买");
        BuySomething buySomething = new Guide("Guide");
        System.out.println(buySomething.getThingName());
        System.out.println(buySomething.getBuyerName());
        System.out.println(buySomething.getThingPrice(buySomething.getThingName()));
        System.out.println(buySomething.bargainirg(buySomething.getThingName(),
                buySomething.getBuyerName()));
        buySomething.deal(buySomething.getThingName(), "Buyer");
        
        System.out.println("导购帮助选购,本人砍价,购买");
        System.out.println(buySomething.getThingName());
        System.out.println(buySomething.getBuyerName());
        System.out.println(buySomething.getThingPrice(buySomething.getThingName()));
        buySomething.setBuyerName("Buyer");
        System.out.println(buySomething.bargainirg(buySomething.getThingName(),
                buySomething.getBuyerName()));
        buySomething.deal(buySomething.getThingName(), buySomething.getBuyerName());
        
        System.out.println("本人出马");
        buySomething.setBuyerName("Buyer");
        System.out.println(buySomething.getThingName());
        System.out.println(buySomething.getBuyerName());
        System.out.println(buySomething.getThingPrice(buySomething.getThingName()));
        System.out.println(buySomething.bargainirg(buySomething.getThingName(),
                buySomething.getBuyerName()));
        buySomething.deal(buySomething.getThingName(), buySomething.getBuyerName());
        
    }

}

3.7 结果

逛超市吧
导购全权购买
导购熟悉超市环境,获取商品名称的速度比买家快
thingName
Guide
导购熟悉超市环境,获取商品名称的速度比买家快
导购询问价格一般都比较贵
100
导购熟悉超市环境,获取商品名称的速度比买家快
导购砍价几乎是象征性的砍价
0
导购熟悉超市环境,获取商品名称的速度比买家快
不管导购多么的努力,决定权还是在买家身上
买家经过长时间的考虑,最终决定买下来
导购帮助选购,本人砍价,购买
导购熟悉超市环境,获取商品名称的速度比买家快
thingName
Guide
导购熟悉超市环境,获取商品名称的速度比买家快
导购询问价格一般都比较贵
100
导购需要明确的知道,自己服务的买家是谁Buyer
现在的操作人Buyer
导购熟悉超市环境,获取商品名称的速度比买家快
导购砍价几乎是象征性的砍价
0
导购熟悉超市环境,获取商品名称的速度比买家快
不管导购多么的努力,决定权还是在买家身上
买家经过长时间的考虑,最终决定买下来
本人出马
导购需要明确的知道,自己服务的买家是谁Buyer
现在的操作人Buyer
导购熟悉超市环境,获取商品名称的速度比买家快
thingName
Buyer
导购熟悉超市环境,获取商品名称的速度比买家快
导购询问价格一般都比较贵
100
导购熟悉超市环境,获取商品名称的速度比买家快
导购砍价几乎是象征性的砍价
0
导购熟悉超市环境,获取商品名称的速度比买家快
不管导购多么的努力,决定权还是在买家身上
买家经过长时间的考虑,最终决定买下来

4.总结

大概有一下几点:
首先对于一些方法,代理相当于是透明的,比如上述例子中的setBuyerName方法和deal方法,不管调用的是代理的方法还是本体的方法,最后都是调用本体的方法。所以代理在这两个方法中就相当于是透明的。

至于透明的实现方式,是通过委托来实现的。
可以很清楚的知道,每一个代理都会持有一个本体的对象,当遇到代理无法完成的操作时,代理就会创建本体的对象,然后把操作交给本体完成。

当代理和反射之间的关系非常的复杂或者调用非常的频繁时,可以使用反射的方式。比如在例子中,新增一个本体,只需要重新写一个本体的类就行,调用的时候设置名字就是类名就ok。可以无限的复用代理类。

同样的由于代理类持有的是接口,而接口代理与本体都需要实现方法,所以,新增一个代理可以使用原来的本体。

这样就做到本体与代理相互补充,无限扩充。

考虑到多线程或者多个代理需要创建同一个本体的情况,代理创建本体的方法应该用synchronized关键词修饰。

还有就是创建一个对象比较费时,使用代理可以先处理代理能够处理的操作,只有等到需要本体执行特定的操作时,才创建本体对象。
所以使用代理可以实现懒加载,懒创建等等,加快加载的速度。
23种设计模式

    原文作者:算法小白
    原文地址: https://blog.csdn.net/a18792721831/article/details/85138283
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞