I'm working on a tool where users can use their own annotations to describe data processing workflow (like validation, transformation etc).
我正在开发一种工具,用户可以使用自己的注释来描述数据处理工作流程(如验证,转换等)。
Besides using ready-to-use annotations, users can user their own: in order to do this they need to declare annotation class itself, and then implement annotation processor (<--it's the main point of this question actualy).
除了使用现成的注释之外,用户还可以自己使用注释:为了做到这一点,他们需要自己声明注释类,然后实现注释处理器(< - 这是这个问题的主要要点)。
The configured method for data processing may look like this one:
配置的数据处理方法可能如下所示:
void foo(@Provide("dataId") @Validate(Validator.class) String str) {
doSmth(str);
}
There're naturally three groups of annotations:
自然有三组注释:
- those which produce initial values;
- those which transforms values (converters);
- those which just read values and perform some work (validators, different consumers).
产生初始价值的那些;
转换价值的那些(转换器);
那些只读取价值并执行一些工作的人(验证者,不同的消费者)。
So I need to make a choise: either create one interface for handling all these types of annotations, which can look like this one:
所以我需要做一个选择:要么创建一个接口来处理所有这些类型的注释,它们看起来像这样:
interface GenericAnnotationProcessor {
Object processAnnotation(Annotation annotation, Object processedValue);
}
Or I can add 3 intefaces to the API:
或者我可以在API中添加3个接口:
interface ProducerAnnotationProcessor {
Object produceInitValue(Annotation annotation);
}
interface TransformerAnnotationProcessor {
Object transformValue(Annotation annotation, Object currentValue);
}
interface ConsumerAnnotationProcessor {
void consumeValue(Annotation annotation, Object currentValue);
}
The first option is not very clear in use, but the third option pollutes the API with 3 almost similar interfaces.
第一个选项在使用中不是很清楚,但第三个选项使用3个几乎相似的接口污染API。
What would you choose (first of all as an API user) and why?
您会选择什么(首先作为API用户)以及为什么?
Thanks!
3 个解决方案
#1
0
I would create the first, more general interface, then define the three different implementation classes. Without knowing more about how you will be using this, my first instinct would be to define the Interface and/or a base class (depending upon how much common implementation code was shared between the different processors), and then add specialized processor implementation in derived types, all of whihc share the common interface.
我将创建第一个更通用的接口,然后定义三个不同的实现类。在不知道如何使用它的情况下,我的第一直觉是定义接口和/或基类(取决于在不同处理器之间共享多少常见实现代码),然后在派生中添加专用处理器实现类型,所有whihc共享通用接口。
In using the API, I would expect to declare a variable which implements GenericAnnotationProcessor, and then assign the appropriate implementation type depending upon my needs.
在使用API时,我希望声明一个实现GenericAnnotationProcessor的变量,然后根据我的需要分配适当的实现类型。
It is early here in Portland, OR, but at this moment, at 50% of my required caffeine level, this seems to me like it would provide maximum flexibility while maximizing cade re-use.
这是在俄勒冈州波特兰市的早期,但就目前而言,在我所需咖啡因水平的50%时,我觉得这样可以提供最大的灵活性,同时最大限度地减少重复使用。
Of course, your actual reuirements might dictate otherwise . . .
当然,您的实际要求可能会另有规定。 。 。
Hope that was helpful!
希望有用!
#2
0
Just diving deep into your problem.
深入探究你的问题。
As they are executing similar task, with some variance, Strategy pattern #Example should assist you.
由于他们正在执行类似的任务,但有一些差异,策略模式#Example应该会帮助您。
Your problem should look like something below.
您的问题应该如下所示。
interface GenericAnnotationProcessor {
Object processAnnotation(Annotation annotation, Object processedValue);
}
interface ProducerAnnotationProcessor implements GenericAnnotationProcessor {
}
interface TransformerAnnotationProcessor implements GenericAnnotationProcessor {
}
interface ConsumerAnnotationProcessor implements GenericAnnotationProcessor {
}
Now you can follow example from Wiki
现在你可以按照Wiki的例子
class Context {
// map of annotation processors
// register(add/remove) annotation processors to the map
public int executeAnnotationProcessor(Annotation annotation, Object processedValue) {
return locateAnnotationProcessor(annotation).processAnnotation(annotation, processedValue);
}
private GenericAnnotationProcessor locateAnnotationProcessor(Annotation annotation) {
// return expected annotation processor
}
}
I believe you can understand.
我相信你能理解。
#3
0
You can use Interfaces Extending Interfaces More on there
您可以在那里使用Interfaces Extending Interfaces More
Similar to classes, you can build up inheritance hierarchies of interfaces by using the extends keyword, as in:
与类类似,您可以使用extends关键字构建接口的继承层次结构,如下所示:
interface Washable {
void wash();
}
interface Soakable extends Washable {
void soak();
}
In this example, interface Soakable extends interface Washable. Consequently, Soakable inherits all the members of Washable. A class that implements Soakable must provide bodies for all the methods declared in or inherited by Soakable, wash() and soak(), or be declared abstract. Note that only interfaces can "extend" other interfaces. Classes can't extend interfaces, they can only implement interfaces.
在此示例中,接口Soakable扩展了接口Washable。因此,Soakable继承了Washable的所有成员。实现Soakable的类必须为Soakable,wash()和soak()声明或继承的所有方法提供实体,或者声明为abstract。请注意,只有接口可以“扩展”其他接口。类不能扩展接口,它们只能实现接口。
Hope it helps.
希望能帮助到你。
#1
0
I would create the first, more general interface, then define the three different implementation classes. Without knowing more about how you will be using this, my first instinct would be to define the Interface and/or a base class (depending upon how much common implementation code was shared between the different processors), and then add specialized processor implementation in derived types, all of whihc share the common interface.
我将创建第一个更通用的接口,然后定义三个不同的实现类。在不知道如何使用它的情况下,我的第一直觉是定义接口和/或基类(取决于在不同处理器之间共享多少常见实现代码),然后在派生中添加专用处理器实现类型,所有whihc共享通用接口。
In using the API, I would expect to declare a variable which implements GenericAnnotationProcessor, and then assign the appropriate implementation type depending upon my needs.
在使用API时,我希望声明一个实现GenericAnnotationProcessor的变量,然后根据我的需要分配适当的实现类型。
It is early here in Portland, OR, but at this moment, at 50% of my required caffeine level, this seems to me like it would provide maximum flexibility while maximizing cade re-use.
这是在俄勒冈州波特兰市的早期,但就目前而言,在我所需咖啡因水平的50%时,我觉得这样可以提供最大的灵活性,同时最大限度地减少重复使用。
Of course, your actual reuirements might dictate otherwise . . .
当然,您的实际要求可能会另有规定。 。 。
Hope that was helpful!
希望有用!
#2
0
Just diving deep into your problem.
深入探究你的问题。
As they are executing similar task, with some variance, Strategy pattern #Example should assist you.
由于他们正在执行类似的任务,但有一些差异,策略模式#Example应该会帮助您。
Your problem should look like something below.
您的问题应该如下所示。
interface GenericAnnotationProcessor {
Object processAnnotation(Annotation annotation, Object processedValue);
}
interface ProducerAnnotationProcessor implements GenericAnnotationProcessor {
}
interface TransformerAnnotationProcessor implements GenericAnnotationProcessor {
}
interface ConsumerAnnotationProcessor implements GenericAnnotationProcessor {
}
Now you can follow example from Wiki
现在你可以按照Wiki的例子
class Context {
// map of annotation processors
// register(add/remove) annotation processors to the map
public int executeAnnotationProcessor(Annotation annotation, Object processedValue) {
return locateAnnotationProcessor(annotation).processAnnotation(annotation, processedValue);
}
private GenericAnnotationProcessor locateAnnotationProcessor(Annotation annotation) {
// return expected annotation processor
}
}
I believe you can understand.
我相信你能理解。
#3
0
You can use Interfaces Extending Interfaces More on there
您可以在那里使用Interfaces Extending Interfaces More
Similar to classes, you can build up inheritance hierarchies of interfaces by using the extends keyword, as in:
与类类似,您可以使用extends关键字构建接口的继承层次结构,如下所示:
interface Washable {
void wash();
}
interface Soakable extends Washable {
void soak();
}
In this example, interface Soakable extends interface Washable. Consequently, Soakable inherits all the members of Washable. A class that implements Soakable must provide bodies for all the methods declared in or inherited by Soakable, wash() and soak(), or be declared abstract. Note that only interfaces can "extend" other interfaces. Classes can't extend interfaces, they can only implement interfaces.
在此示例中,接口Soakable扩展了接口Washable。因此,Soakable继承了Washable的所有成员。实现Soakable的类必须为Soakable,wash()和soak()声明或继承的所有方法提供实体,或者声明为abstract。请注意,只有接口可以“扩展”其他接口。类不能扩展接口,它们只能实现接口。
Hope it helps.
希望能帮助到你。