Monday, November 30, 2009

97 Things Every Project Manager Should Know


I have now finished reading each book within the 97 series:


As expected, most topics within this book emphasized the importance of communication and people. Barbee Davis, the author of the book also has a 60-minute Webcast about this book that you may be interested in if you can not get your hands on the book.

My Favorite Tips:

  • Success Is Always Measured in Business Value (Page 36) by Barbee Davis
    • Favorite Quote:
      "We need to focus on the fact that the project is only as successful as the business value it adds to the organization."

    • Key Message:
      It is extremely important that everyone involved on the project is aware of the business value the project will deliver. This will clarify the project objective and it allows the team to focus on a single team goal. Most developers focus on code quality, good design principles, and code maintenance. While all of those attributes are valuable, none is more important than the business value that your team ultimately delivers for your customer.

  • Value Results, Not Just Effort (Page 58) by Venkat Subramaniam
    • Favorite Quote:
      "Encourage programmers to report the progress they make, rather than how long they work. Let them know that you care about getting results rather than keeping track of how long they spent at the computer."

    • Key Message:
      We typically track effort because it is the simpler of the two metrics to calculate. The time sheet will show effort. Alternatively, results will require a calculation of hours worked and velocity. Ultimately, the focus must be on maximizing velocity and not just effort.

  • Developer Productivity: Skilled Versus Average (Page 26) by Neal Ford
    • Favorite Quote:
      "Understand that really good software developers are much more productive than average ones. In fact, some statistics say that really good developers are multiple orders of magnitude better than poor ones."

    • Key Message:
      Dave Thomas gave a similar talk about this topic in 2003. Continuous learning is the key point within this post. Combined with the right tools and knowledge you will see greater efficiency gains on your projects. The real challenge is allocating time to focus on your continuous learning efforts.

  • Provide Regular Time to Focus (Page 40) by James Leigh
    • Favorite Quote:
      "Typically, a person takes about 20 minutes to regain his train of thought after one of these interruptions. A 5-minute question actually costs 25 minutes. Interruptions and recovery time consume 28% of a typical knowledge worker's day."

    • Key Message:
      Interruptions are not going away. In fact, actually responding to questions and attending meetings will improve productivity for others within the team. What's the solution to the interruption problem? There is no ideal solution to this problem. However, if you provide good documentation, training, and education, interruptions should be diminished. If you still find that distractions are an occurrence, try working several hours outside of core hours. There will be fewer interruptions outside core hours. While interruptions will not go away, you can configure your daily schedule to find more ideal focus time.

  • Add Talents, Not Skills, to Your Team (Page 14) by Richard Sheridan
    • Favorite Quote:
      "My advice to anyone seeking to build a strong team is to hire for talents, not for skills. What talents do I look for when hiring technologists for my development teams? Good kindergarten skills:"

    • Key Message:
      This tip changed the way thought about hiring. I was a believer in tech skills first and team skills second. Tech skills can be learned relatively quickly. The same can not always be said about team skills.

Friday, October 30, 2009

97 Things Every Programmer Should Know



The 97 series now consists of the following titles:

The architect book was very good. The programming topics were also good but I found more value within the architecture discussions. I definitely want to get my hands on the project management book soon. I have a feeling that one will be a bit more humorous.


