谷歌Car引入装饰者模式

谷歌增强Car问题

  • java设计了汽车开发约定ICar类
1
2
3
4
5
public interface ICar {
public void start(); //启动
public void run(); //运行
public void stop(); //停止
}
  • 希望在将谷歌Car接入到生态圈平台时,增强汽车启动功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public  final class GoogleCar implements ICar {   //我已经final了 不让任何类继承我去重写方法

@Override
public void start() {
System.out.println("GoogleCar判断天气是否良好");
System.out.println("GoogleCar判断情况是否良好");
System.out.println("GoogleCar控制谷歌汽车启动"); //调用谷歌汽车提供的c语言函数
}

@Override
public void run() {
System.out.println("控制谷歌汽车运动");
}

@Override
public void stop() {
System.out.println("控制谷歌汽车停止");
}

}
  • 现在在谷歌Car的基础上去查天气情况
**1.手动在谷歌Car上自己添加(除非开发的时候把源码给你)
**2.new一个类继承谷歌Car,重写方法(除非谷歌Car不是final 可以被继承)
**3.new一个类实现Icar,增强方法(装饰者模式)**

装饰者模式(实现接口)

  • 使用环境:适用于二次开发的时候,无法(×)获取到源码(不能在源码更改),无法(×)使用继承(不能重写)前提下,要对已存在对象上的功能增强.

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

  • 实现思路: new一个类实现ICar接口,然后test测试的时候new的对象是GoogleCar对象

  • 弊端:如果被实现的接口中的方法过多,装饰类中的方法过多冗余(原来的方法不能太多)

MyCar(新创建的类 实现原来的接口)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MyCar implements ICar{
ICar car;

//构造方法
public MyCar(ICar car) {
this.car=car; //通过TestCar里面new的对象传过来
}

@Override
public void start() {
System.out.println("MyCar判断天气是否良好"); //增强的部分
System.out.println("MyCar判断路况是否拥堵"); //增强的部分
car.start();
}

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

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

测试类TestCar

1
2
3
4
5
6
7
8
public class TestCar {
public static void main(String[] args) {
ICar car=new MyCar(new GoogleCar()); //面向接口编程 右边new的是GoogleCar对象
car.start();
car.run();
car.stop();
}
}

分析:
其实就是test里面new的对象 –> 新写的增强MyCar的构造方法接收 –> 然后调用方法(里面既有新写的方法内容 + 谷歌原来的方法内容)


动态代理(字节码)

解决装饰者模式中实现方法太多接口的冗余问题

  • 原理:通过虚拟机在内存中创建类似MyCar.class文件

    要创建MyCar.class文件告诉虚拟机:

    1_被创建的字节码文件上应该有多少方法
    2_被创建的字节码上的方法如何来实现

在class类里面本来就有.class的文件用于虚拟机识别的字节码:

只是在前面ICar和GoogleCar的基础上直接写test测试用字节码方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class TestCar {
public static void main(String[] args) {
//使用字节码

//1param: 固定值: 告诉虚拟机用哪个字节码加载器加载内存中创建出的字节码文件
//2param: 告诉虚拟机内存中正在被创建的字节码文件中应该有哪些方法
//3param: 告诉虚拟机正在被创建的字节码上的各个方法如何处理

ICar car=(ICar)Proxy.newProxyInstance(TestCar.class.getClassLoader(), GoogleCar.class.getInterfaces(),new InvocationHandler() { //第三个参数使用匿名内部类

//method:代表正在执行的方法
//args:代表正在执行的方法中的参数
//Object:代表方法执行完毕之后的返回值
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

if(method.getName().equalsIgnoreCase("start")){ //让你本来有的方法和要改变的方法对比
System.out.println("检查天气是否良好");
method.invoke(new GoogleCar(), args); //这是固定的调用GoogleCar的方法
System.out.println("检查路况是否拥堵"); //增强的方法(位置可以变化)
}
else
{
method.invoke(new GoogleCar(), args); //这是固定的调用GoogleCar的方法
}
return null;
}

});

car.start(); //调用方法输出结果
car.run();
car.stop();

}
}

字节码加载器(3种 – 系统引导加载器): jdk有一些程序 – 专门将各种字节码文件 – > 到内存(IO流技术)


动态代理解决全站乱码

1.项目中新建一个页面Index.html

1
2
3
4
5
6
7
8
9
10
11
<h1>post方式提交中文</h1>
<form action="/day18_v3/ServletDemo" method="post">
User:<input type="" name="username"/><br/>
<input type="submit"/>
</form>

<h1>get方式提交中文</h1>
<form action="/day18_v3/ServletDemo" method="get">
User:<input type="" name="username"/><br/>
<input type="submit"/>
</form>

2.servlet代码

1
2
3
无论是在post/get方法,执行以下语句不存在中文乱码问题(可以在前面加一句防止乱码的)
String um=request.getParameter("username"); //获取username
System.out.println(um);

3.过滤器Filter中,为request上的getParameter()功能进行增强

判断当前的请求是get/post  
  request.getMethod();
如果是post, 
      设置一句话: request.setCharacterEncoding(“utf-8”); 
                      放行
如果是get,
      调用原先的String v=request.getParameter(name);
                  将v进行转码,
                      放行

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 谷歌增强Car问题
  2. 2. 装饰者模式(实现接口)
  3. 3. 动态代理(字节码)
  4. 4. 动态代理解决全站乱码
,