CFObjective Session: Build a ColdFusion powered AIR application

I'm putting the finishing touches on my upcoming presentation, Build a ColdFusion powered AIR application, for CF.Objective() and wanted to pass on some interesting news.

A couple of weeks ago, Terry Ryan, invited me to expand my presentation to cover AIR+ColdFusion functionality to be released in CF 9 Centaur. I'm totally thrilled to present a few CF9 features and am busy redoing the presentation so we can all get a better look at what CF9 brings to Rich Internet Applications. The illustrious Dan 'Big Pipes' Vega was also tapped to present some CF9 content at CF.Objective() so I'm pretty interested to see what he's going to show.

The upcoming CF9 brings many game-changing features to the table and adds a lot to the ColdFusion+RIA equasion. CF.objective() 09 is turning out to be the first public discussion on CF9 Centaur features and you don't want to miss these sessions, do you?

What? You've not registered for CF.Objective() yet? You can still take advantage of historically low airfare and the extended Early Bird Special, just do it before March 31st, ok? Check the sessions if you still need more convincing!

I present You Got Your ColdFusion In My Adobe Air! to TACFUG March 18th

You Got Your ColdFusion In My Adobe Air!

Meeting: 3/19/09 6:00 PM SRA International

Come see how to use ColdFusion to power an Adobe AIR desktop application.

Adobe AIR is quickly gaining momentum as a pioneer of the Rich Desktop. ColdFusion is a rapid development platform providing rich services and timely functionality for business applications.

When the two come together, it is the greatest combination since Reeses Peanut Butter Cups...

More info at TACFUG

I Present Making Bad Code Good To The CFMeetup March 5th @ 6:00 EST

At 6:00 EST this Thursday, March 5th, I present Making Bad Code, Good to the Online ColdFusion Meetup. You can attend this presentation virtually, by visiting the Online ColdFusion Meeting Room at 6:00 EST.

If you work on a legacy application, or on code built by lots of developers over the years, you likely laugh your way through this presentation. I promise to be thought provoking and challenge the way you write code. In this session, we'll look at lots of code samples and walk through making incremental changes to speed development, reduce errors and make life easier for everyone involved.

Ideas and concepts in this presentation will help you improve your existing applications and write more maintainable code.

The recorded presentation can be watched now!

Libpurple I Hate You

I use both Pidgin and Adium for chat clients. Both use libpurple, which has always been a good thing... that is until 2-19-2009. Why does that day live in infamy, you ask? Well that is when Adium updated to a new version and broke my gTalk network.

The symptoms are kind of strange. I can connect Adium to gTalk and my contacts load and turn grey. When I right-click on a contact, I get an option to 'Re-request Authorization', almost like I was blocked by all 200 gTalk contacts at once. I'm one for conspiracy, but I am also one to believe in software problems. Especially when I can use the Gmail interface to talk to my gTalk clients with no problems at all. I'm fairly sure it is libpurple because that seems to be the only link between Pidgin (on windows) and Adium (on mac) and they both broke at the same time.

So, libpurple developers out there, please look upon me with grace and kindness. Fix your freaking software and let me gTalk it up once again!

How to Unrecover Deleted Files

Through an accident, I blame the dog for this one, my entire documents folder got deleted this morning. To compound the issue, the folder was 'too big' for the wimpy Recycle Bin, so the files were permanently deleted. When I realized what had happened, I nearly went into shock.

Customer documentation, contracts, important pictures of aforementioned dog, all down the drain. I'm definitely going to have a bad day now...I thought.

After normal breathing resumed, I learned 2 things.

  • System Restore does not help unrecover files
  • I really should have backed up my computer

I'm calmly writing this blog post because I found Free Undelete by Recoveronix Ltd. Free Undelete will look for deleted files and directories and restore them to their former glory. Brilliantly simple to use, and priced at $0 for personal use, I am a fan for life.

Recoveronix Ltd has an entire suite of recovery products like:

Get familiar with this list. I know grad students that would give their right arm to get back a mistakenly deleted thesis.

Important!! Read This!!

If you are furiously downloading Free Undelete right now to recover files of your own, pay attention to the following tips from the FreeUndelete folks:

