Archive for the ‘Uncategorized’ Category

WE’VE MOVED!!!

August 28, 2012

Thanks for visiting our blog!! We’ve recently moved our blog (and all of these posts) over to DevelopwithPurpose.com

Please join us over there and continue to follow as our journey of coding hope and helping people beat debt continues!

Is branching an OOP code-smell?

June 9, 2011

A code smell is a hint that something has gone wrong somewhere in your code. Use the smell to track down the problem

Kent Beck via http://c2.com/cgi/wiki?CodeSmell

I’ve developed a new code-smell sensitivity to “if.” In fact, branching in general triggers an alarm as I read through code (especially if I just typed it). 

Can something so fundamental to programming be a code smell? That gets me thinking that maybe it isn’t so fundamental to OOP.  In high academia, I was told that “structured programming” was the greatest formalism since the slicing of bread. There are 3 required pillars to structured programming:

  1. Sequence – A set of statements are executed in a certain order.
  2. Selection – Statements are executed conditionally.
  3. Iteration – A set of statements can be executed multiple times.

In light of declarative programming and OOP, all of these may be a code smell. For now, I’ll just tackle ‘selection’ and come back to the others as time permits.

Lest I wax too abstract, let’s start with some code (in pidgin java):

switch (pizza.crust) {
   case Pizza.CRUST_THICK:
      doughInOunces = 16 ;
      bakeTimeInMinutes = 13;
      break;
   case Pizza.CRUST_THIN:
      doughInOunces = 12;
      bakeTimeInMinutes = 8;
      break;
   case Pizza.CRUST_PAN;
   default:
      doughInOunces = 19;
      bakeTimeInMinutes = 18;
}

Here we have a selection, a choice if you will.  How much dough do we need and how long do we bake it? Well that depends on the thickness of the crust. Another way of saying that is that it depends on the type of pizza. That’s our first hint. First a detour through some smarter minds than mine.

I’m a big fan of the “Tell, don’t ask” principle and its close relative, “The Hollywood Principle.” Essentially, you don’t ask an object about its state and then act based on that state; you tell the object what you want it to do. In my example, the client code asks the pizza object about its state and makes a decision based on that state. That decision probably belongs near the state itself.

Here’s my proposed alternative (again in pidgin java):

class ThinCrust extends Pizza.Crust {
   int getDoughInOunces() { return 12; }
   int getBakeTimeInMinutes() { return 8; }
}
class ThickCrust extends Pizza.Crust {
   int getDoughInOunces() {return 16; }
   int getBakeTimeInMinutes() { return 13; }
}
class PanCrust extends Pizza.Crust {
   int getDoughInOunces() { return 19; }
   int getBakeTimeInMinutes() { return 18; }
}

And here’s the modified client code:

doughInOunces = pizza.crust.getDoughInOunces(); 
bakeTimeInMinutes = pizza.crust.getBakeTimeInMinutes(); 

Recall the ‘type’ hint. If you have a choice based on some type of something and you’re using a language with a type system (if not, I’d really like to hear about it), use that! In my modifications I created an inner type ‘Crust’ for the ‘Pizza’ type. Now the ‘selections’ are tucked into the types.

In the client code, I just tell the object of a certain (and probably unknown-at-compile-time) type to give me the data I need.

Okay, okay, I’m actually asking for data again. With more refactoring, my client code should actually just look like this:

pizza.bake()

The behavior that uses the values for baking time and amount of dough would still be needed, but only inside the pizza object. The pizza object itself would still want to get these values from its crust inner type, perhaps composed through an inversion of control (IoC) container like Spring.

Is there a case where one needs to perform selection instead of deferring the decision to a type? That is, what are the exceptions to my argument above?

Making Coldfusion sensitive to your (JSON) case

December 20, 2010

I inadvertently discovered that, contrary to popular belief and my own past experiences, ColdFusion can honor your variables’ case when using the built-in SerializeJSON.

First, the simple approach, which fails to produce most obvious results.

<cfscript>
 map = {};
 map.someNumber = 4;
 map.someString = "Hello JSON";
</cfscript>
<cfoutput>
 #SerializeJSON( map )#
<cfoutput>

This produces the following results. Notice that the keys (properties in JavaScript parlance) are UPPERCASED as though the serializer were shouting at you.