My Favorite Things Programmers Should Know:

  • The Professional Programmer by Uncle Bob
    • Favorite Quote:
      "Professionals are responsible. They take responsibility for their own careers. They take responsibility for making sure their code works properly. They take responsibility for the quality of their workmanship. They do not abandon their principles when deadlines loom. Indeed, when the pressure mounts, professionals hold ever tighter to the disciplines they know are right".

    • Key Message:
      This post was unquestionably at the top of the my list. The entire message is about personal responsibility. This one's a wall hanger. Print it out, frame it, and hang it up! This post reminded me of the talk I heard Dave Thomas give many years ago at No Fluff Just Stuff.


  • Don't Rely on "Magic Happens Here" by Alan Griffiths
    • Favorite Quote:
      "You don't have to understand all the magic that makes your project work, but it doesn't hurt to understand some of it — or to appreciate someone who understands the bits you don't."

    • Key Message:
      Can you fulfill the roles of every individual on your last project? Image how valuable you'd be if you could. Again, the more knowledge you have, the more efficient you and your project will be.


  • Hard Work Does not Pay off by Olve Maudal
    • Favorite Quote:
      "programming and software development as a whole involve a continuous learning process."

    • Key Message:
      Continuous learning is the key point within this post. Combined with the right tools and knowledge you will see greater efficiency gains on your projects. The real challenge is allocating time to focus on your continuous learning efforts.


  • First Write, Second Copy, third Refactor by Mario Fusco
    • Favorite Quote:
      "So the first time you are implementing something new, write it in the most readable, plain, and effective way. It is definitely too early to put the general part of your algorithm in an abstract class and move its specialization to the concrete one or to employ any other generalization pattern".

      "The second time you face a problem that resembles the one you solved before, the temptation to refactor that first implementation in order to accommodate both these needs is even stronger. But it may still be too early. It may be a better idea to resist that temptation and do the quickest, safest, and easiest thing it comes you in mind: Copy your first implementation".

      "When you need that solution for the third time, even if to satisfy a slightly different requirement, the time is right to put your brain to work and look for a general solution that elegantly solves all your three problems. Now you are using that algorithm in three different places and for three different purposes, so you can easily isolate its core and make it usable for all three cases".


    • Key Message:
      The Rule of Three also applies for reuseability. For example, in order for a solution to be classified as a design pattern the rule of three must apply. If you can successfully apply the same pattern across three separate systems you have a design pattern. Furthermore, this rule also applies to API design. If your API can successfully be consumed by three separate clients, you have a very concrete and proven design. Applying the Rule of Three for shared services or libraries is also valuable.

Wednesday, September 30, 2009

YUI to the rescue

Are you still rolling your own HTML user interface components? If you are, take a look at what YUI has to offer. The advantages of leveraging YUI's standard components are abundant.

YUI Advantages:

  • Saves cost on development effort. The suite of controls are already developed and tested. This allows your team to work on more valuable tasks.
  • Excellent performance. YUI has adopted many of the great performance improvement practices that were identified in Best Practices for Speeding Up Your Web Site. Several of the performance improvements include:
    • Minified JavaScript and CSS files. This will improve page load performance with smaller files to download.
    • Aggregated or rolled-up JavaScript and CSS files. This will improve page load performance with fewer HTTP requests.
    • Yahoo will host the files on their own Content Delivery Network. In addition, Yahoo will compress and cache all of their controls for even greater performance. They also manage versioning.
  • Components are supported across all A-Grade browsers
  • Helps non-UI experts design beautiful user interfaces. Yahoo provides the design and CSS layout for all of their components.
  • 508 compliant. All components are screen reader accessible.
  • All components already have extensive documentation with many examples.
  • Reusable. You can apply the YUI controls everywhere because they are not proprietary.
  • Technology agnostic. These controls can be applied across all Web environments regardless of technology (Java, .NET, Rails, etc.).
  • Support many features that allow you to change behavior without customizing the code.
  • Thier code is clean. I validated their JavaScript with JSLint and few errors were reported. I also validated their CSS files and no major issues existed either.


YUI Disadvantages:

  • Some controls are not bullet proof. For example, there is a sorting issue with their datatable control if you embed the component within a table. However, this is not an issue if you are working in a CSS based design.
  • They do not have everything but the list is extensive.


Recommendations:

  • Try to avoid customizations. Customizing the code will make it difficult to migrate to newer versions in the future.

Monday, August 31, 2009

Preventing Buffer Overflow Attacks

Is your website resilient enough to withstand a buffer overflow attack? A buffer overflow attack is actually one of the simpler attacks a malicious user may attempt. Imagine the following scenario. You have a public facing web page that allows unauthorized users to submit data. A malicious user probes your site to see if you have exposed this vulnerability. If your site is at risk, it may only take minutes for the user to bring your site down if they employ a botnet attack.

The Attack

  • The simplest attack method is for malicious users to throw overloading (2GB - 8GB) amounts of data in a text field in hopes of crashing the server due to out of memory errors.


