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

区别

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

相关推荐
捕鲸叉3 小时前
C++软件设计模式之外观(Facade)模式
c++·设计模式·外观模式
小小小妮子~4 小时前
框架专题:设计模式
设计模式·框架
先睡4 小时前
MySQL的架构设计和设计模式
数据库·mysql·设计模式
Damon_X12 小时前
桥接模式(Bridge Pattern)
设计模式·桥接模式
越甲八千16 小时前
重温设计模式--享元模式
设计模式·享元模式
码农爱java18 小时前
设计模式--抽象工厂模式【创建型模式】
java·设计模式·面试·抽象工厂模式·原理·23种设计模式·java 设计模式
越甲八千18 小时前
重温设计模式--中介者模式
windows·设计模式·中介者模式
犬余18 小时前
设计模式之桥接模式:抽象与实现之间的分离艺术
笔记·学习·设计模式·桥接模式
Theodore_102220 小时前
1 软件工程——概述
java·开发语言·算法·设计模式·java-ee·软件工程·个人开发
越甲八千21 小时前
重拾设计模式--组合模式
设计模式·组合模式