Wednesday, February 25, 2015

Daily Lesson 2 of 2 : Output format of queries

So I was debugging an issue with a service that process data from a db table. I created a quick unit test, queried for the data, copied the results, pasted into the test and found nothing wrong.


A colleague was at my desk for something else and witnessed what I was doing, he reminded me to switch my query output to output text instead of the table format because the table output doesn't display all characters. It missed things like newlines and control chats...AHA! There was the new line in the subject data for an email! Now I had it and was able to prove that it was the culprit.


But now I have to ask why it was there to begin with! Sanitize user supplied data. If the target is a email subject, remove invalid newline chars.

Daily Lesson 1 of 2 : Test Project in .NET

Make sure that your test project has the same .NET framework setting as the code it's testing.


I was working through an issue with emails not being sent via a windows service running on a loop with a heartbeat to process emails from a DB table queue. Design issues aside, there was an error being logged about the set operation of the .NET MailMessage Subject property.


In order to debug the issue, I whipped up a quick test project in Visual Studio with a single test class with a single method. The method set the Subject property in a for each loop with a try-catch-throw wrapped around the set call. The throw generated a new exception with the current subject from the loop so I know which one was causing the issue.


Next, I grabbed all the queued subjects with a SQL statement which appended " to the front and ", to the back of all subjects in the queue table. I ran the query, copied the results, pasted into the test inside the array initializer. Ran the test and milliseconds later it passed. WTF!?


I examined the MailMessage class from the original and noticed it was from .NET 2 and the one in my test proj was from .net 4. Duh, use the same version of .NET in the test proj as the source code version. So I changed the version in the test project to 3.5 and now it was in synch.


Ran the test again and BAM passed again...seriously!!? Lesson Learned 2 of 2 tells why.

Wednesday, February 18, 2015

javascript double negative !!

I was looking at htmlbars on github and saw something new to me.


if(!!value)...


In other words, if value is falsey. If it's unidentified, the first ! will return false, then the second will return true due to negation.


A quick search turned up that this is borrowed from C. It's sort of like a cast to boolean.

Tuesday, February 10, 2015

Juxtaposed Between a Mess and Clean Code

On the one hand, I'm learning so much about how to write clean code; while on the other, I inherited a complete mess. At the same time, I'm working on another legacy code base that was the number one mess. If anything, this juxtaposition is reinforcing the lessons I'm entrenching myself in.


Let this example suffice to illustrate the mess I'm washing through:


<?php>
if(($_GET['job'] == 'placeorder') || ($_GET['job'] == 'cancelorder'))
$form .= '<div '.lookup_data($data, get_user(...),...,).' class="'.get_class_for_job($_GET['job']).'"'.....more form stuff....
$db.open();
$tmp_result = $db.mysqli_query('select '.$tbl_order_columns_array.explode().' from tbl_orders where '.check_for_id($_GET['order_id']....db result handling to follow
$form .= '<script type=\"text/javascript\"> function checksomething('.$_GET['order_id'].'....more escaped javascript followed by more php, html, SQL and comments that state the obvious. And the typical length of files is on the order of thousands of lines with each statement on one line. Some lines go on for hundreds of characters.


The whole program is like a run-on sentence with the structure being dictated by the layout of the page. There are some base helper functions that do some work. However, the generic nature of those interfaces make for too much logic for them to be easily understood. I'm encountering if statements that are hundreds of lines long followed by an else or perhaps elseifs; nested ifs on the order of five or more; loops that contain hundreds of lines of code. The bottom line is that all of this makes for really poor readability. When code is difficult to read, it is difficult to comprehend. When it is difficult to comprehend, it is difficult to support. When it is difficult to support, service level declines, defect rates go up, support eats up more time which means less time to spend on other commitments, which means defect rates go up... Enter the viscous cycle!



Thursday, February 5, 2015

The Five Why's of BDD

While researching BDD and Cucumber, I came across the Five Why's.




Applied to User Stories, Requirements, whatever...the technique borrowed from Root Cause Analysis can be used to evaluate features. Basically you ask the question why five times and that should get to a solid justification for the feature or that it's not worth much and should be either abandoned or backlogged in the wish list.

Tuesday, February 3, 2015

Delivering Early Value - The True Benefits

I just started scratching the surface of Real Options (lmgtfy). What this means for software projects is very interesting. It offers full justification, in most cases, to invest in early delivery of select features.




The chosen features may not necessarily be the most important to the desired final product. They may be of greater value when they offer options, or at least enable some decisions to be delayed.








That being said, there is also may be a benefit from delivering the reusable components sooner when compared to other components and features. For example, in an Enterprise Applications environment where the system involves integration between several components and subsystems, delivering the shared components first may offer a great benefit if other projects can utilize those components.




Project A is expected to run 12 months and will deliver several components that can be reused by other planned projects. Project B is expected to run 4 months and is planned to start 3 months after Project A.


If B can benefit from a component or feature (CF) from A, then both will benefit from delivery of CF if it can be completed before B has a dependency on CF.




The obvious benefit is that CF can be used by B as well as A. The Real Options benefit is that the Opportunity Cost of CF would not be a total loss if A is killed after the 3 month milestone. Essentially, early delivery of shared CF creates a material benefit in that it produces the option to abandon A for other reasons.


I may not be hitting the mark completely with respect to Real Options, but it made me think a bit about how we can plan our work when there are multiple ongoing projects, or even when there may be a benefit beyond the current project. I'm not suggesting this to be taken as a rule, just something to consider when planning projects.





Sunday, February 1, 2015

Code Better - One Simple Rule For Writing Better Methods

Here's one simple rule for writing better methods. More of a guideline or incantation if you will. Describe what the method does in ubiquitous language. If you use the word AND the method needs to be refactored.


It's not so wrong that a method is the entry point to doing multiple things though. The difference is that a method that is this entry point should "coordinate the actions and activities involved in doing x and y and z.
For example, a method that is the entry point for initializing and saving some entity could have a signature Person InitializeAndSavePerson(). The method should therefore call two methods as is implied by the name, perhaps a constructor also.


public static Person InitializeAndSavePerson()
{
var person = new Person();
person.Initialize();
person.Save();
return person;
}


All of the work to initialize is done in the initialize method and all the work for saving is done in Save().


Perhaps you prefer procedural style to DDD for this sort of thing, here's an example for that.


class PersonManager
{


public Person InitializeAndSavePerson()
{
var person = this.personFactory.GetPerson();
person = this.personInitializer.Initialize(person);
return this.personDataWriter.SavePerson(person);
}


}


Notice that the Initialize returns person. It's probably not technically necessary to do so since person is likely a ref type, but stylistically it better shows intent. This leads to greater readability.


Whatever style you use, the bottom line is that a method does one thing - coordinate or do work.