The Prevention

  • Bounds checking on the server-side is the most effective solution for preventing buffer overflows. For example, if you are using Spring's annotation-based validation this is all you would need:

    /**
    *
    * Spring's annotation reference documentation
    * Configuration setup example
    */
    public class Student {

    @NotBlank
    @Length(max = 50)
    private String firstName;

    @Length(min = 1, max = 50)
    private String lastName;

    }


    HTML's maxlength attribute is NOT sufficient:
    <input type="text" name="firstName" maxlength="50" />
    This is not secure because there are tools that will enable users to bypass this HTML tier of validation. You must perform max length validation on the server-side as in the example above.
  • Leverage the bulkhead stability pattern to decouple your authenticated business critical applications from your publicly exposed (more vulnerable) applications. The goal of this pattern is to preserve the stability for a particular group of customers. Most software attacks are targeted at publicly available web sites. You should leverage this pattern if you want to help preserve the stability of your authenticated users during an attack on your publicly available sites.
  • Prefer to keep public data out of session. This simple solution will help preserve memory if a user attempts a buffer overflow attack.

Friday, July 31, 2009

JavaScript Singletons

JavaScript singletons are relatively simple to create. With two additional characters you can define your object as a singleton. I'll show how this is accomplished in a moment. In my prior JavaScript post I talked about why the module pattern was preferred for creating objects. Those objects were prototype-based and multiple instances were allowed. The following examples illustrate the preferred way to create singletons with the Module pattern. This should be your preferred creational pattern for creating JavaScript singletons.

Singleton Pattern Example #1:

/*
* Singleton counter example.
*/

var mySingletonCounter = function() {

/* private, static variables */
var count = 0;

return {
/* public methods */
increment: function (inc) {
alert('Adding ' + inc + ' to count.');
count += inc;
},

getCount: function() {
alert('The current count is ' + count);
return count;
}
};
}(); // <- These two parentheses define the object as a singleton. It assigns the result of invoking this function to mySingletonCounter.


To exercise the singleton, the button below will execute the following code:

mySingletonCounter.increment(2); mySingletonCounter.getCount();
Run Singleton Counter



Singleton Pattern Example #2:

/*
* Singleton data access example.
*/

var mySingletonData = function() {

/* private, static variables */
var data = {
1: "Harry Potter and the Philosopher's Stone",
2: "Harry Potter and the Chamber of Secrets",
3: "Harry Potter and the Prisoner of Azkaban"
};

return {
/* public methods */
getData: function() {
return data;
}
};
}();


Reference the singleton object in the following manner:

mySingletonData.getData()[2];
Run Singleton Data



Advantages:

  • It is extremely simple to declare a JavaScript object as a singleton. More dynamic languages are focusing on simplicity. For example, Groovy has recently provided the @Singleton transformation to simplify Singleton creation.
  • Improved run-time performance vs the prototype-based creational pattern.
  • You still leverage all the advantages that the module pattern provides.

Saturday, June 27, 2009

Agile: A requirements change is a competitive advantage

At what point in the lifecycle should requirements be locked down?
  1. Before development begins
  2. Never
  3. Somewhere in between

Most developers will immediately choose "Before development begins" for simplicity. However, if you work in an agile environment that responds well to change then there are many advantages to "Never".

Advantages of Changing Requirements

  • Changing requirements will improve the product and should give you a competitive advantage.
  • Changing requirements will evaluate the efficiencies of your development, QA, and deployment processes. Highly effective or agile teams will deliver the new requirement relatively pain-free.
  • Changing requirements encourage automation throughout the lifecycle. The important factor here is that it encourages automation across all departments (development, QA, deployment). The following attributes must exist within each department for this strategy to be successful:

    • Development:
      • Automated JUnit tests - frequent changes must be tested efficiently.
      • Continuous Integration - frequent changes require stable environments.
      • Code reviews - This knowledge transfer session will give your team the flexibility of having anyone work any task more efficiently.

    • QA:
      • Automated regression tests - frequent changes must be tested efficiently.

    • Deployment:
      • Automated deployment scripts - simplify and more accurately deploy the changed release modules.

  • Software must be delivered faster so the customer's can identify the change points sooner in the lifecycle. The goal is to deliver testable software quicker. How many of you deliver testable code after iteration one? How many of you have customer demos of working software after iteration one? The goal is to identify changes sooner in the lifecycle and this will help minimize the risk of failing to meet your production delivery date.

