2

determineSubClass当所有涉及的类都在同一个项目中(是 的成员)时,以下代码可以很好地工作BaseClass

protected static BaseClass determineSubClass(String p1, int p2, Boolean p3) {

    BaseClass baseObj = null;
    if ( (baseObj = SubClassOne.ofType(p1, p2, p3)) != null )
      return baseObj;
    else if ( (baseObj = SubClassTwo.ofType(p1, p2, p3)) != null )
      return baseObj;
    else if ( (baseObj = SubClassThree.ofType(p1, p2, p3)) != null )
      return baseObj;
    else if ( (baseObj = SubClassFour.ofType(p1, p2, p3)) != null )
      return baseObj;
    else
      return new SubClassDefault(p1, p2, p3);
}

但现在,我想将 移动BaseClass到一个共享库项目,其中SubClassOneSubClassTwoSubClassThree没有SubClassFour在库中定义,而是在使用该库的应用程序中定义。

我当然可以BaseClass回到使用这个库的每个应用程序,但我想知道:

  • 有更好的解决方案吗?
  • 有没有一种解决方案可以让我保留BaseClass在 Library 项目中并消除它了解从它派生的所有超类的需要?

编辑(回答下面的@ahmet alp balkan 问题):

ofType()每个子类做两件事:

  1. 根据 String p1 的内容和其他参数 p2 和 p3 确定要实例化的子类是否属于它的类型。
  2. 如果答案是肯定的,它会实例化一个 self 子类的对象。否则,返回 null。

至于您的第二个问题,BaseClass此时所有子类都拥有公共数据成员和方法,并且只有这个静态方法旨在委派确定要实例化的子类的责任。

顺便说一句,多亏了你的问题,我注意到我原来的帖子中有一个可怕的错字:“SuperClassOne”应该是“SubClassOne”等。

4

2 回答 2

1

您的静态determineSubClass方法是工厂方法。它显然不应该位于 上BaseClass,因为不仅基类不应该对子类一无所知,而且在您的情况下,它也不知道任何关于它的信息,因为您想在另一个项目中找到基类。不,此方法应位于负责创建BaseClass实例的工厂类中。您应该做的是定义一个接口(或基本类型),用于在应用程序的组合根BaseClass中创建实例BaseType并定义一个实现。当您有多个应用程序时,它们可能每个都有不同的集合BaseClass子类型,因此每个应用程序都有不同的工厂。当你有了这个结构后,你可以将工厂注入到需要BaseClass实例的类中。

它可能看起来像这样:

// Shared library
public interface IBaseClassFactory
{
    BaseClass CreateNew(String p1, int p2, Boolean p3);
}

public abstract class BaseClass
{
}

// Application code
public class SubClassOne : BaseClass
{
}

public class SubClassTwo : BaseClass
{
}

// Note that this consumer depends on IBaseClassFactory.
public class SomeConsumer
{
    private IBaseClassFactory baseClassFactory;

    public SomeConsumer(IBaseClassFactory factory)
    {
        this.baseClassFactory = factory;
    }

    public void Consume()
    {
        BaseClass instance = this.baseClassFactory
            .CreateNew("foo", 0, false);

        // use instance
    }
}  

// Composition root
class BaseClassFactory : IBaseClassFactory
{
    public BaseClass CreateNew(String p1, int p2, Boolean p3)
    {
        BaseClass baseObj = null;

        if ((baseObj = SubClassOne.ofType(p1, p2, p3)) != null)
           return baseObj;
        // etc
        else
            return new SubClassDefault(p1, p2, p3);
    }
}
于 2011-06-30T04:30:54.733 回答
1

基类知道它的超类并不是一个好习惯。它违反了大约一半的 OO 原则;).....

我会将该方法移到一个名为 HierarchyManager 或类似的新类中,并在那里拥有该方法。你甚至可以在那里建立一些层次结构 -> 你可以有效地使这个方法“可扩展”......

例如在图书馆你可以有:

BaseClass -> A, B (A, B subclassing BaseClass) 和一些LibraryHierachyManager 处理这三个类...

然后在应用程序中使用它:

C、D(继承 BaseClass 或 A 或 B)

和一些 ApplicationHeararchyManager 做:

public static BaseClass determineSubClass(String p1, int p2, Boolean p3) {
    if (baseObj = C.ofType(.....) { 
    ....


    } else {
      return LibraryHierarchyManager.determineSubClass(p1,p2, p3);
    }
}
于 2011-06-30T00:47:34.227 回答