Are You Writing Baby Proof Software?

July 27th, 2009 Josh No comments

The other day while eating lunch the topic of newborns came up. We discussed that when parents prepared for a newborn to enter their home, they gave their best effort to ensure that the home was “baby proof”. Outlets were covered, stairway gates were in place, and cabinets locked to stop the little one from getting into trouble with anything in reach. Now they look back as their children become mobile, and say a whole new can of worms is opened. Cabinets are not locked to protect what is inside. They are locked to prevent them being turned into steps to get other items originally out of reach.

christmas-tree

Baby proofing your home serves as a solid analogy to writing software. As much as we wish it were not true, we unintentionally write buggy software. If you are lucky, the bugs are never found once the software goes out the door. Try as much as you wish to hide the errors and gracefully recover, there is always some way to work around the system. Users are just like babies in that they just putter around in the application trying different things until they find what works. They may not be expect to find these issues, but once they find them, watch out because they’ll remember how to get back and exploit what you hoped was "safe software". The Twilight Hack for example allowed Wii users to exploit a buffer overflow just by changing the name of the character’s horse.

It is very difficult to try and prevent this seeing how you cannot really tell exactly what you are looking for. Keep in mind though that software development is a lot more forgiving than raising a child. You cannot run usability tests in your house to see how safe it is. The only solution that I have to getting around this is to draw from past experiences. Focus on thorough testing and make sure past issues are no longer a problem.

Below is a refresher on the types of software testing that most products should undergo:

  • Unit Testing – validate that individual units of your code work for a given input and expected output. Never rely on external factors to write your unit tests (e.g. Database Engine having correct data and up to date)
  • Integration Testing – ensure that you are clear of your expectations and what you expect when working in multiple distributed environments or systems
  • Performance/Load Testing – you will want to try and avoid being surprised when you get a call on Cyber Monday telling you that your site is offline due to heavy load
  • Usability Testing – before you go live, do some testing on your application to make sure that you see how well subjects can perform tasks and respond to errors
  • Regression Testing – remember that feature that you added in last month’s release? Yeah well now the user cannot update their profile ever since then. Regression test to ensure that updates you make do not cause existing functionality to break.
  • Security Testing – is your software capable of SQL Injection? Do you follow correct authorization rules for your users and does your data retain its integrity?
Categories: Testing Tags:

Five Steps to Making Fellow Developers Miserable

July 23rd, 2009 Josh No comments

1. Long Method

Short methods specific to single units are bad. Try to limit the number of methods in each class. This will ensure that each method is as long as possible.

Workaround: In order to prevent long method from happening, I recommend limiting the length of your functions to 30 lines or less (40 including exceptions).  Focus on keeping your functions less then one screen’s length.  Try bumping up the font-size of your IDE so that a lot less code fits on the screen.

2. Out of Sync Comments

Just like you learned in college, comments are the best form of documentation. Comment blocks are better. Provide details about every line of code and include pre-conditions, post-conditions, and expected exceptions. Comments are important because they help other developers calling the code understand how it works.

/// <summary>

/// Saves data into database

/// </summary>

/// <remarks>

/// Save Data opens up a SqlCommand object and calls the

/// sp_SaveUsers stored procedure to save a user object.

/// </remarks>

/// <preconditions>

/// User object must be created. sp_SaveUsers must exist in SQL server

/// </preconditions>

public void SaveData()

{

//Get Connection String

string connectionString;

SqlConnection connection = new SqlConnection(connectionString);

//Open Connection

connection.Open();

//Create Sql Command call “sp_SaveUsers”

SqlCommand cmd = new SqlCommand();

cmd.Connection = connection;

cmd.CommandText = “INSERT INTO USERS (userId, userName) VALUES (?,?)”;

cmd.CommandType = System.Data.CommandType.TableDirect;

//Add Parameters for Stored Proc

cmd.Parameters.Add(u.ID);

cmd.Parameters.Add(u.Name);

//Execute Command

cmd.ExecuteNonQuery();

//Close connection

connection.Close();

}

Workaround: If you are going to write comments, specify the problem that your code solves, not how it solves it. Think of the last time you picked up a book at the store and read the back. Would you have wanted it to tell you what the story is about, or how the plot is laid out? If you change the implementation (bug, refactor, etc.), the comments can remain the same. Try and get away from code commenting all together by writing self-documenting code. For examples read Jeff Atwood’s Coding Without Comments.

3. Bloated Class

Enforce a limit to the number of classes allowed in the codebase. To reinforce this, place all logic into one big blob class.  With this class you are the ultimate tool that can do anything. The more classes you have, the more source files you maintain. More source files increase the compile time of your project.

