Как отменить зависимость для класса Factory перенесена в библиотеку - PullRequest
2 голосов
/ 30 июня 2011

Следующий код работает очень хорошо, когда все участвующие классы находятся в одном проекте (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 в проект общей библиотеки, в котором SubClassOne, SubClassTwo, SubClassThree и SubClassFour не определены в библиотеке, но скорее в приложениях, использующих эту библиотеку.

Конечно, я могу переместить BaseClass назад к каждому приложению, использующему эту библиотеку, но мне интересно:

  • Есть ли лучшее решение?
  • Есть ли решение, которое позволило бы мне хранить BaseClass в библиотеке проект и устранить необходимость в этом знать обо всех суперклассах происходит от этого?

РЕДАКТИРОВАТЬ (отвечая на вопрос @ahmet alp balkan ниже):

ofType() каждого подкласса делает 2 вещи:

  1. Определяет, основываясь на содержании Строка p1 и другие параметры p2 и p3, является ли подкласс быть экземпляром его типа.
  2. Если ответ положительный, это создает объект себя подкласс. В противном случае возвращает ноль.

Что касается вашего второго вопроса, BaseClass на данный момент содержит общие элементы данных и методы для всех подклассов и только этот единственный статический метод, который нацелен на делегирование ответственности за определение подкласса, подлежащего реализации.

Кстати, благодаря вашему вопросу я заметил ужасную опечатку в своем оригинальном сообщении: «SuperClassOne» должен быть «SubClassOne» и т. Д.

Ответы [ 2 ]

1 голос
/ 30 июня 2011

Ваш статический 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);
    }
}
1 голос
/ 30 июня 2011

Базовый класс не очень хорошо знает о своих суперклассах.Это нарушает примерно половину принципов ОО;) .....

Я бы переместил метод в новый класс с именем HierarchyManager или что-то в этом роде и получил бы метод там.Вы могли бы даже построить некоторую иерархию там -> вы могли бы эффективно сделать этот метод «расширяемым» ....

Например, в библиотеке вы могли бы иметь:

BaseClass -> A, B (A, B подклассификация BaseClass) и некоторый LibraryHierachyManager, обрабатывающий эти три класса ...

и затем в приложении, использующем его:

C, D (создание подкласса BaseClass или A или B)

и некоторые ApplicationHieararchyManager делают:

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


    } else {
      return LibraryHierarchyManager.determineSubClass(p1,p2, p3);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...