技术干货程序员

Java 设计模式(13) —— 代理模式

2018-05-24  本文已影响72人  磊_lei

一、代理模式

为一个对象提供一个替身,以控制对这个对象的访问。

被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象代理模式有很多变体,都是为了控制与管理对象访问

代理模式

二、RMI示例

上篇博文状态模式中的示例糖果机项目,现在如果要改进远程控制的糖果机,则本地程序无需修改,只需新增远程代理控制即可。就可使用RMI远程通讯。

1.定义接口远程调用的接口方法

/**
 * 定义服务的接口,继承RMI的远程协议
 */
public interface MyRemote extends Remote{

    public String sayHello() throws RemoteException;
    
}

2.RMI服务端


/**
 * RMI服务端,实现接口方法,提供服务
 */
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {

    protected MyRemoteImpl() throws RemoteException {
        super();
    }

    @Override
    public String sayHello() throws RemoteException {
        return "Hello World!";
    }

    public static void main(String[] args) {

        try {
            MyRemote service = new MyRemoteImpl();
            // LocateRegistry.createRegistry(6600);
            Naming.rebind("rmi://101.232.197.163:6600/RemoteHello", service);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.toString());
        }


    }
}

3.RMI客户端


/**
 * RMI客户端,远程连接服务端,调用远程服务
 */
public class MyRemoteClient {
    public static void main(String[] args) {

        new MyRemoteClient().go();
    }

    public void go() {
        try {
            MyRemote service = (MyRemote) Naming.lookup("rmi://127.0.0.1:6600/RemoteHello");
            String s = service.sayHello();
            System.out.println(s);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

以上是简单的RMI调用方法示例,可以尝试用来改进之前状态模式的糖果机项目为远程控制的糖果机

三、几种常见的代理模式

一个动态代理和保护代理的示例:人物的打分,自己只能看自己的分数或者给别人打分


/**
 * 定义代理的接口方法
 */
public interface PersonBean {
    String getName();
    String getGender();
    String getInterests();
    int getHotOrNotRating();
    
    void setName(String name);
    void setGender(String gender);
    void setInterests(String interests);
    void setHotOrNotRating(int rating);
}


/**
 * 代理接口的方法实现
 */
public class PersonBeanImpl implements PersonBean {
    String name;
    String gender;
    String interests;
    int rating;
    int ratingcount = 0;

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

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

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

    @Override
    public int getHotOrNotRating() {
        if (ratingcount == 0) return 0;
        return (rating / ratingcount);
    }

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

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

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

    @Override
    public void setHotOrNotRating(int rating) {
        this.rating = rating;
        ratingcount++;
    }

}


/**
 * 动态代理,保护代理,不是本人的属性提供代理方法
 */
public class NonOwnerInvocationHandler implements InvocationHandler {
    PersonBean person;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {

        if (method.getName().startsWith("get")) {
            return method.invoke(person, args);
        } else if (method.getName().equals("setHotOrNotRating")) {
            return method.invoke(person, args);

        } else if (method.getName().startsWith("set")) {
            return new IllegalAccessException();
        }

        return null;
    }

}


/**
 * 动态代理,保护代理,自己允许调用的方法提供代理
 */
public class OwnerInvocationHandler implements InvocationHandler {
    PersonBean person;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {

        if (method.getName().startsWith("get")) {
            return method.invoke(person, args);
        } else if (method.getName().equals("setHotOrNotRating")) {
            return new IllegalAccessException();
        } else if (method.getName().startsWith("set")) {
            return method.invoke(person, args);
        }

        return null;
    }

}

四、总结

Java设计模式所有示例代码,持续更新中

上一篇 下一篇

猜你喜欢

热点阅读