Encapsulation does not necessarily means getters and setters. And have more than one aspects:
- Inside structure control.
 - Input data validation.
 - Outside access control.
 
Lets consider 'Outside access control'.
While we directly do not know which class calls method, it's hard to limit context of (method) call. It is possible, but amount of work is to big now time.
Any way what solutions do we have?
Control by 'key'.
public final class SetByLock {
  private SetByLock(Object acessKey) {
    this.acessKey = acessKey;
  }
  private final Object  acessKey;
  private String      data;
  public String getData() {
    return data;
  }
  public void setData(Object accessKey, String data) {
    if (acessKey != accessKey) { throw new UnauthorizedAccessException(accessKey == null ? "null" : accessKey.toString()); }
    this.data = data;
  }
}Control by 'delegated accessor'.
public class Container<Type> {
  public Type  element;
}
public class SetByAccessor {
  public SetByAccessor(Container<Accessor> accessorContainer, String data) {
    this.data.data = data;
    if (accessorContainer != null) {
      accessorContainer.element = new Accessor(this.data);
    }
  }
  private Local  data  = new Local();
  public String getData() {
    return data.data;
  }
  /*
   * Store local data
   */
  private static class Local {
    public Local() {
    }
    public String  data;
  }
  /*
   * Allow to more access
   */
  public static class Accessor {
    public Accessor(Local data) {
      if (data == null) { throw new NullPointerException(Local.class.getSimpleName()); }
      this.data = data;
    }
    private Local  data;
    public void setData(String data) {
      this.data.data = data;
    }
  }
}
Problem is when we have lot's of elements to control. 1000 objects force us to store 1000 Accessor-s
Mixed solution.
public class SetByMixed {
  public SetByMixed(Object accessKey, String data) {
    this.data.data = data;
    this.accessKey = accessKey;
  }
  private final Object  accessKey;
  private Accessor    accessor;
  public Accessor getAccessor(Object accessKey) {
    if (this.accessKey != accessKey) { throw new UnauthorizedAccessException(accessKey == null ? "null" : accessKey.toString()); }
    if (accessor == null) {
      accessor = new Accessor(data);
    }
    return accessor;
  }
  private Local  data  = new Local();
  public String getData() {
    return data.data;
  }
  /*
   * Store local data
   */
  private static class Local {
    public Local() {
    }
    public String  data;
  }
  /*
   * Allow to 'limited' access
   */
  public static class Accessor {
    public Accessor(Local data) {
      if (data == null) { throw new NullPointerException(Local.class.getSimpleName()); }
      this.data = data;
    }
    private Local  data;
    public void setData(String data) {
      this.data.data = data;
    }
  }
}
Key just need to be controlled to do not leak out.
Summary.
I just wander, if we really need all this stuff when we want limit write access?
0 comments / komentarz(y):
Post a Comment