0

我在一个巨大的项目中有两个父类,比如说ClassAClassB. 每个类有很多子类,子类又有很多子类,子类又有很多子类,以此类推。

我的任务是“嫁给”这两个“家庭”,让他们都继承自单亲。我需要为他们的两个组合子类(子类)创建ClassA一个ClassB类(父类)。

ClassA并且ClassB两者目前都在实施Serializable

我目前正在尝试使两个继承链都继承自ClassA,然后将所有函数和数据成员从 复制ClassBClassA. 这很乏味,我认为这是一个糟糕的解决方案。

解决这个问题的正确方法是什么?

编辑 - 一些澄清

ClassA并且ClassB基本上做同样的事情(当然,通过一系列许多类和方法调用对许多存储过程进行许多调用)。

ClassA然而,通过我们实现的基于服务的新(Jersey)架构调用了一半的存储过程。我本质上是在“FamilyB”中实现新的面向服务的功能,就像我们在“FamilyA”中已经完成的那样。问题是这些家族中的每一个都是巨大的——许多类和长的继承链,做小的改变会对继承链产生蝴蝶效应。

如果需要澄清,请告诉我。

4

3 回答 3

3

想到的第一个答案是“一般来说,不”。

为了使其合理,A 和 B 应该是其他事物的特例——尽管这是可行的,但似乎不太可能。

除此之外,我看不出有任何理由组合任何代码(还有很多不这样做的理由)。是否有某种原因你不能简单地让它们都扩展 X,并将所有代码留在原处?


我认为我还没有足够的信息来获得清晰的图片,但会继续使用我目前所拥有的信息。

如果您实现了 Class A 和 Class B 都扩展的 Class X,那么这不会改变任何子类或任何一个类或任何子类的任何使用。这当然是我要开始的地方。

public Class X implements Serializable {}

public Class A extends X implements Serializable
{
  // retain all current code to start
}

public Class B extends X implements Serializable
{
  // and here be all current code also
}

您说您目前正在考虑将 B 类合并到 A 类中;这听起来有问题;A 和 B 共享“大约一半”的代码,并且在它们下面都有一个大的继承树——实例化 A 类子类的东西可以通过让 A 获得一些新功能来改变其行为。

所以相反,我会慢慢地将事物从 A 移动到 X 并从 B 移动到 X。只有当它们在 A 和 B 树之间具有共性时,我才会尝试移动它们。

例如,假设您在 A 中有方法 abc(),在 B 中有 def() 具有相同的功能。您可以将此功能移至 X 并随心所欲地调用它 - 我可能会尝试给它起一个我认为最能描述其功能的名称,无论它来自 A、B 还是我编造的一个新名称。然后 abc() 和 def() 可以调用这个新函数,并且可以从它们中删除这些方法的代码。

public class X implements Serializable
{
  public void abcdef()
  {
    // common functionality, merged from A and B
  }
}

public class A extends X implements Serializable
{
  public function abc() { abcdef(); }
}

public class B extends X implements Serializable
{
  public function edf() { abcdef(); }
}

以这种方式进行的一个好处是,每一步都清楚地知道已经完成了什么。您可以用注释很好地标记它并对其进行审查,和/或对其进行测试以确保两种重构方法的功能都是完整和正确的;这可以在重构一个、两个或多个方法后完成,具体取决于您是否有用于审查和/或测试的良好设置。

唯一可能中断的情况是,由于某种原因,您希望两个继承树中的方法调用者发生变化,但我没有任何理由(还)认为这是必要的。希望所有方法至少有合理的名称来描述它们所做的事情并传递需要传递的参数,并且顶部的重构只影响实现,而不是调用。无论如何,这看起来是一项足够大的工作,我希望您不必更改调用和功能。

于 2013-11-08T21:45:49.547 回答
1

你为什么不创建一个新的类来ClassA扩展ClassB然后开始合并共享功能。

确保合并代码确实ClassA有意义ClassB

于 2013-11-08T21:49:45.140 回答
1

我的直觉是创建一个具有ClassAClassB作为成员的对象的新类,然后将其用作您本质上想要从ClassA和派生的事物的基类ClassB。例如:

class ClassAB
{
    private ClassA a;
    private ClassB b;

    public void doSomething()
    {
         a.doSomething();
    }

    public void doSomethingElse()
    {
         b.doSomethingElse();
    }

    ...
}

ClassA当然,这很乏味,但与尝试返工并使之成为可能相比,这似乎更容易并且导致错误的可能性要小得多ClassB。这在这种情况下有效吗?

于 2013-11-08T21:45:49.197 回答