Disadvantages of Changing Requirements

  • Changing requirements may delay the project. This is where the debate typically begins. However, if you initially plan for some percentage of change you should be fine. Identifying change early in the lifecycle will also help remedy the impact.

The Hybrid Example

Which auto makers were most successful with their hybrid initiatives? It was the automakers that adopted lean/agile practices many years ago. The automakers that did not change soon enough are now scrambling to recover. Changing requirements can have a huge competitive advantage if your environment responds well to change. A key attribute of being agile is adapting to change.

Thursday, May 7, 2009

JavaScript: The Good Parts


What's the most popular functional language? JavaScript is. And if you are interested in learning the finer points of the language I recommend Douglas Crockford's latest book titled JavaScript: The Good Parts. It is a very quick read at only 145 pages! The most valuable lesson I learned from the book was the correct way to create JavaScript objects with the Module Pattern. The following examples illustrate the Module pattern. This creational pattern leverages closure to achieve encapsulation, information hiding, and global safety. No other JavaScript creational pattern provides these capabilities. This should be your preferred creational pattern in JavaScript.

Module Pattern Examples:

/**
* A search module that provides the ability to search by name.
*/

var search = function (criteria) {
/* private variables */
var name = criteria.name;

/* private methods */
var renderResponse = function() {
alert('rendering response for: ' + name);
};

/* return our public API methods */
return {
execute: function() {
alert('searching for: ' + name); // Perform an AJAX search
renderResponse(); // Perform renderResponse as part of the AJAX callback.
}
};
};


Instantiate a new search object:
search({'name':'Johnny'}).execute();

Run search example


Alternatively, if you prefer to return your public API methods via assignment you may find this example to be simpler:

var search = function (criteria) {
/* private variables */
var that = {};
var name = criteria.name;

/* private methods */
var renderResponse = function() {
alert('rendering response for: ' + name);
};

/* Assign public API methods to that. */
that.execute = function () {
alert('searching for: ' + name); // Perform an AJAX search
renderResponse(); // Perform renderResponse as part of the AJAX callback.
}

return that; // return by assignment example.
};


Module Pattern Advantages

  • Improved encapsulation. For example, if the renderResponse functionality is only pertinent to search, we can encapsulate that behavior within the search object.
  • Better information hiding. No consumers of the search module will be able to call renderResponse directly because it is private.
  • The objects are global-safe. You will not see any references to the this keyword anywhere. This will eliminate any possibility of altering global variables.
  • Requires less effort than other creational patterns (pseudoclassical pattern, Object.create pattern).


JavaScript Resources:

  • JavaScript: The Good Parts presentation from the Google Code Blog.
  • In particular, I found the following sections within JavaScript: The Good Parts to be most valuable for me. These mere ten pages of content were worth the cost of the book!:
    • Chapter 4 (Functions):
      • Closure
      • Module
    • Chapter 5 (Inheritance):
      • Functional
  • JSLint: an excellent tool for code quality analysis.
  • Doug Crockford has at least eight JavaScript presentations available at YUI theatre


Monday, April 20, 2009

Kanban: The Good Parts

Kanban Estimates

Struggling with those developer estimates? If you are, you may want to give Kanban's estimation practice a try. The Kanban methodology almost entirely eliminates the estimation process. Instead of using formal planning and estimation all features have approximately the same size. Hours that were previously burnt estimating are actually spent delivering software. When compared to the Scrum estimation model, this style of estimation is very lean.

Advantages:
  • Hours previously spent estimating are spent delivering software.
  • The focus is on delivering software more rapidly vs focusing on when the software will be delivered.
  • Does not invest heavily in a metric that is not scientific or always accurate.
Disadvantages:
  • High level estimates are still necessary for resource planning.

Kanban Stand ups

Unlike Scrum stand ups where each individual answers the three magical questions of: what did I do yesterday, what am I doing today, and what issues do I have. Kanban focuses exclusively on issues. For example, the global question now becomes: Does anyone have any issues?

Advantages:
  • Quicker stand ups.
  • The stand up scales better for larger teams.
  • Issues are the main focus.
Disadvantages:
  • May lose visibility of what each member is working on.

Resources

Monday, April 6, 2009

Secure Computing: Preventing Cross Site Scripting (XSS)

XSS prevention cheat sheet

