Magic Coincidental Reflection

MagicCoincidentalReflection (in Java) is what you have when you have to use reflection instead of instanceof to determine what you can do with an object.

Isn't that how Smalltalk does it?

Generally, in Smalltalk, you just send a message to the object assuming that it will do what you mean. If the object implements the message, it does it. If not, it is sent doesNotUnderstand, which it does understand. This seems chaotic and error-prone at first glance - at least it did to me - but in fact it is simple, elegant, and reliable.

I would call smalltalks strategy: ApplyRobustDefaultBehavior? and it is a principle we do in C++ in some way as well. It helps to get clean client code (without ugly exceptions) and allows for robust fallback implementations if you are able to override the default at the calling side. The NullObject pattern is one incarnation of the principle. -- PeterSommerlad


Can someone provide an example?

A: You're implementing an interpreter.

That is, the calling code is so data driven that it doesn't know what methods it will be calling. The calling code's data tells it what methods to call, and it uses reflection to select or match parameters specified in its data to the actual parameters, and then it makes the call.

A: You're adding a ThingListener? to an object.

There's no such interface as ThingListenable? which supplies addThingListener and removeThingListener, so you can't simply do ((ThingListenable?) obj).addThingListener. Instead you have to use reflection to find the addThingListener method and then invoke it. The coincidence is that you think the object has the method, and it really does. The magic is that anything works at all. MagicCoincidentalReflection is meant to be a bad thing, because the better way to do it would be define the ThingListenable? interface and use DeterministicGuaranteedToWorkInterfaces?.


It's (almost?) always better to define interfaces for the different capabilities that client code would want to query for, and then FallBackOnReflection as a way of implementing those interfaces. --NatPryce

I do not think so. Client code gets easily bloated by too many interfaces to deal with. I still have to explain why I TypeSafeInterfacesConsideredHarmful?. -- PeterSommerlad

My comment referred to Java code specifically. Type-safe interfaces make no sense in languages such as SmallTalk. However, Java code that uses what appears to be MagicCoincidentalReflection is usually interacting with the reflected objects through some higher level protocol. That protocol can be defined as a Java interface (or perhaps multiple interfaces) and a default implementation provided that uses reflection to make it easy for programmers to write classes that support the interface. However, reflection is inefficient and so programmers can implement the interface by hand if reflection proves too slow. -- NatPryce


I take it the key word here is "Coincidental"? We're concerned that different classes will use the same method name for different things, and we think using "interfaces" will make this problem go away?

I think it's more that "Coincidental" refers to the fact that you don't know what kind of object you are dealing with before you receive it. This is sort of like when you use a JavaCollection? and it returns an Object from a call to get. You then have to cast the Object to whatever you want to use it as. If you don't know what you are dealing with before it arrives, you have to use reflection instead of just doing instanceof. Using instanceof is between 9 and 12 times faster than using reflection so....

Also, adding "interfaces" doesn't help with method name collision (at least not in Java). It's possible to have a class implement two interfaces that declare the same method. Interfaces just allow you to specify what methods there will be. The DiamondInheritanceProblem? still exists from that point of view but since the implementation class can only have one method with a given name, it can't have "implementation collisions".


CategoryReflection


EditText of this page (last edited October 25, 2013) or FindPage with title or text search