Blob Class

Workaround: Follow the Single Responsibility Principle (SRP) to keep the implementation of your class specific to its’ purpose. Classes should only have one reason to change, and no other components of that class should be affected during that change.

4. Classes that are “involved”

The more that each class knows and relies on another class, the better your code is as a single unit. New developers will need to understand every class in your solution because one change creates a ripple effect throughout the system. Dependency hell is much nicer than it sounds.

dominos

Workaround: Develop code that is loosely coupled. Loosely coupled code is attained by making each class units that do not have knowledge of how other classes work. This creates more flexible design. Do not overkill as too much can lead to unneeded code complexity.

5. Developer Ego

The smarter a developer and the better coder that they believe they are, the better the code output. The only one capable of creating awesome code is one who looks at the world as one complex problem. Try to avoid breaking it down into simple smaller problems, otherwise any regular programmer is capable of doing your job.

Workaround: Give the developer the smack-down.

* DISCLAIMER * Please note that my views are that of the Workaround type method and this article is meant to prove humor at what can go wrong when unsafe practices are used. Also keep in mind, I’ve probably done each and one of these plenty of times in my career.

Categories: Series, Unmaintainable Code Tags:

Creating too Big to Fail Apps

April 1st, 2009 Josh 2 comments

I can’t help it. I read Steve’s post too big to fail on brip blap and I immediately apply its principle to life as a developer. The focus is about breaking down “too big to fail” life events into smaller more manageable components that are less likely to wreak havoc.

Too Big to Fail

How is this relevant to anything in the world of software development?

1. System Design

When designing systems, separate components by logic functionality. Systems that are responsible for continuous database queries, should not be tied to a web site that serves content, such as in Simulate a Windows Service using ASP.NET. While this idea may be good in theory and for any shared hosting environment when you can’t install or run services on the server, the potential that a deadlock or frozen thread occurs will increase. If that occurs, you can kiss all of your active user sessions goodbye.

2. Application Design

Separate application logic out so that when one component gets changed, it doesn’t force a complete rewrite. Websites and web services should not tie directly to the data layer. Design N-layer systems (read the differences between N-Tier and N-Layer applications) so that there are no direct dependencies on lower-level technologies being used.

Maintainability in separate components increases as the number of layers does. Take this in moderation though, too much loose-coupling in your layers, leads to overkill and needless complexity.

3. Class Design

When designing classes, follow the Single Responsibility Principle (SRP) of the S.O.L.I.D Class Design Principles. If your class has more than one reason to change, then it may be “too big to fail”. The below example helps:

public class Worker

{

    public string GetTaxRate() { }

    public void Save() { }

    public string GetId() { }

}

The above breaks the SRP because any minor change required to one of the three purposes of this class causes the whole class to change:

  1. The process to calculate the tax rate of the employee
  2. Database Schema that matches to the Worker
  3. Employee Id that is used. SSN today, numeric number tomorrow

Any single change impacts the class which is responsible for three very different purposes. While this is not “too big to fail”, the class is “too big for its own good”.

Categories: Development Tags:

Usability – Does it Exist or is it Just a ‘Theory’?

March 12th, 2009 Josh No comments

Have you ever heard a non-technical computer say that they are having computer problems whether it be viruses, pop-up porn ads, slowdowns, or network problems? Often they do not know where it came from. Hearing this have you immediately thought, “I never have any of those types of problems. This person must just not know how to use their computer.”?

As developers we don’t have these problems because we understand how a computer should work. We know what will get us into trouble and can easily identify warning signs. We also troubleshoot ourselves out of situations. In short, regardless of how usable the system, mentally we understand what needs to be done to get what we need.

Is this how it should work? Certainly not. We cannot take users for granted, hoping that they understand how to use our application. A user interface should handle system and application commands that a user wishes to run. If our users knew they had to call process A, click button B five times, and cache the response before the desired result would occur, there would be no need for usability (or us). Users would be smarter, and perfectly capable of troubleshooting their own bugs.

Such a perfect world does not exist and it is our responsibility to ensure that the software we release to our users doesn’t have any potential holes or pesky bugs in it. We must focus on making our applications more user friendly so that it is obvious when they perform an action that endangers their computer, or that those actions never occur in the first place. As developers how do we do that?


Usability Testing in Progress

Usability

So what can be done? Do we preach that usability testing is necessary before production? No. That music falls on deaf ears. Besides, who wants to give up valuable project time or money to test an application that is already behind? Even when usability testing is scheduled and performed, there is such a short amount of time left in the development schedule to fix any recommended changes.

