Java - Обработка различных версий зависимости - PullRequest
0 голосов
/ 02 апреля 2019

Я борюсь с небольшой проблемой системы типа Java +, и, возможно, некоторые из вас вдохновлены решением этой проблемы.

Справочная информация:

Я реализую приложение Java, которое использует язык, специфичный для предметной области (DLS). DLS генерируется код и упакован с основным приложением. В конце концов, приложение должно поддерживать разные версии DSL.

На первый взгляд, это не проблема, поскольку разные версии DLS используют разные имена пакетов, ala *.sdtl.v2.* и *.sdtl.v2.*. Каждый из пакетов содержит все элементы, которые принадлежат DLS в текущей версии, например , синтаксический анализатор и элементы синтаксиса.

Проблема:

Моя проблема сейчас в том, что я хотел бы иметь какой-то переключатель для центральных элементов DSL, например, анализатор языка. Коммутатор должен, например, вернуть правильный анализатор для данной версии.

Пример:

class Parser {

public static Object forVersion(int version) {
    switch (version) {
        case 1:
            return new *.stdl.v1.parser.Parser();
        case 2:
            return new *.stdl.v2.parser.Parser();
    }
}

К сожалению, кажется невозможным найти значимую сигнатуру этого метода. Поскольку элементы DLS (например, класс Parser) являются сгенерированным кодом, и все версии этого класса не имеют общего суперкласса (кроме Object), очевидно, невозможно найти тип возврата для этих методов, кроме Object.

Мой текущий обходной путь - это класс-оболочка для сгенерированных классов анализатора с общим суперклассом. Это позволяет мне придать этому методу более конкретный тип, однако он только переносит проблему на следующий уровень, поскольку возвращение синтаксического анализатора также является синтаксическим элементом, который относится к версии.

abstract class ParserWrapper {
    final int version;
    protected ParserWrapper(int version) {
        this.version = version;
    }
    public abstract Object parse(String string);
}
class STDLv1Wrapper extends ParserWrapper {
    public Node parse(String string) {
        return new *.stdl.v1.parser.Parser().parse(string);
    }
}
class STDLv1Wrapper extends ParserWrapper {
    public Node parse(String string) {
        return new *.stdl.v2.parser.Parser().parse(string);
    }
}
class Parser {
    public static ParserWrapper forVersion(int version) {
        switch (version) {
            case 1:
                return new STDLv1Wrapper();
            case 2:
                return new STDLv2Wrapper();
        }
    }
}

У кого-нибудь есть более изящное представление о том, как справиться с этой ситуацией?

...