Proper Usage Techniques

A deleted file is essentially an area on disk designated as free and ready to accept data (such as contents of some other file). Luckily, unless the area has already been overwritten, it still holds the contents of the deleted file. Due to this fact it is possible to undelete files.

This fact also dictates the following procedure for using FreeUndelete:

  1. Stop any activity on the disk you are going to undelete files from! Remember that writing to that disk can damage the contents of the deleted files. Examples of disastrous activity include: copying files to the disk, installing programs there or running programs that use the disk as their swap media.
  2. Download and install FreeUndelete. Whenever possible, save the setup executable and install the program to a disk that does not hold files you need to undelete.
  3. Run and use FreeUndelete.
  4. 11816 Views Print Print Comments (7) Random, Wow

Of Software Design, The Law of Demeter and Credit Card Companies

The Law of Demeter is a Software Engineering principle guiding how objects should talk to each other. From Wikipedia:

The Law of Demeter (LoD), or Principle of Least Knowledge, is a design guideline for developing software, particularly object-oriented programs ...[and] ...can be succinctly summarized as "Only talk to your immediate friends." The fundamental notion is that a given object should assume as little as possible about the structure or properties of anything else (including its subcomponents).

We Don't Need No Stinking Laws

Now, I'm no fan of laws, so I privately refer to this as the General Guideline of Demeter, even though it doesn't sound as snappy or cool. However, just because there are valid reasons to break it, doesn't take away from the validity of the intent. Let's look at 2 code examples blatantly ripped off from the CFCDEV mailing list:

Conforms To Law General Guideline of Demeter

view plain print about
1Room.canCustomizeWindow()
2Room.canSelectStyle()
3Room.hasCeilingFan()

Violates Law General Guideline of Demeter

view plain print about
1Room.getPlan().canCustomizeWindow()
2Room.getPlan().canSelectStyle()
3Room.getPlan().hasCeilingFan()

Ok, So What?

In the conforming set of statements, the room is asked directly whether or not certain things can happen. The implementation (steps required to complete the task) are hidden from the calling code. This is encapsulated and will help insulate callers from changes in the implementation.

In the violating set of statements, the calling code has to get a reference to Room, then ask Room for a Plan and then query the plan. Now calling code is expected to know about this Plan and what the plan knows. This adds another level of coupling and if Plan changes, then a whole lot of code has to change as well.

However, to the programmer, the violating syntax (Room.getPlan().canSelectStyle()) could make sense. It might be that the programmer doesn't want to refactor Room and using getPlan() is a faster way to do something. If the code works, is it wrong?

I Don't Follow All This Abstract Stuff. You Are Losing Me!

Ok, fair enough. My eyes glaze over with too much abstract stuff too. Let's look at an analogy.

I made a call to a credit card company. The essence of the call was:

CC Rep: CreditCardRep.answerPhone()
Thanks for calling Law Of Demeter Credit Card Company, how may I help you?

Me: Hi, My name is Dan Wilson. I have a question as to a charge on my latest bill.

CC Rep: Hi Dan, I'm Tracy. I can help you with that. For security purposes, what is your account number, mothers maiden name and shoe size?

Me: Acct: 333-444-555-5555 mothers maiden: Stratulat Shoe Size: 9

CC Rep: CreditCardRep.verifyAccountInformation()
     Perfect. What is the charge you wish to inquire about?

Me: I have a 17.99 charge to ILovePets.com on Feb 7th. I can't find my receipt so I don't know what this is for.

CC Rep: CreditCardRep.lookUpTransaction() From the transaction details, you purchased a red dog sweater. Do you recall that purchase?

Me: (Embarassed) Yeah. ok No problem. I also wanted to change my mailing address. Can you help me with that?

CC Rep: Of course, what is the new address?

Me: 123 ColdFusion Lane, Surf City, North Carolina.

CC Rep: CreditCardRep.updateAccountAddress()
     Ok. I've updated the address. Is there anything else I can help you with?

Me: No thanks. That takes care of me.. have a nice day!

CC Rep: OK Dan. Thanks for calling Law Of Demeter Credit Card Company. Have a nice day.

What Am I Supposed To Get From That Example?

