Release 1.2.1 (4/14/2005)
« Concepts & Core Files | Contents | Designing Models »
This section explains how to structure your application and provides some general design guidelines for building object-oriented applications.
This section explains how to structure your application to fit both Mach II and our standard directory structure guidelines.
This has already been discussed under Mach II Core Files. This is the central configuration file for a Mach II application that specifies all the listeners, events and views etc. As mentioned above, it lives outside the document root.
This is a directory structure convention used by Mach II to separate the CFCs
used by an application. Although it is not required to follow the Mach II convention,
it is actually fairly convenient. Under your application components directory,
create these three directories: model, filters, plugins. At Macromedia, all
our components live outside the document root so we end up with this structure:
{cfmxroot}/extensions/components/{appname}/model/
{cfmxroot}/extensions/components/{appname}/filters/
{cfmxroot}/extensions/components/{appname}/plugins/
CFCs in the model directory are a combination of listeners that extend MachII.framework.Listener and framework-neutral business model components.
CFCs in the filters directory are event filters that extend MachII.framework.EventFilter.
CFCs in the plugins directory are plugins that extend MachII.framework.Plugin.
Other CFCs that are used to support the application can live in either the
model directory or if appropriate in another more suitable directory,
e.g., when wrapping existing application CFCs in a Mach II application skin.
To keep the model directory organized, it may be a good idea to create separate sub-directories within it for the listeners if you have several of them, or even create a listeners directory directly under your {appname} directory:
.../components/{appname}/model/listeners/ - just the listeners
.../components/{appname}/model/ - other, framework-neutral, business objects
or:
.../components/{appname}/listeners/ - just the listeners
.../components/{appname}/model/ - other, framework-neutral, business objects
Another possibility is to keep your listeners and business objects together but clearly identify your listeners through a naming convention, e.g., SomethingListener.cfc.
Which approach you choose will likely depend on how many listeners your application has and whether or not you are reusing the business objects in another context.
Another directory structure convention, this is used to separate out the .cfm files that render HTML. These .cfm files live in the views directory underneath
the application directory, either under the document root or under the include
directory for that application. At Macromedia, we put our views outside the
document root:
{cfmxroot}/extensions/includes/{appname}/views/
Since we have a mapping from /cfinclude to {cfmxroot}/extensions/includes/ we
define the global Mach II property applicationRoot, in mach-ii.xml,
to be "/cfinclude/{appname}" instead
of just "/{appname}" so that Mach II can find the view .cfm files.
This section provides guidance on designing your Mach II application. We start with some general design guidelines in this section and then subsequent sections cover models - including design patterns - then views, event handlers, event filters and finally plugins.
You can approach the design of a Mach II application from two different view points: from the business model or from the user experience. In most cases, you will be able to perform a certain amount of the design in parallel in these two areas. As you will see in the sections below, the business model components can be designed and implemented independently of the rest of the application (and usually independently of the Mach II framework itself). The user interface can also be designed and - for the most part - implemented independently of the rest of the application. The interactions in the user interface drive the design of the event model in a Mach II application which then, in turn, drives the design of the event handlers and listeners, constrained by the interface of the business model. For teams where the user interface work and back end engineering work are handled by separate individuals or groups, this allows for more efficiency early in the project lifecycle. Furthermore, the loose coupling encouraged by Mach II allows for more flexibility and easier maintenance, later in the lifecycle.
For many developers, especially those new to Object-Oriented Design, the hardest part of building an application in an OO style is determining which components are needed. If you can write a short coherent narrative that describes the interactions in your business logic, you'll find that most of the nouns in that narrative suggest themselves as components and most of the verbs suggest themselves as methods on those components. Most - not all. Remember that not everything needs to be a component - some things simply aren't important enough in the overall business model to require a component to model their behavior. In one application, a person's name might be important enough to be modeled as a component that understands title, greeting, first (given) name, family name, middle name or initial, suffix etc but in another application it may suffice to have a string for full name (or perhaps two strings for first and last name). There are no hard and fast rules.
Once you have your components identified, you need to consider how well-defined they are. Each component should be highly cohesive - it should do (or represent) one "thing" only and do it well. The components should also be loosely coupled - they should not need to know about or depend on each other in order to do their "one thing". Be prepared to refactor your code to improve the cohesion and reduce the coupling - your first choice of components may be obvious but won't necessarily be the best representation of your business logic. If you find it hard to represent a relationship between two or more components, perhaps the relationship itself is sufficiently important to need its own component - sometimes the relationship may actually be more important than the entities it connects. Also remember that a relationship between two components represents coupling between those components. Abstracting the relationship into its own component can often reduce the coupling between other components and so provide more flexibility.
The other key point to consider is inheritance versus composition. Many OO novices see inheritance everywhere and try to have components extend other components left, right and center. Inheritance is a very special relationship between components: it means "is-a". It really isn't as common as most people seem to think and it is also a form of very tight coupling between the parent and child components. Unless the relationship genuinely represents an immutable "is-a" relationship - where a child component instance is wholly substitutable for the parent component instance in every use case - then you should consider some form of composition instead. Composition can be broadly described as "has-a" or "refers-to" relationships. A good example of this is the Employee / Manager model. Novices often try to model this with inheritance - a Manager "is-a" Employee - but this breaks down when you start to consider promotions and substitutions and so on. A more accurate model is that an Employee "has-a" Role and Manager "is-a" Role. When a regular employee is promoted, it is only really their role that changes and, in some companies, an employee can actually have multiple roles, especially if the company has a "matrix reporting" system or bestows temporary roles on employees.
Good Object-Oriented Design takes time and practice so leverage other people's work by learning about and using Design Patterns - they are your friend!
« Concepts & Core Files | Contents | Designing Models »
RSS feed | Send me an e-mail when comments are added to this page | Comment Report
Current page: http://livedocs.adobe.com/wtg/public/machiidevguide/structure.html
Comments
No screen name said on Mar 28, 2005 at 4:57 AM :