{"SOMENUMBER":4.0,"SOMESTRING":"Hello JSON"}

This becomes a problem when you deserialize the JSON in a case-sensitive context (i.e. JavaScript in a browser). It turns out this has little to do with the serialization and more to do with how ColdFusion creates struct keys from your (case-insensitive) code. We can help ColdFusion “do the right thing” by being more explicit with our keys.

Instead of creating a struct with variable names (which ColdFusion treats as case-insensitive), we’ll create struct keys with strings (which maintain their case.)

<cfscript>
 map = {};
 map[ "someNumber" ] = 4;
 map[ "someString" ] = "Hello JSON";
</cfscript>
<cfoutput>
 #SerializeJSON( map )#
</cfoutput>

This results in the following:

{"someNumber":4.0,"someString":"Hello JSON"}

Now we have no surprises when we consume this JSON in a browser. Our JavaScript object literals can use the same keys our CFML struct literals did.

What a Year

December 22, 2009

Our existing website was about 5 years old. After 5 years and uncounted utterances of  “Hey! We have a great new product that needs exclusive top billing on our website!” our web presence was… a bit busy.

We took our time, did our homework, researched, discussed, and planned a long project. In March, Right after we started into what became thousands of man hours, we had ANOTHER cool idea. Right in the middle of a season of economic uncertainty Dave led the team to do an event giving reasons to be hopeful. In early March we had a full workload and an unrelated idea. 2 months later on April 23rd, we had a fully functional website serving 1,000,000 people watching streamed video at 6,000 volunteer locations.

Of course that means that we pushed back launching the main site… right? Well,  no.  Did we work a ton of overtime? Well, we did some but it wasn’t 2 months worth. The new website is now up at www.daveramsey.com, and the side idea is up at www.townhallforhope.com.

I love that we did all of it without staying at the office so much that we forgot who our kids are. It’s been a great year. I’m excited to see what comes next!

User Error + QBQ → User Interface Error

November 7, 2009

About once a day, I sift through our aggregated Web server error messages.  My usual sorting goes something like “this needs to be addressed, that one is novel, this one is my personal test and can be ignored.”  Usually there’s at least one issue where my first reaction is “Oh, that’s just user error.”

One particular error kept coming up from our internal users to the point that it became a nuisance, and I cried out “Why can’t they get that right?!” Immediately, I was convicted by what I had read in QBQ: The Question Behind the Question (a must-read for the Dave Ramsey team).  That wasn’t a ‘QBQ’ question. What can I do so that my internal users will get that right? In this case, a drop-down list contained an invalid option entitled “Select an Option”   The solution was obvious, remove the invalid option and enhance the then-arcane validation message. This process can be generalized to the following:

User Error + QBQ → User Interface Error

Don’t get me wrong, some times a user behavior is just too bizarre to code around it.  (The customer isn’t always right.) Sometimes a customer just needs some education.  The point is that as the solution developer, I’m responsible (at least in part) for my end-users’ actions. It is neglect of this truth that yields the bad reputation programmers get for their people skills.

Let’s do better. The next time you’re faced with a “PEBKAC” (Problem Exists Between Keyboard And Computer) error, before you write it off as ID-10-T, consider the UI or the UX or the messaging or the training. You’ll ultimately wind up with a better product.  Who knows, maybe you’ll even create documentation.

Zooming like a pro with MapQuests AS3 api!

October 21, 2009

Wow, so I have had a ticket sitting in my queue for some time now that I didn’t think would be easy. What we had to do was zoom into a location while leaving that location in the same relative position for the user. After much thinking (about two hours) I came up with my solution. We use MapQuests AS3 api to interact with our maps.

The principle is simple. Figure out where the users mouse is. Get the XY, zoom in, figure out what LatLng is in that XY Position, and get the difference. Then apply the difference to the center point and set the new center point.

public function zoomMapKeepingXYCoords():void
{
var mouseXY:IPointXY = new PointXY(myMap.mouseX, myMap.mouseY);
var mouseLL:IPointLL = myMap.pixToLL(new PointXY(myMap.mouseX, myMap.mouseY));
setZoom(myMap.getZoomLevel() + 1);
var newLLatXY:IPointLL = myMap.pixToLL(mouseXY);
var latDiff:Number = mouseLL.lat – newLLatXY.lat;
var lngDiff:Number = mouseLL.lng – newLLatXY.lng;
var centerAftZoom:IPointLL = myMap.getCenter();
var newCenter:IPointLL =
       new PointLL(myMap.getCenter().lat + latDiff,myMap.getCenter().lng + lngDiff );
myMap.setCenter(newCenter);
}

