I am creating a custom query class, and i am unsure about the most elegant way to code it.

The goals are:

Easy to use

Extensibility

Flexible so that complex queries can be formulated

Approaches

Currently i can think of two alternatives.

1. Builder pattern

Result r = new Query().is("tall").capableOf("basketball").name("michael").build();

The methods is() , capableOf() and name() return a self-reference to the Query object. build() will return a Result object.

2. Static Imports

Result r = new Query(is("tall"), capableOf("basketball"), name("michael"));

The methods is() , capableOf() and name() are static imports and return Condition objects. The Query constructor takes an arbitrary number of conditions and returns the result.

And/Or/Not queries

More complex queries like the following are complicated to formulate:

tall basketball player named [michael OR dennis] UNION silver spoon which is bent and shiny

Builder pattern:

Result r = new Query().is("tall").capableOf("basketball").or(new Query().name("michael"), new Query().name("dennis")). union( new Query().color("silver").a("spoon").is("bent").is("shiny") ). build();

This is difficult to write and read. Also, i do not like the multiple use of new .

Static imports:

Result r = new Query(is("tall"), capableOf("basketball"), or(name("michael"), name("dennis"))). union(color("silver"), a("spoon"), is("bent"), is("shiny"));

Looks better to me, but i do not really like the use of static imports. They are difficult in terms of ide integration, auto-completion and documentation.

Sum up

I am looking for an effective solution, therefore i am open to suggestions of any kind. I am not limited to the two alternatives i presented, if there are other possibilities i'd be happy if you tell me. Please inform me if you need further information.