Design Pattern to return only 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 values ​​and is 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 several clients who want to use instances of the above class, but some are only interested in getting a small subset of the variable values, not all:

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 tell the MyService client only what is of interest. Something like that:

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 to be wrong as the other values ​​will be zero. Is there a better way to design this?

EDIT:

To be more specific, I am working with user attributes in an LDAP system. Instead of having a "God object" of all the attributes of a person, I would only like to override the subset I need for each use case. For example, one application might require uid and fullName; the other might need uid, phone number, group, etc.

Thank.

+3


source to share


4 answers


It smells like a class of God, or, at best, a class that has poor cohesion. Classes should be simple and cohesive. Cohesion means that there is a topic that is obvious (given by the name) and that the methods support this topic. When you have a class called Utilities, this is a great example of a class with poor concatenation (a lot of methods and attributes get cluttered there due to no better place to put them).

You can refactor the God class or break objects and use composition according to the needs of the client classes.



If you post the real names of your class (instead of Foo, etc.), we can give you better design ideas. These details matter.

+2


source


One of the simplest solutions is to declare multiple interfaces with different sets of getters, implement all of them in your class, and create 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()

, whereas client B works with interface B and can only call getB()

.



If any client C needs to work with both A and B, you can: 1. access both interfaces 2. access MyClass directly 3. define another C interface that extends A and B, so client C will work with it.

Obviously, this solution is not generic and may require defining multiple interfaces in some cases.

If you want to be flexible and decide on a set of functions that the client can access at runtime, you can use interfaces, but not implement them in your class, but use a dynamic proxy to wrap your class and expose the required interface. However, this solution will run slower due to the reflection calls.

There are other solutions I can think of, but I hope the ones already written here are enough for you.

+3


source


You need a combination of Singleton and Facade design patterns.

A singleton should only store one copy of the object Foo

inside MyService

. The person will only provide methods getA()

, getB()

etc. For each required data combination.

Client

the class will call the facade to get the required information. In fact you can make your own My Service

both singleton and facade to solve this problem.

class MyService{
   private static Foo foo;
   private MyService(){}
   static{
      foo = initFoo(); // initialize the Foo object
   }

   // Now provide the facade api for each required combination

  static getA(){return foo.getA();}
  static getB(){return food.getB();}
  // etc ....
}

      

if you have multiple versions (or) versions Foo

then create a Factory to get the correct version inside yours Facade

.

0


source


Can you use interfaces like Facades and Adapters (they really aren't adapters, only specialized collectors) to retrieve data? eg.

interface IFooA {
   A getA();
}

interface IFooB {
   B getB();
}

public class Foo implements IFooA, IFooB {
  // ....
}

public class MyService {
  // code not optimized for brevity!

   public IFooA retrieveFooA() {
        return new IFooAAdapter().getOnlyIFooASubset();
   }

   public IFooB retrieveFooB() {
        return new IFooBAdapter().getOnlyIFooBSubset();
   }

      

0


source







All Articles