不继承对象的公共代码

时间:2016-05-20 08:16:43

标签: java

假设我们有两个类class1class2,它们是生成的类。这些类彼此非常相似,甚至一些方法都是相同的,因此我想在验证期间为它们使用相同的代码。所以,因为它们都是生成的,所以我不能为它们创建一个抽象类。这就是我现在这样做的方式,但我不能说我喜欢它。

if (myObject instanceof Class1) {
  if (((Class1) myObject).getId().length() > MAX_LENGTH) {
     throw new Exception();
  }
} else if (myObject instanceof Class2) {
  if (((Class2) myObject).getId().length() > MAX_LENGTH) {
     throw new Exception();
  }
}

有更好的方法吗?

6 个答案:

答案 0 :(得分:2)

我认为这是一个稍好的版本:

String id = null;
if (myObject instanceof Class1) {
  id = ((Class1) myObject).getId();
} else if (myObject instanceof Class2) {
  id = ((Class2) myObject).getId();
}
if (id == null || id.length() > MAX_LENGTH) {
  throw new Exception();
}

但这只是我对你的具体例子的看法,而不是解决你的一般问题。如果您知道该方法将在那里,您可以随时使用反射。

答案 1 :(得分:2)

我认为适配器模式可能是一个想法(可能不是真正的这种模式,但这个想法来自他)。

这可能只是为你做了很多工作的例子,但对于更复杂的工作,这是一个很好的approch(当然是个人观点)。

创建一个接口,这个类将调整这些函数,如下所示:

原始类

A类

public class A {

private int id;

    public A(int id){
        this.id = id;
    }

    public int getId() {
        return id;
    }
}

B级

public class B {

    private int id;

    public B(int id){
        this.id = id;
    }

    public int getId() {
        return id;
    }
}

创建如下界面:

public interface Adapter {

    public int getId();
}

创建两个适配器:

适配器A:

public class AdapterA implements Adapter{

    private A a;

    public AdapterA(A a){
        this.a = a;
    }

    public int getId() {
        return a.getId();
    }
}

和适配器B

public class AdapterB implements Adapter{

    private B b;

    public AdapterB(B b){
        this.b = b;
    }

    public int getId() {
        return b.getId();
    }
}

现在,如果您需要使用此类,只需创建一个适配器并调用这些适配器的getId。

使用您的示例(Class1 = A和Class2 = B)

  Adapter adapter = new AdapterA(a); //This mean that you need to create the Adapter when you create (receive the class A or B)
  //Adapter adapter = new AdapterB(b);

  if (adapter.getId().length() > MAX_LENGTH) {
     throw new Exception();
  }

如果一个方法有不同的名称,你只需更新特定适配器中的getter,后面的逻辑就不会改变。因此,如果在B中,getId变为getIdentity,则唯一的更新将在adapterB中。

答案 2 :(得分:1)

正如我评论的那样,一种方法是在getId

中使用共享方法interface
public interface ClassInterface
{
    public String getId ();
}

public class Class1 implements ClassInterface{
    public String getId (){
        //class 1 implementation
    }
}

public class Class2 implements ClassInterface{
    public String getId (){
        //class 2 implementation
    }
}

答案 3 :(得分:1)

假设你不能修改所有生成的类(这看起来很奇怪),这就是我用内省做的方法:

Class clazz = myObject.getClass();
Method getId = clazz.getMethod("getId");
Object result = m.invoke(myObject);
if (((String)result).length() > MAX_LENGTH) {
    throw new Exception();
}

请注意,这假设您的类具有唯一的getId()方法,没有参数。如果情况并非如此,那么你必须进一步推动并检查方法签名。

此外,我认为这不比您当前的示例代码更好。如果真正的代码有5个以上不同的类,或者你需要对它们进行5个以上类似的操作,我可能会使用它。

答案 4 :(得分:1)

如果您声称它们是相同的,您也可以尝试使用反射通过其签名获取常用方法。它会是这样的:

if (o instanceof Class1 || o instanceof Class2) {
    Class classDescr = o.getClass();
    Method m = classDescr.getMethod("method");
    m.invoke(o);
}

如果两个类都使用没有参数的方法method,它就可以正常工作。当然不考虑一些反思开销。

答案 5 :(得分:0)

根据代码生成工具的功能,您可以使用通用界面。也许你甚至可以让这个工具创建在其他类(委托)中使用的公共类。