设计模式|代理模式、以《安家》为模型轻松理解静态代理和动态代理

目录

代理模式概念

代理模式实例

静态代理

动态代理


代理模式概念

代理模式是设计模式中运用较广泛且容易理解的一个。代理模式的概念是为其他对象提供一个代理,以控制这个对象的访问,代理对象在客户端和目标对象之间起到中介的作用。代理模式的优点是隔离被代理对象和调用者、一定程度降低耦合度,扩展性好、保护目标对象、增强目标对象。缺点是增加系统复杂性、降低被调用对象的响应速度。

代理模式在实际运用中分为静态代理和动态代理两种,静态代理是指在编译期间就知道被代理类的情况,动态代理是在运行期间才知道被代理类的情况。


代理模式实例

房屋中介是现实生活中最接近代理模式思维的一个职业。把中介帮房主销售房子、收取佣金的行为抽象成程序语言就是代理模式。笔者此处就以最近热播的电视剧《安家》中的桥段讲解代理模式。电视剧围绕坐落在上海静安区的一家中介门店讲述了多个有温情的故事。静宜门店的主要经营业务是卖房和租房,卖房业务又分为卖民居和卖老洋房,卖老洋房需要验证购房人的资产情况,身价不满8千万的客户没有购房资格,老洋房的交易佣金是1%。普通民居不验证资产,佣金2%。

接下来用代码实现出上述业务场景。

静态代理

静宜门店在徐店长的带领下开始接业务了,这天一个业主进店要销售一套老洋房,签合同后静宜门店便开始紧锣密鼓的卖老洋房工作。验证购房资格--->签购房合同--->获取佣金,交易完成这个过程是一个完整的代理过程。用静态代理的模式实现如下

public class SellingHouseStaticProxy {
    interface OldForeignStyleHouse {
        public void sell();
    }
    //实现类
    static class OldForeignStyleHouseImpl implements OldForeignStyleHouse {
        @Override
        public void sell() {
            System.out.println("售卖老洋房,房产变现。。。。。");
        }
    }
    //安家天下代理类
    static class AnJiaOldForeignStyleHouseProxy implements OldForeignStyleHouse {
        private  OldForeignStyleHouse oldForeignStyleHouse;
        public AnJiaOldForeignStyleHouseProxy(OldForeignStyleHouse oldForeignStyleHouse){
            this.oldForeignStyleHouse = oldForeignStyleHouse;
        }
        public void checkIntelligence(){
            //验证买方购房资格
            System.out.println("安家天下验证老洋房买方购房资产通过");
        }
        public void obtainCommission(){
            System.out.println("安家天下收取佣金1%,老洋房交易完成");
        }
        @Override
        public void sell() {
            checkIntelligence();
            oldForeignStyleHouse.sell();
            obtainCommission();
        }
    }
    public static void main(String[] args) {
        OldForeignStyleHouse sell = new OldForeignStyleHouseImpl();
        AnJiaOldForeignStyleHouseProxy proxy = new AnJiaOldForeignStyleHouseProxy(sell);
        proxy.sell();

    }
}

OldForeignStyleHouse类就是老洋房的抽象类,它有一个sell(售卖)方法。OldForeignStyleHouseImpl类实现了老洋房接口。AnJiaOldForeignStyleHouseProxy类是安家天下静宜门店类,它同样实现了老洋房的接口,所以它有老洋房的售卖属性,作为房产中介已经积累了一些老洋房销售经验,为了提高效率会先验证购房资产,在交易成功后会收取佣金,交易完成。

客户端调用输出:

安家天下验证老洋房买方购房资产通过
售卖老洋房,房产变现。。。。。
安家天下收取佣金1%,老洋房交易完成

动态代理

使用静态代理卖老洋房是很香,但是拓展太不方便了。静宜门店有卖民居、卖老洋房、卖老洋房、卖商铺等业务,后期还可能拓展卖场、公寓等业务,为类业务都加一套静态代理太冗余。所以此处引入动态代理的方式覆盖所有业务线。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class SellingHouseDyamicProxy {
    //老洋房类
    interface OldForeignStyleHouse {
        public void sell();
    }
    //老洋房实现类
    static class OldForeignStyleHouseImpl implements OldForeignStyleHouse {
        @Override
        public void sell() {
            System.out.println("售卖老洋房,房产变现。。。。。");
        }
    }
    //普通民居类
    interface GeneralHouse {
        public void sell();
    }
    //普通民居实现类
    static class GeneralHouseImpl implements GeneralHouse {
        @Override
        public void sell() {
            System.out.println("售卖居住房,房产变现。。。。。");
        }
    }
    static class AnJiaProxy implements InvocationHandler {
        private Object obj;

        public AnJiaProxy(Object o) {
            this.obj = o;
        }
        public void checkIntelligence(Method method) {
            if(method.getDeclaringClass().equals(OldForeignStyleHouse.class)){
                //验证买方购房资格
                System.out.println("安家天下验证老洋房买方购房资产通过");
            }else{
                System.out.println("此房非老洋房,不需要验证购房人资产");
            }
        }
        public void obtainCommission(Method method) {
            if(method.getDeclaringClass().equals(OldForeignStyleHouse.class)){
                System.out.println("安家天下收取佣金1%,老洋房交易完成");
            }else{
                System.out.println("安家天下收取佣金2%,交易完成");
            }
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            checkIntelligence(method);
            Object  result = method.invoke(this.obj, args);
            obtainCommission(method);
            return result;
        }
    }

    public static void main(String... args) {
        OldForeignStyleHouse oldForeignStyleHouse = new OldForeignStyleHouseImpl();
        OldForeignStyleHouse oldForeignStyleHouseSell = (OldForeignStyleHouse) Proxy.newProxyInstance(
                oldForeignStyleHouse.getClass().getClassLoader(),
                oldForeignStyleHouse.getClass().getInterfaces(),
                new AnJiaProxy(oldForeignStyleHouse));
        oldForeignStyleHouseSell.sell();

        System.out.println("-----------------------分割--------------------");

        GeneralHouse generalHouse = new GeneralHouseImpl();
        GeneralHouse generalHouseSell = (GeneralHouse) Proxy.newProxyInstance(
                generalHouse.getClass().getClassLoader(),
                generalHouse.getClass().getInterfaces(),
                new AnJiaProxy(generalHouse));
        generalHouseSell.sell();
    }
}

OldForeignStyleHouse和OldForeignStyleHouseImpl是老洋房接口和实现GeneralHouse和GeneralHouseImpl是普通民居接口及实现。AnJiaProxy是动态代理的安家天下静宜门店类,它不实现特定接口,而是在运行期间根据客户端调用情况动态识别。无论再拓展什么业务只要符合规范接口轻松使用代理销售类。
客户端调用输出:

安家天下验证老洋房买方购房资产通过
售卖老洋房,房产变现。。。。。
安家天下收取佣金1%,老洋房交易完成
-----------------------分割--------------------
此房非老洋房,不需要验证购房人资产
售卖居住房,房产变现。。。。。
安家天下收取佣金2%,交易完成

参考资料:

设计模式之静态代理与动态代理


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值