The best strategies for preventing Cross Site Scripting can be found in OWASP's XSS prevention cheat sheet. Several important notes include:
  • You MUST use the escape syntax for the part of the HTML document you're putting untrusted data into. There is no single escape function that can be applied for all output contexts (HTML, CSS, JavaScript). ESAPI has an API that provides encoding rules for a particular output context. Refer to the OWASP's prevention rules for more details.
  • It is impossible to secure a JavaScript context with escaping. This is an important note because there is no defense to this scenario except to eliminate the output of dynamic content within your JavaScript context entirely.

XSS and JSTL

JSTL used appropriately will protect you from an XSS attack within your HTML context. For example, this a valid JSTL solution:
<%-- XSS safe --%>
<c:out value="${untrusted_data}" escapeXml="true" />
By default, the excapeXml attribute is "true" within the out tag so you don't have to explicitly declare it.

The JSTL expression language alone will NOT protect you from an XSS attack. For example this is not safe and MUST be avoided for all untrusted data:
<%-- Not XSS safe --%>
${untrusted_data}

XSS input validation

Validating input characters for malicious data should not be your only method of prevention. It is recommended to always escape untrusted data on the output side because you account for all data regardless of where the data originated from. Maybe the data was maliciously altered in the database or perhaps your third-party vendor sent harmful data outside HTTP. Input validation does not account for those scenarios and should not be used as your only defense. Output escaping with ESAPI or JSTL covers all bases regardless of where the data originated from. If you prefer to validate user input for XSS you may use regular expressions. A whitelist strategy of allowing positive characters is preferred. For example, the regular expression code below is a whitelist pattern that only allows certain characters as valid input:
public final class ValidationUtils {

/* Whitelist validation example. Only allow alphanumerics and special characters: -@&., */
public final static Pattern VALID_TEXT_FIELD_PATTERN = Pattern.compile("[A-Za-z0-9-@&\\.,\\s]*");

public static final boolean isValid(Pattern pattern, final String value) {
return pattern.matcher(value).matches();
}

}

XSS and JSON

If you are using JSON on the client-side make sure you also validate your JSON content for malicious data. Douglas Crockford, in his recent book JavaScript: The Good Parts recommends using JSON.parse() for all untrusted content. JSON.parse() will throw an exception if the text contains anything dangerous.

Thursday, March 26, 2009

Identify security gaps with Tamper Data

How secure is your application? Why not perform a security audit yourself. Tamper Data is a very helpful Firefox tool to help identify security gaps your applications may have. Do you really think your hidden form fields are safe? Do you think your select list data can't be altered? Basically, all data exposed to the browser context can be altered by the end user.

Advantages of Tamper Data

  • Tamper data will show you how easy your data can be attacked. Every post parameter can be altered. This includes hidden fields and select list values.
  • Tamper data helps emphasize the data you must secure from a malicious user. Are you exposing any identifier values within the browser context? Look for these primary key values. You may find these in edit or search result screens. If you do expose sensitive keys, a malicious user may alter them as they search for sensitive data.
  • Tamper data makes it very easy for developers to quickly test your application against cross site scripting (XSS) and SQL injection attacks.
  • QA can leverage Tamper Data to identify security gaps also. This is a practice that is not very common. Tamper Data can simplify this effort.


How to setup Tamper Data

  1. From within Firefox, download: Tamper Data.
  2. After the download is complete, you may access the Tamper Data screen from either the Tools menu or View menu:

    Accessing tamper data from tools menu Accessing Tamper data from view menu, side bar sub menu
  3. Start Tamper data by clicking the "Start Tamper" button: start tamper button


  4. You can now test your application for any gaps. You may tamper with any post parameter values that appear in the right pane:tamper screen shot

Alright, so what are a few strategies for securing our data? In my next post I will discuss a few defensive programming practices to help secure your sensitive data. I'll also expose a JSTL gap that makes you vulnerable to XSS attacks.

Thursday, March 12, 2009

Prefer CSS-based designs

Are you leveraging the full potential of CSS? Traditionally, tabled-based layouts were the standard for structuring content. CSS provides many advantages that we should be leveraging today. In short, table-based designs should forever be deprecated.

