Head First Design Patterns -代理模式

什么是代理模式

代理模式为另一个对象提供替身或者占位符,以便控制客户对对象的访问,管理访问的方式有很多种。例如远程代理、虚拟代理、保护代理等。

远程代理:管理客户和远程对象之间的交互。

虚拟代理:控制访问实例化开销大的对象。

保护代理:基于调用者,控制对对象方法的调用。

类图

代码

案例:防止对person类的访问中,访问了不该访问的方法

以保护代理为例,主要是基于java内置的动态代理,来控制对对象方法的调用,其类图如下:

Person接口

java 复制代码
public interface Person {
    String getName();

    String getGender();

    String getInterests();

    int getGeekRating();

    void setName(String name);

    void setGender(String gender);

    void setInterests(String interests);

    void setGeekRating(int rating);
}

Person实现类

java 复制代码
public class PersonImpl implements Person{
    String name;
    String gender;
    String interests;
    int rating;
    int ratingCount = 0;

public PersonImpl(String name, String gender, String interests, int rating, int ratingCount) {
        this.name = name;
        this.gender = gender;
        this.interests = interests;
        this.rating = rating;
        this.ratingCount = ratingCount;
    }

@Override
public String getName() {
   return name;
}

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

@Override
public int getGeekRating() {
   if (ratingCount == 0) {
       return 0;
   } else {
       return rating  / ratingCount;
   }
}

@Override
public void setGeekRating(int rating) {
   this.rating += rating;
   ratingCount++;
}

@Override
public void setGender(String gender) {
   this.gender = gender;
}

@Override
public String getGender() {
   return gender;
}

@Override
public String getInterests() {
   return interests;
}

@Override
public void setInterests(String interests) {
   this.interests = interests;
}

NonOwnerInvocationHandler类

java 复制代码
//InvocationHandler
public class NonOwnerInvocationHandler implements InvocationHandler {
    Person person;

    public NonOwnerInvocationHandler(Person person) {
        this.person = person;
    }

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
        if (method.getName().startsWith("get")) {
            return method.invoke(person, args);
        } else if (method.getName().equals("setGeekRating")) {
            return method.invoke(person, args);
        } else if (method.getName().startsWith("set")) {
            throw new Throwable();
        }
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

    return null;
}
}

OwnerInvocationHandler类

java 复制代码
public class OwnerInvocationHandler implements InvocationHandler {
    Person person;

    public OwnerInvocationHandler(Person person) {
        this.person = person;
    }

// 
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   try {
       if (method.getName().startsWith("get")) {
           return method.invoke(person, args);
       } else if (method.getName().equals("setGeekRating")) {
           throw new Throwable();
       } else if (method.getName().startsWith("set")) {
           return method.invoke(person, args);
       }
   } catch (InvocationTargetException e) {
       e.printStackTrace();
   }

   return null;
}
}

测试:

java 复制代码
public class Test {
    public static void main(String[] args) {
        Person kang = new PersonImpl("kwb", "boy", "ball", 1, 3);
        Person owner = getProxy.getOwnerProxy(kang);

        System.out.println(owner.getName());
    }
}

区别

装饰器模式为对象加上行为,而代理则是控制访问。

相关推荐
小飞悟11 小时前
一打开文章就弹登录框?我忍不了了!
前端·设计模式
Ares-Wang11 小时前
设计模式》》门面模式 适配器模式 区别
设计模式·适配器模式
不修×蝙蝠11 小时前
设计模式深度解析:单例、工厂、适配器与代理模式
单例模式·设计模式·代理模式·适配器模式·工厂
C雨后彩虹12 小时前
行为模式-策略模式
java·设计模式·策略模式
玩代码12 小时前
模板方法设计模式
java·开发语言·设计模式·模板方法设计模式
queenlll14 小时前
Codeforces Round 1034 (Div. 3)
代理模式
画船听雨眠aa17 小时前
23种设计模式--#2单例模式
单例模式·设计模式
饕餮争锋19 小时前
设计模式笔记_结构型_桥接模式
笔记·设计模式·桥接模式
我爱吃菠 菜19 小时前
手撕设计模式之消息推送系统——桥接模式
java·设计模式·桥接模式
vvilkim20 小时前
深入理解设计模式:命令模式详解
设计模式·命令模式