Mach-ii for newbies - part2
Written by Trond
Ulseth (www.waterswing.com/blog)
1. Introduction
Hello, and
welcome back. This is the follow up to a part 1 (obviously), originally posted
at Easycfm.com (http://tutorial345.easycfm.com/).
If you did not read that one yet you probably should (or maybe not - what do I
know? At any rate, I won't come after you if you don't).
A lot of
things have happened since I wrote part 1. In the meantime I've been developing
on my first real OO (Object Oriented) application. That application was written
without using mach-ii or any other framework though.
One thing I
feel I did not emphasize in part 1 (actually, looking back I see I did not
mention it at all) is that the mach-ii framework is "created to help software
development and maintenance using an OO style" (quote from mach-ii.info). In other words, to use and leverage the mach-ii
framework you should (no - need to) understand OOP.
Remember in
part 1 I suggested that even though we did not see the payoff of using mach-ii
right away "we'll just have to trust that there will be some payoff for the
extra work further down the road". After finishing that OO project I can
definitely say that there is payback down the road. And looking at the
improvements using the mach-ii framework would bring to that project had it
been used, I see that the payoff would be doubled (or at least enhanced pretty
much).
However -
for now - OOP will not be the subject of this tutorial series. I've had a lot
of positive feedback from the first part, but also some criticism. One of the
critics was that I focused very much on the mach-ii.xml
configuration file, while going pretty quick through the bean concept. While
agreeing that understanding the bean concept is important, a bean is not a
mach-ii specific subject, while the mach-ii.xml file
is mach-ii specific to the highest degree. So that is the walk I'll walk and
talk I'll talk for now.
Let me just
quickly remind you of the disclaimer from part 1: "I am learning as I'm
writing, or writing as I'm learning. I can therefore not give any guaranty that
what I am doing is totally best practices, or that I have so much understanding
of what I'm doing that I explain it as clear as could be possible. I'll try
though to write in an easy to understand and slightly entertaining way."
Enough
jabbering! Let's dive into the mach-ii waters again.
2. A short repetition
Let's just
quickly go through what we learned/did in the first part.
Now do you
remember the assignment I gave you at the end of part 1?
Without any
further ado, here's the solution:
<event-handler event="message.create" access="public">
<event-bean
name="message" type="MyGuestbook.model.message.message"
/>
<notify
listener="messageListener" method="createMessage" />
<view-page name="mainTemplate"
/>
</event-handler>
I'm pretty
sure that you had that one figured out yourself.
3. Where do we go from here?
The obvious
first thing to do is to get the submitted messages displayed on our page. So we
need to query the database for inserted messages, and find the mach-ii way of
getting the output displayed on our display page.
In the
first part we used a CRUD cfc for putting a message into the database. But I
also said that a CRUD should only deal with one record in the database at a
time. So for queries retrieving multiple records we need to create another cfc,
a so called gateway.
We write
the following code, and save it as messageGateway.cfc
in our model/message/ directory.
|
<cfcomponent displayname="Message
Gateway" hint="I am a data gateway to messages"> <cffunction name="init"
access="public" returntype="MyGuestbook.model.message.messageGateway"
output="false"> <cfargument name="dsn"
type="string" required="true" /> <cfset variables.dsn = arguments.dsn /> <cfreturn this /> </cffunction> <cffunction name="findMessages"
access="public" returntype="query"
output="false"> <cfset var findMessages
= 0 /> <cfquery name="findMessages"
datasource="#variables.dsn#"> SELECT
* FROM
guestbook ORDER
BY id </cfquery> <cfreturn findMessages /> </cffunction> </cfcomponent> |
So we
started out with the familiar part this time. The init method
we remember from the CRUD (go back and read part 1 if you're insecure about it
- I know I did). Then the findMessage method is a good ole' SELECT * query.
Seeing that
the init method here is the same as in the CRUD is a pretty good clue that the
gateway also is called from a listener. So now we're going to do the same. In
fact we'll do it in the same listener. So let's open up the messageListener.cfc
and modify it as so:
|
<cfcomponent extends="MachII.framework.Listener" displayname="Message
Listener" hint="I am the listener for messages"> <cffunction
name="configure" access="public" returntype="void"
output="true" displayname="Listener
Constructor" hint="I initialize
this listener as part of the framework startup."> <cfscript> var dsn = getAppManager().getPropertyManager().getProperty("dsn"); variables.messageCRUD = CreateObject("component",
"MyGuestbook.model.message.messageCRUD").init(dsn, "MyGuestbook"); variables.messageGateway = CreateObject("component",
"MyGuestbook.model.message.messageGateway").init(dsn, "MyGuestbook"); </cfscript> </cffunction> <cffunction name="createMessage" access="public" returntype="void" output="false" displayname="Create Message" hint="I cause
message to be created from the current event object."> <cfargument name="event"
type="MachII.framework.Event"
required="yes" displayname="Event"
hint="I am the current event" /> <cfset var message =
arguments.event.getArg("message") /> <cfset variables.messageCRUD.create(message)
/> </cffunction> <cffunction name="getAllMessages"
access="public" returntype="query"
output="false" displayname="Get All
Messages" hint="I return a query containing all of the
messages."> <cfreturn
variables.messageGateway.findMessages
|