如何对不共享相同接口但不可修改的类进行分组?

时间:2013-11-28 12:42:59

标签: java design-patterns

我有几个没有通用接口或超类的遗留类,但具有相同的方法。大多数这些方法都受到保护。

无论如何,我想编写一个在这些类上始终执行相同例程的服务,因此无论它是什么类,都会调用相同的方法。

通常我会给这些类一个通用接口,但是我不能修改遗留类,尽管我必须使用它们。

有没有机会将它们分组?也许是一个我不知道的设计模式?

class classA {
    protected String getData() {
        return "I'm class A";
    }
}

class classB {
    protected String getData() {
        return "I'm class B";
    }
}



class MyGeneralService {

    void execute(<ClassA or B> clazz) {
        //do something
        clazz.getData();
        //do something
        //call another methods that are common to both classes
    }
}

4 个答案:

答案 0 :(得分:1)

这听起来就像Adapter Pattern旨在解决的问题一样。

基本上,使用关联的适配器类包装每个旧类, 实现一个公共接口。适配器类应该根据需要简单地转发方法调用。

注意:您希望从外部世界调用的方法为protected这一事实很奇怪。适配器模式无法帮助您调用之前无法调用的方法(当然,除了通过反射)。

答案 1 :(得分:1)

我建议使用装饰模式。如果使用相同的包名创建装饰器类,则可以访问受保护的方法

答案 2 :(得分:0)

如果对象只能是A类或B类,那么为什么不呢:

if (clazz instanceof A) {
     ((A)clazz).getData();
} else {
     ((B)clazz).getData();
}

或者为A和B创建包装器,这些包装器实现了一个公共接口,就像注释一样。

否则你可以使用反射:

void execute(Object obj) {
    //do something
    try {
        Method method = obj.getClass().getMethod("getData");
        method.setAccessible(true);
        String value = (String) method.invoke(obj);

        //do something
        //call another methods that are common to both classes
    } catch (NoSuchMethodException nsmx) {
        // object does not have the method 
    }

}

答案 3 :(得分:0)

这样的事情应该有效:

class ClassA {
  protected String getData() {
    return "I'm class A";
  }

}

class ClassB {
  protected String getData() {
    return "I'm class B";
  }

}

class ClassC {
  public String getData() {
    return "I'm class C";
  }

}

interface HasData {
  public String getData();

}

class DataA extends ClassA implements HasData {
  @Override
  public String getData() {
    return super.getData();
  }

}

class DataB extends ClassB implements HasData {
  @Override
  public String getData() {
    return super.getData();
  }

}

class DataC extends ClassC implements HasData {
  // No need to redefine it if it is already public.
}

class MyGeneralService {

  public <C extends HasData> void execute(C c) {
    c.getData();
  }

}