代理模式 它是一种软件开发设计模式
使用代理的目地:因为目标对象无法满足用户的需求,所以使用代理类来增强目标对象
1.代理的分类
静态代理 |–IO里面的静态代理使用的相当多 动态代理 |–jdk动态代理 |–cglib的动态代理
静态代理
1.使用继承实现静态代理
目标类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.course.curd;public class DatabaseCurd { public void add () { System.out.println("insert data into table" ); } public void update () { System.out.println("update table data" ); } public void delete () { System.out.println("delete table data" ); } public void query () { System.out.println("query table data" ); } }
代理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.course.extend;import com.course.curd.DatabaseCurd;public class DatabaseDML extends DatabaseCurd { public void add () { openConnection(); super .add(); closeConnnection(); } public void openConnection () { System.out.println("conn.open()" ); } public void closeConnnection () { System.out.println("conn.close()" ); } }
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package com.course.test;import com.course.curd.DatabaseCurd;import com.course.decorator.DatabaseOperate;import com.course.extend.DatabaseDML;public class Test { public static void main (String[] args) { DatabaseDML databaseDML = new DatabaseDML (); databaseDML.add(); } }
2.使用装饰者模式实现静态代理
目标类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.course.curd;public class DatabaseCurd { public void add () { System.out.println("insert data into table" ); } public void update () { System.out.println("update table data" ); } public void delete () { System.out.println("delete table data" ); } public void query () { System.out.println("query table data" ); } }
代理类
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 package com.course.decorator;import com.course.curd.DatabaseCurd;public class DatabaseOperate { private DatabaseCurd databaseCurd; public DatabaseOperate (DatabaseCurd databaseCurd) { this .databaseCurd = databaseCurd; } public void query () { openConnection(); databaseCurd.query(); closeConnnection(); } public void openConnection () { System.out.println("conn.open()" ); } public void closeConnnection () { System.out.println("conn.close()" ); } }
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package com.course.test;import com.course.curd.DatabaseCurd;import com.course.decorator.DatabaseOperate;import com.course.extend.DatabaseDML;public class Test { public static void main (String[] args) { DatabaseCurd databaseCurd = new DatabaseCurd (); DatabaseOperate databaseOperate = new DatabaseOperate (databaseCurd); databaseOperate.query(); } }
3.常见方法(使用接口)
为了保证代理类与目标类的对应方法的方法名一致,可以使用接口的方式。
目标类与代理类都实现同一个接口。
接口
1 2 3 4 5 package com.course.dao;public interface UserDao { public void addUser () ; }
1 2 3 4 5 package com.course.dao;public interface DepartmentDao { public void addDepartmentDao () ; }
目标类
1 2 3 4 5 6 7 8 9 10 11 12 package com.course.dao.impl;import com.course.dao.UserDao;public class UserDaoImpl implements UserDao { @Override public void addUser () { System.out.println("Save user" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 package com.course.dao.impl;import com.course.dao.DepartmentDao;public class DepartmentDaoImpl implements DepartmentDao { @Override public void addDepartmentDao () { System.out.println("Save department" ); } }
代理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package com.course.proxy;import com.course.dao.UserDao;public class UserDaoProxy implements UserDao { private UserDao userDao; public UserDaoProxy (UserDao userDao) { this .userDao = userDao; } @Override public void addUser () { System.out.println("open transaction" ); userDao.addUser(); System.out.println("commit transaction" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package com.course.proxy;import com.course.dao.DepartmentDao;public class DepartmentDaoProxy implements DepartmentDao { private DepartmentDao departmentDao; public DepartmentDaoProxy (DepartmentDao departmentDao) { this .departmentDao = departmentDao; } @Override public void addDepartmentDao () { System.out.println("open transaction" ); departmentDao.addDepartmentDao(); System.out.println("commit transaction" ); } }
测试类
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 package com.course.test;import com.course.dao.DepartmentDao;import com.course.dao.UserDao;import com.course.dao.impl.DepartmentDaoImpl;import com.course.dao.impl.UserDaoImpl;import com.course.proxy.DepartmentDaoProxy;import com.course.proxy.UserDaoProxy;public class Test { public static void main (String[] args) { UserDao userDao = new UserDaoImpl (); UserDaoProxy userDaoProxy = new UserDaoProxy (userDao); userDaoProxy.addUser(); DepartmentDao departmentDao = new DepartmentDaoImpl (); DepartmentDaoProxy departmentDaoProxy = new DepartmentDaoProxy (departmentDao); departmentDaoProxy.addDepartmentDao(); } }
3.静态代理说明
在JDK的IO流里面大量使用了静态代理,可以去看看源代码
4.静态代理总结: (1) 可以做到在不修改目标对象的功能前提下,对目标功能扩展. (2) 缺点:
因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多。
每有一个目标类就需要有一个代理类,目标类每添加一个方法,就需要在代理类中添加相应的方法,这样就会有很多代理类,很难维护。
如何解决静态代理中的缺点呢?答案是可以使用动态代理方式