My recommendation is that usability testing should come as an iterative and cyclical process throughout the development life cycle. It should not be considered usability, but instead usability development. Team members should be aware of it from the point requirements are defined to the point that the final piece of code is written.

This should be done by pushing the below responsibilities onto all team members:

  • Do not let anyone test their own code for the final round of testing
  • Concentrate on understanding the needs of users early
  • Perform early and continuous testing. This can be done through peer developer testing or lead developer testing core functionality
Categories: Development Tags:

Soft Coding

February 26th, 2009 Josh No comments

Do you know what is potentially worse than hard coding values into your source? Soft coding. Why? First a definition:

Soft coding is the act of writing code so that it depends on external settings such that behavior may change without updating the source.

The reason we hard code is because we are lazy and don’t know any better expect that given conditions will never change. Soft coding is born out of opposite reasons. Soft coding is intended to accommodates business rule units subject to change so that application modifications can occur without forcing code pushes or deployments. Soft coding is often seen in the form of configuration files.

Used cautiously soft coding can provide ways to make code become dynamic (switching logging formats, web service URLs, using reflection to create different business objects, etc.). When used in excess, soft coding complicates code by over-abstraction and develops into an anti-pattern.

<BizRuleEngine>

 <RedirectToImageProcessor>

  <if expression=inparameters[0] > inconditions[0]>

    <inparameters>size</inparameters>

    <inconditions>value</inconditions>

    <processor ref=BizRuleEngine.ImgProcessor, BizRuleEngine />

  </if>

 </RedirectToImageProcessor>

</BizRuleEngine>

Below are a few of the pitfalls that I’ve run into with soft coding:

  1. Increase of complexity: Developing dynamic code based on configuration values is essentially equal to writing another new language. The problem here is that we try to account for every possible scenario by making the code capable of doing things that will never be done. This results in spaghetti code and it just gets messy.
  2. Development complications: Code is written in an IDE because it can interpret the grammar and check for syntactical errors. Debugging is a breeze in most cases. Again, we are writing a new language and the problem is that we often don’t put as much time and effort into this portion of it. A lot of room is left open for loopholes and unaccounted conditions, while increasing the possibility that an unexpected exception will occur.
  3. End-user error: MY opinion is that this is a big issue for CMS sites. Developers spend lots of time building out the site, making it template based, and hand it over. The new owners then proceed to make content changes that bring the site to its knees.

The better your software is when produced, the less customization it will really need and the less users will find that they wish to change it.

Categories: Development Tags: ,

Specialist vs. Jack of All Trades

February 12th, 2009 Josh No comments

Do you focus on the details necessary to complete a task, or do you dwell on end results and overlook implementation details needed to achieve? Are you big picture or little picture?

Little Stone Carrying Big StoneI believe that the big picture people will inevitably rise above the smaller more detail-oriented picture people. This view does not state that the little picture people will fall off the face of the earth as the big picture people rise to power, but instead represents it as a yin-yang relationship in which one cannot be successful without the other.

This analogy can apply to almost anywhere, but for now put it in perspective of people trying to determine their career path, specifically in the technology industry. At this point in my life I am an impressionable, eager developer, faced with a difficult decision:

Should I become a Technology Specialist or a Jack of All Trades?

Do I want to put forth all my efforts into a specific product or do I want to step back a level and just understand a little about it and let the experts take care of all the nitty-gritty details?

I choose this example because I cannot see a path that says one of these is better than the other. I believe the decision to be made is a decision that no one can make but you. As a developer are you really interested in being an e-commerce, AJAX, or CMS “go-to” guy? Or, are you more interested in understanding most of the strong (and weak) points of many different product lines and knowing enough to be dangerous in any scenario?

Employers have use for both types of people. There is a time and a place. When business is booming and there is money to throw at the problem, bring in the specialist (and pay more). They are the sharpest tool in the shed and the one who will crank out the quality solution as fast as possible. Reverse that situation and do some budget cuts, lay off employees, and we find that a company can’t afford to pay as many specialists. They can pay our jack of all trades the salary of one person, and pile on the workload (of many people) for the same price. Do you see the trade-off?

I’ve made my decision. Up until a few months ago, I wanted to be a jack of all trades until I realized that choice lacked some opportunities available only to specialists. After further thought, I have settled on jack of all trades master of some. As to what that “master of some” will be, I do not yet know. Time will determine that.

On another note, this may be going against the other author’s post, but I believe that we must all show a bit more humility and acknowledge that even though we think we are big picture there is always a bigger fish in the sea that is more bigger picture and depends on us to implement the details.

The Reverse of Job Security

January 29th, 2009 Josh No comments

During times like these, why should I give up my responsibilities and throw away any job security that I have?

