OK, let me back this up to First Principles.  We ought to be able to agree
on the following points:

  1. The semantic ordering required by RFC 2821 is mandatory.

  2. The ordering is based upon any preference indicated by
     the MX record.

  3. There may be more than one entry with the same preference.

  4. Ordering of records with the same preference is required
     to be randomized.

     [RFC 2821: "If there are multiple destinations with the
      same preference and there is no clear reason to favor
      one (e.g., by recognition of an easily-reached address),
      then the sender-SMTP MUST randomize them to spread the
      load across multiple mail exchangers for a specific
      organization.]

  5. There may be more than one IP address for a given host.

  6. IP addresses for a given host must be tried in the order
     presented.

     [RFC 2821: "The destination host (perhaps taken from the
      preferred MX record) may be multihomed, in which case
      the domain name resolver will return a list of
      alternative IP addresses.  It is the responsibility of
      the domain name resolver interface to have ordered this
      list by decreasing preference if necessary, and SMTP
      MUST try them in the order presented.

That is the contract mandated by RFC 2821, and it does required an order.
Hopefully we can also agree on another point:

  7. One of the fundamental principles of object programming is
     implementation hiding.

What does implementation hiding mean?  It doesn't mean that the behavior of
a class is hidden.  It means that the implementation of that behavior is
hidden.  In this case, it is semantically important that the client be given
contents in a certain order, but how that order is computed or how it is
maintained should be opaque to the client.

The key issue here appears to be the entirely false premise that Collection
implies a lack of order, and the equally false premise that List implies
anything about order other than index.
If either of those false premises were true, we wouldn't be having this
argument.

I am presuming from the arguments presented that everyone is in favor of
strong typing.  Fine.  But this is also not an issue of strong vs weak
typing.  Earlier Serge raised the issue of Object vs Collection, saying
(paraphrasing) that methods would just return Object if type didn't matter.
The difference is that we would need to cast from Object to a Collection,
but we don't need to cast from a Collection to a more specific type in order
to access the necessary behavior.  If we never need to know anything about
an object other than that it IS an Object, then returning an Object would be
perfectly valid, because that interface provides the desired behavior.
Anything more specific that the interface that provides the necessary
behavior begins to violate the principle of implementation hiding.

INTERNALLY, as a matter of implementation, we receive an array from DNSJava,
and we sort that array with Array.sort.  After that we create a Vector from
that array, and return the Collection.  The Collection interface provides
the ability to get an Iterator, and iteration is the only behavior we allow
of a client.  In fact, I am quite tempted to insert a call to
Collection.unmodifiableCollection() in our implementation.

But, you say, List provides order!  It says so!  This is a misinterpretation
of what List means by order.  What List means by order is the ability to
manipulate the list by index.  If our client code needed to manipulate the
results, having the ability to manipulate the order of the collection using
the index would be a compelling argument.  But our clients only iterate.

Iteration is opaque.  The whole point of an Iterator is implementation
hiding.  Switching to List violates the principle of implementation hiding
by mandating that our iteration be index based.  Furthermore it does not buy
us the benefit that people seem to believe that it would.

Look at the code as it exists today.  Change the signature to return List,
and comment out the Array.sort call.  You would have a List that is of no
value.  You would have enforced nothing, nor implied that there is an
important semantic order was important.

Now, as for some specific comments:

> The salient fact is that a /contract/ accompanies the List interface.
> This contract is critical to our application and does _not_ accompany
> the Collection interface.

Please document the List-specific methods that embody this critical
contract.

> returning a list provides a degree of compile-time checking
> for adherence to our required contract, returning a
> Collection does not.

There is no such benefit, as indicated by my observation regarding the
removal of Array.sort in the code.  From the perspective of the provider, we
must still document the semantic contract, and they must still implement it.
The client must still take the Iterator, and trust that it is in the correct
order.  Therefore I consider this to be demonstrably false: returning a List
does not provide any useful degree of compile-time checking, and prevents
the use of any other Collection subclass that would provide the correct
behavior.

> Returning a Collection implies that any Collection could be substituted.

 - Returning a Collection implies only that from the
   perspective of the client the exposed behavior is
   that of a Collection.  Nothing more or less.

 - Returning a List adds nothing more or less than
   the presence an index ordered relationship between
   elements.  Exposing a List violates the principle of
   implementation hiding unless the interface contract
   requires index-based behavior.

Charles did the correct thing when he hid the implementation, and exposed
the narrow interface.  If anything, the change that I might make would be to
change the return type from Collection to Iterator.  Iteration is the only
permissible operation allowed to our client code, and the only reason for
our client code to have a Collection is to avoid having to rebuild the data
set in order to renew the Iterator.  We should probably use
Collection.unmodifiableCollection() to enforce the immutable nature of the
provided contents.

Again, if someone can demonstrate the List methods that embody this presumed
contract, I'm happy to listen.  The fact that we don't use methods other
than those found on Collection belies the necessity, in my view.

        --- Noel


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to