首先装饰者模式。侧重点是在为所装饰的对象增强功能。
//定义装饰者的接口
//定义装饰者的接口
public interface Human {
public void wearClothes();
public void walkToWhere();
}
//定义装饰者
//作用就是我们可以任意传进来一个Human的一个实现类,然后用抽象类封装这个实现类,
//不仅可以使用该实现类的自己方法,也可以加强该实现类的基本方法,
public abstract class Decorator implements Human{
private Human human;
public Decorator(Human human){
this.human=human;
}
public void wearClother(){
human.wearClothes();
}
public void walkToWhere(){
human.walkToWhere();
}
}
//作用: 当我们想要单独增加实现类的方法,或者加强它本身之前已有的方法时候。
public class Decorator_zero extends Decorator {
public Decorator_zero(Human human) {
super(human);
}
public void goHome() {
System.out.println("进房子。。");
}
public void findMap() {
System.out.println("书房找找Map。。");
}
@Override
public void wearClothes() {
// TODO Auto-generated method stub
super.wearClothes();
goHome();
}
@Override
public void walkToWhere() {
// TODO Auto-generated method stub
super.walkToWhere();
findMap();
}
}
public class Decorator_first extends Decorator {
public Decorator_first(Human human) {
super(human);
}
public void goClothespress() {
System.out.println("去衣柜找找看。。");
}
public void findPlaceOnMap() {
System.out.println("在Map上找找。。");
}
@Override
public void wearClothes() {
// TODO Auto-generated method stub
super.wearClothes();
goClothespress();
}
@Override
public void walkToWhere() {
// TODO Auto-generated method stub
super.walkToWhere();
findPlaceOnMap();
}
}
public class Decorator_two extends Decorator {
public Decorator_two(Human human) {
super(human);
}
public void findClothes() {
System.out.println("找到一件D&G。。");
}
public void findTheTarget() {
System.out.println("在Map上找到神秘花园和城堡。。");
}
@Override
public void wearClothes() {
// TODO Auto-generated method stub
super.wearClothes();
findClothes();
}
@Override
public void walkToWhere() {
// TODO Auto-generated method stub
super.walkToWhere();
findTheTarget();
}
}
//定义被装饰者,被装饰者初始状态有些自己的装饰
public class Person implements Human {
@Override
public void wearClothes() {
// TODO Auto-generated method stub
System.out.println("穿什么呢。。");
}
@Override
public void walkToWhere() {
// TODO Auto-generated method stub
System.out.println("去哪里呢。。");
}
}
//测试类,看一下你就会发现,跟java的I/O操作有多么相似
public class Test {
public static void main(String[] args) {
Human person = new Person();
Decorator decorator = new Decorator_two(new Decorator_first(
new Decorator_zero(person)));
decorator.wearClothes();
decorator.walkToWhere();
}
}
也就是给我们一个接口,然后我们可以使用多个实现类实现接口,再者使用一个抽象类继承它,抽象类中传入实现类,(在抽象类中我们可以加强实现类,或者扩展共同功能)然后我们可以用装饰1,装饰2,装饰3 来继承抽象类。这个过程就是使被装饰类,增强功能,更加强大!
静态代理
一 代理概念:
为某个对象提供一个代理,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。
侧重点在:对委托类方法的控制,也就是委托类某些方法不让外界知道,可以使用代理模式,通过访问第三方,访问原函数的方式,达到上面的目的,这样当我们使用调用类的时候,不知道是使用的的是第三方,还是自己的。
1.代理接口:
-
-
-
-
public interface Subject {
-
-
-
-
-
public void dealTask(String taskName);
-
}
2.委托类,具体处理业务
-
-
-
-
public class RealSubject implements Subject {
-
-
-
-
-
-
@Override
-
public void dealTask(String taskName) {
-
System.out.println("正在执行任务:"+taskName);
-
try {
-
Thread.sleep(500);
-
} catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
}
3.静态代理类
-
-
-
-
public class ProxySubject implements Subject {
-
-
private Subject delegate;
-
-
public ProxySubject(Subject delegate) {
-
this.delegate = delegate;
-
}
-
-
-
-
-
-
-
@Override
-
public void dealTask(String taskName) {
-
long stime = System.currentTimeMillis();
-
-
delegate.dealTask(taskName);
-
long ftime = System.currentTimeMillis();
-
System.out.println("执行任务耗时"+(ftime - stime)+"毫秒");
-
-
}
-
}
4.生成静态代理类工厂
-
public class SubjectStaticFactory {
-
-
-
public static Subject getInstance(){
-
return new ProxySubject(new RealSubject());
-
}
-
}
5.客户类
-
public class Client1 {
-
-
public static void main(String[] args) {
-
Subject proxy = SubjectStaticFactory.getInstance();
-
proxy.dealTask("DBQueryTask");
-
}
-
-
}
动态代理
动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。这里介绍两种动态代理。
jdk动态代理是由java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的,总的来说反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。
首先是jdk动态代理方式
1.定义接口和实现类
public interface UserService {
public String getName(int id);
public Integer getAge(int id);
}
public class UserServiceImpl implements UserService {
@Override
public String getName(int id) {
System.out.println("------getName------");
return "Tom";
}
@Override
public Integer getAge(int id) {
System.out.println("------getAge------");
return 10;
}
}
2.jdk动态代理的实现
public class MyInvocationHandler implements InvocationHandler {
private Object target;
MyInvocationHandler() {
super();
}
MyInvocationHandler(Object target) {
super();
this.target = target;
}
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
if("getName".equals(method.getName())){
System.out.println("++++++before " + method.getName() + "++++++");
Object result = method.invoke(target, args);
System.out.println("++++++after " + method.getName() + "++++++");
return result;
}else{
Object result = method.invoke(target, args);
return result;
}
}
}
public class Main1 {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
InvocationHandler invocationHandler = new MyInvocationHandler(userService);
UserService userServiceProxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(), invocationHandler);
System.out.println(userServiceProxy.getName(1));
System.out.println(userServiceProxy.getAge(1));
}
}
代理步骤:1 创建被代理的类以及接口。
2 创建一个实现接口invocationHandler的类,它必须实现invoke方法。
3 通过proxy的静态方法 newProxyInstance(ClassLoader loader,class[] interfaces,InvocationHandler)创建一个代理
4 通过代理调用方法。
其次使用cglib实现动态代理
cglib依赖的是cglib包下的methodInterceptor接口,每调用代理类的方法,都会调用intercept方法
public class CglibMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("------before " + methodProxy.getSuperName() + "------");
Object o1 = methodProxy.invokeSuper(o, args);
System.out.println("------after " + methodProxy.getSuperName() + "------");
return o1;
}
}
public class M {
public static void main(String[] args) {
CglibMethodInterceptor cglibProxy = new CglibMethodInterceptor();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserServiceImpl.class);
enhancer.setCallback(cglibProxy);
UserService o = (UserService) enhancer.create();
o.getName(1);
o.getAge(1);
}
}
|