Archive for March, 2008

Write Fail-Safe Code


Photo courtesy of rpongsaj

When something is said to be fail-safe, that means it is designed in such a way that when it breaks, it will do so with the least amount of harm.  This is important in software development because there are ways to minimize the impact something has when things go south.  All it takes is some unexpected value to come into your logic to produce an unexpected result.  You want to make sure that if something goes wrong, that it will take the path that will do the least amount of damage. Think of it as an exercise on covering your own ass.

Let's evaluate the following bit of code:

public decimal CalculateCharges(Order o,Customer c){
    decimal val=0;
    switch (c.VipLevel) {
	case 0:
            val=o.Total;
            break;
        case 1:
            val = o.Total * .1m;
            break;
        case 2:
            val = o.Total * .2m;
            break;
    }
    return val;
}

This is a simple example that has a lot wrong with it, but let's just assume that this funtion is being used is production to get the value from an order to stick on an invoice or sent to a credit card processing gateway. It's been running along merrily for a year without issue. One day your marketing dept decides that we need a Level 3 customer that gets charged full price, but gets some other benefit that is totally unrelated to the scope of this code. What happens now? With the code above it looks like you are going to be giving away free product for those awesome level 3 customers.

The most obvious thing here is to make sure that all of your case statments have a default handler:

public decimal CalculateCharges(Order o,Customer c){
    decimal val=0;
    switch (c.VipLevel) {
	case 0:
            val=o.Total;
            break;
        case 1:
            val = o.Total * .1m;
            break;
        case 2:
            val = o.Total * .2m;
            break;
        default:
            val=o.Total;
    }
    return val;
}

Always having a default for your case statement is just good practice. But, let's just assume that in place of the simple switch statment there is some crazy set of weaving logic that has been hacked up by 3 different former employees. You know the type of stuff I'm talking about. It's that smelly code that you're afraid to touch because it works, but you're not sure why. Now the code looks like this:

public decimal CalculateCharges(Order o,Customer c){
    decimal val=0;
    #region Al's Code -- Don't Touch!
       if(condition1 &&
          (condition2 || condition3 && !false) ||
          (1=0 || c.MakeRemoteCall(o.Total,false,1,"Fred")==3.23)
         ){
            decimal subVal=38;

            if(Global.YoMomma==YoMommaSoFatJokes.Number194){
                subVal=o.Total/CONSTANT_VALUE;
            }else if(Life==42){
                subVal=7;
            }

            if(condition1 || condition2){
		subVal+=3.27m;
            }
            if(condition1 && condition3){
                subVal*=.99m;
            }
	    if(condition3 && !condition2){
		subVal=o.Total;
            }
            if(subVal > 7 && subVal < o.Total)
		val=subVal;
       }else if (o.Date.DayOfWeek==DayOfWeek.Tuesday &&
                  o.Date.PhaseOfMoon==MoonPhases.Full &&
                  Global.Hell==HellStatus.FrozenOver
                 ){
            val=o.Total/DateTime.Now.Ticks;
       }
    #endregion
    return val;
}

You've all seen code written like this (maybe some by me, eek!), and if it's in your code base, you are going to keep that region rolled up so you never have to look at that.

public decimal CalculateCharges(Order o,Customer c){
    decimal val=0;
    //+ Al's Code -- Don't Touch!

    return val;
}

All of this silly example code to make a point right? Yes, I'm getting there. If we're under the assumption that Al's code works as expected today, but might not be future-proofed, then we can make sure that the worst thing that happens is that we charge the normal price. So, as long as Al's code doesn't depend on the value of "val" being zero, then we can rewrite it to be this:

public decimal CalculateCharges(Order o,Customer c){
    decimal val=o.Total;  //Default to the order charges
    //+ Al's Code -- Don't Touch!

    return val;
}

