Java 设计模式以仅返回对象中的某些LDAP属性

Java 设计模式以仅返回对象中的某些LDAP属性,java,design-patterns,ldap,Java,Design Patterns,Ldap,假设我有以下类,有许多实例变量和相应的getter和setter: 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; } pub

假设我有以下类,有许多实例变量和相应的getter和setter:

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; }
  ...
}
但是,这似乎是错误的,因为其他值将为null。有更好的设计方法吗

编辑:

更具体地说,我正在LDAP系统中处理用户属性。我不想拥有一个包含一个人所有属性的“上帝对象”,我只想收回每个用例所需的子集。例如,一个应用程序可能需要uid和全名;另一个可能需要uid、电话号码、组等


谢谢。

您需要将单体和立面设计模式相结合

单例是在
MyService
中只保留
Foo
对象的一个副本。该面将仅提供
getA()
getB()
等。。。每个所需数据组合的方法

Client
类将调用facade以获取所需信息。事实上,您可以将您的
我的服务
作为singleton和facade来解决这个问题

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 ....
}

如果您有多个实现(或)版本的
Foo
,那么在
Facade
中创建一个工厂来检索正确的版本。您可以使用接口作为Facade和“适配器”(它们实际上不是适配器,只是专门的构建器)来检索数据?e、 g

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

一个最简单的解决方案是使用不同的getter集声明多个接口,在类中实现所有接口,并使不同的客户端使用不同的接口

比如说

interface A {
    String getA();
}

interface B {
    String getB();
}

class MyClass implements A, B {
    String getA() {...}
    String getB() {...}
}
现在客户端A与接口A一起工作,只能调用
getA()
,而客户端B与接口B一起工作,只能调用
getB()

如果某些客户端C必须同时使用A和B,则您可以: 1.让它访问两个接口 2.让它直接访问MyClass 3.定义扩展A和B的其他接口C,以便客户端C使用它

显然,此解决方案不是通用的,在某些情况下可能需要定义许多接口

如果您想灵活地决定客户端在运行时可以访问的功能集,您可以使用接口,但不能在类中实现它们,而是使用动态代理包装类并公开所需的接口。但是,由于反射调用,此解决方案的工作速度会变慢


我还可以考虑其他解决方案,但我希望这里已经写好的解决方案对您来说已经足够好了

这闻起来像上帝的类,或者充其量只是一个内聚性差的类。类应该有简单的设计和连贯性。内聚意味着有一个明显的主题(由名称给出),并且方法支持该主题。当您有一个名为“Utilities”的类时,它是一个内聚性差的类的很好的例子(很多方法和属性都被塞进了其中,因为没有更好的地方放置它们)

您可以根据客户机类的需要,选择或分解对象并使用组合


如果你发布你的班级的真实姓名(而不是Foo等),我们将能够给你更好的设计思路。这些细节很重要。

您可以使用factory,创建FooFactory接口,对于每个客户端使用不同的实现如何将
Foo
划分为多个子类,每个子类都派生自一个公共类,其中只有特定的实例变量集,教提供者填充这些子类,我喜欢这个想法,因为这是重新设计(重构)臃肿的
MyClass
的第一步,而这正是问题的根源。Facade使“复杂的类子系统”更易于使用。这里的问题是Foo类的行为就像一个“类的复杂子系统”。这不是一个类应该是什么。我添加了额外的细节。本质上,我正在从LDAP系统中获取用户属性,不想在用例不需要时为用户收回所有内容。您不是第一个遇到这种问题的人。我看了你的编辑。将LDAP放在问题中是非常重要的,即使是标题也是如此。
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 ....
}
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();
   }
interface A {
    String getA();
}

interface B {
    String getB();
}

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