1.增强方法
1)修改源代码:即对需要进行增强的方法的源代码进行修改,使得方法更符合具体的需求;
缺点:修改麻烦,当需要增强的方法数量太大时,代码修改量大,不利于提升开发效率
public void eat(){
System.out.println("吃");
}
public void sleep(){
System.out.println("睡");
}
修改源代码增强:
public void eat(){
System.out.println("增强开始");
System.out.println("吃");
System.out.println("增强结束");
}
public void sleep(){
System.out.println("喜欢白天睡觉");
System.out.println("睡5个小时");
}
2)子类继承父类,重写父类的方法增强
子类继承父类的所有非私有的属性和方法,可以对父类方法进行重写
super.eat 父类的eat方法,
public class Dog implements Animal {
public void eat(){
System.out.println("吃");
}
public void sleep(){
System.out.println("睡");
}
}
继承增强:
public class DogSon extends Dog {
@Override
public void eat() {
super.eat();
System.out.println("增强");
}
@Override
public void sleep() {
super.sleep();
System.out.println("增强");
}
}
3)使用装饰模式增强:
指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。
例如:过滤流
字符流:FilterReader、FilterWriter 节点流:FilterInputStream、FilterOutputStream
1.定义接口类
public interface Animal {
void eat();
void sleep();
}
2.定义接口实现类
public class Dog implements Animal {
public void eat(){
System.out.println("吃");
}
public void sleep(){
System.out.println("睡");
}}
3.定义代理类 (相当于中介,可以代理多个类,但是一次只能代理一个类)
public class daiLI implements Animal {
private Animal animal = new Dog();
@Override
public void eat() {
System.out.println("daili");
animal.eat();
}
@Override
public void sleep() {
System.out.println("daili");
animal.sleep();
}
4)静态代理
优点:
代理使客户端不需要知道实现类是什么,怎么做的,而客户端只需知道代理即可(解耦合)
缺点:
1)代理类和委托类实现了相同的接口、相同的方法,代码重复。新增方法时,代理类和委托类都要进行定义实现,加大了代码维护的复杂度。
2)代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。
**
* 静态代理,一次只能代理一个对象
* 隐藏了真实的对象,用户无需关心真实对象,通过操纵代理对象实现真实的对象方法
* 增强
*
* 动态代理
* */
public class daiLI implements Animal {
private Animal animal = new DoG();
@Override
public void eat() {
System.out.println("daili");
animal.eat();
}
@Override
public void sleep() {
System.out.println("daili");
animal.sleep();
}
静态代理和装饰模式的区别:
1、增强对象不同
装饰模式:对构造方法传入的对象进行增强
代理模式:隐藏了真实的对象,用户无需关心真实对象,通过操纵代理对象实现对真实对象方法的增强
2、增强时期不同
静态代理是一种编译期增强,还没运行就已经知道增强的目标对象。
装饰者是运行时增强,只有运行时才知道具体增强的目标。
3、原则上的区别
代理为了控制对某个函数前后的操作,而装饰着模式是为了添加某一操作
4、实现上的区别,
代理模式的类一般和被代理类的操作一致,因此构造函数一般不传入类对象,使用时的不同如下: Logger logger = new Proxy(); // 代理模式 (为了让Proxy的行为像Logger) Logger logger = new DecorateLogger(new Logger()); // 装饰者模式,还可以有更多层
5)动态代理
**
* 动态代理 Proxy
* 使用java提供的Proxy类完成动态代理
* */
public class TestProxy {
public static void main(String[] args) {
DoG doG = new DoG();
// 参数一类 加载器
// 参数二 类实现的接口
// 参数三 InvocationHandle 参数方法参数对象
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("动态");
doG.eat();
} else if ("sleep".equals(method.getName())) {
System.out.println("动态");
doG.sleep();
}
return null;
}
});
animal.sleep();
animal.eat();
}