Hi everyone,

Sorry if I join this discussion a little bit late (thanks to Howard Fore and
Robert Bailey for the invitation!).
I am glad to get feedbacks from "MVCF".

First of all, what you can find on benorama.com are the results of my
attempts to build a "methodology" for a complete rewrite of our application
from CF5 to CFMX. It was based on my own CF experience and best
practices/design patterns usually used in J2EE and .NET world.
It was in august 2002.
We have successfully apply those concepts and we should launch our new
application CFMX-based next month.
I haven't updated the site since then, even if it has a little bit evolved.

I'll present the latest version of my works at CF_Europe in London (29/30
may) (and I will take the time to update benorama.com).
Till then, here are some updates...

FUSEBOX
Many people compare MVCF to Fusebox, but it is not exactly the same thing.
As Sean rightly said on his blog, MVCF is not a "framework", it is more a
"methodology" or a set of best practices (that you can use in your own
home-made frameworks...).
The aim is to have a Rapid Application Development "methodology" to build
structured CFMX applications.
I've tried to make it as "logic", "simple" and "natural" as possible :
- a "page" is a "page" (a layout defining which view components to display),
- a view component is independent from any views/controllers,
- a model component is independent from any views/controllers.
To understand a CF application following most of MVCF concepts is very easy
: you just have to look at the directories structure and read the code
(which is not exactly the case with highly-structured frameworks where
you'll have to deep into the configuration files...).

STRUTS
Concerning Struts, I haven't use it on a "real" application, but from what
I've read (few books), it seems to be a great highly-structured framework
especially designed for "form-based web applications" (mainly Backoffice
applications).
But in my opinion, it is way too complex for most of web applications,
especially "content-based web applications" (Frontoffice applications, such
as 95% of websites).


CONTROLLER LAYER of MVCF
In 100% MVC approach, all the user interactions should call the Controller,
which then redirects the user to the corresponding View.
The thing I don't like with Struts and Fusebox MVC approach is that content
component "get" operations must be made by the Controller and then passed to
a "dumb" View. Controllers have to be aware of the content of the View...
When you add/modify some content in a page, you'll have to add/modify the
content "get" operations to the corresponding Controllers, which prevents
you to build "clean" and re-usable View Components.
In my opinion, when the user ask to go to the home page, controllers should
only redirect the user to the home page...
It is the View component in the home page that "knows" what content is
required.

That's why I use pagelets which allow me to build View Components that you
can plug in any pages.
In MVCF, Controllers are only used for form post operation when content
components are called for "creation/update/delete" operations.
In the View, content component are directly called inside the corresponding
pagelets (but only "get" operations, no "creation/update/delete"). Pagelets
are not linked to any Controllers, except for form POST operations.
It is much more easy to understand, to develop AND to maintain.
There is no configuration files, no "action classes", no servlet mappings...


VIEW LAYER of MVCF
I've made some improvements (not online yet on benorama.com...) on the
Presentation/Layout Layer.
Instead of using multiple pages for each possible layout, I create now one
single page with a "fuse mechanism".
I use a "url.Layout" parameter associated to a <cfswitch> do define which
pagelets to display.

For example, in the BlogMX sample application, instead of having 3 pages
("index.cfm", "display.cfm" and "edit.cfm"), I would have only one main
layout script "article.cfm" with all the different possible layouts.

<cfsilent>
 <!--- Import the coldfusion layout taglibs --->
 <cfimport prefix="layout" taglib="/blogmx/system/cftags/layout">
 <cfimport prefix="ui" taglib="/blogmx/system/cftags/ui">

 <!--- Import the coldfusion i18n functions --->
 <cfinclude template="#application.stVirtualPath.CFLibs#/i18nLib.cfm">

 <cfparam name="url.Layout" type="string" default="previewArticles">

 <!--- Defined I18N bundles to be used in the current page --->
 <cfset LSBundle('common','common')>
 <cfset LSBundle('article','article')>
</cfsilent>

<cfoutput>
<layout:page>

<layout:pagelet name="com.mycompany.nav">

<table width="100%">
<tr>
 <td width="80%" valign="top">

  <cfswitch expression="#url.Layout#">
  <cfcase value="previewArticles">
   <layout:pagelet name="com.mycompany.article.previewArticles">
  </cfcase>
  <cfcase value="displayArticle">
   <layout:pagelet name="com.mycompany.article.displayArticle">
  </cfcase>
  <cfcase value="editArticle">
   <layout:pagelet name="com.mycompany.article.editArticle">
  </cfcase>
  </cfswitch>

 </td>
 <td width="20%" valign="top" align="right">

  <cfif session.member.isAuthor()>
   <ui:button href="#cgi.SCRIPT_NAME#?layout=editArticle&articleid=0"
text="#LSMessage('BUTTON_PUBLISH','article')#">
  </cfif>

  <cfif not session.member.isLogged()>
   <layout:pagelet name="com.mycompany.security.displayLoginForm">
  </cfif>

 </td>
</tr>
</table>

</layout:page>
</cfoutput>

It has 2 main advantages :
- less pages and a single main layout definition, usually nav and menu
doesn't change, so it is more logical to define them only once,
- href links aren't hardcoded anymore.

In pagelets, all the href links should be
href="#cgi.SCRIPT_NAME#?layout=someLayoutName&params=someParameters...".
Like this, pagelets can be included in any layout pages.

For example, in the BlogMX sample application, in
com.mycompany.article.previewArticles, in previous version, script names
were hardcoded :
"... href="article.cfm?articleid=#qArticles.ID#" ... "

Now, it is :
"... href="#cgi.SCRIPT_NAME#?layout=displayArticle&articleid=#qArticles.ID#"
... "

Like this, I could use this pagelet in any layout script, I would just have
to implement the "displayArticle" layout fuse.


MODEL LAYER of MVCF
Another topic, I have not yet covered on benorama.com is the different use
of CFCs on the Model Layer.
This is what I've posted of cf-talk few weeks ago.

I usually create :
- Entity CFCs that correspond to physical persistent entity (usually a
single row in one or several database tables).
 they inherits from a base Entity.cfc with "init" and "getProperties or
getValueObject" methods,
 they usually have at least "load/create/store/remove or
get/create/update/delete" methods,
 Ex. :
 <cfscript>
 newsEntityInstance =
createObject("component","com.mycompany.news.NewsEntity");
 newsEntityInstance.get(1011);
 newsEntityInstance.title = "I have changed the title";
 // or newsEntityInstance.setTitle("I have changed the title"); // if you
create setter/getter functions for each properties
 newsEntityInstance.update();
 </cfscript>

- Utility CFCs that encapsulate generic business logic and are not
persistent and stateless.
 Ex. :
 <cfscript>
 newsUtility = createObject("component","com.mycompany.news.NewsUtility");
 lastNewsRecordSet = newsUtility.getLastNews();
 </cfscript>

- Session CFCs that act as a facade to handle the client session
(statefull).
 Ex. :
 <!--- use the com.mycompany.member.MemberSession CFC put in session
scope --->
 <cfif session.currentMember.hasTheRightToDoThat()>
  ...
 </cfif>

This is how I use CFCs for a 100% ColdFusion-based application, but if you
have good J2EE skills in your team and if it is required, you might replace
those CFCs by JavaBeans/POJOs or EJBs (with all their pros and cons...).
In fact, this methodology could also be used in a 100% java development with
JSP (for layout and pagelets) and Beans.


WEB-INF > CF-INF
I don't use the WEB-INF folder anymore.
Instead, I create a "CF-INF" folder where I put all the components,
pagelets, controllers, UDF lib...
Then I have a "wwwroot" for each applications where I put the "layout"
pages.
There is nothing linked to my applications under the Jrun or ColdFusion
installation and system directories.

Here is our structure (that we use with CFMX Pro/Ent or CFMX for J2EE) :
d:/applications >> ColdFusion pages accessible through HTTP (~wwwroot)
d:/applications/www.myappA.com - an application A (only layout CFM pages and
SWF app), document root of an Apache Virtual host
d:/applications/www.myappB.com - an application B (only layout CFM pages and
SWF app), document root of an Apache Virtual host

d:/applications/CF-INF/ >> ColdFusion components, lib...
d:/applications/CF-INF/ - XML config files for all the applications
d:/applications/CF-INF/cfcomponents - CFC root (business/data components)
d:/applications/CF-INF/cfpagelets - Pagelets root (view components)
d:/applications/CF-INF/cfcontrollers - controllers
d:/applications/CF-INF/cflibs - UDF Lib root
d:/applications/CF-INF/cftags - CF custom tags
d:/applications/CF-INF/lib - Java libraries root
d:/applications/CF-INF/fla - Flash source root

d:/files >> Static files
d:/files/www.myappA.com/i18n - properties files for internationalization of
application A
d:/files/www.myappA.com/cache - cache root
d:/files/www.myappA.com/mappingA - an example of Apache mapping for static
files (for example /images)
(in our case, all the static files are on a dedicated files server running
only Apache, files.myappA.com)

d:/database >> database files root

Then we add the following mappings in jrun.xml :
<virtual-mapping>
<resource-path>/CF-INF</resource-path>
<system-path>d:/applications/CF-INF/</system-path>
</virtual-mapping>
<virtual-mapping>
<resource-path>/com</resource-path>
<system-path>d:/applications/CF-INF/cfcomponents/com</system-path>
</virtual-mapping>

Next step would be to write utilities similar to the CFC explorer, in order
to get auto-documentation :
- Pagelet explorer, list of all the pagelet packages in the CF-INF folder,
showing a description of the pagelet and the required parameters (could be
automatic by scaning the <cfparam> tags at the begining of the pagelets,
between the <cfsilent></cfsilent> tags),
- Controller explorer, list of all the controllers.

What do you think about all those updates?

Sincerely,

Benoit Hediard
www.benorama.com


----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the word 'unsubscribe cfcdev' 
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

Reply via email to