Digital Edition

SYS-CON.TV
Build a Simple Mach-II Application
Build a Simple Mach-II Application

In the August edition of CFDJ, Ben Edwards and I presented a first look at Mach-II, a new, object-oriented framework for building software applications. In this issue, I offer a tutorial (with commentary) on building a simple Mach-II application.

My choice of subjects for our Mach-II application may have been influenced by spending the last two and a half weeks in Las Vegas training students on Java, Mach-II, and Fusebox 4, culminating in the Fusebox conference. What inspired me for the application was watching otherwise intelligent people trying to outdo each other in throwing away money. Blackjack and poker, I understand; there the player does have some possible positive expectation, but craps and roulette? Watching players eagerly give up 5% or more to the house – with predictable results – I decided that the new Las Vegas slogan, "What happens here stays here," should be amended to "What you bring here stays here."

In this Mach-II application, we'll build a roulette game. While our game is admittedly not as much fun as the real thing, it has the distinct advantage that you can cheat to make yourself a winner without risking a late-night meeting with someone named "Vinny."

Let's start by quickly reviewing key Mach-II concepts. The architecture of Mach-II is known as event-based, implicit invocation. Each request to the framework spawns an event, an encapsulation of the request that includes such things as form and URL variables. The system then looks for software components known as listeners that are registered at configuration as listening for certain events. At configuration time, the system architect registers the listener, the way the listener should be called (using an invoker), and the method to be called. The framework itself knows nothing about what the listeners are up to, nor does any listener correspond with any other. The system is said to be highly cohesive (listeners have a highly focused mission) and loosely coupled (listeners are unaware of each other).

To determine the events the system needs, let's create a narrative that describes the roulette system. It might look something like this:

A player logs into the system, providing his or her name and starting balance. The player is then shown a roulette table from which to select numbers to bet on and an amount to be bet on each number.When the betting is done, the wheel is spun and the dealer pays off any winning bets according to the traditional American-style odds.

Since there are 38 numbers on an American wheel (the integers 1–36 accompanied by a zero and a doublezero), the true odds on any number being chosen are 38:1. The payoff, however, is only 35:1. The house edge is therefore 5.26%. If this doesn't seem too onerous, consider that the 5% edge is not on the bankroll, but on the action. Action is defined as the total amount risked: each new time "through" the bankroll represents that much more action. A $100 bankroll can easily generate $1000–2000 in action. Take 5% of that action and you can see why Las Vegas can afford to air-condition the desert, provide free drinks, and put on some nifty entertainment. (Several years ago, a casino executive was asked by a talkshow host what the casino did with "system players" – people who had developed a system whereby they thought they could beat the house odds. The executive's response? "We send a limo to the airport to pick them up.")

What events can we discover from our narrative? The ones I've identified are shown below in Table 1:

 

Why is there no event for WheelSpin, PlayerWins, or PlayerLoses? Understanding this is key to understanding event-based systems in which not all actions are events and not all components are listeners.

Consider that an object-oriented application is made up of many components that comprise an object model. The object model identifies the components with their associated methods that form a scale model of the system under study. The object model should be independent of the application using it.

If you're familiar with the Unified Modeling Language (UML), you'll recognize that the object model is presented in the form of a class diagram. While CFCs aren't strictly classes, they exhibit many similarities, so much so that a class diagram can be of great benefit. There are many excellent UML modeling tools available, but for our purposes we recommend the excellent Web-based gModeler created by Grant Skinner and built on Flash (www.gModeler.com).

What components and what methods do we need for roulette? Answering this question goes to the heart of how you choose to model the portion of the world under study. There are no right/wrong answers here, only better or worse judgments. The ones I've used for our sample application are shown in Figure 1.

 

All components are modeled as CFCs. The RouletteTable CFC is the key component; three of the other four components relate to it through the mechanism of composition, also known as "has-a" relationship – as in "a RouletteTable has a History." The other component, BankAccount, also relates to the Person CFC through composition. (For more on class relationships, see my book, Discovering CFCs, from techspedition.com.)

These CFCs can and should be built independently of our Mach-II application. We can create test scripts to ensure that each component is doing its job properly. For example, an extremely simple (and inadequate) test script to see that RouletteTable's generateWinningNumber() is working properly might look like this:

<cfset table = CreateObject('component',
'RouletteTable') />
<cfset winningNumber =
table.generateWinningNumber() />
<cfoutput>
#winningNumber#
</cfoutput>

When we're done, we should have a working, consistent model of a roulette game. We don't, though, have an application. For that, we turn to Mach-II. We need to find a way "into" our object model. This is accomplished by having a system component act as a listener for application events. The RouletteTable is an ideal candidate for a listener, since all other components relate directly or indirectly to it.

