To me, the question is the other way round. At what point does an XML Document become so cumbersome, that you have to start using SAX instead of DOM?
I would only use SAX for a very large, indeterminately-sized stream of data; or if the behaviour the XML is intended to invoke is really event-driven, and therefore SAX-like.
The example you give looks very DOM-like to me.
- Load the XML
- Extract the title node(s) and "do something with them".
EDIT:
I'd also use SAX for streams that may be malformed, but where I want make a best-guess at getting the data out.
The problem here is the signature of setLocation
. It's stringly typed.
To elaborate: Why would it expect String
? A String
represents any kind of textual data. It can potentially be anything but a valid location.
In fact, this poses a question: what is a location? How do I know without looking into your code? If it were a URL
than I would know a lot more about what this method expects.
Maybe it would make more sense for it to be a custom class Location
. Ok, I wouldn't know at first, what that is, but at some point (probably before writing this.configuration.getLocation()
I would take a minute to figure out what it is this method returns).
Granted, in both cases I need to look some place else to understand, what is expected. However in the latter case, if I understand, what a Location
is, I can use your API, in the former case, if I understand, what a String
is (which can be expected), I still don't know what your API expects.
In the unlikely scenario, that a location is any kind of textual data I would reinterpret this to any kind of data, that has a textual representation. Given the fact, that Object
has a toString
method, you could go with that, although this demands quite a leap of faith from the clients of your code.
Also you should consider, that this is Java you're talking about, which has very few features by design. That's what's forcing you to actually call the toString
at the end.
If you take C# for example, which is also statically typed, then you would actually be able to omit that call by defining behavior for an implicit cast.
In dynamically typed languages, such as Objective-C, you don't really need the conversion either, because as long as the value behaves like a string, everybody is happy.
One could argue, that the last call to toString
is less a call, than actually just noise generated by Java's demand for explicitness. You're calling a method, that any Java object has, therefore you do not actually encode any knowledge about a "distant unit" and thereby don't violate the Principle of Least Knowledge. There is no way, no matter what getLocation
returns, that it doesn't have a toString
method.
But please, do not use strings, unless they are really the most natural choice (or unless you're using a language, that doesn't even have enums ... been there).
Best Answer
There are two major concepts in confusion: binding and loading. It is conflated by the concept of DataBinding, which is somewhere in the middle often doing both. After considering it, I am going to add one more concept, to complete the trifecta, dispatch.
Types
Late Binding: type is unknown until the variable is exercised during run-time; usually through assignment but there are other means to coerce a type; dynamically typed languages call this an underlying feature, but many statically typed languages have some method of achieving late binding
Implemented often using [special] dynamic types, introspection/reflection, flags and compiler options, or through virtual methods by borrowing and extending dynamic dispatch
Early Binding: type is known before the variable is exercised during run-time, usually through a static, declarative means
Implemented often using standard primitive types
Functions
Static Dispatch: known, specific function or subroutine at compile time; it is unambiguous and matched by the signature
Implemented as static functions; no method can have the same signature
Dynamic Dispatch: not a specific function or subroutine at compile time; determined by the context during execution. There are two different approaches to "dynamic dispatch," distinguished by what contextual information is used to select the appropriate function implementation.
In single [dynamic] dispatch, only the type of the instance is used to determine the appropriate function implementation. In statically-typed languages, what this means in practice is that the instance type decides which method implementation is used irrespective of the reference type indicated when the variable is declared/assigned. Because only a single type -- the type of the object instance -- is used to infer the appropriate implementation, this approach is called "single dispatch".
There is also multiple [dynamic] dispatch, where input parameter types also help determine which function implementation to call. Because multiple types -- both the type of the instance and the type(s) of the parameter(s) -- influence which method implementation is selected, this approach is dubbed "multiple dispatch".
Implemented as virtual or abstract functions; other clues include overridden, hidden, or shadowed methods.
NB: Whether or not method overloading involves dynamic dispatch is language-specific. For example, in Java, overloaded methods are statically dispatched.
Values
Lazy Loading: object initialization strategy that defers value assignment until needed; allows an object to be in an essentially valid but knowingly incomplete state and waiting until the data is needed before loading it; often found particularly useful for loading large datasets or waiting on external resources
Implemented often by purposefully not loading a collection or list into a composite object during the constructor or initialization calls until some downstream caller asks to see the contents of that collection (eg. get_value_at, get_all_as, etc). Variations include loading meta information about the collection (like size or keys), but omitting the actual data; also provides a mechanism to some runtimes to provide developers with a fairly safe and efficient singleton implementation scheme
Eager Loading: object initialization strategy that immediately performs all value assignments in order to have all the data needed to be complete before considering itself to be in a valid state.
Implemented often by providing a composite objects with all their known data as soon as possible, like during a constructor call or initialization
Data Binding: often involves creating an active link or map between two compatible information streams so that changes to one are reflected back into the other and vice versa; in order to be compatible they often have to have a common base type, or interface
Implemented often as an attempt to provide cleaner, consistent synchronization between different application aspects (eg view-model to view, model to controller, etc.) and talks about concepts like source and target, endpoints, bind/unbind, update, and events like on_bind, on_property_change, on_explicit, on_out_of_scope
EDIT NOTE: Last major edit to provide description of examples of how these often occur. Particular code examples depend entirely on the implementation/runtime/platform