Job security should not be because you are the only one capable of performing fixer-upper tasks or upgrading a legacy system.

Job security should mean the company views you as an irreplaceable asset. If job security were based on your responsibility of maintaing an application or system, how are you ever able to grow and take on new projects?

Imprisoned

As a consultant, I ended up in this scenario because the responsibility of the developed system was left completely in the hands of contractors. Any full time employees who were previously involved left the company. When I was the last contractor on the project and ready to start another gig, upper management discovered that there were no internal developers with knowledge of the system that was built. I became irreplaceable, but not because of my abilities. I and the upper management team failed to ensure that other developers understood the system. No one had the confidence that they would be able to maintain it should something go wrong. As a result, this hurt me by preventing me to take on additional work opportunities and start on other projects.

Unfortunately we cannot always depend on management to take care of spreading knowledge around to other teams as that requires more resources to schedule on their part. The key here is spreading the knowledge by taking initiative. Invite other developers, junior ones specifically, in to your circle and educate. Question them and teach them. Tell them you are doing this so you can move on they gain a more well-rounded view of different application designs and roles. Make it sound interesting. Don’t pass on what you did right about the system. Pass on what is wrong with the system and what you would have done different so that they learn from your mistakes.

Categories: Professionals Tags: ,

Over Complicating Your Job

January 15th, 2009 Josh 1 comment

Elaborating a bit more on my last post on dealing with poorly designed applications, as developers we often find ourselves in sticky situations where it consumes more time to fix something that should take little to no effort at all. I will be the first to admit that I have caused my own fair share of these problems.

Transformer

Below are some of the most trivial solutions that I’ve collected from my own experience and samples that I’ve read. These can be fixed by better development and coding standards:

1. Over Designing

Ever meet someone too smart for their own good? There is a fine line that smart people often cross when writing code. Once this line is crossed, the code they produce becomes an inversion of their intelligence. You can identify this when they constantly refactor code that you’ve written to be more efficient, dynamic, generic, and re-usable. I’ve seen developers try to make .NET generics generic.

public class BaseGenericWrapper<T> : IGeneric

{

 

}

Please do not invent something that will synergize the evolution of social networking when all you need to do is build a blog. Yes, some things are prone to change (content, configuration variables) so don’t hard code those. At the same time, if your team is the only one using the application and are expected to maintain it, then make the solution straight-forward and simple. They will thank you after they make an emergency fix.

2. Code Complexity

Nothing can be worse than a lack of unit tests when making modifications or upgrades to someone else’s code. With poorly written code, it is difficult to determine if the change being made will break anything or not. Even worse, is the change that has to take place in the spaghetti function that has 800 lines of code in it. One line gets changed and it seems as though you just witnessed the program in self-destruct mode.

Maybe an analogy will help here:
If I were asked to find my keys in my own house, I would have an idea where to look. The kitchen, the bowl by the front door, etc.. This is because it is my house and I am most familiar with it. Now imagine I asked you to find some keys in my house. Where would you start? Would you start looking for a utility bowl that said “keys” on it, would you look in drawers throughout the kitchen, pockets in a coat?

Sometimes our code closets are left in a state of disarray for someone else to take care of. When they need to change something, do they know where to look? Is your code clean and self-descriptive so that they can easily understand what each function does to prevent a change in the wrong place?

3. Over Commenting

As a student going through school, we were taught to comment our code. I was told to provide pre-conditions and post-conditions as well as a summary and a description of every parameter to all public/private/internal methods. You’ve seen it happen and I’ve seen it happen, another developer (or yourself) comes along and makes changes to the way the code works, adds a variable or a parameter or two, and then doesn’t update the comments. At that point our entire easy code universe is out of sync.

What about saving yourself the time and instead of writing code that requires comments to explain how it works, you write code that is completely legible and flows together so that it requires no additional comments? Take a look at this snippet that I grabbed from Jeff Atwood’s Coding Without Comments and you’ll be able to see what I mean.

This:

r = n / 2;

while (Math.Abs(r – (n / r)) > t)

{

    r = 0.5 * (r + (n / r));

}

Console.WriteLine(“r = “ + r);

becomes this with a comment:

//square root of n with Newton-Raphson approximation

r = n / 2;

while (Math.Abs(r – (n / r)) > t)

{

    r = 0.5 * (r + (n / r));

}

Console.WriteLine(“r = “ + r);

and can be simplified to this:

private double SquareRootApproximation(int n)

{

    int r = n / 2;

    while (Math.Abs(r – (n / r)) > t)

    {

        r = 0.5 * (r + (n/r));

    }

    return r;

}