Note how I called the CC company and talked with a representative. I only spoke to that representative and was not exposed to any implementation nor had to talk to any other objects to get my tasks done. Let's look at the converse example:



CC Rep: CreditCardRep.answerPhone() Thanks for calling Demeter Violation Credit Card Company, how may I help you?

Me: Hi, My name is Dan Wilson. I have a question as to a charge on my latest bill.

CC Rep: Hi Dan, I'm Tracy. I can help you with that. For security purposes, what is your account number, mothers maiden name and shoe size?

Me: Acct: 333-444-555-5555 mothers maiden: Stratulat Shoe Size: 9

CC Rep: CreditCardRep.verifyAccountInformation()
     Perfect. I can refer you to our Payment Inquiry Department. May I place you on hold?

Me: Ummm... ok.

CC Rep: Perfect. CreditCardRep.getPaymentInquiryRep() ......

CC Rep 2: Hello, this is Jessica, the Payment Inquiry ObjectRepresentative. For security purposes, what is your account number, mothers maiden name and shoe size?

Me: (Grumbles... didn't I already say this once?) Acct: 333-444-555-5555 mothers maiden: Stratulat Shoe Size: 9

CC Rep 2: CreditCardRep.getPaymentInquiryRep().verifyAccountInformation()
     Perfect. What is the charge you wish to inquire about?

Me: I have a 17.99 charge to ILovePets.com on Feb 7th. I can't find my receipt so I don't know what this is for.

CC Rep 2: CreditCardRep.getPaymentInquiryRep().lookUpTransaction()
     From the transaction details, you purchased a red dog sweater. Do you recall that purchase?

Me: (Embarassed), yeah. ok No problem. I also wanted to change my mailing address. Can you help me with that?

CC Rep 2: No, I am sorry. Our Address Change department handles that. Would you mind if I placed you on hold?

Me: (Grumbles, looks at watch) Ummm... ok.

CC Rep 2: Perfect. CreditCardRep.getPaymentInquiryRep().getAddressChangeRep() ......

CC Rep 3: Hello, this is Ann, the Address Change ObjectRepresentative. For security purposes, what is your account number, mothers maiden name and shoe size?

Me: (Grumbles... Kicks Dog) Acct: 333-444-555-5555 mothers maiden: Stratulat Shoe Size: 9

CC Rep 3: CreditCardRep.getPaymentInquiryRep().getAddressChangeRep().verifyAccountInformation() Perfect. What is the new address?

Me: 123 ColdFusion Lane, Surf City, North Carolina.

CC Rep 3: CreditCardRep.getPaymentInquiryRep().getAddressChangeRep().updateAccountAddress()
     Ok. I've updated the address. Is there anything else I can help you with?

Me: No thanks. That takes care of me.. have a nice day!

CC Rep 3: OK Dan. Thanks for calling Demeter Violation Credit Card Company. Have a nice day.

And What Shall I Gain From That Example?

I'm sure you have had a similar experience calling a credit card company. Did you feel like their processes were well designed? Wasn't it a much cleaner experience to just deal with the main object and let it handle the implementation of getting the tasks done?

Circling back to the Law of Demeter, note this passage from Wikipedia:

When applied to object-oriented programs, the Law of Demeter can be more precisely called the "Law of Demeter for Functions/Methods" (LoD-F). In this case, an object A can request a service (call a method) of an object instance B, but object A cannot "reach through" object B to access yet another object, C, to request its services. Doing so would mean that object A implicitly requires greater knowledge of object B's internal structure. Instead, B's class should be modified if necessary so that object A can simply make the request directly of object B, and then let object B propagate the request to any relevant subcomponents. Or A should have a direct reference to object C and make the call directly. If the law is followed, only object B knows its own internal structure.
So if I am Object A, should I really be exposed to the fact that the credit card company even has a Payment Inquiry Department or an Address Change department? Surely these internal details should be kept inside the CC Company Object, not sprinkled through all the various objects that interact with a Credit Card Company.

What Should I Take Away From This Nonsensical Post?

The call dialogue examples above are contrived, I admit, but think of the above dialogues as a set of design requirements for software. Now ask yourself the following questions:

  • What would have to be updated in each of the designs if the CC company added an account verification department that validated account number, mothers maiden name and shoe size?
  • What would have to be updated in each of the designs if the CC Company merged the Payment Inquiry department with the Address Change Department?
  • Which design better encapsulates the implementation from the caller?
  • Which design incurs less ripple effect from design changes?

Thoughts, concerns, comments? Add them below!

Where Willl The Next RIAAdventure Cruise Be?

Woo Hoo!

The inaugural RIA Adventure cruise was a smashing success. It was fun hanging out with a lively entertaining crew and getting to know each other better, all while drinking in Perfect Weather, Frosty Beverages and Island Sun.

The next cruise could be in a lot of locations, Shannon and I are voting for Alaska. We've never been to Alaska and really think the scenery is something special. So if you would like to see Alaska and hang out with some fun people while doing it, vote for Alaska on the RIA Adventure Poll.

Alaska

What can you code in 90 seconds?

I just finished reading an interesting blog post from Raghu, a flex evangelist at Adobe, and was left with the thought, what can I code in 90 seconds?

<CF_DayDream mode="begin" />

After daydreaming was over, I came to the realization that I can code nothing in 90 seconds. See, I am a terrible typist. Really really bad. So my 90 seconds would be filled with furious pressing of random keys, followed by several impolite words, then rapid jamming of the backspace key. Certainly nothing award worthy.

Thankfully, Raghu has more skills than I. He and Harish won an award for their 90 seconds worth of coding.

Read more at:

http://raghuonflex.wordpress.com/2009/02/15/won-the-yahoo-hackday-thanks-to-flex/

http://blog.flexgeek.in/2009/02/won-y-open-hack-day-with-our-built-in-90-seconds-flex-boss-app/

4295 Views Print Print Comments (2) Flex

Sailing With A Bunch Of Geeks

We Sail In 1 Week!

I was greeted with this news when I woke up. Shannon and I are going on the inaugural RIA Adventure Caribbean Cruise and we are ready to go.

We've both been looking foward to white sandy beaches, water and sun for a while now and with only a week to go, are getting rather excited. We have a little pre-trip trip to the everglades to look forward to and expect to get a full dose of what Florida looked like many thousands of years ago, before the modern inventions of Steam Engine, Air Conditioning and Beach Front Condo.

I know a lot of other cruisers are getting into Miami and might be looking for something to do. We planned to go for a nice dinner on Sunday evening at an authentic Cuban restaurant. It looks like Aaron West is organizing so if you get into Miami in time for dinner on Sunday, head over to Aaron's Cruise Announcement and get on the list.

Tip to Speed Up Your Website - Compress CSS

There are a number of ways to speed up a website. An easy one would be to compress asset files and compact the files. This has been widely done for Javascript files with popular tools such as JSMIN and Packer.

The general idea behind compression/combination is to reduce the number of characters that must be sent over the wire as well as reduce the number of HTTP calls that must be made. Each time a browser gets a request to download a JS file, there is a certain amount of overhead incurred in negotiating and completing the HTTP request. Combining all JS files into one file is a great way to speed up a web application.

Everyone Already Knows This, Right?

Probably. However, CSS files can often be as numerous and verbose as Javascript files. How come there no public outcry for CSS compression/combination?

There happens to be a compressor/combinator that handles CSS files, the YUI Compressor. For most web application developers, YUI Compressor is an annoying tool to use because, as a java application, it must be installed and run from the command line. Yuck!, right?

Scriptalizer, developed by ColdFusion luminary Aaron Lynch, is a web front end for the YUI compressor. Scriptalizer has handled Javascript compression/combination for a while now and is a nicely designed, easy to use tool. Aaron recently added support for CSS compression/combination. Now, dealing with CSS files is as simple as dealing with JS files.

How well does it work?

I added all 14 CSS files from The Health Challenge and compressed/combined them with Scriptalizer. Here are the results:

  • Number of Files Before: 14
  • File Size of All Files: 35.42 KB
  • Number of Files After: 1
  • File Size of All Files: 19.96 KB

As you can see, the reduction was significant. Not only have I cut the size of my CSS assets by ~50%, I have also removed 13 HTTP connections.