如何确保客户端在代理设计模式中使用代理对象?

时间:2017-05-20 10:57:37

标签: java proxy

我想了解代理模式。这是我的问题:

如果代理实现与真实对象相同的接口,我如何确保客户端使用代理而不是真实对象?因为这样,我可以将实际对象的实例分配给接口的引用并直接调用方法,绕过代理。

也许我没有得到它:这个模式不是用来确保客户只与代理交互吗?

或者这是我在我控制的代码中使用的模式吗?

修改

public final class RealClass implements CommonInterfaceForProxyAndRealClasses {

    private String name;
    private String name2;

    RealClass() {
        // TODO Auto-generated constructor stub
    }

    public String getName() {
        return name;
    }

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

    public String getName2() {
        return name2;
    }

    public void setName2(final String name2) {
        this.name2 = name2;
    }

    @Override
    public String allowedMethodGetName() {
        // TODO Auto-generated method stub
        return getName() + getName2();
    }
}

public class ProxyForRealClasses
        implements CommonInterfaceForProxyAndRealClasses {

   @Override
   public String allowedMethodGetName() {
       final RealClass classy = new RealClass();
       classy.setName("hello");
       classy.setName2("new");
       return classy.allowedMethodGetName();
   }

}


final CommonInterfaceForProxyAndRealClasses myobje = new ProxyForRealClasses();
System.out.println(myobje.allowedMethodGetName());

// Shouldn't be possible
final CommonInterfaceForProxyAndRealClasses myobje2 = new RealClass();
System.out.println(myobje2.allowedMethodGetName());

2 个答案:

答案 0 :(得分:1)

  

如何确保客户端使用代理而不是真实对象?

封装。如果将真实对象隐藏为私有字段,则客户端无法访问它。

  

此模式是否用于确保客户端仅与代理进行交互?

它不仅仅是它。您可以使用代理作为底层对象的沙箱(添加安全层),您可以使用代理访问在远程服务器中运行的远程对象,您可以使用代理将一些请求缓存到真实对象,等等。

在远程对象的代理的情况下,提供功能的底层对象的实现甚至不需要在同一物理机器中。在这种情况下,代理将负责转换网络消息中的方法调用,该消息包含有关要引用的对象,要调用的方法和参数的信息。

答案 1 :(得分:1)

这实际上取决于您对代码的控制程度,但这里有一个基于示例代码的示例,这样可以直接阻止两个类的即时创建:

public final class ProxyExample {
    public interface CommonInterfaceForProxyAndRealClasses {
        String allowedMethodGetName();
    }

    private static final class RealClass implements CommonInterfaceForProxyAndRealClasses {

        private String name;
        private String name2;

        RealClass() {
            // TODO Auto-generated constructor stub
        }

        public String getName() {
            return name;
        }

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

        public String getName2() {
            return name2;
        }

        public void setName2(final String name2) {
            this.name2 = name2;
        }

        @Override
        public String allowedMethodGetName() {
            // TODO Auto-generated method stub
            return getName() + getName2();
        }
    }

    private static final class ProxyForRealClasses
            implements CommonInterfaceForProxyAndRealClasses {
        private final CommonInterfaceForProxyAndRealClasses target;
        public ProxyForRealClasses(CommonInterfaceForProxyAndRealClasses target) {
            this.target = target;
        }
        @Override
        public String allowedMethodGetName() {
            return target.allowedMethodGetName();
        }
    }

    public static CommonInterfaceForProxyAndRealClasses getProxiedObjectWithName(String name1, String name2) {
        RealClass realClass = new RealClass();
        realClass.setName(name1);
        realClass.setName2(name2);
        return new ProxyForRealClasses(realClass);
    }
}