避免使用多态时不能使用的实例

时间:2016-03-10 22:16:35

标签: inheritance design-patterns polymorphism object-composition

我使用XSDXJC个文件生成多个类。这些类是作为构建过程的一部分自动生成的,因此无法修改。这些类共享一个共同的结构。我有需要使用这些类的客户端代码。但是,这些客户端逻辑中的一些对于所有类都是相同的。因此,我不想为每个要复制的类复制客户端代码。在这种情况下想到的流行解决方案是使用接口/继承,以便客户端代码仅处理超类/接口而不是特定类。但是,在这种情况下,由于无法修改类,因此无法使用此解决方案。因此,我认为正确的方向是使用组合而不是继承。但是,如果使用了合成,编写类将需要处理每个特定的类,因此我可能最终会有许多if (obj instanceof Type)来分别处理每个案例。

public class A {
    private int id;
    //Properties specific to type A
}

public class B {
    private int id;
    //Properties specific to type B
}

public class C {
    private int id;
    //Properties specific to type C
}

public class Client {
    public void myMethod(Object obj) {
        //obj may be an instance of A, B or C

        //I would like to access the id property (which is common to A, B and C)
        //using the most elegant way

        //Approach using instanceof
        if(obj instanceof A) {
            A objA = (A)obj;
            objA.getId();
        }
        if(obj instanceof B) {
            B objB = (B)obj;
            objB.getId();
        }
        if(obj instanceof C) {
            C objC = (C)obj;
            objC.getId();
        }
    }
}

我考虑过使用一种方法,其中实例被包装,而instanceof逻辑位于包装类而不是客户端代码中。

public class Wrapper {
    private Object obj;

    public int getId() {
        if(obj instanceof A)
            return ((A)obj).getId();
        if(obj instanceof B)
            return ((B)obj).getId();
        if(obj instanceof C)
            return ((C)obj).getId();
    }
}

public class Client {
    public void myMethod(Wrapper wrapper) {
        //Only deals with wrappers, not with the objects themselves

        wrapper.getId();
    }
}

在这种情况下是否需要使用instanceof?如果是,推荐的方法是什么?

修改

反射也可用于避免多个instanceof。根据给定示例,如果在每个类(getId()AB)中定义了C方法,则可能存在以下情况:

public class Wrapper {
    private Object obj;

    public int getId() {
        return obj.getClass().getMethod("getId").invoke(obj);
    }
}

我忘了提到我对XSD没有任何控制权。

1 个答案:

答案 0 :(得分:0)

您可以使用impromptu-interface

  

C#4.0(.net& silverlight)框架允许您包装任何对象   (静态或动态)具有静态接口,即使它没有   继承它。