Advantages for adopting CSS-based designs:

  • CSS-based designs render content better in mobile-based browsers. With mobile apps on the rise it is becoming even more important to apply CSS-based designs today on your regular browser applications. Sites designed with CSS layouts offer much better flexibility in regards to how the content is rendered on the UI. For example, given the same content you may apply a different style for your mobile based application vs your non-mobile based application.
  • Your pages will have less code and become much easier to read. No more <table>, <tr>, and <td> tags to clutter your content!
  • With less code to maintain, refactoring becomes simpler.
  • Your UI becomes more accessible.
  • Lightweight pages will be more performant.

CSS Books:

  • CSS Mastery:
    • This book was the most valuable for me. It's a quick read and their examples are very good. I typically reference their examples first when looking for solutions.
  • CSS The missing manual:
    • This is also a valuable book. This book contains much more content than the prior book and may be targeted for a more introductory audience. Their examples are also good but I typically reference the CSS Mastery examples first.

CSS Tools:

  • FireBug:
    • Arguably the best tool ever invented for Web development. Refer to the FireBug site for their CSS support features. Simply awesome for everything (debugging, JavaScript, CSS)! YSlow is also a helpful FireBug addition that provides an excellent performance report card.
  • YUI Grids CSS:
    • If you are looking for a CSS framework then this may be of value. Their base and grid styles should help with layout while their reset style will help get all browser's on an even playing field. Yahoo has a good demo of its features on their YUI Grids home page.

Saturday, February 28, 2009

Spring Webflow: An elegant DSL for your MVC

Spring Web Flow is an interesting MVC framework. Under the hood, it is an implementation of a Finite State Machine (FSM). However, the beauty of Spring Web Flow is in the simplified DSL templating that Web Flow provides.

First, lets look at a simple example:
<flow start-state="start">

<view-state id="start" view="chooseColor.jsp">
<transition on="red" to="showRed" />
</view-state>

<end-state id="showRed" view="red.jsp"/>

</flow>

This web flow above has two states and one transition. States in web flow typically correspond to views. In this case, my views are JSP's. Transitions will be triggered based on events. Within a JSP, events correspond to buttons or links. The event or button to trigger the red event is defined here:

<html>
...

<form:form action="${flowExecutionUrl}">
<input type="submit" name="_eventId_red" value="Red" />
</form:form>

...
</html>


The flowExecutionUrl contains the context-relative URL to the current flow execution's view state. Alright, so what advantages does web flow provide? Here are a few:

  • Do your business users create use cases or flow charts? If they do, those documents should map uniformly to web flows. In fact, the business users that build the flow charts should be able to interpret your web flow definitions also. Self documenting code that you can also share with the business is valuable.

  • Spring Web Flow provides an additional scope called flowScope. Most applications suffer from session bloat because many developers put data into session out of convenience and do not always think about its consequence. Web Flow alleviates this problem with their flow scope. For example, flow scope is created when your flow starts. And when your flow ends, all data held within flow scope is cleaned up automatically. Now you are running lean! In the example below we put a list of colors in flowScope:
    <flow start-state="start">

    <view-state id="start" view="chooseColor.jsp">
    <on-render>
    <evaluate
    expression="colorService.findAllColors()" 
    result="flowScope.colors" />
    </on-render>

    <transition on="red" to="showRed" />
    </view-state>

    <end-state id="showRed" view="red.jsp"/>
    </flow>



  • Spring Web Flow also has a built-in expression language. The expression language is a feature that allows you to call your Spring beans conveniently from within your flows. In the example above, we fetched our colors from the ColorService.

  • There is less code to maintain compared to the other MVC frameworks. You do not need controller objects anymore. However, you still need to create model objects for binding form data to objects. The form binding in web flow is automatic for simple types.

  • Your flows and transitions can be secured with Spring Security. The example below shows how you may secure your web flow or a transition:
    <flow start-state="start">
    <!-- secure the entire flow -->
    <secured attributes="ROLE_USER" />

    <view-state id="start" view="chooseColor.jsp">
    <transition on="red" to="showRed">
    <!-- secure this transition -->
    <secured attributes="ROLE_ADMIN"/>
    </transition>
    </view-state>

    <end-state id="showRed" view="red.jsp"/>

    </flow>



  • You can achieve reuse with subflows and global transitions.
    <flow start-state="start">

    <view-state id="start" view="chooseColor.jsp">
    <transition on="red" to="showRedSubflow" />
    <transition on="green" to="showGreenSubflow" />
    </view-state>

    <!-- subflow states -->
    <subflow-state id="showRedSubflow"
    subflow="redSubflow.jsp" />
    <subflow-state id="showGreenSubflow"
    subflow="greenSubflow.jsp" />

    <end-state id="thankYou" view="thanks.jsp" />

    <!-- If every page had a cancel button we may declare that transition once. -->
    <global-transitions>
    <transition on="cancel" to="cancel.jsp" />
    </global-transitions>

    </flow>



  • Web flows are browser button friendly. To achieve this, every view state rendered gets stored as a snapshot. When you press the back button, the previous snapshot is retrieved from the snapshot repository. For performance, you may limit the number of snapshots that exist within the snapshot repository.

  • Web flows eliminate the double-submit problem. To accomplish this, Spring will apply the POST-REDIRECT-GET pattern to all POST requests. You may also disable this feature if it's not needed or if you want better performance.

  • As always, Spring has strong JUnit test support to help test your flows.



