Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design Pattern to only return certain LDAP attributes in an object

Let's say I have the following class, with many instance variables and corresponding getters and setters:

public class Foo {
  private String a;
  private int b;
  ...
  private List<String> z;

  public String getA() { return a; }
  public void setA(String a) { this.a = a; }
  public int getB() { return b; }
  public void setB(int b) { this.b = b; }
  ...
}

There is another class that populates the values, and it's resource intensive:

public class MyService {

    public Foo retrieveFoo() {
        // call some resource intensive code to retrieve the values
        String a = getTheString();
        int b = getTheInt();
        List<String> z = getTheList();

        Foo f = new Foo();
        f.setA(a);
        f.setB(b);
        ...
        f.setZ(z);

        return f;
    }

}

I have multiple clients that want to use instances of the above class, but some are only interested in getting a small subset of the variable values and not everything:

public class ClientA {
    private MyService service;

    public void doSomething() {
        Foo f = service.retrieveFoo();
        String a = f.getA();
        int b = f.getB();
        // not interested in anything else
    }
}

 public class ClientB {
    private MyService service;

    public void doSomething() {
        Foo f = service.retrieveFoo();
        List<String> z = f.getZ();
        // not interested in anything else
    }
}

One thing I could do is have the client tell the MyService to only retrieve which values it's interested in. Something like this:

public class ClientA {
    private MyService service;

    public void doSomething() {
        // the Service would only retrieve a and b, which 
        // means all other variables would be set to Null
        Foo f = service.retrieveFoo(Arrays.asList("a","b"));
        String a = f.getA();
        int b = f.getB();
        // not interested in anything else
    }
}

However, this just seems wrong since the other values would be null. Is there a better way to design this?

EDIT:

To be more specific, I'm working with user attributes in an LDAP system. Instead of having a 'God object' of all of a person's attributes, I'd like to only have to pull back the subset that I need for each use case. For example, one application might need uid and fullName; another might need uid, phone number, groups, etc.

Thanks.

like image 285
acvcu Avatar asked Dec 05 '25 21:12

acvcu


1 Answers

One simplest solution is to declare several interfaces with different set of getters, implement all of them in your class and make different clients to work with different interfaces.

For example

interface A {
    String getA();
}

interface B {
    String getB();
}

class MyClass implements A, B {
    String getA() {...}
    String getB() {...}
}

Now client A works with interface A and can only call getA() while client B works with interface B and can only call getB().

If some client C has to operate with both A and B you can either: 1. get it access to both interfaces 2. get it access to the MyClass directly 3. define other interface C that extends A and B, so client C will work with it.

Obviously this solution is not generic and can require definition of a lot of interfaces in some cases.

If you want to be flexible and decide about the set of features that client can access at runtime you can use interfaces, but not implement them in your class but use dynamic proxy to wrap your class and expose required interface. This solution however will work slower due to reflection calls.

There are other solutions I can think about but I hope that already written here are good enough for you.

like image 134
AlexR Avatar answered Dec 08 '25 12:12

AlexR



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!