Sunday, January 11, 2009

OOP Concepts in Drupal

Despite the lack of explicitly-declared classes in Drupal, many
object-oriented paradigms are still used in its design. There are many sets
of "essential features" that are said to be necessary to classify a system
as object-oriented; we will look at one of the more popular definitions and examine some ways in which Drupal exhibits those characteristics.



Objects



There are many constructs in Drupal that fit the description of an
"object". Some of the more prominent Drupal components that could be
considered objects are modules, themes, nodes, and users.



Nodes are the basic content building blocks of a Drupal site, and
bundle together the data that makes up a "page" or "story" on a typical
site. The methods that operate on this object are defined in node.module,
usually called by the node_invoke() function. User objects similarly
package data together, bringing together information about each account on
the site, profile information, and session tracking. In both cases, the
data structure is defined by a database table instead of a class. Drupal
exploits the relational nature of its supported databases to allow other
modules to extend the objects with additional data fields.



Modules and themes are object-like as well, filling the "controller"
role in many ways. Each module is a source file, but also bundles together
related functions and follows a pattern of defining Drupal hooks.



Abstraction



Drupal's hook
system
is the basis for its interface abstraction. Hooks define the
operations that can be performed on or by a module. If a module implements
a hook, it enters into a contract to perform a particular task when the
hook is invoked. The calling code need not know anything else about the
module or the way the hook is implemented in order to get useful work done
by invoking the hook.



Encapsulation



Like most other object-oriented systems, Drupal does not have a way of
strictly limiting access to an object's inner workings, but rather relies
on convention to accomplish this. Since Drupal code is based around
functions, which share a single namespace, this namespace is subdivided by
the use of prefixes. By following this simple convention, each module can
declare its own functions and variables without the worry of conflict with
others.



Convention also delineates the public API of a class from its internal
implementation. Internal functions are prefixed by an underscore to
indicate that they should not be called by outside modules. For example,
_user_categories() is a private function which is subject to change without
notice, while user_save() is part of the public interface to the user
object and can be called with the expectation that the user object will be
saved to the database (even though the method of doing this is
private).



Polymorphism



Nodes are polymorphic in the classical sense. If a module needs to
display a node, for example, it can call node_view() on that node to get an
HTML representation. The actual rendering, though, will depend on which
type of node is passed to the function; this is directly analogous to
having the class of an object determine its behavior when a message is sent
to it. Drupal itself handles the same introspection tasks required of an
OOP language's runtime library.



Furthermore, the rendering of the node in this example can be affected
by the active theme. Themes are polymorphic in the same way; the theme is
passed a "render this node" message, and responds to it in a different way
depending on the implementation of the active theme, though the interface
is constant.



Inheritance



Modules and themes can define whatever functions they please. However,
they can both be thought to inherit their behavior from an abstract base
class. In the case of themes, the behavior of this class is determined by
the functions in theme.inc; if a theme does not override a function defined
there, the default rendering of an interface component is used, but the
theme can instead provide its own rendering. Modules similarly have the
selection of all Drupal hooks to override at will, and may pick and choose
which ones to implement.

No comments: