2015-09-28 1 views
0

мне нужно иметь три бережливость класса: ThriftClassList, ThriftClass1, ThriftClass2. В зависимости от некоторых условий от запроса мне необходимо перейти на ThriftClassList объект класса ThriftClass1 или ThriftClass2.Apache Бережливость полиморфизм

Так что мне нужно иметь какое-то определение таких бережливость

struct ThriftClassList { 
    1: required list<?> data 
} 

Но бережливость не поддерживает такое определение, я могу сделать только

struct ThriftClass1List { 
    1: required list<ThriftClass1> data 
} 

struct ThriftClass2List { 
    1: required list<ThriftClass2> data 
} 

Но я не хочу иметь два четырех класса, ThriftClass1List и ThriftClass2List похожи, я хочу иметь какой-то подстановочный знак.

Выполняет два класса списка - единственный способ решить эту проблему?

ответ

1

Существует нет встроенного способа сделать это с помощью Thrift. Что касается этого ограничения, это может помочь учесть, что Thrift генерирует код для примерно 20 языков. Не все из них поддерживают ООП или сопоставимые концепции, не говоря уже о полиморфизме или более совершенных концепциях, таких как дженерики.

Возможное решение может включать union S:

struct ListElement { 
    1: Foo foo 
    2: Bar bar 
    // add other elements as needed 
} 

struct OuterClass { 
    1: list<ListElement> data 
} 

Единственным недостатком является то, что ничто не мешает вам смешивания Foo и бар в одном экземпляре списка. Если этого следует избегать, добавьте код для проверки этого во время выполнения или определите два разных списка, как вы уже делали в исходном вопросе, чтобы сделать его безопасным с самого начала. Выбор ваш.

+0

Это смешение, и она нарушает единый принцип ответственности. –

+1

Никто не заставляет вас делать это таким образом, если ваша система убеждений говорит иначе. Спасибо за downvote за правильный ответ, который вам просто не нравится из-за аргументов, которые на самом деле не применяются. – JensG

+0

@Johannes Martinsson: Если кто-то еще (конечно, не OP) хочет список только с одним типом элемента, то 'list ' будет достаточно. Не нужно ничего более сложного. Ввод двух списков во внутреннее упущение указывает на то, почему мы используем этот «союз» здесь в первую очередь. Наконец, обертывание этой конструкции в другое 'Outer' является бессмысленным - последнее больше не добавляет значения. Нижняя линия? Если вы считаете, что у вас есть лучший ответ, добавьте его ниже. Но перестаньте проверять ответы других людей на вопросы (verschlimmbessern) (http://www.dict.cc/german-english/verschlimmbessern.html). Спасибо. – JensG

1

Добавить в @JensG ответ. Другой вариант «полиморфизма» состоит в том, чтобы иметь только один тип как необязательный и использовать поле флага, чтобы указать, какие из них существуют.

enum PersonType { 
    CHILD, 
    ADULT, 
    EMPLOYEE, 
    BOSS, 
    DOCTOR 
} 

struct Person { 
    1: i32 personId , 
    2: PersonType type, // Tells us which are set 
    3: double timestamp, 
    4: optional Child child 
    5: optional Adult adult 
    6: optional Employee employee 
    7: optional Boss boss 
    8: optional Doctor doctor 
} 

service API{ 
    Person GetPerson(1: i32 id) 
} 

затем на стороне клиента у вас есть завод:

func getPerson(int id) *Person { 

    p := thrift.GetPerson(1) 
    switch p.type { 
    case thrift.CHILD: 
     return newChild(p) 
    case thrift.ADULT: 
     return newAdult(p) 
    case thrift.BOSS: 
     panic("Not a person") 
    } 
} 
+0

«Союз» также может быть альтернативой (но не обращайте внимания на [THRIFT-3650] (https://issues.apache.org/jira/browse/THRIFT-3650)) – JensG

+0

Как пример кода будет предан, мой usecase в основном голанг. Кроме того, этот билет был «разрешен», поэтому не может быть долгосрочной проблемой. –