Java 如何对不共享同一接口且不可修改的类进行分组?

Java 如何对不共享同一接口且不可修改的类进行分组?,java,design-patterns,Java,Design Patterns,我有几个遗留类,它们既没有公共接口也没有超类,尽管它们有相同的方法。这些方法中的大多数都受到保护 无论如何,我想写一个服务,它总是在这些类上执行相同的例程,因此总是调用相同的方法,不管它是什么类 通常我会给这些类一个公共接口,但是我不能修改遗留类,尽管我必须使用它们 有机会把他们分组吗?也许是我不知道的设计模式 class classA { protected String getData() { return "I'm class A"; } } class

我有几个遗留类,它们既没有公共接口也没有超类,尽管它们有相同的方法。这些方法中的大多数都受到保护

无论如何,我想写一个服务,它总是在这些类上执行相同的例程,因此总是调用相同的方法,不管它是什么类

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

有机会把他们分组吗?也许是我不知道的设计模式

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
    }
}
A类{
受保护的字符串getData(){
返回“我是A级”;
}
}
B类{
受保护的字符串getData(){
返回“我是B级”;
}
}
类MyGeneralService{
无效执行(clazz){
//做点什么
clazz.getData();
//做点什么
//调用两个类通用的另一个方法
}
}

这听起来正是设计用来解决的问题

本质上,用一个关联的适配器类包装每个遗留类,该类实现一个公共接口。适配器类只应根据需要转发方法调用


注意:您希望从外部世界调用的方法受到
保护这一事实很奇怪。适配器模式不会帮助您调用以前无法调用的方法(当然,反射除外)。

如果对象只能是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 
    }

}我建议使用装饰图案。如果使用包的相同名称创建decorator类,则可以访问受保护的方法

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

}
A类{
受保护的字符串getData(){
返回“我是A级”;
}
}
B类{
受保护的字符串getData(){
返回“我是B级”;
}
}
C类{
公共字符串getData(){
返回“我是C类”;
}
}
接口HasData{
公共字符串getData();
}
类DataA扩展类A实现HasData{
@凌驾
公共字符串getData(){
返回super.getData();
}
}
类DataB扩展类b实现HasData{
@凌驾
公共字符串getData(){
返回super.getData();
}
}
类DataC扩展类c实现HasData{
//如果它已经是公共的,则无需重新定义它。
}
类MyGeneralService{
公共无效执行(C){
c、 getData();
}
}

但是我不能从适配器调用受保护的方法。但是你无论如何也不能从外部世界调用受保护的方法……如果调用受保护的方法是你主要关心的问题,你可以使用反射来实现这一点。如果方法受到保护,那么你的包装器可以是声明共享接口的A和B的子类。