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());
    }
}

区别

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

相关推荐
wrx繁星点点6 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
金池尽干8 小时前
设计模式之——观察者模式
观察者模式·设计模式
也无晴也无风雨8 小时前
代码中的设计模式-策略模式
设计模式·bash·策略模式
肘击鸣的百k路17 小时前
Java 代理模式详解
java·开发语言·代理模式
捕鲸叉17 小时前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
wrx繁星点点18 小时前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
凉辰18 小时前
设计模式 策略模式 场景Vue (技术提升)
vue.js·设计模式·策略模式
菜菜-plus18 小时前
java设计模式之策略模式
java·设计模式·策略模式
暗黑起源喵18 小时前
设计模式-迭代器
设计模式
lexusv8ls600h20 小时前
微服务设计模式 - 网关路由模式(Gateway Routing Pattern)
spring boot·微服务·设计模式