您现在的位置是:首页 >学无止境 >【2023-05-10】设计模式(代理,装饰器)网站首页学无止境

【2023-05-10】设计模式(代理,装饰器)

你是我的小毛驴 2024-06-14 17:20:22
简介【2023-05-10】设计模式(代理,装饰器)

代理模式

代理模式就是你想要访问一个对象,可以通过另一个代理对象来访问这个对象,同时代理对象可以对这个对象进行一个增强操作。

代理模式通常分为静态代理模式,动态代理模式,其中动态代理模式又分为jdk动态代理模式和cglib动态代理模式。

1、静态代理

public interface IPhoneService {
    public void playGame();
}

public class PhoneServiceImpl implements IPhoneService{
    @Override
    public void playGame() {
        System.out.println("玩手机");
    }
}

public class PhoneProxy implements IPhoneService{
    private PhoneServiceImpl phoneService;

    public PhoneProxy(PhoneServiceImpl phoneService) {
        this.phoneService = phoneService;
    }

    @Override
    public void playGame() {
        System.out.println("开机");
        phoneService.playGame();
        System.out.println("关机");
    }
}

public class Test {
    public static void main(String[] args) {
        PhoneServiceImpl phoneService = new PhoneServiceImpl();
        PhoneProxy phoneProxy = new PhoneProxy(phoneService);
        phoneProxy.playGame();
    }
}

静态代理实现同一个接口,将目标对象传递到代理对象里面,代理对象对具体方法进行增强处理。

如果接口新增了一个方法的话,那么代理对象也必须实现这个方法,耦合度太高,不太好。

2、jdk动态代理

public interface IPhoneService {
    public void playGame();
}

public class PhoneServiceImpl implements IPhoneService{
    @Override
    public void playGame() {
        System.out.println("玩手机");
    }
}

public class ProxyPhoneJdk implements InvocationHandler {
    public Object phone;

    public ProxyPhoneJdk(Object phone) {
        this.phone = phone;
    }

    //通过invoke方法执行目标方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开机");
        method.invoke(phone,args);
        System.out.println("关机");
        return null;
    }
}

public class Test {
    public static void main(String[] args) {
        PhoneServiceImpl phoneService = new PhoneServiceImpl();
        IPhoneService aa = (IPhoneService)Proxy.newProxyInstance(phoneService.getClass().getClassLoader(), phoneService.getClass().getInterfaces(), new ProxyPhoneJdk(phoneService));
        aa.playGame();
    }
}

由于静态代理缺点太明显,所以有了动态代理,动态代理可以不和目标对象实现同一接口或者继承同一个类

根据名称可知,具体的代理对象是由jdk实现的,在jvm中动态生成代理对象。

jdk动态代理需要目标对象实现了接口才可用。

3、cglib动态代理

public class PhoneService {
    public void playGame(){
        System.out.println("玩手机");
    }
}

public class ProxyPhoneCglib implements MethodInterceptor {
    private Object object;

    public ProxyPhoneCglib(Object object) {
        this.object = object;
    }

    public Object getProxyInstance() {
        //创建代理类
        Enhancer enhancer = new Enhancer();
        //继承要被代理的类
        enhancer.setSuperclass(object.getClass());
        //设置回调函数
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("开机");
        method.invoke(object);
        System.out.println("关机");
        return null;
    }
}

public class Test {
    public static void main(String[] args) {
        PhoneService phoneService1 = new PhoneService();
        ProxyPhoneCglib proxyPhoneCglib = new ProxyPhoneCglib(phoneService1);
        PhoneService proxyInstance = (PhoneService) proxyPhoneCglib.getProxyInstance();
        proxyInstance.playGame();
    }
}

对于没有父类的目标类,cglib创建一个目标类的子类,在子类中进行动态增强。

注.目标类不能是final,目标方法不能是final和static

装饰器模式

装饰器模式可以动态给一个对象添加额外的功能,这个额外的功能可以自由的排列组合。

public interface IPhoneDecService {
    void buyPhone();
}

public class PhoneDecServiceImpl implements IPhoneDecService{
    @Override
    public void buyPhone() {
        System.out.println("买了一个手机");
    }
}

//装饰器
public class DecoratorPhone implements IPhoneDecService{
    private IPhoneDecService phoneDecService;

    public DecoratorPhone(IPhoneDecService phoneDecService) {
        this.phoneDecService = phoneDecService;
    }

    @Override
    public void buyPhone() {
        phoneDecService.buyPhone();
    }
}

public class LinePhoneDec extends DecoratorPhone{
    public LinePhoneDec(IPhoneDecService phoneDecService) {
        super(phoneDecService);
    }
    @Override
    public void buyPhone() {
        super.buyPhone();
        System.out.println("送一根数据线");
    }

}

public class HeadsetPhoneDec extends DecoratorPhone {
    public HeadsetPhoneDec(IPhoneDecService phoneDecService) {
        super(phoneDecService);
    }

    @Override
    public void buyPhone() {
        super.buyPhone();
        System.out.println("送一对耳机");
    }
}

public class ShellPhoneDec extends DecoratorPhone {
    public ShellPhoneDec(IPhoneDecService phoneDecService) {
        super(phoneDecService);
    }

    @Override
    public void buyPhone() {
        super.buyPhone();
        System.out.println("送一个手机壳");
    }
}

public class Test {
    public static void main(String[] args) {
        PhoneDecServiceImpl phoneDecService = new PhoneDecServiceImpl();

        LinePhoneDec linePhoneDec = new LinePhoneDec(phoneDecService);
        HeadsetPhoneDec headsetPhoneDec = new HeadsetPhoneDec(linePhoneDec);
        ShellPhoneDec shellPhoneDec = new ShellPhoneDec(headsetPhoneDec);
        shellPhoneDec.buyPhone();
    }
}

//买了一个手机
//送一根数据线
//送一对耳机
//送一个手机壳
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。