Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2005

Tip: Looking for answers? Try searching our database.

Tagging interfaces

Thread view: 
VisionSet - 29 Nov 2005 13:06 GMT
Why exactly are they bad?

I have a entity, a collection of which is to be associated with an object
that has no need to call any methods on or know anymore than the entity is
of a certain type.  These entities are then passed back to the object that
instantiated them which can cast to the concrete type to do something useful
with them. So a tagging interface seems to fit the bill for my entity.

--
Mike W
klynn47@comcast.net - 29 Nov 2005 14:50 GMT
Who said they're bad?
Jeffrey Schwab - 29 Nov 2005 16:41 GMT
> Why exactly are they bad?
>
[quoted text clipped - 3 lines]
> instantiated them which can cast to the concrete type to do something useful
> with them. So a tagging interface seems to fit the bill for my entity.

Please correct me if I have misunderstood anything:

Each "Entity" requires type-specific processing, but you want the code
for all the processing, for all the different types, to be defined in
one "Master" object.

The Master, which actually created all of these Entities, forgets the
Entities' exact types at some point.  It therefore wants them to be
"tagged," possibly by having them implement empty but nominally
different interfaces.

This sounds like a perfect case for polymorphism.  Forget all the
tagging interfaces.  Have all the Entities implement just one interface,
and each concrete Entity type can implement the interface differently.
If you really want to keep the processing code in the Master object, let
each concrete Entity type just immediately invoke a type-specific
callback method in the Master.

If this isn't clear, or doesn't sound like a good idea, let me know &
I'll whip up some example code.
VisionSet - 29 Nov 2005 16:47 GMT
> > Why exactly are they bad?
> >
[quoted text clipped - 9 lines]
> for all the processing, for all the different types, to be defined in
> one "Master" object.

The number of types (tagged types) and number of master objects is a 1:1
relationship
In fact there is only ever likely to be one entity type and one master
object, but that is not important.
We shall assume other types may exist at some point.

> The Master, which actually created all of these Entities, forgets the
> Entities' exact types at some point.  It therefore wants them to be
> "tagged," possibly by having them implement empty but nominally
> different interfaces.

The tagging is merely type safety mechanism so the surrogate collector can
only collect a certain type, and the master only gets back what it expects.

--
Mike W
Jeffrey Schwab - 29 Nov 2005 18:24 GMT
>>>Why exactly are they bad?
>>>
[quoted text clipped - 35 lines]
> The tagging is merely type safety mechanism so the surrogate collector can
> only collect a certain type, and the master only gets back what it expects.

Wouldn't it be easier, and make your intent clearer, to use generics?
VisionSet - 29 Nov 2005 19:14 GMT
> > The tagging is merely type safety mechanism so the surrogate collector can
> > only collect a certain type, and the master only gets back what it expects.
>
> Wouldn't it be easier, and make your intent clearer, to use generics?

I'll still need a type, no?

Collection<? extends TagIntf>

--
Mike W
Jeffrey Schwab - 29 Nov 2005 19:27 GMT
>>>The tagging is merely type safety mechanism so the surrogate collector
>
[quoted text clipped - 9 lines]
>
> Collection<? extends TagIntf>

You said you wanted the surrogate collector to "only collect a certain
type."  You should be able to use this type as the parameter for the
generic container, e.g.    Collection<Entity>.  No?
VisionSet - 29 Nov 2005 21:24 GMT
> >>Wouldn't it be easier, and make your intent clearer, to use generics?
> >
[quoted text clipped - 5 lines]
> type."  You should be able to use this type as the parameter for the
> generic container, e.g. Collection<Entity>.  No?

I said I wanted to assume that the 1 type may grow to include others,
although only 1 type would be used in any 1 instance of the program, but
that is irrelevent I want the code to be able to support that eventuallity.
Hence the tagging interface.

But I'd heard there really was no defence for tagging interface approach,
and that is is merely a hack to allow introspection.  But when you are faced
with the situation where an objects references are collected at various
places because that is where they naturally belong, and that is the best way
to manage there existence, but no methods are called on them, and you want
to decouple their logic, then this seems like an okay use to me.

--
Mike W
Andrew McDonagh - 29 Nov 2005 23:32 GMT
> Why exactly are they bad?
>
[quoted text clipped - 6 lines]
> --
> Mike W

Before 1.5, Tagging (or more commonly know as 'Marker') Interfaces were
a good way of achieving the same effect as 1.5 Annotations.

They were never bad - mis-understood and therefore mis-used.

Now we have annotations there is certainly less need for them.

Andrew
Chris Smith - 30 Nov 2005 23:27 GMT
> Why exactly are they bad?

My thoughts on the matter.

If you think of what you're doing as a tag interface, then it's probably
a bad idea, at least as of Java 1.5.  The reason is that interfaces are
part of the type system, and as such they imply a certain relationship
between the types of objects that implement them.

There are two ways you can solve this apparent mismatch.

(a) Give up on making the "tag" a type.  With Java 1.5, you'd then
decide to use an annotation, instead.  Annotations don't define type
system relationships, but they do allow you to note information about a
type that can be used (among other places) dynamically at runtime.  For
example, if Java were newly designed today, Cloneable and Serializable
would probably be annotations, because no one ever keeps a variable of
type Serializable or Cloneable.

(b) The other direction: stop thinking of it as a tagging interface, and
start thinking of it as a full-fledged type.  Even if that type doesn't
necessarily need to declare any methods at all (as in your example), it
is a type... and it COULD declare methods.  Once you're comfortable with
that, stop calling it a tagging interface, and stop worrying about bad
design.  (Of course, if you then think of operations that make sense and
are useful to your application on all referents of that type, by all
means add them to the interface... especially if this allows you to take
advantage of polymorphism.)

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

John C. Bollinger - 01 Dec 2005 02:42 GMT
>          if Java were newly designed today, Cloneable and Serializable
> would probably be annotations, because no one ever keeps a variable of
> type Serializable or Cloneable.

I do.  I at times keep variables and declare method parameters and
return types as Serializable in classes that implement Serializable, so
as to improve the likelihood that instances can in fact successfully be
serialized.  Naturally, this tends to involve general-purpose classes
where the declared types would otherwise be Object.  I haven't done this
with Java 1.5 yet, but in a generic class or method I might use
Serializable as an upper type bound or (intentionally) in an
intersection type.  It does not seem that this paradigm ever caught on
in the wider world, but it does lead me to accept Serializable as a very
reasonable type.

In the context of the larger discussion of tag interfaces, however, the
reason that Serializable as an interface makes any sense is that it has
special meaning to the VM.  A type should convey useful information
about objects, and for interfaces without special meaning to the VM, it
is my opinion that at least one method is necessary to make the
information conveyed useful.

Signature

John Bollinger
jobollin@indiana.edu

Chris Smith - 01 Dec 2005 03:18 GMT
> In the context of the larger discussion of tag interfaces, however, the
> reason that Serializable as an interface makes any sense is that it has
> special meaning to the VM.  A type should convey useful information
> about objects, and for interfaces without special meaning to the VM, it
> is my opinion that at least one method is necessary to make the
> information conveyed useful.

I'm not clear on the details of Mike's case... but if he's being
generally accurate in his description, Mike may have a counter-example
to your statement.

In his case, Mike is apparently keeping objects in some kind of
specialized data structure whose behavior (presumably) only makes sense
for objects of that specific type.  The type may not have any general
new operations to introduce, but in may still imply certain constraints
in the way that its objects should be managed.  It may even further
constrain the implementations of inherited method declarations, such as
Object's equals and hashCode.  Much like in the Collections API, then,
the client code is arranged to know the type when it retrieves the
object.

Of course, this new data structure type *could* be written with a type
of Object, but that would imply that it works properly and makes sense
for all Object references... something that may not actually be the
case.  I would think this is exactly the right use for a type, new
operations or not.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

VisionSet - 01 Dec 2005 16:10 GMT
> I'm not clear on the details of Mike's case... but if he's being
> generally accurate in his description, Mike may have a counter-example
> to your statement.

Okay, since I've generated some interest, I'll expand.

I'm attempting to decouple the method of networking from the work that the
server does.
I have a 2 way socket based network layer that can initiate communication,
handle requests and reply with responses in either direction.
This Class is passed handler objects which deal with the requests and return
something appropriate.
In order for the server to pass the correct stuff to specific interested
clients the business part of the server must keep references to its clients.
These references must know how to locate the client but the business part of
the server does not need to know this. So ClientRef has some business stuff
and also a Location reference.  It is this location reference that can be an
empty interface type.  The business layer never needs to know anything other
than it is some form of locator.  The network layer created the Location and
when it gets it back will know how to interrogate it for the address.
I suppose this is by the by, but I guess port and ip address is only ever
going to be the information you need to locate.  But I don't know that for
sure, so the principle stands.

--
Mike W
John C. Bollinger - 03 Dec 2005 03:57 GMT
>>In the context of the larger discussion of tag interfaces, however, the
>>reason that Serializable as an interface makes any sense is that it has
[quoted text clipped - 22 lines]
> case.  I would think this is exactly the right use for a type, new
> operations or not.

I'm still not entirely clear on the details of Mike's case even after he
expanded on it, but I am so far not swayed from my position.  My
argument on this point is much the same as on the Serializable point: it
is incorrect to *do* anything with a reference of a type that has no
members, other than simply to hold it and pass it around, because you
must then make some assumption about the object that is not ensured by
its type.  On the other hand, using a tag interface as the type is just
as bad as using Object: it implies that any object of the tag interface
type is appropriate for use with the application, which is unlikely to
be true.  (Try passing it a "new YourTagInterface() { void darnMySocks()
{}}".)  Somewhere, some time, some body is going to have to cast that
reference to make use of the object, and therein is the indicator of a
problem.

(Of course, if the tag interface extends Serializable, then you can at
least expect to be able to serialize instances....  ;-))

Signature

John Bollinger
jobollin@indiana.edu

Chris Smith - 03 Dec 2005 04:39 GMT
> I'm still not entirely clear on the details of Mike's case even after he
> expanded on it, but I am so far not swayed from my position.

I'm also not swayed, now that I've read Mike's description... but I
think I'm unswayed in the opposite direction as you (if I understand you
correctly).  In this case, I actually think that Mike should be using
Object as the type; no interface, no annotation.  The reason is that a
"location" may be of pretty much any type, not just one that was
designed to work with this data structure.  The only requirement is that
it is later interpretable by the same piece of code that created it.

I don't share the same hostility you express toward casts.  When they
are checked at runtime as Java's casts are, casting is just a perfectly
normal way of telling the compiler some additional information about a
type.  It need not be seen as terribly nefarious.  In Mike's case as
described, using an interface type doesn't just mean modifying classes;
it means potentially creating a new class when InetSocketAddress may be
perfectly good enough!

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Chris Smith - 01 Dec 2005 03:26 GMT
> >          if Java were newly designed today, Cloneable and Serializable
> > would probably be annotations, because no one ever keeps a variable of
[quoted text clipped - 4 lines]
> as to improve the likelihood that instances can in fact successfully be
> serialized.

Perhaps.  I tend to see this as too leaky to be worthwhile.  You're
impacting a lot of code in order to build something that doesn't provide
any additional guarantees.  After all, ArrayList implements Serializable
yet can't guarantee that it can be serialized.

Worse, though, you impact client code here as well.  There are plenty of
good reasons to hold references to objects that you know are
serializable, and yet not use a serializable type.  For example, I often
keep references of type List for obvious reasons, yet List does not
extend Serializable.  I may need to add casts to my code in order to use
an API that uses Serializable as a type, and yet there's no good way
that I could modify my code to hold variables of type Serializable in
the first place.

In the end, I dismiss use of Serializable as a type as being without
significant merit.  If it could make serialization safe, of course, that
would be phenomenal... but it can't.  Instead, it only adds more static
hurdles to using what is ultimately a runtime-checked feature anyway.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

John C. Bollinger - 03 Dec 2005 03:27 GMT
>>>         if Java were newly designed today, Cloneable and Serializable
>>>would probably be annotations, because no one ever keeps a variable of
[quoted text clipped - 9 lines]
> any additional guarantees.  After all, ArrayList implements Serializable
> yet can't guarantee that it can be serialized.

I did say I wanted to "improve the likelihood" of being able to
serialize instances, not that I wanted to ensure successful
serialization.  If the approach I describe were ubiquitous then it would
be much more effective.

> Worse, though, you impact client code here as well.  There are plenty of
> good reasons to hold references to objects that you know are
[quoted text clipped - 4 lines]
> that I could modify my code to hold variables of type Serializable in
> the first place.

I disagree.  For a class whose instances are expected to routinely be
serialized, declaring method parameters to be Serializable both
reinforces the point with the class' users and provides some degree of
compile-time checking.  It is incorrect to keep references of a
non-Serializable type and nevertheless expect the referenced objects to
be Serializable, even if you "know" that they really are, just as it is
incorrect to keep references of type Collection and yet assume that the
referenced objects are Lists.  Indeed, the error is precisely in relying
on knowledge about the objects' classes that is not reflected in their
references' declared types.  Typecasts (of reference types) are usually
a sign of this kind of error, with the only exception I can think of
being casting to disambiguate an overloaded method invocation.

By the way, the type safe solution in the List example is not to cast,
but rather "new ArrayList<SomeSerializableType>(myAnyList)".

(Aside: avoiding most need to engage in the kind of incorrect coding
discussed above is by far my favorite aspect of both generics and
covariant return types.)

> In the end, I dismiss use of Serializable as a type as being without
> significant merit.  If it could make serialization safe, of course, that
> would be phenomenal... but it can't.  Instead, it only adds more static
> hurdles to using what is ultimately a runtime-checked feature anyway.

No, it can't make serialization safe, because serialization is
fundamentally unsafe.  I remain convinced, however, that it makes
serialization saf*er* -- by making some of the class' expectations
explicit in its structure -- and, moreover, that it presents no
additional hurdle whatsoever to otherwise typesafe code.

Signature

John Bollinger
jobollin@indiana.edu

Chris Smith - 03 Dec 2005 04:29 GMT
> I disagree.  For a class whose instances are expected to routinely be
> serialized, declaring method parameters to be Serializable both
[quoted text clipped - 4 lines]
> incorrect to keep references of type Collection and yet assume that the
> referenced objects are Lists.

Even accepting this idea, you are forced to make a choice eventually
between several good design ideas.  Perhaps it would be good to extend
Java to allow type (List & Serializable), in the manner of generic type
bounds... but that feature isn't currently available.  I'd certainly far
rather use List and imply Serializable than use ArrayList just to get
the Serializable statically declared.

I just don't see that there's much benefit to half-solving problems of
verifiability.  It's still not verifiable, and that's the end of the
story.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

John C. Bollinger - 06 Dec 2005 04:31 GMT
>                                     Perhaps it would be good to extend
> Java to allow type (List & Serializable), in the manner of generic type
> bounds... but that feature isn't currently available.  I'd certainly far
> rather use List and imply Serializable than use ArrayList just to get
> the Serializable statically declared.

Believe it or not, I almost wrote something to that effect myself.  I
would be downright *delighted* to be able to use intersection types in
declarations.

Signature

John Bollinger
jobollin@indiana.edu



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.