In conclusion, Spring Web Flow is a very unique MVC framework. It is an ideal solution for simplifying complex work flows. I particularly like the simplicity of the domain specific templating language (DSL), the flowScope, and the expression language capabilities.

Thursday, February 19, 2009

Designing for Accessibility

How accessible is your website? If you are interested in finding out, you may enter your URL at the WAVE website for a quick evaluation. You may also download the WAVE Firefox plug-in for even greater control.

Well, did your site have any errors? Technically, you do not have anything to worry about unless your site is for a government agency. In any case, Web standards are a good thing to design for and this WAVE plug-in can be a great tool to help find any gaps you may have. In addition, this tool can also serve as another check list item for your next client-side code review.

If you are interested in designing for accessibility, the effort is minimal. For example, you can achieve nearly zero accessibility errors by simply focusing on these three categories:
  1. Create accessible forms
  2. Create accessible images with appropriate alt text
  3. Use appropriate heading and table header tags

You may be wondering about dynamic content. If you have dynamically updated content, you will also want to learn about ARIA (Accessibility of Rich Internet Applications). For example, if you have data that gets dynamically updated within a <div> tag you can include aria attributes to notify assistive technologies of dynamic content updates. Here are several examples that demonstrate how to make your dynamic content accessible. There is nothing to install to take advantage of ARIA. ARIA is supported in Firefox 3+ and IE 8+.

In conclusion, the effort involved to implement these accessibility standards is relatively minor. In return, you are designing towards standards, your site is consumable by a larger user base, and you have just given your sales team another competitive advantage. The WAVE plug-in also gives you and your QA team an automated tool to evaluate pages for accessibility compliance.

Thursday, February 12, 2009

A Spring Pattern for Error Logging

Looking for an effective error logging solution? I recently found this pattern from the Pro Spring 2.5 team and it has several very elegant features which include:
  • It is an AOP based solution so it will prohibit you from infecting your business logic with error logging details. This concept isn’t new. The next two features I thought were more interesting.
  • The log details are written to a database. In fact, the exception will only get written once. If an identical exception occurs the count of that occurrence will be incremented. This reduces the redundancy that we see in file based solutions.
  • For reporting purposes, the following exception details will be captured:
    • number of occurrences (nice feature)
    • exception name
    • class and method name
    • method arguments (nice feature)
    • stack trace
    • timestamp of last occurrence



An example report may look like:


There are two components necessary to complete this task. An aspect for identifying the level at which you want to capture exception logging. And secondly, a data access object to manage the persistence. Here's an example of the Spring Aspect that will intercept all Service method calls:

@Aspect
@Component
public class ErrorLoggingAroundAspect {

@Autowired
private ErrorLogDao errorLogDao;

@Around("execution(* com.mycompany.myproject.service.*Service*.*(..))")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
pjp.getSignature().getName();
try {
return pjp.proceed();
} catch (Throwable t) {
insertThrowable(t, pjp);
throw t;
}
}


