In most cases I prefer immutable interfaces.  However, immutable interfaces
pose an interesting problem for contract testing and for the permissions
implementation.

In contract testing you get have a producer to create instances of an
interface and tests you run against it.

However, since you don't have any setters to call on the instance you can
not know what the result of any particular getter should be.

The only choices that I see for this case are:

   1. Don't test the immutable interface separately and therefore miss some
   implementations.  That is only test the immutable interface when paired
   with the mutable interface.
   2. Modify the producer interface so that the producer will create the
   data necessary to execute the tests.  This results in complicated producers.

Keeping in mind that contract tests allow us to write tests for the Graph
interface and then create very simple implementations of suites for each
implementation on Graph.  This means that when we add ad method or detect
an incorrectly implemented method we can modify the contract test and all
implementations are then properly tested.

In the permissions implementation we wrap the interfaces with dynamic
proxies that intercept calls to verify if the user has permission to make
those calls before execution, wrap the results with "secured" versions, and
in some case filter results (e.g. iterators).  This system will be
perfectly happy running against immutable interfaces.  The interesting part
is that the system can take mutable objects and return objects that throw
exceptions when the user does not have access (much the same as the current
read only implementations do).  But you can not know *a priori* which
methods will throw exceptions.

This leads me to one more observation. When building the permissions layer
I learned that simple objects like RDFNode can return complex objects like
Model.  I believe that an immutable model  would have to return an
immutable RDFNode. The signature of the Immutable RDFNode should indicate a
return of an Immutable Model.  But to be a drop in replacement for a
standard RDFNode it will need to return a Model.  Classes like RDF lists
also pose interesting problems.

So while I like immutable interfaces in general, I think that back fitting
them here is problematic.  Scan through the permissions layer for some idea
of the complexity.

Having written all of this I think I have come to believe that low level
tools like Jena or data stores in general, should not have immutable
interfaces.  Immutable interfaces belong at a slightly higher architectural
level or at the extreme boundary of the project.  For example if Jena had a
webservice API that retrieved Models and such then it might makes sense for
the deserialized versions to be immutable.

Claude


On Tue, Nov 14, 2017 at 12:12 AM, Adam Jacobs <jacobs_...@hotmail.com>
wrote:

> The subject of immutability was raised in JENA-1391 (
> https://issues.apache.org/jira/browse/JENA-1391).
>
> Specifically, the `getUnionModel` method in Jena 3.4 returns an immutable
> model view, and the implementation of the aforementioned story includes
> methods that will return an immutable dataset view.
>
> The question is whether these immutable views deserve their own
> interfaces. Currently, the views are returned using what I called
> "unexpected immutability" because they implement mutable interfaces. This
> introduces the potential for `UnsupportedOperationException`s.
>
> Unfortunately, that (degenerate) pattern is used in Java's `Collections`
> utility as well (https://docs.oracle.com/javase/8/docs/api/java/util/
> Collections.html) but Scala is a clean example to draw inspiration from:
> by implementing immutable interfaces as parents to their mutable
> counterparts (rather than vice verse) we can satisfy the Liskov
> Substitution Principle.
>
> Obviously, implementing that solution is easier to do from scratch than in
> an existing code base; but I imagine it could be done in multiple phases,
> by introducing the new interfaces and using them in new methods (with easy
> conversion to mutability via union) while gradually retrofitting older
> methods.
>
> The question then, is whether such a change is worthwhile...




-- 
I like: Like Like - The likeliest place on the web
<http://like-like.xenei.com>
LinkedIn: http://www.linkedin.com/in/claudewarren

Reply via email to