This example is a little forced. My real-world examples are a lot more complicated. It's important to realize that business rules will change and sometimes funny stuff might end up in your data that you weren't expecting 2 years ago. Try to write your code in a way that if(when) it gets confused that it takes the path of least damage.

Email Subscriptions

I've turned on the email subscription feature from feedburner.  I'm not sure if any of you are interested, but the option is there now.  I've placed a sign up form in the right sidebar.  It's also worth noting that your email address will only be used for delivering content from the site.  I promise not to share it with any spam lords.

That's all I have for now.  I'll leave it up if it's mildly successful. 

My Healthcare Rant


Photo courtesy of kreg.steppe

I'm hearing more and more cries of people who claim that they cannot afford healthcare coverage.  In fact, two recent ones were by acquaintances who I truly believe CAN afford healthcare.  Just because your employer doesn't offer coverage doesn't mean that you can't have it.  In fact, if you have a cell phone, you can mostly cover the cost of a single member of your family for that price.  I know most of you will be tempted to click away, remove me from your feed reader, and never return, but just hear me out on this one.

All of this revolves around a High Deductible Health Plan (HDHP) coupled with a Health Savings Account (HSA).  I encourage you to read about these further, but the idea is this:  You sign up for a HDHP with a large deductible.  You will pay out of pocket (HSA) up to the deductible, and after that your insurance company will pick up 100%.  Consider this catastrophic coverage.  Now, when you go to the doctor, you are responsible for paying the bill, but you will receive in-network discounts for going to providers who are contracted with the network of your insurance carrier. 

Alongside this HDHP, you will want to set up a HSA account. HSA is a tax-benefited bank account for storing funds to be allocated to healthcare expenses.  You can put money into the HSA tax-free and can use that money to pay for healthcare expenses tax-free.  If you use the money in it for non-healthcare expenses, you will be taxed on that money and will be subject to a 10% penalty unless you are 65 or older.  If you are 65 or older, then you will only be responsible for the taxes.  Aside from the tax benefits, you will now have more control over your health care needs.  You won't have to seek approval from your primary-care doctor in order to see a specialist.

In case you are wondering how much it will cost you, here's an example HDHP from Blue Cross Blue Shield of Tennessee.  If you look at their premiums tables, a 25-29 yr old non-smoking male (like myself) can get a $2,850 deductible plan for $87.10 a month.  My cable+Internet bill could cover that easy, or my wife's cell phone bill would almost cover that.  It's also important to note that BCBST offers an even cheaper basic coverage that's not HSA eligible, but would only set me back $58.69 with a $3,500 deductible.  I'm using BCBST as an example insurance because that is who I currently have through my employer.  I'm sure there are similar offerings from other companies.

Obviously, there are those who still can't afford what I'm showing above, but I have a feeling a lot of people can.  Let's stop trying to use health insurance for our day to day aches and pains and use it for what it should be: help when the unthinkable happens.  I currently have an HDHP+HSA for my wife and I and it has been working out great.  We've managed to set aside a nice bit into our HSA to cover our deductible for several years should something tragic happen.  We get the same service we always got with traditional health insurance.  Also, I'm sure we're paying less than we were paying with traditional insurance with the super high premiums plus co-pays.  I'll try to drum up another post later with a comparison of the two.

All of this is just establishing your priorities.  Would you rather have a cell phone or health care coverage?  No one is going to take care of you, you are going to have to do that yourself.  If that means sacrificing a few luxuries, then you just have to do it.  I'm sure this will become a hotter topic as the elections draw closer.

I’m Done With Inline SQL


Photo courtesy of ViaMoi

When I began working "in the real world" almost 4 years ago, I came into an environment with SQL embedded directly into the code as strings.  At the time, it seemed simple. We only had 4 apps: data importer, data exporter, ui for employees to search/view/edit/create, and a web site.  There wasn't much that could go wrong.  We basically had one table of maybe 200,000 rows that our entire company was built off of.  The only thing that really could go wrong was forgetting to truncate a long string or escaping a tick mark.  Even if this did come up, the impact was small and not a big deal.

