Wednesday, August 27, 2008
"As a user, I can select my preferences and save them



so that the program will do the right thing."

ahem...

Sometimes we in the software business need to realize that the people using our software are not experts in the field. We must become experts at understanding the requirements and implications of the domain for which we write software, but we can not expect our users to do the same. We must be able to make some decisions with the software so that it does the "right thing" for the user. In today's world, software users have little time to fiddle with settings or options. They just need the software to do a job for them and do it the right way the first time. Our impatient "get it now" society of users definitely has this attitude. If our software doesn't do what they need it to do, they will more likely abandon it for something else before attempting to fiddle with settings, parameters, options, and preferences.

Our product owners need to be keenly aware of this attitude, and get the balance right with the features and stories that the customer base needs. While this is not an easy task, it is a very important one. As our software gets smarter and smarter, it should be more aware of what the user is attempting to accomplish, and it should make some decisions and assumptions based on the mode of intent. In addition (here is the key point missing from most software today) we need to *tell* the user what the mode is, and what the assumptions are. If we got it wrong, or the user wanted something else, then s/he has the opportunity to change the operating mode before the software attempts to do the "wrong" thing.

A "mode" could be an entire slate of preference settings, that come packaged out of the box with the defaults set for performing a specific task, or scenario. This entire slate could be modified if the user is advanced and cares to fiddle with them, but having the entire slate saved as a set, that could be chosen as a very simple selection. Then, always make it clear what the system operating mode is, and how to change it.

Keep it simple by being smart about what the user is trying to accomplish and make some decisions. Select the most appropriate mode, then - most importantly - communicate those decisions to the user, and let them know what the software is assuming about the task they are trying to perform. Give the user choices about how to control the software, and change its mode, but keep the goal to be helping the user stay more focused on performing the task at hand.
Wednesday, August 27, 2008 5:00:11 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, July 18, 2008
I have heard a lot of discussion lately about the use of the "#region" directive in C#. There are various camps (some religious) on this topic, so let me throw in my twopence.

Many developers like to use regions to collapse sections of the code because it makes it easier for them to focus on a particular section. That's nice.

If there is that much code in a single file (which *should* be only ONE class), then there is probably too much code in that class. Class design should be focused on one specific thing. According to good OO principles, classes should be autonomous, and do one specific thing. Classes should be intelligent groupings for functionality relating to a specific, focused purpose. The use of the region to group code bits together in a file is a good indication that there is probably too much code.

Simplicity is a highly desired principle in software development. It's the simplest thing that gets the kudos, not the most complicated. Developers who try to write complex, convoluted code so that they can look good to their peers are really doing the opposite. Added complexity is very costly, in time for other people to understand it, debug it, and maintain it.

Here are some ways to determine some code smells in this area.

  • Do methods have more than 25 lines of code? If so they are probably too big - this is a code smell.
  • Do classes have more than 12 methods? If so, this may be another code smell. Classes that have lots of methods probably are doing too much. See if they can be broken out into more focused pieces.
  • Are there more than 3 constructors? Sometimes a lot of constructors could be a code smell indicating using a class for different things in different places.
Anyone else have any metrics that they use? Please respond with comments below.

These kinds of things should be completely discussed on a team, and woven into working agreements, and coding standards guidelines. Teams that work within these are the most productive because everyone is on the same page and playing by the same set of rules. If your team doesn't have a guideline for these kinds of things, I would encourage you to write one up today and get input from your team.
Design | Team
Friday, July 18, 2008 8:19:59 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, July 10, 2008
First off, let's get something out in the open. As an agile software developer, I have a couple of strongly held beliefs.

Design isn't optional.
Architecture isn't optional.

DTSTTCPW doesn't mean "no up-front design, we'll just wing it." [That's DO THE SIMPLEST THING THAT COULD POSSIBLY WORK for all y'all who don't speak acronym.]

When we fail to refactor our new code into the existing code, we get odd bits of functionality that stick out from the existing design like warts on a bowling ball. The idea behind refactoring is that we intend to make sure that we *always* have a round ball. Refactor doesn't mean just change a signature or two. Sometimes it means we need to go back to the design white board and figure out what we need to have *now* given the current functionality requirements. We almost always need to change the existing code's design and integrate the new code so that all appears cohesive, each and every time we write new code. Iterative development doesn't intend that we make a bunch of atomic changes and just glue them together.

Code design at each check-in should be able to withstand scrutiny of any outside reviewer, and the design should be up to engineering standards. We still call it software *engineering* not software *art*. Many teams I see are missing this point completely and are producing code that should have been re-designed rather than just having new code glued on. With each check-in we should be able to look over our classes and functionality and say, "yes, this is something that would withstand the scrutiny of a code reviewer not on my team, without excuses or explanation." If I have to couch it and say "well, we will be fixing that in the next release" or "we'll revise that in a later check-in" this is technical debt, and therefore a process smell. Developers that are stuck in this rut need to be re-trained that they aren't "done" with the code until it is production-quality.

If there are warts on your software, this is a very loud process smell, and it should be addressed directly. Make sure that the team understands that this is not an acceptable way to work on an agile team. Re-design in refactoring and adding new code should be common, and discussed among the team after the stand-up meeting daily. "Yesterday I re-factored and re-engineered the Widget classes, so that they now have the new functionality we need in story XXX and are more streamlined to what we are delivering this sprint. Today I plan to have a half-hour review with the team so everyone is on the same page with the re-design. Then I will incorporate all the feedback, get the final code reviewed and coordinate the check-in with the rest of the team to make sure I don't block anyone. I'll make the appointment for the review with everyone after the stand-up."

Make sure that everyone understands that the code as a whole should be well-designed at each commit point, and that this isn't optional. It needs to be expected behavior on the team. This also means that estimation of effort may (and should) go up, for complexity on tasks in both story points and hours. We don't look at revising design as "additional work" just like we don't view unit tests as "additional work." These things are both fundamental parts of the iterative process. Without adhering to these principles, iterative development just won't work, and we might as well go back to waterfall.

If your team has the process smell of needing to budget additional work for refactoring the design, perhaps it's time to go to the team and discuss what Agile software development really means, and that it doesn't mean lower-engineering quality software.

Thursday, July 10, 2008 7:18:51 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |  Trackback