JavaWeb学习之设计模式

Posted 一杯水M

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaWeb学习之设计模式相关的知识,希望对你有一定的参考价值。

一、单例模式:只有一个实例的对象

代码:

public class SingleTemp{
	private SingleTemp(){
		
	}
	
	public static SingleTemp single = new SingleTemp();
	
	public static SingleTemp getInstance(){
		return single;
	}
}

二、装饰者模式:增强原始代码的功能,在不改动原始代码的基础上

继承也可以实现

原始代码:

public interface ICar {
	public void start();
	public void run();
	public void stop();
}

public class GoogleCar implements ICar{
	@Override
	public void start(){
		...
	}
	@Override
	public void run(){
		...
	}
	@Override
	public void stop(){
		...
	}
}

继承代码:

public class MyCar extends GoogleCar{	
	@Override
	public void start(){
		//增强代码....
		super.start();
		//增强代码....
	}
}

public class Test{
	public static void main(String[] args){
		ICar car=new MyCar();
		car.start();
	}
}

很完美的实现我们想要的增强功能,且没有改动源代码。但是很多时候源代码(源代码被final修饰)是不允许继承的话,继承就不能实现了。

这就要用到装饰者模式

装饰者模式的场景:无法获取源码,无法使用继承,要增强已经存在对象上的功能

前提:可以获取到被装饰的对象(GoogleCar)实现的所有接口(ICar)

代码:

public final class GoogleCar implements ICar{
    @Override
    public void start(){
        ...
    }
    @Override
    public void run(){
        ...
    }
    @Override
    public void stop(){
        ...
    }
}

public class MyCar implements ICar{    
    ICar car;
    
    public MyCar(ICar car){
        this.car=car;
    }

    @Override
    public void start(){
        //增强代码....
        this.car.start();
        //增强代码....
    }
    
    @Override
    public void run(){
        //增强代码....
        this.car.run()
        //增强代码....
    }
    @Override
    public void stop(){
        this.car.stop()
    }
}

public class Test{
    public static void main(String[] args){
        ICar car=new MyCar(new GoogleCar());
        car.start();
    }
}

弊端:如果被实现的接口中的方法过多,装饰类中的方法就会冗余,一些不需要增强的方法需要重写其方法

三、动态代理(Proxy.newProxyInstance)

原理:通过虚拟机在内存中创建字节码文件

1、通过虚拟机在内存中创建字节码文件,字节码文件的内容是:增强功能的类中的所有方法(是指类实现的所有接口中的方法,不包含类自身的方法)

2、通过字节码加载器把字虚拟机在内存中创建的节码文件加载成字节码对象

3、虚拟机修改内存中的字节码对象中的方法具体处理

具体代码如下:

public class Test{
    public static void main(String[] args){
        //1.根据GoogleCar字节码文件获取其实现的所有接口
        //2.获取接口中所有的方法
        /*
        Class[] clazz=GoogleCar.class.getInterfaces();
        for(Class cla : clazz){
            Method[] mds= cla.getMethods();
            for(Method method : mds){
                method.getName();
            }
        }
        */
        
        /*    
            参数1:固定值(字节码加载器加载内存中字节码文件,创建字节码对象)
            参数2:创建字节码对象中有哪些接口
            参数3:创建字节码对象中接口的方法的具体处理
        */        
        ICar car = (ICar)Proxy.newProxyInstance(Test.class.getClassLoader,GoogleCar.class.getInterfaces()
                                ,new InvocationHandler(){
            /*
                method:正在执行的方法
                args:正在执行的方法中的参数                
                Object:方法执行后的返回值
            */
            @Override
            public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
                Object obj = null;
                if(method.getName().equalsIgnoreCase("start")){
                    //增强代码......
                }
                // 执行当前方法
                obj = method.invoke(new GoogleCar(),args);
                
                return obj;
            }
        });
        
        car.start();
        car.run();
        car.stop();
    }
}

 

以上是关于JavaWeb学习之设计模式的主要内容,如果未能解决你的问题,请参考以下文章

JavaWeb学习之BS/CS架构及tomcat容器项目部署

Day10 JavaWeb学习之Tomcat,Web 应用服务器

JavaWeb学习之动态页面技术(JSP/EL/JSTL)

Java学习之Javaweb核心servlet

JavaWeb学习之Servlet基础

JavaWeb学习之Servlet基础