2016-08-29 7 views
1

Как я могу создать java-интерфейсы вместо абстрактных классов для моей службы, используя компилятор протоколов буферов?Как сгенерировать java-интерфейсы вместо абстрактных классов для моей службы, используя протокол буферов протоколов?

Сейчас я использую плагин Gradle, который принимает файлы .proto и генерирует абстрактные классы для моих сервисов вместо интерфейсов. Это может быть проблематично, учитывая, что Java не позволяет расширять несколько классов.

Я не мог найти решение или способ до сих пор после прохождения документации, поэтому любая помощь будет отличной.

Мой build.gradle выглядит следующим образом

apply plugin: 'java' 
apply plugin: 'com.google.protobuf' 

buildscript { 
    repositories { 
    mavenCentral() 
    } 
    dependencies { 
    // ASSUMES GRADLE 2.12 OR HIGHER. Use plugin version 0.7.5 with earlier 
    // gradle versions 
    classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0' 
    } 
} 

repositories { 
    mavenCentral() 
    mavenLocal() 
} 

// IMPORTANT: You probably want the non-SNAPSHOT version of gRPC. Make sure you 
// are looking at a tagged version of the example and not "master"! 

// Feel free to delete the comment at the next line. It is just for safely 
// updating the version in our release process. 
def grpcVersion = '1.0.0' // CURRENT_GRPC_VERSION 

dependencies { 
    compile "io.grpc:grpc-netty:${grpcVersion}" 
    compile "io.grpc:grpc-protobuf:${grpcVersion}" 
    compile "io.grpc:grpc-stub:${grpcVersion}" 
} 

protobuf { 
    protoc { 
    // The version of protoc must match protobuf-java. If you don't depend on 
    // protobuf-java directly, you will be transitively depending on the 
    // protobuf-java version that grpc depends on. 
    artifact = 'com.google.protobuf:protoc:3.0.0' 
    } 
    plugins { 
    grpc { 
     artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" 
    } 
    } 
    generateProtoTasks { 
    all()*.plugins { 
     grpc { 
     // To generate deprecated interfaces and static bindService method, 
     // turn the enable_deprecated option to true below: 
     option 'enable_deprecated=false' 
     } 
    } 
    } 
} 

// Inform IntelliJ projects about the generated code. 
apply plugin: 'idea' 

idea { 
    module { 
    // Not using generatedSourceDirs because of 
    // https://discuss.gradle.org/t/support-for-intellij-2016/15294/8 
    sourceDirs += file("${projectDir}/build/generated/source/proto/main/java"); 
    sourceDirs += file("${projectDir}/build/generated/source/proto/main/grpc"); 
    } 

я узнал причину, почему она не создает интерфейсы, похоже, он устарел, так что я не уверен, что это способ создания интерфейса. если вы посмотрите на мой build.gradleoption 'enable_deprecated=false' включение этого метода в true приведет к созданию интерфейсов, однако аннотации говорят, что он устарел, поэтому я не уверен, что является новым способом создания интерфейса. Мне нужен интерфейс, а не абстрактные классы.

ответ

0

С точки зрения API, интерфейсы Java должны быть неизменными после их создания, чтобы не допустить нарушения потребителей и разработчиков интерфейса. Поскольку добавление новых методов в существующую службу должно быть совместимо с API, grpc-java был вынужден удалить интерфейсы.

Использование методов по умолчанию в Java 8 может быть опцией, но grpc-java не может потребовать Java 8 в ближайшее время, так что это, вероятно, новый аромат.

+0

без интерфейсов код становится более уродливым и громоздким. поскольку Java не позволяет расширять несколько классов, и единственный способ иметь множественное наследование в Java - это реализация нескольких интерфейсов. почему бы не предоставить оба варианта (абстрактные классы и интерфейсы)? вы можете сказать, что нужно использовать абстрактные классы до Java 7, а также использовать интерфейс, если у них есть Java 8..Это было бы намного более справедливым. В другом случае многие шаблоны проектирования говорят, что код для интерфейса не является классом. настолько важно, что просто не имеет смысла ничего не поддерживать. – user1870400

+0

Это правда, что дизайн обычно включает интерфейсы, но они должны быть неизменными. Я предлагаю вам прочитать конец Effective Java, Item 18, который суммируется как «Исключение из этого правила - это случай, когда легкость эволюции считается более важной, чем гибкость и сила». gRPC-сервисы _must_ позволяют эволюционировать. –

+0

уверен, что я не согласен с этим, но почему бы не поддержать как абстрактные классы, так и интерфейсы в зависимости от версии Java? – user1870400