设计模式之代理模式

今天好没状态,感觉浑身无力。

参考:《设计模式之禅》、博客:https://www.cnblogs.com/ygj0930/p/6542259.html

1、定义:代理模式就是指给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。类似于生活中的中介。(代理模式主要使用java中的多态)

为什么用代理模式:

(1)中介隔离作用:在某些情况下,一个客户类不想或不能直接引用一个委托对象,而代理类可以在客户类和委托对象之间起到中介作用,其特征是代理类和委托类实现相同的接口。

(2)开闭原则,增加功能:可以通过代理类增加额外的功能来扩展委托类的功能,这样只需要修改代理类而不是委托类,符合开闭原则,

2、静态代理:

/**
 * 代理接口
 * 定义一个代理类和被代理类公有的接口
 */
public interface PeopleProxy {
    // 定义共有方法
    public void eatChciken();
    public void drink();
    public void study();

}
/**
 * 实现类,也是被代理的类
 */
public class Children implements PeopleProxy {
    @Override
    public void eatChciken() {
        System.out.println("小孩要吃鸡肉!!!!");
    }

    @Override
    public void drink() {
        System.out.println("小孩要喝水!!!!");
    }

    public void study() {
        System.out.println("我正在学习!!!!");
    }
}
public class Youth implements PeopleProxy {

    // 定义私有的接口
    private PeopleProxy peopleProxy;

    public Youth() {
        // 大人默认为小孩的代理
        this.peopleProxy = new Children();
    }

    // 它可以是任何小孩的代理,只要是小孩就行
    public Youth(PeopleProxy peopleProxy) {
        this.peopleProxy = peopleProxy;
    }

    @Override
    public void eatChciken() {
        // 帮代理的小孩吃鸡
        this.peopleProxy.eatChciken();
    }

    @Override
    public void drink() {
        // 帮代理的小孩喝水
        this.peopleProxy.drink();
    }

    @Override
    public void study() {
        // 此处为一个新的代理
        this.peopleProxy.study();
    }
}
/**
 * 小孩的父母,将小孩托管给了别的年轻人
 */
public class FatherAndMother {
    public static void main(String[] args) {
        // 观察管理小孩的年轻人
        Youth youth = new Youth();

        // 看自己的孩子怎么吃鸡肉的
        youth.eatChciken();
        // 看自己的小孩怎么喝水
        youth.drink();
        // 比如,再添加一个方法,看小孩如何学习,此时只需要在接口中添加方法,在小孩类中实现即可
        youth.study();
    }
}
/**
 * 这样就完成了一个代理模式,其实在我们自己做项目时经常会用到,比如在一个SSM项目中,
 * 我们一般通过业务接口去访问业务类,但是在业务较复杂时,这样就会很繁琐,因为需要注入很多个业务类。
 * 此时我们就可以使用代理模式,创建一个类,在此类中获取所有的业务对象,在controller中只需要注入中一个类就可以了
 */
/**
 * 此例为静态代理,优点是:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。
 * 缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。
 */

优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。

缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。

3、动态代理:

动态代理类的源码是在程序运行期间,通过JVM等反射机制动态生成。代理类和委托类的关系是运行时才确定的。

使用JDK生成的动态代理的前提是目标类必须有实现的接口。

但是:某个类没有实现接口,就不能使用JDK动态代理

/**
 * 代理接口
 */
public interface BuyHouse {
    void buyHouse();
}
接口的实现:
public class BuyHouseImpl implements BuyHouse {
    @Override
    public void buyHouse() {
        System.out.println("我要买房子!!!");
    }
}

/**
 * 代理类
 */
public class BuyHouseProxy implements BuyHouse {
    private BuyHouse buyHouse;

    public BuyHouseProxy (final BuyHouse buyHouse) {
        this.buyHouse = buyHouse;
    }

    @Override
    public void buyHouse() {
        System.out.println("买房前准备!!!");
        buyHouse.buyHouse();
        System.out.println("买房后准备!!!");
    }
}
/**
 * 动态代理处理类
 */
public class DynamicProxyHander implements InvocationHandler {

    private Object object;

    public DynamicProxyHander(final Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("买房前准备!!!");
        Object result = method.invoke(object, args);
        System.out.println("买房后准备!!!");
        return result;
    }
}
/**
 * 动态代理测试类
 */
public class DynamicProxyTest {

    public static void main(String[] args) {
        // 获取被代理的对象
        BuyHouse buyHouse = new BuyHouseImpl();
        /**
         * Proxy.newProxyInstance()指定的三个参数,
         * ClassLoder loser:指定当前目标对象使用的类加载器
         * Class<?>[]{} interfaces:指定目标对象实现的接口类型,使用泛型确认类型
         * InvocationHnder:指定动态处理器,指定目标对象的方法时,会触发事件处理器的方法
         */
        BuyHouse ProxyBuyHouse  = (BuyHouse)Proxy.newProxyInstance(BuyHouse.class.getClassLoader(),
                new Class[]{BuyHouse.class}, new DynamicProxyHander(buyHouse));
        ProxyBuyHouse.buyHouse();

    }
}

《《《感觉最近自己状态不是很好,不过所有的文章都会慢慢补充的,学到哪是哪。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值