1. 代理模式
1.1思考:如何增强方法
public class Dog {
public void eat(){
System.out.println("狗正在啃骨头");
}
public void bark(){
System.out.println("狗正在汪汪汪的叫");
}
}
1.1.1 修改源代码
public class Dog {
public void eat(){
System.out.println("eat方法增强开始");
System.out.println("狗正在啃骨头");
System.out.println("eat方法增强结束");
}
public void bark(){
System.out.println("bark方法增强开始");
System.out.println("狗正在汪汪汪的叫");
System.out.println("ebark方法增强结束");
}
}
弊端:
修改源代码如果类比较多,修改起来比较麻烦
1.1.2 使用继承的方式
public class DogSon extends Dog {
public void eat(){
System.out.println("eat方法增强开始");
System.out.println("狗正在啃骨头");
System.out.println("eat方法增强结束");
}
public void bark(){
System.out.println("bark方法增强开始");
System.out.println("狗正在汪汪汪的叫");
System.out.println("ebark方法增强结束");
}
}
测试类
public class TestDog {
public static void main(String[] args) {
Dog dog = new DogSon();
dog.eat();
dog.bark();
}
}
1.2 装饰模式
过滤流使用了装饰模式
1.2.1 装饰模式的实现步骤
- 1.定义一个接口对象
public interface Animal {
void eat();
void bark();
}
- 2.定义一个Dog类实现该接口
public class Dog implements Animal{
public void eat(){
System.out.println("狗正在啃骨头");
}
public void bark(){
System.out.println("狗正在汪汪汪的叫");
}
}
- 3.定义修饰类
装饰类,必须实现Animal接口
public class ZhuangShi implements Animal {
private Animal animal;
//通过构造方法传入被装饰的对象
public ZhuangShi(Animal animal) {
this.animal = animal;
}
@Override
public void eat() {
System.out.println("增强eat方法开始");
animal.eat();
System.out.println("增强eat方法结束");
}
@Override
public void bark() {
System.out.println("增强bark方法开始");
animal.bark();
System.out.println("增强bark方法结束");
}
}
public class TestZhuangshi {
public static void main(String[] args) {
Dog dog = new Dog();
ZhuangShi zhuangShi = new ZhuangShi(dog);
zhuangShi.eat();
zhuangShi.bark();
}
}
1.3 代理模式
1.3.1 静态代理
public class DaiLi implements Animal {
private Animal animal = new Dog();
@Override
public void eat() {
System.out.println("增强eat方法开始");
animal.eat();
System.out.println("增强eat方法结束");
}
@Override
public void bark() {
System.out.println("增强bark方法开始");
animal.bark();
System.out.println("增强bark方法结束");
}
}
public class TestDaiLi {
public static void main(String[] args) {
DaiLi daiLi = new DaiLi();
daiLi.bark();
daiLi.eat();
}
}
1.3.2 装饰模式和代理模式的区别
- 装饰模式对构造方法传入的对象进行增强
- 代理模式隐藏了真实的对象,用户无需关心真实对象,通过操作代理对象实现对真实对象方法的增强。
1.3.3 动态代理
实现方法:两种使用java提供的类和CGLIB
实现方式一:
使用Proxy类实现
//使用java提供的Proxy类完成动态代理
public class TestProxy {
public static void main(String[] args) {
Dog dog = new Dog();
//创建代理对象
//第一个参数是真实对象的类加载器
//第二个参数表示真实对象实现哪些接口
Animal animal = (Animal) Proxy.newProxyInstance(dog.getClass().getClassLoader(), dog.getClass().getInterfaces(), new InvocationHandler() {
@Override
//第一个参数是代理对象,第二个参数是方法对象,第三个参数是方法参数对象
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("eat".equals(method.getName())) {
System.out.println("增强eat方法开始");
dog.eat();
System.out.println("增强eat方法结束");
} else if ("bark".equals(method.getName())) {
System.out.println("增强bark方法开始");
dog.bark();
System.out.println("增强bark方法结束");
}
return null;
}
});
animal.eat();
animal.bark();
}
}