On the Taxenomy of Ducks:
Using Object Inrospection and Reflection to Manage Systems Integrity When I was 12, my brother and sister and I spent a week in Seatle, visiting my grandparents during winter breaker. On the Tuesday of our visit, my grandmother had her bridge club over, and my grandfather was out taking care of some holiday shopping, so my siblings and I were left to entertain ourselves for a few hours. It was was raining outside, so my sister decided she would read a book. My brother wanted to play a game (I was hoping we would play chess). So, he went to grandmothers game closet, and pulled out a box, handed it to me and asked me to set it up, so we could play a game. The box was labelled Chess, and had pictures of a chess board and chess pieces on the outside, so I was excited to play a game of chess. I opened up the box, and began to set up the board pieces, and I found that a few pawns were missing. I could have just told my brother we could not play, as there were pieces missing. I could have gone and interrupted grandmother’s bridge game, to ask her if she knew where the missing pieces were. But I found some dice laying on the table, so I substituted the dice for the missing pawns, so we could play a game, and asked my brother “Okay, white or black?”
The roles and responsibilities and expectations of objects in software systems are subject to the requirements, methods and organization of the system architect, and the engineering team lead. How objects handle their input objects is an age old problem, and with the inroduction of distributed systems, the shapes and sizes of input objects can suffer from their own contraints. An object needs to have a way of behaving when it is handed an object for processing, and the first thing it needs to do is inspect the input. If the input is not what it requires, then it needs to either handle that somehow, or throw an error.
This principle of software development has become topical because of the fairly recent adoption of a practice dubbed “Duck Typing” by some, popular in ColdFusion and Ruby development circles. So, what is “Duck Typing” and why does it raise discussion around object behavior? In software languages like C++ and Java, objects are classified by types, which define specifically what properties they have, and what methods are available. When the C++ or Java code is compiled, the compiler checks to ensure that the inputs to object methods are of the expected types, and if not, a compiler error is thrown. In interpreted systems, like Ruby, or JIT compiled systems like ColdFusion, the types are checked at runtime JIT compile time. If the objects are strongly typed, an error is thrown. This is much like my brother handing me the box from the game closet. If the box was not labelled Chess, I could have objected and handed it back to my brother.
The practice of “Duck Typing” is to abandom this practice, and let the called object deal with whatever object it is handed. In practical terms, this is a shift of responsibilities from the caller, software environment or compiler, to the called object. The objection to “Duck Typing” is that often this means a shift of responsibility to quality control, the bug tracking team, customer service and the project manager who is left explaining why their enterprise web system is crashing, and the development team is having difficulty tracking the bugs. What has not been clarified in some team development environments, is that there has been a shift in responsibility. Someone has to pick up the slack. It is left to the called object to be more diligent in checking it’s input, and more flexible in how it handles the input. Like, when I discovered there were pieces missing from the chess set, and I made a couple of pawns out of dice, the team needs to be clear on what the object has the authority to do, to perform its function.
There are a few strategies which need to be embraced when the protective tools of compile and runtime type checking, because in the end, the software needs to work.
1) Internal type checking with _types, so the object can compare the meta data with the input
2) Object introspection
And/or build/deploy time:
1) Unit testing to check types