Have Fun!

Independence Delay

July 3, 2009

W3C announced today the end of the XHTML 2 working group charter.  It has long been apparent that HTML 5 would become a reality, much to my chagrin, but I had hoped deep down that XHTML2 would not die.  You see, HTML 5 is a great tactical move to progress HTML making multimedia easier (among other things) for content authors. However, strategically, I feel this sets back the Web, particularly the semantic Web. I am disappointed, not because XHTML 2 has better features than HTML 5, but because the promotion of HTML 5 over XHTML 2 moves the Web in the wrong direction.

What’s so great about XHTML2

What’s so great about XHTML2? There are some nice cleanups, like replacing <h1-6> with a simple <h>.  The <hr> is replaced with a more semantically-named <separator>. The generalization of the href and src attributes were also pretty exciting. However, the biggest thing is decentralized extensibility. In fact, the W3C mentioned this in their FAQ regarding the end of XHTML2. The very existence of HTML 5 exemplifies why this is a big deal. Decentralized extensibility means we can create our own vocabularies independent of browser implementations.

The current state of things

As a developer, you’re stuck with the elements a user-agent implements.  With HTML, you are limited to what a consortium managed to agree upon and browser authors implemented (somewhat) consistently. The needs of content authors and the capabilities browsers have outgrown the existing centralized vocabularies of HTML 4 and XHTML 1.  HTML 5 addresses this problem with a brute force method: keep improving the centralized vocabulary, and try to keep up with the developer community.

Where we could be headed

If we currently live in the era of the Web browser, we ought to be headed toward the era of the XML browser.With XML, we have more liberty. We can create XML documents with our own vocabularies. We can even define the vocabularies through DTDs or other schemata.  We can mix and match our vocabularies with others. We can define the layout and presentation of new languages with CSS and XSL-FO. Better still, we can define what our new elements and attributes mean through RDF and its related technologies. This is the key.

Every time I mention this, I get the same question, “How would a browser know that my attribute mynamespace:foo@fetcherator is the same as html:a@href?” This is where RDF comes in. With semantic technologies, we can define our vocabularies in such a way that a browser will know.

Why can’t we head there with HTML 5?

We can. In fact, I believe we will (though perhaps more slowly now). My concern is the motivation behind the HTML enhancements in HTML 5 vs XHTML 2. XHTML 2 was a continuation of the W3C’s efforts to bring the benefits of XML into HTML, while HTML 5 seems to bring the benefits of new user agent capabilities into HTML. We need to decouple the user agent capabilities from our document vocabularies. This is true independence.

We can still do this.  The future may still be bright. I hope that we do not lose the vision as we postpone liberty for the comforts afforded by the latest iteration of a centralized HTML.

Plan your escape

March 21, 2009

URL encoding is not character/entity encoding.

This should go without saying, but I frequently see this confused by experienced developers, especially when working with dynamic/loosely typed languages.

URL encoding is for URLs (URIs to be more generic).  The only time to URL-encode a string is when it is part of a URL.  JavaScript provides encodeURI(), encodeURIComponent(), decodeURI, and decodeURIComponent().  In ColdFusion, you can use the  URLEncodedFormat() and URLDecode() functions.  PHP provides urlencode(), rawurlencode() and their decode counterparts.

Entity encoding is used for representing characters in a document that lie outside of the document character set or have a special meaning within the document.  For example In XML, &, <,>,”,and ‘ have to be encoded as entities (‘&amp;, &gt;, etc.) in the document source code.  Typically, characters outside of “low” ASCII need to be encoded as well.  In client-side code, you typically need not worry about entity-encoding. You’re working with a DOM, not document source code, so entity expansion/subsitituion has already been done.

ColdFusion is a little tricky on this one.  There is no equivalent to PHP’s htmlentities.  You basically have two options, HTMLEditFormat and XMLFormat.  The former will encode characters with special meanings, but it misses high-ASCII (and higher).  The latter will encode high-ASCII, but will not use special HTML entity names.  It’s for (the more generic) XML after all.  XMLFormat escapes characters using character entity references.

