Hi Paul,
thanks for your feedback, that's much appreciated.
The reason for the restriction basically is that a client of an API
doesn't necessarily know its implementation. Let's for instance assume
a client receives an implementation of the OrderService interface via
dependency injection:
public class Shop {
@Inject
private OrderService orderService;
...
}
Here, the programmer of the Shop class doesn't know which
implementation will be injected, maybe it's SimpleOrderService, maybe
it's an implementation type not even known to the Shop programmer at
all. If it would be legal to add parameter constraints to the
OrderService implementation, there is no way to find out for the
caller what parameter values for placeOrder() are valid.
Another example is a list, e.g. List<Foo>. When iterating over the
list, each element could be of another type implementing Foo. If
different parameter constraints could be declared by each of these
implementations, how would the caller know which constraints he has to
obey when invoking a method on the list elements?
AFAICS there is not really a difference to this whether one considers
interfaces and implementations or (base) classes and classes derived
from those. In both cases a strengthening of parameter constraints
would be an issue for the caller when polymorphism comes into play.
Design by contract also mentions this limitation, see e.g. the WP
article [1]. Note that some other implementations explicitly allow a
weakening of pre-conditions (by OR-ing the pre-conditions defined in a
hierarchy, effectively applying the weakest one), while the BV
proposal prohibits a re-definition of parameter constraints. So far I
didn't see a good use case for this and felt that allowing a weakening
makes things only more complex, but we can discuss this if we find
good use cases for this.
Does that help answering your question?
--Gunnar
[1]
http://en.wikipedia.org/wiki/Design_by_contract
2012/7/17 Paul Benedict <pbenedict(a)apache.org>:
I think there is a general problem with the application of this
rule:
"a method's preconditions (as represented by parameter constraints)
may not be strengthened in sub types"
The problem is that this could hurt API developers who publish basic
interfaces but where implementation designers are free to choose
validations specific to their system. Example 4.11 is a great example:
public interface OrderService {
void placeOrder(String customerCode, Item item, int quantity);
}
public class SimpleOrderService implements OrderService {
@Override
public void placeOrder(
@NotNull @Size(min=3, max=20) String customerCode,
@NotNull Item item,
@Min(1) int quantity) { ... }
}
I can see no good reason why this should be disallowed. The spec is
assuming that because no constraints are on the interface, no
implementation may ever use constraints. This is a poor assumption. It
is actually a blockade to any system that currently exists -- being
created prior to BeanValidation -- who could benefit from adding
method-level validation in their implementation.
This can be easily corrected though. Apply these rules only on
concrete classes. If SimpleOrderService2 extends SimpleOrderService,
then spec should disallow the strengthening of constraints. In
summary, don't consider interfaces (unless the interfaces themselves
have annotated constraints?).
Do you see the problem I am addressing?
Thanks,
Paul
_______________________________________________
beanvalidation-dev mailing list
beanvalidation-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/beanvalidation-dev