欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

23种java设计模式之装饰者模式及动态代理

程序员文章站 2022-07-05 11:12:37
设计模式不管对于何种语言都是存在的,这里介绍的是java的模式 装饰者模式是在二次开发中应用比较多的一款模式,当然了用反射也是可以实现的,今天介绍的是装饰模式,有兴趣的朋友可以自己去了解一下反射是怎么实现的。 在实际的开发中是无法拿到源码的,代码的可使用性也被final了,所以最常见的二次开发(二次 ......

设计模式不管对于何种语言都是存在的,这里介绍的是java的模式

装饰者模式是在二次开发中应用比较多的一款模式,当然了用反射也是可以实现的,今天介绍的是装饰模式,有兴趣的朋友可以自己去了解一下反射是怎么实现的。

在实际的开发中是无法拿到源码的,代码的可使用性也被final了,所以最常见的二次开发(二次开发就是给原有的代码中对功能做一些增强)就是通过装饰模式来实现的效果,使用这个模式有一个前提就是:可以获取到装饰对象的实现的所有的接口才可以用此模式下面大家可以直接可以看代码了:

1 我这里先定义了一个接口Car:

public interface Car {
    
    public void init();
    public void start();
    public void decread();

}

2.定义了一个原有的实现类carss;也就是我们说的要对其进行二次开发的产品源代码:(这里就是我们说的可以获取可以实现的接口)

public final class Carss implements Car{

    @Override
    public void init() {
        
        System.out.println("初始化");
    }

    @Override
    public void start() {
        
        System.out.println("开始");
    }

    @Override
    public void decread() {
        
        System.out.println("结束");
    }

}

3.要加入的功能 Ca类:这个是主要的,我们这里以接口Car作为Ca的属性

public class Ca implements Car{
    
    Car car;

    public Ca(Car car) {
        this.car = car;
    }

    @Override
    public void init() {
        
        System.out.println("这是装饰者模式的实现");
        car.init();
    }

    @Override
    public void start() {
        
        car.start();
    }

    @Override
    public void decread() {
        
        car.decread();
    }

}

4.最后是实现的功能:

public class demo1 {

	public static void main(String[] args) {
		//这里拿到了Carss的权限是可以new的
		Car car=new Ca(new Carss());
		car.init();
		car.start();
		car.decread();
	}

}

  这就是一个简单的装饰者模式:

装饰者模式有一个问题就是当实现的接口方法过多,这样就会对代码造成过多的冗余,这就有了动态代理模式:

动态代理模式的原理:虚拟机在内存中创建类似class文件,而前提是在创建的时候要通知虚拟机在创建的字节码文件上有多少方法

字节码的文件是就是我们熟知的class文件

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class demo1 {

    public static void main(String[] args) {
        
        
        /**
         * Jdk的代理模式
         * newProxyInstance的参数 1.固定值:告诉虚拟机用哪个字节码加载器加载内存中创建的字节码文件
         * 2.通知虚拟机正在被创建的字节码文件中应该有哪些方法
         * 3.通知虚拟机正在被创建的字节码上的各个方法如何处理也就是如何增强
         */
        Car c=(Car)Proxy.newProxyInstance(demo1.class.getClassLoader(), Carss.class.getInterfaces(),new InvocationHandler() {
            
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                
//                //System.out.println(method.getName());
                //这里就可以选择自己需要的那些方法        
                if(method.getName().equalsIgnoreCase("start")) {
                    method.invoke(new Carss(), args);
                    System.out.println("这是通过动态代理添加的");
                }
                else method.invoke(new Carss(), args);
                
                return null;
            }
        }); 
        c.init();
        c.start();
        c.decread();
        /*//这里拿到了Carss的权限是可以new的
        Car car=new Ca(new Carss());
        car.init();
        car.start();
        car.decread();*/
    }

}

 

今天的分享就到这里了。喜欢这篇文章的朋友可以点个赞哦!!!!!!