简体   繁体   中英

how to make sure client uses proxy object in proxy design pattern?

I am trying to understand the proxy pattern. Here's my question:

If a proxy implements the same interface as the real object, how can I make sure a client uses the proxy and not the real object? Because that way, I can assign an instance of the real object to a reference of the interface and call the methods directly, circumventing the proxy.

Maybe I'm not getting it: Isn't this pattern used to ensure that clients only interact with the proxy?

Or is this a pattern that I would use in code that I control?

EDIT

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

how can I make sure a client uses the proxy and not the real object?

With encapsulation. If you hide the real object as a private field, the clients cannot access it.

Isn't this pattern used to ensure that clients only interact with the proxy?

It's more than it. You can use a proxy as a sandbox to the underlying object (adding a security layer), you can use a proxy to access a remote object that runs in a remote server, you can use a proxy to cache some requisitions to the real object, and etc..

In the case of a proxy of a remote object, the implementation of underlying object that provides the functionality doesn't even need to be in the same physical machine. In this case the proxy will be responsible to convert the method calls in a network message that contains the information about the object to be referenced, the method to be called, and the parameters.

It really depends on how much control you have over the code, but here is one example based on your sample code, this would prevent instantation of both classes directly:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM