Are tag (or “marker”) interfaces obsolete?

2019-04-10 13:42发布

问题:

I'm trying to help a coworker come to terms with OO, and I'm finding that for some cases, it's hard to find solid real-world examples for the concept of a tag (or marker) interface. (An interface that contains no methods; it is used as a tag or marker or label only). While it really shouldn't matter for the sakes of our discussions, we're using PHP as the platform behind the discussions (because it's a common language between us). I'm probably not the best person to teach OO since most of my background is highly theoretical and about 15 years old, but I'm what he's got.

In any case, the dearth of discussions I've found regarding tag interfaces leads me to believe it's not even being used enough to warrant discussion. Am I wrong here?

回答1:

Tag interfaces are used in Java (Serializable being the obvious example). C# and even Java seem to be moving away from this though in favor of attributes, which can accomplish the same thing but also do much more.

I still think there's a place for them in other languages that don't have the attribute concept that .NET and Java have.

ETA:

You would typically use this when you have an interface that implies an implementation, but you don't want the class that implements the interface to actually have to provide that implementation.

Some real world examples:

Serializable is a good example - it implies that there is an implementation (somewhere) that can serialize the object data, but since a generic implementation for that is available, there is no need to actually have the object implement that functionality itself.

Another example might be a web page caching system. Say you have a "Page" object and a "RequestHandler" object. The RequestHandler takes a request for a page, locates/creates the corresponding Page object, calls a Render() method on the Page object, and sends the results to the browser.

Now, say you wanted to implement caching for rendered pages. But the hitch is that some pages are dynamic, so they can't be cached. One way to implement this would be to have the cacheable Page objects implement an ICacheable "tag" interface (Or vice-versa, you could have an INotCacheable interface). The RequestHandler would then check if the Page implemented ICacheable, and if it did, it would cache the results after calling Render() and serve up those cached results on subsequent requests for that page.



回答2:

In .Net Tag interfaces can be great for use with reflection and extension methods. Tag interfaces are typically interfaces without any methods. They allow you to see if an object is of a certain type without having the penatilty of reflecting over your objects.

An examples in the .Net Framework INamingContainer is part of ASP.Net



回答3:

I'd call myself an OO programmer, and I've never heard of a tag interface.



回答4:

I think tag interfaces are worth discussing, because they're an interesting corner case of the concept of an interface. Their infrequent use is also worth noting, though!



回答5:

I've used tag interfaces a couple of times in an object model representing a SQL database. In these instances, it's a subtype of the root interface for particular types of objects. It's easier to check for a tag interface than an attribute ('obj is IInterface' rather than using reflection)



回答6:

The .NET Style guide says to use Attributes rather than tag/marker interfaces.

alt text http://www.freeimagehosting.net/uploads/th.4528577db5.jpg
Click for Full image
source: http://www.informit.com/articles/article.aspx?p=423349&seqNum=6
or any number of other exposure points of Cwalina's recommendations, like the book.



回答7:

I've used a tag interface twice in the past month. They can cut through some nasty problems when refactoring to make a function more generic.

That said, another thing I just discovered is using a tag interface as a parent class to a bunch of related interfaces with methods. The object can be passed around, and various preprocessors can check to see if they need to deal with a particular object. A way of keeping the processing in a separate object where it belongs, but the implementation details of processed objects in their definitions where they belong.



标签: oop theory