The concept applies outside of this concrete example, but this is the example that led me to channel my angst into what I hope is a helpful guide post for others.  In fact, you’ll notice that two paragraphs above, Word Press has transformed my double and single quotes to right-double and left-single quotes, respectively.  What are some other escaping/transforming pitfalls you’ve seen?

User-Centric Development

March 18, 2009

The keynote at DevLearn 2008 this past past fall was given by Dan Roam, the author of The Back of the Napkin. Dan spoke about the importance of thinking visually, especially when problem solving.

His presentation spurred a conversation between myself and the other Lampo attendees at the conference: Jon Shearer and Michael Finney. We were discussing how bad things can happen when software engineers find a neat “feature” they can work into an app, regardless of whether the users want or need it.

This brought Finney to a perfect, real-life example of this concept in action. He had recently purchased a new Gateway laptop with a built-in 802.11n wireless network adapter. When using the wireless, however, he had noticed that it would occasionally slow to a crawl. It’s never terribly convenient to troubleshoot this type of problem, especially when so many components are involved (ISP, broadband modem, wireless router, laptop hardware, OS…) and the problem is intermittent.

Well, last weekend, he had a guest in his house with a laptop, and he was able to do a side-by-side speed test during one of these episodes, and he discovered that while the other laptop was getting about 20mbps down, his was getting about 20kbps down.

This took the network out of the troubleshooting stack, so he really dug into the laptop to locate the source of the problem. Before long, he found a “feature” that is new to Windows Vista.

As with prior versions of Windows, you can create and customize power schemes to use when on battery power in order to preserve battery life by throttling the power that certain components use. It is common to scale back the processor speed or the LCD brightness to achieve longer batter life.

Well, Vista has added Wireless Network Adapter Throttling into the default power saver scheme, effectively crippling your network speeds in the name of battery preservation. Let’s think this through for a minute. I want to preserve battery life, so having to sit and wait 1000x longer for a website to come up (all while my LCD and processor burn through battery while I sit and do nothing) is the answer?

Just because you can do something as a developer with the technology you have, doesn’t mean you should.

And just in case you got to this post by searching for an answer to your network slowdown woes, here’s how you change this setting in Vista. Control Panel -> Hardware & Sound -> Power Settings -> Change Plan Settings (on your currently selected power plan) -> Change advanced power settings -> Wireless Adapter Settings -> Power Saving Mode. That’s right, 7 clicks deep, one of which includes clicking on “Sound”. *sigh*

Look under the turtle

November 14, 2008

Developers understand that code reuse necessitates a simple-to-learn interface.  Typically, this leaves us adding another layer of abstraction (aka. “turtle”) to the existing turtle-pile.  This is all wonderful and leaves us feeling warm and fuzzy, except that abstractions are leaky at best.  Usually these new clever interfaces simplify doing whatever you need to do (as long as it is what the API author says you want to do). This means that in order to consume another’s code, I must first learn his or her clever new interface and the interfaces below it.

Recent projects have brought me to the realization that sometimes it’s better to remove a layer of abstraction.  I recently built a solution that involved thermal transfer printing bar codes on pre-printed ticket stock.

The printer uses a proprietary Postscript-like language for creating fields and updating their values throughout the course of a print job.  The printer also came with several half-baked utilities to almost simplify the job of getting it to print what I want, but not quite.  After perusing the developer’s guide, it turned out to be as simple as sending control characters to a parallel port.  I wrote a ‘driver’ in ColdFusion that reads the ticket records from the database and generates a .prn file (just ASCII control codes).  Now I can simply cat the generated file to the fancy printer from any machine that has a parallel port regardless of operating system and without having to install printer drivers.

Albert Einstein is quoted as saying “Things should be made as simple as possible, but no simpler.”  In the example above, I had to learn something new either way—the formatting codes or the libraries that came with the printer.  The libraries failed to simplify the interaction because they did not provide a complete abstraction; I would still have to delve a layer deeper for some of the things I needed.

Think about the abstractions you provide.  Do they really simplify? Will a user of your API need to delve a layer deeper?  If so, you’ve only created an obstacle.

Let’s be really clever developers; let’s learn the abstractions we already have and create clever documentation for other developers.