private void insertThrowable(Throwable t, ProceedingJoinPoint pjp) throws IOException {
StringWriter stackTrace = new StringWriter();
t.printStackTrace(new PrintWriter(stackTrace));
stackTrace.close();
StringBuilder methodArgs = new StringBuilder();
for (Object argument : pjp.getArgs()) {
if (methodArgs.length() > 0) methodArgs.append(",");
methodArgs.append(argument);
}
methodArgs.insert(0, "(");
methodArgs.insert(0, pjp.getSignature().getName());
ErrorLog errorLog = new ErrorLog(
t.getClass().toString(), stackTrace.toString(), methodArgs.toString());
this.errorLogDao.insert(errorLog);
}
}


public class ErrorLog {
private String exceptionName;
private String stackTrace;
private String method;
private int count = 1;

public ErrorLog(String exceptionName, String stackTrace, String method) {
this.exceptionName = exceptionName;
this.stackTrace = stackTrace;
this.method = method;
}
}



Here's the example DAO that will persist the exception to memory. A real solution would persist to a database.

/** Persists to memory.*/
@Repository
public class ErrorLogDaoImpl implements ErrorLogDao {

private List<ErrorLog> errors = Collections.synchronizedList(new LinkedList<ErrorLog>());

public void insert(ErrorLog errorLog) {
for (ErrorLog log : this.errors) {
if (log.getMethod().equals(errorLog.getMethod()) &&
log.getStackTrace().equals(errorLog.getStackTrace())) {
log.setCount(log.getCount() + 1);
return;
}
}
this.errors.add(errorLog);
}

public List<ErrorLog> getAll() {
return this.errors;
}
}


In addition to the code above, you will also need to include <aop:aspectj-autoproxy/> within your Spring configuration file. This tag scans for @Aspect's and turns them into proxies.

Again, I like this solution because it keeps the business-tier clean of logging details, there are no redundant error log messages like we see with file-based solutions, and the persisted data allows for much simpler error reporting. In addition to error logging, I also see this pattern being a good solution for business auditing too.

Saturday, February 7, 2009

Pro Spring 2.5: the Good, the Bad, and the Ugly

Pro Spring 2.5 covers the new 2.5 additions to the Spring framework. The table of contents is viewable from the Apress web site.


The Good:

  • In addition to the new core framework features (JDBC, AOP, remoting, transaction management) they also included chapters about Spring MVC, Spring Web Flow, JMX, testing, and performance tuning.

  • The authors do a good job of including introductory content for new Spring users. In fact, the first eight chapters (Part I) were targeted towards users getting started with Spring.

  • The author's explain many of the new features in great detail and had code examples for nearly everything. However, there are some gaps in their code examples.

  • If you are a fan of Josh Bloch's puzzler's then you will definitely enjoy some of the code examples. The disappointing point is that these were not intentional mistakes! If you do not like puzzlers, then move this one to the bad and ugly category.

The Bad and Ugly:

  • The source code examples in this book contained many typos and copy-paste errors. More than I had ever seen an any book previously. Unfortunately, this may cause confusion for new Spring users.

My recommendation (3.9 stars out of 5):
I originally preordered this book based on the reputation of the first
Pro Spring book. That book was very good and it had great reviews to back it up. Despite the typo's, I have found value in this book. I have given brown bags on the new features of Spring, Spring MVC, and Spring Web Flow and I gathered most of my content from this book. This book has been a good compliment to the Spring reference documentation. However, If you can't tolerate an occasional typo then you may want to avoid this book completely.

Wednesday, February 4, 2009

97 Things Every Software Architect Should Know – The Book

Richard Monson-Haefel's list of 97 Things Every Software Architect Should Know is expected to be released soon by O'Reilly. I personally want to thank Richard for assembling this great list! We have always seen the architectural and programming design pattern books on the shelves but this one will be an awesome compliment.

I think these types of books where content is submitted by many contributors will become much more popular going forward. Career 2.0, by Jared Richardson, is another new book where the content was gathered in a similar fashion. In fact, you may submit your experiences for this book now on their Career 2.0 blog.

Is this a trend? Not sure, but it is interesting.

Tuesday, January 27, 2009

Developing Expertise

Looking for an exciting talk on developing expertise? I definitely recommend Dave Thomas' talk on "Herding racehorses and racing sheep." I was fortunate enough to attend this talk at NFJS back in 2003 and it is still a classic. The talk is also very humorous:) The wizard vs wizard argument and the wizard vs novice points were hilarious. Thanks Dave, this advice has been very helpful for me over the years!