设计模式——代理模式

Posted macro-renzhansheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式——代理模式相关的知识,希望对你有一定的参考价值。

基本原理:

//源接口

public interface Sourceable {
     public void method();
}

//实现接口类

public class Source implements Sourceable{
     @Override
     public void method() {
         // TODO Auto-generated method stub
         System.out.println("源方法");
     }
}

//代理对象实现类——将实现类 封装到 代理实现类,同时实现同一个接口

public class Proxy implements Sourceable{
     private Sourceable source;
     public Proxy(Sourceable source) {
         this.source = source;
     }
     @Override
     public void method() {
         // TODO Auto-generated method stub
         System.out.println("before invoke");
         source.method();
         System.out.println("after invoke");
     }
}

//测试

public class Demo {
     public static void main(String[] args) {
         new Proxy(new Source()).method();
     }
}


综合案例:

//接口

public interface UserDao {
void save(User user);
void delete();
}
//存储User对象
public class User {
private String name;
private Integer age;
public User(){
super();
}
public User(String name,Integer age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString(){
StringBuilder tmp = new StringBuilder();
tmp.append(name);
tmp.append(",");
tmp.append(age);
return tmp.toString();
}
}

业务层:UserService

//直接调用

public static void directCall(){
User user = new User();
user.setName("macro");
user.setAge(25);
//内名内部类实现
UserDao userDao = new UserDao() {
@Override
public void save(User user) {
//入库,打印信息(简单不限制输入内容)
System.out.println("保存用户信息:"+user.toString());
}
@Override
public void delete() {
}
};
userDao.save(user);
User user1 = new User("",20);
User user2 = new User("小海",-10);
userDao.save(user1);
userDao.save(user2);
}

静态代理——跟杨老师的Dao、Serivice、Controller 等吻合!

//将接口实现类封装到代理对象中

//接口实现类

public class UserDaoImpl implements UserDao{

@Override
public void save(User user) {
//入库
//初始判断条件简单
if(user.getName()==null || user.getName().length()<=0){
System.out.println("用户名输错");
return;
}
if(user.getAge() == null || user.getAge().intValue()<0){
System.out.println("用户年龄输错");
return;
}
System.out.println("入库用户信息:"+user.toString());
}

@Override
public void delete() {
System.out.println("执行删除操作");
}
}

//代理对象

public class StaticProxyUser implements UserDao {
private UserDao target;
public StaticProxyUser(UserDao userDao){
this.target = userDao;
}
//增加参数校验
@Override
public void save(User user) {
//增加判断条件
if(user.getName()==null || user.getName().length()<=0){
System.out.println("用户名称输错,入库失败");
return;
}
if (user.getAge()<0 ||user.getAge()>200){
System.out.println("用户年龄输错,入库失败");
return;
}
//调用原来的对象入库等操作
target.save(user);
//System.out.println(user.toString());
}

@Override
public void delete() {

}
}

//调用

public static void staticProxyCall(){
UserDaoImpl userDaoImpl = new UserDaoImpl();
StaticProxyUser staticProxyUser = new StaticProxyUser(userDaoImpl);
User user = new User();
user.setName("macro");
user.setAge(25);
staticProxyUser.save(user);
user.setName("小海");
user.setAge(-1);
staticProxyUser.save(user);
User user1 = new User("",3);
staticProxyUser.save(user1);
}


JDK代理——缺少理论理解???

//实现Invocationhandler接口

public class UserInvocaHandler implements InvocationHandler {
public Object object;
public UserInvocaHandler(Object object){
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//return null;
System.out.println("开始执行JDKProxy");
//添加限制条件
if(args != null && args.length==1){
if(args[0] instanceof User){
User user = (User) args[0];
if (user.getName() == null || user.getName().trim().length()<=0 ){
System.out.println("姓名为空,不保存");
return false;
}
if (user.getAge() == null || user.getAge()<0 ){
System.out.println("年龄小于0,不保存");
return false;
}
}
}
Object result = method.invoke(object,args);
System.out.println("执行结束JDKProxy");
return result;
}
}
//调用过程
public static void jdkProxy(){
User user = new User("macro",26);
UserDaoImpl userDao = new UserDaoImpl();
UserInvocaHandler handler = new UserInvocaHandler(userDao);
//UserDao 必须是接口
UserDao userDao1 = (UserDao) Proxy.newProxyInstance(
userDao.getClass().getClassLoader(),
userDao.getClass().getInterfaces(),
handler
);
//System.out.println("开始执行JDKProxy");
userDao1.save(user);
//System.out.println("执行结束JDKProxy");

User user1 = new User("macro1",-6);
User user2 = new User("",26);
userDao1.save(user1);
userDao1.save(user2);
userDao1.delete();
}

Cglib代理

//同样:实现 MethodInterceptor接口

public class User2DaoCglibProxy implements MethodInterceptor {
private Object object;
public User2DaoCglibProxy(Object object){
this.object = object;
}
public Object getProxyInstance() {
Enhancer en = new Enhancer();
en.setSuperclass(object.getClass());
en.setCallback(this);
return en.create();
}

@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("开始执行");
Object result = method.invoke(object,objects);
System.out.println("结束执行");
return result;
//return null;
}

/*@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
return null;
}*/
}
//调用该代理方法
public static void cglibProxy(){
User user = new User("macro",26);
User2Dao user2Dao = new User2Dao();
//UserInvocaHandler handler = new UserInvocaHandler(userDao);
User2DaoCglibProxy cglibProxy = new User2DaoCglibProxy(user2Dao);
User2Dao user2DaoProxy = (User2Dao) cglibProxy.getProxyInstance();

user2DaoProxy.save(user);
User user1 = new User("",26);
user2DaoProxy.save(user1);
User user12 = new User("hr",-6);
user2DaoProxy.save(user12);
}

以上是关于设计模式——代理模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式

原谈谈对Objective-C中代理模式的误解

Java 之 设计模式——代理模式

Spring AOP高级——源码实现动态代理技术

Java入门——面向对象基础

设计模式,代理模式