Abstractions vs Patterns
What follows is some random thoughts on simplicity and abstract/unrestricted vs explicit/uniform/constrained.
- Abstraction: The condition of being so lost in solitary thought as to be unaware of one’s surroundings
- Pattern: A person or thing considered worthy of imitation.
Networks
In SOAP/WSDL, the network is abstracted away. A service is associated with a port, which is associated with a binding, which is associated with a transport and a port type. Port types can define any number of operations, each of which associates input messages with output messages.
In REST/HTTP, the network is explicit. Every resource is
associated with a URI that is expected to implement a uniform set
of operations (in particular, GET
, POST
,
PUT
, DELETE
). In particular, much
as every Java object is expected to implement
toString
, every URI is expected to respond to
GET
.
See also REST + SOAP.
Other Examples
Smaller, and sometimes less clear, examples:
Rasmus Lerdorf states that Database abstraction is mostly a myth; and describes the “shared nothing” architecture of PHP — essentially touting the lack of a feature as a selling point of PHP.
In JDO, persistence is explicit.
In E4X, XML is explicit.
In HTML, presentation is often intermixed with content. In CSS, presentation is every bit — if not more so — as explicit; it is simply re-factored into a uniform mechanism.
The implementation of Ant dispatches the information found in the build.xml file to tasks implemented in Java based on a simple design patterns and introspection.
In Java Web Application Archive files, and in Ruby on Rails, directory names (and in some cases, file names) convey important information.
DuckTyping replaces pre-planned hierarchies with similarities in structure. In Python, it is common for a method to accept a file-like object as opposed to requiring that such an object explicitly inherit from a specific file class.
In Python, indentation is uniform and constrained.
Identifiers
Identifiers in Java may be associated with packages, classes, interfaces, methods, fields, constants, variables, or parameters without restriction.
In Ruby, the first characters of a name indicate how the name is used. Local variables, method parameters, and method names should all start with a lowercase letter or with an underscore. Global variables are prefixed with a dollar sign ($), while instance variables begin with an ‘at’ sign (@). Class variables start with two ‘at’ signs (@@). Finally, class names, module names, and constants should start with an uppercase letter.
In Perl, sigils convey data type information. In C/C++, Hungarian notation was once quite popular.
Some Java and C# programmers adopt prefixes for privately scoped
class members (example: prefixing with an underscore or
m_
).
Patterns
JavaBeans is a pattern that requires the developer or IDE to write more code. In general, public properties need not be named the same as the protected or private field that “backs” it.
In Python, you only write data descriptors when you need to
override __get__
, __set__
, or
__delete__
. The nearest equivalent to the
concept of “private” involves a naming convention.
In Ruby, public members and the private members that back them
are associated with attr
declarations.
In all three languages, constructors/initializers tend to
contain a lot of logic of the form this.foo=foo
(or
self.foo=foo
in Python, or @foo=foo
in
Ruby).
Parting Thoughts
A toddler can often recognize a cat by pattern. It is not until high school or college that a teenager understands the classification of felis domesticus.
Patterns tend to surface common details. Abstractions tend to hide unnecessary details. Those that favor abstractions see them as hiding complexity. Those that don’t tend to see abstractions as adding complexity. “Now you have two problems”
Depending on your point of view, this example is either complex (two or four languages, little separation of concerns), or simple (view-source, copy paste, one can safely make simple changes without understanding how everything works).
Once people lock into either patterns or abstractions, they tend to become religious about them.
Despite the emotional attachments that people have with both, there is no universal abstraction or universal set of patterns that everybody will agree upon. There certainly is no universal consistency in the examples cited above. Additions and counter-examples in comments and trackbacks are welcome.
In the long run, I feel that “fewest moving parts” generally wins out over “hides the details I don’t care about”.