CFWheels - Pragmatic, Beautiful Code
-
Upload
indiver -
Category
Technology
-
view
104 -
download
0
description
Transcript of CFWheels - Pragmatic, Beautiful Code
CFWheels Pragmatic, Beautiful code
Indy Nagpal Straker Software Melbourne, November 2010
A bit about me
• CTO, Straker Software, New Zealand
• Been doing CF (and Flex) for a while
• Cloud-based CF Using Railo
• In love with Ruby (the language) & Rails
– Was in love with Groovy (still am, I think)
• nagpals.com/blog
Rapid ≠ Agile
Agile
• Early, continuous delivery of software
• Welcome changing requirements
• Deliver working software frequently
• Working software = progress
• Technical excellence and good design
• Simplicity is essential – work not done
“There comes a time in the history of every project when it becomes
necessary to shoot the engineers and begin production.”
Need
• Quickly build and deploy database-driven web apps
• Rapid iterations in a testable fashion
• Easy for multiple developers to understand
• Working app is more important than configuring the app
Search…
• Tried lots of frameworks/methodologies
• Ruby on Rails addressed most issues
• Learn another language and framework
• Defeats the whole purpose
• Enter, CFWheels…
What is CFWheels
• Framework inspired by Ruby on Rails
• Simple organization system
• Suited for typical, database-driven web applications
• A couple of years’ old – fairly mature
Convention over configuration
• Possibly the single most important thing
• Mostly convention, minor configuration
• Easy to
– turn on
– tune in
– drop out
Directory structure • webroot – models– controllers– views
– images– javascripts– stylesheets
– plugins
– tests– events– config
Intuitive Code Structure • View
– Responsible for display and user interaction – Receive data from controller
• Controller – Process requests from view – Get/process data from model – Make data available to the view
• Model – Interacts with the database layer – Responsible for validation – Other methods to process/message data
Convention - URLs
• URLs mapped to controllers/models/views
http://blog/posts/edit/1Controller: Posts
Model: Post
Action: Edit
Key: 1
View – http://blog/posts/ /views/posts/index.cfm
<cfparam name="posts"><ul><cfoutput query="posts"><li> #linkTo( text = "#posts.title#", action= "edit", key = post.id, title = "Edit #posts.name#" )#</li>
</cfoutput></ul>
Controller – http://blog/posts/ /controllers/Posts.cfc
<cfcomponent extends="Controller"><cfscript>function index(){ posts = model("post").findAll(order="createdAt")}
</cfscript></cfcomponent
Model – http://blog/posts/ /models/Post.cfc
<cfcomponent extends="Model"><cfscript>function init(){ belongsTo("author") hasMany("comments") validatesLengthOf( properties = "title", minimum = 10, maximum = 255)}
</cfscript></cfcomponent>
Convention – Files & Database
• Place in appropriate folders – MVC
• Plural database names, singular model names
– DB Table: posts– Model: Post.cfc
• Database fields: id, createdat, updatedat
Built-in ORM
• Simple and elegant
• All major databases supported
• Almost no setup required – baked in
• CRUD instantly available via models/plugin
• Finding data using “finders” – findOne(), findAll(), findByKey()…
Associations models/Post.cfc
<cfcomponent extends="Model"> <cfscript>
function init(){ belongsTo("author") }
</cfscript> </cfcomponent>
models/Author.cfc
<cfcomponent extends="Model"> <cfscript>
function init(){ hasMany("posts") }
</cfscript> </cfcomponent>
<cfscript>posts = model("post").findAll(include="author")author = model("author").findOneByKey(key=params.key,include="posts")
</cfscript>
Dynamic Finders
• Dynamic finders are magical model("user").findOne(where="username='bob' and password='pass'")
rewritten as
model("user").findOneByUsernameAndPassword("bob,pass”)
URLs and Routing
• Beautiful URLs – http://blog/a-good-url
• Powerful routing mechanism <cfset addRoute( name = "showPost",
pattern = "/[key]”, controller = "Posts", action = "show")>
• Can be turned REST-full
Multiple response formats • http://blog/posts
• http://blog/posts.xml
• http://blog/posts.json
• http://blog/posts.csv
• http://blog/posts.pdf
Common tasks done
• Adding timestamps
• Flashing messages
• Pagination
• Sending multi-part emails
• Redirecting users
Lots of helper functions • Views
selectBox()
linkTo()
timeAgoInWords()paginationLinks()
titleize()pluralize()
• Model validatePresenceOf()
findAll()
findOneByKey()afterSave()
• Controller flash()
isGet()sendMail()
Plugins
• Neat architecture to add/override functionality
• Extremely useful
– Scaffold –generate CRUD application
– DBMigrate – Add/edit database structure
– Remote Form Helpers – Ajax with forms
– Localizer – Localizing an application
Baked in testing
• Ships with RocketUnit <cfcomponent extends="tests.Test"><cfscript>
function test_1_get_timezones(){ qTimezone = model("Timezone").getTimezones() assert("isQuery(qTimezone) ") assert("qTimezone.recordcount eq 56")}
</cfscript></cfcomponent>
Environments
• Different setup for applications based on stages of development
– Design, Development, Production, Testing, Maintenance
• Differ in terms of caching, error-handling
• Switch environments via config/url
Docs/Support
• Very helpful docs at cfwheels.org
• Active and supportive mailing list
• Quite a few screencasts
• Direct knowledge transfer from Ruby on Rails books/docs (e.g., Head First Rails)
• Bunch of blogs
IDE Support
• Eclipse, CFBuilder
– Syntax Dictionary
• Textmate
– Bundle
• Coda
– Lacking, but works by adding Clips
Beauty
• Simple code organization and flow
• Easy to understand code – eyeballing code
• Common tasks done with minimal code
• Pretty URLs
• Almost zero configuration, with power to configure as much as needed
Pragmatic
• Focus on simple code that solves issues
• Trades pure OO for simplicity and structure
• Easy to not use the framework if needed
• Common web application problems already solved – why reinvent the wheel(s)!
Wrap up
• Evaluate if you need a ‘framework’
• Learn URL rewrites (Apache, IIS)
• Dabble with Ruby on Rails
• cfscript = succinct code
• Worth trying out just to see how problems can be solved in a different manner