With our events and our listener determined, it's time to create the view pages that the player will see. There are only two: the initial player login page and the roulette table itself (see Figures 2 and 3).

 

 

Since roulette players (like many gamblers) have a poor concept of odds, the house indulges their fantasy by showing previous winning numbers so that players can judge which numbers are "due." After several plays, the "Previous winners" section of the table is populated (see Figure 4).

 

With the scale model built and the view pages created (the code for this application can be downloaded from www.mach-ii.com), we're ready to tie everything together.

Start by creating a roulette directory structure under your webroot that looks like that shown in Figure 5.

 

The model directory should house all of the CFCs shown in our class diagram. The views directory should hold the two view pages identified. If you recognize the terms, model and view, from the Model-View-Controller design pattern, you may be wondering where the controller directory is. In Mach-II, the framework itself is the controller.

The configuration of the system is the work of mach-ii.xml, found in the config directory. For this article, I show only the germane sections of the file dealing with events and listeners (see Listing 1).

The only listener specified is rouletteTable, which is invoked using a built-in Mach-II invoker, MachII.framework. invokers.CFCInvoker_EventArgs. While we don't have space to go into invokers, we can say that this invoker will turn all URL and form variables into a structure that is then passed to the listener. The <event-handlers> section holds individual <event-handler> elements. Each event-handler defines an event and the listeners and/or views that are affected by it.

At runtime, player requests trigger events. The Mach-II framework reacts to these events, calling the prescribed method for each listener in the order in which each was registered, passing a reference to the event to the affected listener. Listeners can return information to the system through the resultKey attribute of the event-handler. This variable can then be read by the view pages.

Events and listeners can themselves announce new events. We can see that the settlement event announces a showTable event. When you examine the full code, you can find listeners (CFCs) that also announce events.

Events can be provided with event mappings. Since listeners are part of the object model and since many applications may be served by a single object model, there is no assurance that events announced by listeners will match the event handlers shown in the application. In order to provide as loose a coupling between components as possible, the event-mapping element maps events announced by listeners to events present in the application's configuration file. This sort of flexibility is a hallmark of Mach-II with its reliance on ease of application maintainability.

To fully understand the roulette application, download and study the code from www.mach-ii.com. Whether Mach-II fits your application framework needs is, of course, something you must decide. But if flexibility and maintainability are important goals of your system, Mach-II is definitely worth your consideration.

About Hal Helms
Hal Helms is a well-known speaker/writer/strategist on software development issues. He holds training sessions on Java, ColdFusion, and software development processes. He authors a popular monthly newsletter series. For more information, contact him at hal (at) halhelms.com or see his website, www.halhelms.com.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1



ADS BY GOOGLE
Subscribe to the World's Most Powerful Newsletters

ADS BY GOOGLE

The explosion of new web/cloud/IoT-based applications and the data they generate are transforming ou...
CI/CD is conceptually straightforward, yet often technically intricate to implement since it require...
Enterprises are striving to become digital businesses for differentiated innovation and customer-cen...
Containers and Kubernetes allow for code portability across on-premise VMs, bare metal, or multiple ...
Digital Transformation: Preparing Cloud & IoT Security for the Age of Artificial Intelligence. As au...
DevOps is often described as a combination of technology and culture. Without both, DevOps isn't com...
DXWorldEXPO LLC announced today that All in Mobile, a mobile app development company from Poland, wi...
The now mainstream platform changes stemming from the first Internet boom brought many changes but d...
DXWorldEXPO LLC announced today that Ed Featherston has been named the "Tech Chair" of "FinTechEXPO ...
Chris Matthieu is the President & CEO of Computes, inc. He brings 30 years of experience in developm...
Bill Schmarzo, author of "Big Data: Understanding How Data Powers Big Business" and "Big Data MBA: D...
Andi Mann, Chief Technology Advocate at Splunk, is an accomplished digital business executive with e...
In this presentation, you will learn first hand what works and what doesn't while architecting and d...
The Internet of Things is clearly many things: data collection and analytics, wearables, Smart Grids...
To Really Work for Enterprises, MultiCloud Adoption Requires Far Better and Inclusive Cloud Monitori...
We are seeing a major migration of enterprises applications to the cloud. As cloud and business use ...
If your cloud deployment is on AWS with predictable workloads, Reserved Instances (RIs) can provide ...
Disruption, Innovation, Artificial Intelligence and Machine Learning, Leadership and Management hear...
We build IoT infrastructure products - when you have to integrate different devices, different syste...
Consumer-driven contracts are an essential part of a mature microservice testing portfolio enabling ...