I managed to move away from the concatenated SQL statements to parameterized SQL relatively quickly if for nothing else just readability.  That's basically where I stopped.  I kept hearing and reading the debates for and against stored procs, and was never swayed from the ways I had learned already.  I started hearing about ORM software and gave a few a try.  Nothing really swayed me while we had our single table.

A few years back we did a massive database conversion to normalize our defunct single table.  The company was growing and our data needs were expanding.  All software was retooled using existing methods and everything painfully got switched over.  Now, here I am 4-years hardened into the real world, and I'm tired of buggy SQL strings.  Our business has expanded so much, and our simple single table SQL statements have turned into crazy multi-table joined monsters.  It just didn't scale and now the code is uglier for it.  Now we have maintenance and testing issues that we're working through.

I've just recently had a few experiences with ORM software and it's so much easier to write and debug code.  I want all of the SQL interactions to be isolated so that they can be tested by someone else (preferably, the ORM vendor).  I just want a platform to use and not worry about it.  If I need to do something crazy, I can create a view or stored proc and have the db check my syntax for me.  I'm sure there will be cases where it makes sense to write some inline SQL , and that's okay.  I'll isolate it and test the snot out of it.  I'm just done having code littered with SQL strings.

This is all just a part of learning and growing.  I'm sure that if I had come into an environment with an existing ORM in place, then I wouldn't have learned half the SQL I know now.  My SQL-Fu seems to have grown by leaps and bounds in the last year or two.  Knowing that, I don't regret the path I took to get to this point.  I do know that I'm sure as hell not looking forward to re-writing those legacy apps as they start giving me issues.

Crystal Reports Suck

There, that feels way better. I'm sure a co-worker will want to chime in here and say it's not so bad. Still, "not so bad" is not "awesome" or even "usable". Sure, you can get things done, but it usually involves prayers, the alignment of the sun and moon, and a goat with red hair.

I've yet to try some of the alternatives out there. I'm sure they are better (how could they not be), but Crystal Reports ships with Visual Studio and that's what my company uses. Maybe one day I'll get off my bum and try a few demos. I still have a feeling that it would be hard to convince the company to spend money on a different reporting engine when we have one already.

The only day I was fussing around with a report, and I think I figured out why it bugs me so much:

  1. It doesn't feel very object oriented. If I have an invoice with line items in memory as objects, I just want to pass the invoice to the report and then be able to create a sub-report on the lines. Further more, I'd like to reuse that bill object report and be able to place it in a larger report that I could pass a collection of bill objects. Maybe I need that report to print the invoices, and then a summary page. Keep in mind I'm not talking about a dataset with 2 datatables contained. I'm just talking about an invoice object that contains a collection of line items. Maybe I'm missing something here, and if I am, please someone put me out of my misery.
  2. It doesn't work with Nullables.
  3. The syntax inside is not the syntax outside. I don't like the basic language and I don't feel like I should have to use it just to create a report.
  4. Lack of templating/style sheets. This one feature would be huge. It would be awesome to create a company wide style sheet and just apply that to any report. Marketing decides that the company logo needs to be refreshed? Change it in one style sheet. Some dummy in sales broadcasts an internal report full of clients to a competing company? Fire him, then change your template for internal reports to have an "internal use only" disclaimer, and hope the next salesperson will notice your bold red disclaimer at the bottom.

I'm sure there is more I could come up with here, but lunch time is sharply coming to a close. I think I've just been spoiled with web development. The same engine I'm using for gathering input is the same for reporting, it's called the browser. Sure, you have some browser quirks to deal with, but at least it's a consistent experience. I can use my server side language of choice to generate markup and then make it all look the same with CSS. I'd love to hear some opinions on this. Maybe I could learn something to help me not hate it so bad.

Next Page »