See how much easier it is to understand? I don’t have to understand that that the complex code calculates a square root since the method name explicitly states it.

Having said these points, there are many things that you can do to simplify code and make it more developer friendly. Be careful not to waste too much time breaking code down and finding re-usable solutions. I’ve walked my self into many a corner trying to come up with creative ways from having to write a ton of GUI code and handle dynamic layouts. Just keep it simple and the code will speak for itself.

Do you have any tips for keeping code simple and straight to the point?
How do you feel about the way that our developers that come straight out of school code? Are they taught properly?

Categories: Development Tags:

Dealing with a Poorly Designed Application

January 1st, 2009 Josh No comments

Auto Mechanic: Sir, I’ve replaced the spark plug on your car.
Customer (sarcastically): What’s the damage?
Auto Mechanic: $600.
Customer: $600?!!!! How? It was just a simple fix!
Auto Mechanic: In theory, it should have been. But the way the engine was built and the placement of the plug made it very difficult to fix. We had to tear half of the front end off in order to get at it.

Unintelligent Design

I hope this never occurs to any of you, but it definitely puts the problem of inheriting a poorly written/design application into perspective. “If only things had been done right the first time, changing it would be so much easier”. How many times have you heard that mantra? Hindsight is 20/20. We should focus on how we deal with these messy situations instead of complaining about them. Here are a couple thoughts:

1. Relax, look around, and determine what is going on.
Before you go haywire on your project manager and threaten to quit the company, put a positive spin on it. Remember you were asked to be the expert and fix someone else’s mistake. Make sure you really determine what the problem is. Is the problem the fact that this was written poorly, or is the problem because you have to maintain it?

2. Recognize what you can change.
If the application that you were asked to fix is completely abysmal, make sure that you don’t dig yourself into a deeper hole. You obviously don’t want to work on this application longer than necessary (unless you are a glutton for punishment). At the same time, question why things were done the way they were. Reasons may have been entirely political and you may have absolutely no control over design. Don’t focus on those scenarios, focus on situations where you can help the next developer who needs to fix this.

3. Make sure you know what you are talking about
.
Ensure that this is a poorly written application because it uses bad design methodologies, not because someone else wrote it. In explaining the problem to your peers and other developers, avoid a negative attitude. They are just going to see you as someone who complains, not someone who solves problems. When solving the problem, don’t create change for the sake of it or because you think you can do it better. The time for design has passed, this is development. Unless you were asked to do a rewrite, do a fix.

4. Lose your fear.

If you’ve got the last point down and you know what you are talking about, lose your fear. Dive right in. Express what is incorrect with the application to managers and see how they respond with it.

5. Get away from it.

I solve my most difficult problems away from the computer. Sometimes it happens at home, sometimes during dinner, and even in the shower. You know the deal. If it isn’t an urgent production issue, give yourself a 24 hour mental break. Think about something else. This answer will come to you tomorrow and you will laugh that the solution is not as complex as you expected. 

6. Attack it in units
.
Don’t bulldoze the whole project. Take notice of the systems’ components and break the problems down into smaller units. Ask yourself how you can make these pieces perform more efficient. If you can’t get any more juice out of it, then make the code more readable and understandable. As you further break the code down into individual methods and components you can create unit tests to ensure that each portion is acting as intended. This will benefit future developers so that they can easily make changes and ensure that they aren’t breaking existing functionality.

7. Use this as an opportunity to educate others!
Always come away from every experience with something you have learned. It may be something you learned not to do, but either way you know better. I will repeat, hindsight is 20/20. Use it as the chance to help others know better too. Find a junior level developer and challenge them. Ask them what they think the problem is and see if they are capable of producing a better solution.

I read somewhere, developers have a high tolerance for working with ugly code (as long as they were the one who wrote it). No one wants to openly admit that they created a code catastrophe. However, really what we should do when we write code is not put others in harms’ way like we have been. In order to do that, we should make sure that the code we write can be broken down into as many chunks as possible. Complex problems require simple solutions. There is always the developer with an ego problem who tends to believe the opposite. They think that complex problems require tricky coding. Sometimes those developers are so concerned for writing a generic solution to the problem that they go above and beyond what the requirements ask for and in the end make it more difficult to troubleshoot or fix the problem.

Categories: Development Tags:

Shout Out: SecurePaste

July 22nd, 2008 Josh No comments

I’m referring to the original SecurePaste application created by Jason Fayling. SecurePaste is a nifty application that allows developers to paste large documents (preferably source code) to each other and access it via URL. Amazingly simple idea, like I said, just make sure that you use the original one linked here in the post.

Categories: Shout Out Tags: