10

Besides Presentation-abstraction-control and other patterns that are used in Drupal core, are there any other design patterns prominently used in the more popular contributed modules such as Views, CCK, and Features?

  • 2
    As reported in the faq, "You should only ask practical, answerable questions based on actual problems that you face. Chatty, open-ended questions diminish the usefulness of our site and push other questions off the front page." – kiamlaluno Sep 14 '11 at 23:47
  • 1
    this might be a good community wiki topic though – Chaulky Sep 14 '11 at 23:48
  • Community Wiki is not used anymore for questions that are not acceptable, or that are borderline. See The Future of Community Wiki. – kiamlaluno Sep 15 '11 at 7:57
  • 2
    On the other side, I think this is an interesting topic. Suggestion for a better question: "Is there a design pattern which can solve problem X?". Because that's what design patterns are for, solving a problem, they shouldn't be used just so that they are used. – Berdir Sep 17 '11 at 15:45
  • 1
    @kiamlaluno, I would argue that the question is not unanswerable, chatty, or impractical, though it may arguably be open-ended. My purpose in asking the question is to get a better sense of how design patterns are used, in code that I'm somewhat familiar with. – Matt V. Oct 12 '11 at 21:48
10
+50

One place to start is with core itself and the patterns exposed to contrib. - a great write-up by Larry Garfield (Crell) can be found in a Drupal Watchdog article.

Observers, visitors, and peeping toms

Drupal is actually built on the twin patterns of Observer and Visitor, although it doesn't call them by name. Instead, it calls them hooks. hook_node_load(), hook_user_login(), and so forth are, in essence, observers on nodes and users. hook_form_alter(), hook_node_view(), and so forth are, in essence, visitors. Because Drupal does not differentiate between the two, some hooks could arguably be considered both patterns but the principle is the same.

Factories and commands

There are several variations on the Factory pattern, but they all boil down to the same idea: One object, a client, asks another object, a factory, for an appropriate implementation of a piece of logic, but doesn't care which it is. That's up to the factory to decide. Consider the db_insert() function, the important bits of which are show below:

   function db_insert($table, array $options = array()) {
       // ...
       return Database::getConnection($options['target'])->insert($table, $options);
     }

The Database::getConnection() method is a factory that returns a connection object appropriate for this site.

Doctor Drupal's Dependency Injection

In Drupal 6, the menu system was gutted and rewritten to be a multi-step process. We would now implement the same page callback like this:

   function example_menu() {
       $items['node/%node/example'] = array(
         'page callback' => 'example_page',
         'page arguments' => array(1),
         // ...
       );
       return $items;
     }

     function example_page($node) {
       // Do useful stuff here.
     }

In this new setup the menu router gets more complex. In return, however, the page callback gets the node on which it depends passed to it, that is, injected into it. That gives us a number of benefits.

Go for Broke(r)

One common approach is some variation on the idea of a Broker or Mediator. In this design, an object doesn't request information from another object directly. Instead it asks an intermediary object, which may have been injected into it, to make such a request on its behalf. While it still means the first object has to actively request information, it is only tightly coupled to the mediator object and not to the myriad of other objects it may need to request information from. That means if those other systems change we need only update the mediator, not every system that touches it.

Not the answer you're looking for? Browse other questions tagged or ask your own question.