Tuesday, January 13, 2015

Passing Knowledge with Code

As a programmer, sometime or another you will be needed to dig into a legacy system.  Whether you're making changes or maybe trying to rewrite it, you'll need to understand what's going on.

One of the biggest problems with legacy systems is that there are few to no people who truly understand that system anymore.  The original creators have more than likely moved on leaving you to interpret what variable 'x' is supposed to mean.

As you can imagine it can be very time consuming dissecting a system that doesn't follow modern coding conventions, but we need to understand that the code we write will also someday be a legacy system.  Someone is going to inherit the system you are writing right now.  So, the question is, are they going to curse you for it or thank you for passing on your knowledge?

Self Documenting Code

One of the biggest things we can do as programmers is make sure our code describes itself.  We can do this by careful naming conventions that describe what our intent is.  A variable named 'x' gives no context or meaning, but variable 'numberOfSandwhiches'  describes pretty well what is being stored.  

Self documenting code, while verbose, is the best way to have your code describe what it is doing.  It also goes hand in hand with refactoring, or rewriting a piece of logic without changing the contract.  For example, lets say we have a code block like this:

if(hunger > 0 && bread > 2 && meat > 1 && lettuce > 0 && tomatoes > 0) {
  sandwhich = new Sandwhich(bread, meat, lettuce, tomatoes);
  numberOfSandwhiches++;
}

At first glance it may not be perfectly clear what's going on with the large list of ingredients in the if statement. But, the idea of refactoring is to make the code easier to understand so we can make it a little clearer by writing it like this.

if(hunger > 0 && ingredientsAvailable()) {
  sandwhich = new Sandwhich(bread, meat, lettuce, tomatoes);
  numberOfSandwhiches++;
}

Hopefully the refactored code is easier to understand at a glance so that whenever future me, or whoever else is going to be looking at this in the future, can quickly understand the intent.

Comments

There is always a big debate about how many comments are appropriate.  Some purists will say that if you need comments your code is not self documenting enough and needs to be refactored.  

I prefer the practical approach.  Leave comments if you need to, but make sure they actually communicate meaning and context.  People in the future might not have access to the bug tracking tools you use today so comments like '// Fixed bug 43453'  are less than useful.  

But having said comments are okay, I feel I should also give a warning.  If you find yourself leaving a lot of comments that could be a code smell and maybe some refactoring would do your code some good.  While comments are useful, most of the code should describe itself.  

Conclusion

To close I want to reiterate on the importance of passing your knowledge in your code.  You may not realize how much you time you'll be saving some future programmer by writing good documented code.

To help us remember to do this I recommend using fear-driven development: Always code as if the next person to maintain your code is a homicidal maniac who knows where you live.

Tuesday, December 30, 2014

Kaizen: The Key to Continous Improvement

Below are some notes from a presentation I watched about continuous improvement, which should be at the core of any organization that's serious about becoming better.

Learn more about Kaizen here:
http://en.wikipedia.org/wiki/Kaizen

Watch the presentation here:

Culture
  • Small and continuous improvement
  • Quick win
  • Accept Failures
  • Improve Quality
  • Empower people
  • Develop People
  • Shared long term purpose
  • Reduce waste
  • Visualize problems
  • Stop and fixing
Resistance to change
  • Use small changes
  • Influencing people over time
    • Celebrate wins
  • Sense of urgency
Plan - Do - Check - Act
  • Create a feedback loop
  • Plan
    • Clarify the problem
    • Break it down
    • Set the target to achieve
    • Analyze root causes & get metrics
    • Develop countermeasures
  • Do
    • See countermeasures through
  • Check
    • Check process and result
  • Act/Adapt
    • Standardize success
Why Kaizen Succeeds?
  •  Establish a sense of urgency
  • Create a vision
  • Empower others to act on the vision
  • Plan for and create short-term wins
  • Consolidate improvements
  • Embrace changes and new approaches
Kaizen Event
  • Improve producitivy
  • Cross functional team
  • Provide immediate value
  • Duration between 3-5 days
    • Pre Kaizen
      • ID the problem and collect metrics
    • Day 1-2 
      • document current state of the problem
    • Day 2-3
      • Root cause analysis and set goals to achieve
    • Day 3-5
      • Improve process
    • Post Kaizen
      • Analyze every month if the improvement benefits
  • Daily Kaizen
    • Focus in short term goals and quick win
    • Individual or small teams
    • hour/daily review cycle
    • reinforces the learning and development through practice of problem solving
    • create new standards improving people and the organization
    • reduce waste and learning by doing
Top 10 reasons why Kaizen fails
  • Absence of real culture - "this is the way we've always don it"
  • Politics and blame games
  • Fear culture - resistance to change
  • No follow up after a kaizen event
  • No sense of ownership/empowerment
  • Short term vision - No sense of urgency
  • Failure to identify problems - no problem is a problem
  • Failure to see root causes
  • Failure to plan and execute
  • Lack of resources -  time, knowledge
Small changes to start
  • Coach people
  • Empower people
  • Boost the team morale
  • Lead by example
  • Improve your standards
  • Visualize your flow and identify the problems
  • Always start from 1 or 2 teams
  • Celebrate success
  • Use metrics to identify improvements
  • Accept failure and learn from it
References
  • Agile Kaizen by Angel Mednilla
    • ISBN 978-3-642-54991-5
  • The Spirit of Kaizen by Robert Maurer
    • ISBN 978-0071796170
  • Creating a Kaizen Culture by Jon Miller, et al
    • ISBN 978-0071826853



Monday, October 20, 2014

Creating a JSON Schema from a POJO

If you're documenting your REST API it might be useful to show the schema definition behind the JSON objects being used.  The JSON Schema format provides a definition similar to XML's XSD.

It isn't very difficult to generate a JSON schema with Jackson.  Given a simple POJO with some properties which includes a list of another simpler POJO:

public class SimplePojo {

 private Integer id;
 private String name;
 private String description;
 private List children;
 // getters and setters ommitted
}
public class SimplePojoChild {

 private Integer id;
 @JsonProperty("cName")
 private String childName;
 @JsonProperty("cDescription")
 private String childDescription;
 // getters and setters ommitted
}

We can use the Jackson JsonSchema Module to generate the Schema with code similar to this:
public class JsonSchemaGenerator {

 public static void main(String[] args) throws JsonProcessingException {
  ObjectMapper mapper = new ObjectMapper();
        SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
        mapper.acceptJsonFormatVisitor(SimplePojo.class, visitor);
        JsonSchema schema = visitor.finalSchema();
        System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema));

 }

}

This code would generate this json schema:
{
  "type" : "object",
  "id" : "urn:jsonschema:com:bmchild:model:SimplePojo",
  "properties" : {
    "children" : {
      "type" : "array",
      "items" : {
        "type" : "object",
        "id" : "urn:jsonschema:com:bmchild:model:SimplePojoChild",
        "properties" : {
          "cName" : {
            "type" : "string"
          },
          "id" : {
            "type" : "integer"
          },
          "cDescription" : {
            "type" : "string"
          }
        }
      }
    },
    "name" : {
      "type" : "string"
    },
    "description" : {
      "type" : "string"
    },
    "id" : {
      "type" : "integer"
    }
  }
}

The only downside is if you're using a different version of jackson (we were using one from the codehaus repo) you'll need to change your json annotations so it will print out correctly.

All the code can be found on My Github Account

Tuesday, September 2, 2014

SQL Server: Get Foreign Key Name by Table and Column

I ran across a scenario where I was trying to drop a column that was a foreign key.  When I executed the code to drop it it said there was a dependent object on the column being dropped.  The dependent object was the FK constraint.  So, I need a programatic way of getting the FK constraint name so it could run in our migrations.



The script came from this SO thread.

Monday, August 18, 2014

Splitting a String by Length or Position

Here is a simple method to split a string into a list of substrings based on length.  For example, given the string "12345678901", if we were to split by 2 we would expect a result like {"12", "34", "56", "78", "90", "1"}.

Here is the method and tests:

Thursday, July 17, 2014

CAS Basic Authentication Filter

CAS is a great single sign on(SSO) solution and spring security also includes a lot of helpful classes to implement it in Java apps.  However, getting CAS to use Basic Authentication took some persuading.

It involved creating a new filter that could be placed in front of CAS's spring filter( org.springframework.security.cas.web.CasAuthenticationFilter).  But since CAS's filter only redirects to the login screen if a user isn't logged in, we needed to do some authentication before the filter executes so it can do it's thing (like populating UserAuthorities and UserDetails so we can use spring security's annotations like @Secured, etc).

So below is the new basic authentication filter.  It authenticates via CAS's rest web service so that will need to be enabled.  Once it authenticates it "adds" the service ticket to the HttpServletRequest object.  I say "add" because you can't really add a parameter to the request, you have to wrap it in an HttpServletRequestWrapper.  The whole thing kind of feels like a hack, but I couldn't find, or come up with, a better solution.  
 


Tuesday, July 1, 2014

More Useful Eclipse Templates

I was moving to Eclipse Luna and I realized I didn't export my templates from kepler.  Here are some useful ones, besides the ones I've posted about before.



And for convenience here is an import xml you can use to load all my favorites.