Sunday, January 27, 2013

Correctness, Clarity, and Changeability

I have a strong personal drive is improve my productivity as a software developer. Consequently I do a fair bit of reading and thinking about how individuals and teams create good software. Since this is a baby blog I figure it might be a good idea to start by exploring some of my ideas about what "good software" looks like.

Like any other human endeavor, software development is kind of messy. We don't communicate well; we make mistakes every day; we are horrible at predicting the future; we make irrational and imperfect decisions. But we still manage to succeed, and occasionally we succeed brilliantly. Developers who are the most effective -- who succeed brilliantly -- have learned how to become really good at creating good software.

So what does good software look like, from the perspective of a software developer? There are a lot of "right" answers to this. One that I've come up with and like is in the title of this post, and yes, I came up with those three words because I like alliteration. Good software has the attributes of correctness, clarity, and changeability.

Correctness means satisfying the needs of the customer. If it doesn't do what the customer wants and needs, it isn't correct. In development-speak, this means the software satisfies the functional and non-functional requirements. Functional requirements are the 'what' of the software; the features I can use. Non-functional requirements are 'qualities' of the software; things like security and performance and robustness and availability and usability. Correctness is subjective, which is why there is often a lot of (sometimes heated) discussion among stakeholders about whether some program ought to have fewer bugs, or have more features, or be more usable, or be more responsive.

Clarity means the code, build scripts, shell scripts, database queries and scripts, internal documentation, configuration files, and other bits necessary to create a piece of software are as easy to understand as possible. The source should be self-documenting and well-organized, so that its behavior and purpose are obvious. Self-documenting code is obvious in its intent. It's characterized by meaningful names; by constants instead of magic numbers. Self-documenting code makes it easy to answer the question, "What does this code do?" Well-organized code makes it easy to answer the question, "Where is the code that ...?" The package (namespace) structure is clear; classes in each package are closely associated; structural and behavioral associations and dependencies are easy to find. The overall project structure makes it easy to find all of the code, scripts, configuration files, etc. that need to be changed in order to implement a feature.

Changeable means that the software is as easy to change as possible. Implementing new features and refactoring to support new requirements should require a minimum of effort. Good design and a solid test suite go hand in hand with changeable software. Good design makes it easy to make changes and still have the system compile. A good test suite makes it easy to make changes and still have the program work correctly. Use good design principles like DRY and GRASP and SOLID, and write good unit tests, and you'll have code that is easier to modify.

So how do we create software that is correct, clear, and changeable? The best answer I have found is in the principles of agile development. Agile development allows a team to be effective and productive over time. Or to put it another way, agile methods lead to software that is correct, clear, and changeable.


Thursday, January 17, 2013

Configuring SSH to Disable Host Key Checking

I often use scp to copy files between Linux/Windows systems, and ssh to remotely log in. In our work environment, we frequently redeploy new virtual machine ISOs. This causes scp and ssh to complain because the host's key has changed. Following the steps at I found at Linux Commando, here is how to configure SSH to disable the standard check for keys. NOTE: This can prevent SSH from detecting a real man-in-the-middle attack, so use with caution. I have configured this to only work with internal IP's. There are two ways to do this. The once-only way is from the command line:
$ ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
This tells ssh to use /dev/null for the known_hosts file, and to not use strict host key checking. For a more permanent way, put the following into the beginning of your ~/.ssh/config:
Host 192.168.*
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
(In my case 192.168.* refers to the internal network. Your environment may be different.)

This works on both Linux and Cygwin.