Skip navigation.
Home
That which cannot be rendered in binary is by definition a delusion
 

Domain Objects and Nodes

There are several goals for a node based domain system. The Zupal node and domain system should:

  • Ensure the nodes link well to each other and can retrieve and CRUD their linkages
  • Couple content to a data source for custom data -- potentially, even one that already exists
  • To cloak data interchange inside the domain system

This system will be accomplished with a series of role based classes.

Domain classes with Zupal interface

These will handle the atomic exchange of data; in the begining Zupal will be bound to the Zend_DB component but some room should be made for allowance of other ActiveRecord systems into the fold. The status() method will be an important "real time" heartbeat detector to validate the status of the data in the underlying mechanism. Down the road, the interface could be wrapped around any number of data sources, from web applications to text based data or XML files.

Domain Abstract Class

A domain class handles basic I/O, simple queries, etc. It is not required to satisfy the Node Interface (see below); however, it can be made to implement said interface 

Node Interface

The Node Iterface defines how a node is required to behave. It defines a contract of association, display, and CRUD handles. The latter is important in order to resolve the response of other nodes to the deletion or updating of node content (if any), and allows us to hang a management and editorial tool set around nodes that Drupal is famous for.

What's in a node (and why should I care)?

A collaborator on Zupal wanted to get a sense of why I care so much about nodes.

A node is of course at its core, an association pattern. A node says, "If field a of foo links to me (thorugh field a) it is as if field a of foo is linked to my identity -- bar record 12252." This is a pattern similar to a handle. It means that unlike traditional associations which are bound to a single table, foo can now link (through a) to ANY node-bound table.

From a CMS point of view this means you can make content trees that have no real constraints. Your home page can have a list of six things which come from any node-bound table. This is the beginning of a polymorphic pattern, but certainly not the end.

Once you have polymorphic associations, you then can have polymorphic patterns around members of these associations. You can create an interface, associated with nodes, at a high level.

  • Every node has a title.
  • Every node has a teaser block.
  • Every node can be rendered as a page
  • Every node can be accessed through a consistent link pattern (as with the url of this page -- /node/109

You can create default handlers for generic node-bound content (scaffolding). You can create an administrative section that handles nodes -- and by implication node-bound content.

This means that a node is not just a table, or the active record that reflects that table. It is a domain object pattern that begins with an interface, applied to a domain object, and ends with a system that has a homogeneous system of policy that all subscribers have to agree with.

Note that this doesn't imply that a node management system has to force all content to be node based. For instance, a lead management system would not probably benefit by forcing all raw leads to be nodes -- there is too much raw, redundant, junk data in leads. However it might benefit from making contacts as nodes: contacts are qualified, and are likely to be assigned to (associated with) users (sales people), and put through generic lists. They will probably also associate with content like companies, locations, and other varieties of information which may (or may not) be node typed.

Further, a contact might benefit from polymorphic behavior -- for instance, a contact might be promoted to a client, and recieve additional functionality (the ability to purchase goods or services, a purchase record, a credit rating, etc.)

So the question of whether or not a piece of content benefits from being a node is: does a piece of content, now or in the future, seem like it is likely to benefit from polymorphic behavior, and could you see it as being  a useful member of heterogeneous lists?

It is very likely that you will always want raw leads to be discrete from your recognized contacts; when you want lead information it will proably be aggregated through SQL and kept in its own balkanized table. However editorial content is always going to be extremely heterogeneous and interlinked.

Nodes enable fuzzy behaviors that SQL is not designed to and in some cases actively resists. It also allows you to develop a system of reusable patterns of content management -- which are essentially interfaces -- and design domain objects that respond to these contracts.

As these contracts are interfaces they do not imply or restrict you to any one pattern of resoulution. You can in fact, reject on a tactical level, a behavior. For instance, if you decide that a receipt is a node, you might force the "edit" action of  the receipt domain object to throw an error (throw new NodeException("You can't edit receipts", $this->node_id(), $this->node_type)) if the action is contrary to the intent of a node.

You can also define other node related interfaces (Node_Tree_Interface, for instance) that defines specialized behavior in the node context.

As nodes are an interface, they are of course an opinion about how content should be identified, managed, and respond to CRUD requests. It doesn't define how specifically it should link out to other nodes. A node doesn't have a parent, for instance -- though a Node_Tree_Interface member will. It is at minimum, a leaf. As an atomic block, though, it enables more complex behavior such as trees, set members, stacks and versions.

The first design requirement for nodes in Zupal is that they form the foundation for a content website. Content will first and foremost be arranged in simple trees, but as well, through sets (taxonomy) be viewable in association with their content properties. If you tag a blog entry as "Kitten", you by implication, enable a "kitten page" where all kitten related content can be listed and viewed.

But I hate interfaces!

Interfaces have gotten a bad rap -- they often slow you down and are symptomatic of beaurocratic enterprise applications. However whether the definitioon of a node is a base class or an interface, it is going to be a contract of some sort.

An interface allows you to define any sort of satisfier: if you accept the node interface, you don't have to accept any parent class (and therefore any implementation pattern). If you define a node as an (abstract) class, you obligate your developers to your implementation. You can of course, have both -- an interface and an abstract class that satisfies the interface. However the latter strategy offers the users a canned solution: an interface-less abstract class enforces it.

Drupal has demonstrated that node behaviors can have applications far beyond (and inclusive of) that basic framework. They do so without either an interface or a class structure -- technically. However the hook system is from an architectural point of view, an abstract class. It uses event methodology to define activity and passes the node content through the handlers. This pattern mimics the funtionality of OOP without using OOP as a vehicle (and they are quite conscious of it.) The Drupal teams' general outlook is, "We have satisfied every problem that OOP is designed to handle, and in fact, go beyond PHP's lack of multiple inheritance. Why would we want to bind outselves to an architecture that would destroy multiple inheritance without adding anything to the picture?" As well they admit, Drupal began long before objective patterns were mature in PHP. 

This logic is airtight uniless you accept interface as a valid pattern for multiple inheritance -- and a lot of people do not. However if you do accept interfaces as a usefu pattern, and do happen to like objective code, Zupal is for you.

For instance, a node based product system can reflect a set of products that have a very deep set of properties beyond their qualifying node behavior. Consider a site that sells vehicles. You can make a node type for planes, cars, boats, trains, motorcycles, an bicycles. Each of these elements might be bound to a basic vehicle interface (top_speed, max_people, min_crew, cargo_pounds, cargo_space) for consistency's sake, but can have specific properties beyond that interface that reflect their specific qualities (planes have allowance for ceiling, turn rate, FCC classifiication; tanks have weapons properties; etc.

Once you reach a specific class that isn't likely to have sub-classes, you aren't likely to need or want an interface contracts slowing you down. And in fact the only interface you are obligated to consider at all is the node interface, which enables the GUI and core systems of Zupal. (i.e., the vehicle interface is optional -- if you don't want to write a vehicle interface you can always just write a vehicle class and inherit subclasses from it.) In short, the only interface you are required to accept is that of the fundamental node interface: all others can be used or ignored as you like. You will be offered a set of classes (Zupal_Node_Tree_abstract) that implement a few basic interfaces, but allowed to forsake these as you like, and/or implement their interfaces in your own way.

For instance, if you want to use MPTT for your metadata table, meaning your tree will be made only of your domain metadata table, you don't have to use Zupal_Node_Tree_Interface OR Zupal_Node_Tree_Abstract. your tree is quirky -- you'll be forming a tree of your metadata table, then loading their node implementations. Having stepped off the reservation of the node tree system, you are free to do whatever you like with your tree, while still getting benefit from the fact that its members are nodes and therefore qualify for the node display, associativity, and CRUD tools offered by Zupal.

AttachmentSize
interfaces.png94.09 KB

Post new comment

  • Allowed HTML tags: <a> <p> <span><small> <div> <h1> <h2> <h3> <h4> <h5> <h6> <img> <map> <area> <hr> <br> <br /> <ul> <ol> <li> <dl> <dt> <dd> <table> <tr> <td> <em> <b> <u> <i> <strong> <font> <del> <ins> <sub> <sup> <quote> <blockquote> <pre> <address> <code> <cite> <embed> <object> <param> <strike> <caption>
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options