Software Development


Agile Practices&Project Management01 Dec 2016 10:55 pm

I style myself an agilist and generally move in a circle of Agile and Lean minded colleagues. So when I mention that I am currently enrolled in an employer-sponsored PMP prep class, the responses I get tend to range from quizzical to shocked. While the PMI is making efforts to embrace agile practices, the PMBOK and this class is still decidedly waterfall. There are statements a-plenty like “process B cannot start before process A completes” that indicate a mentality of lock-step execution and tight coupling. So Why am I, an agilist, taking such a course?

Deeply entrenched in government contracting as I was when I discovered agile, I have had my fair share of CMMI as well. Like the PMI, CMMI has a deep heritage in waterfall processes, yet has acknowledge the value and tried to incorporate agile and lean principles and practices into its toolbox. And lets faces it, CMMI level 5, for any company that ever makes it that far, is all about institutionalizing continuous process improvement across the enterprise. Think company-wide Kaizen, explained using waterfall terminology.

My experience is that there are opportunities for synergies between CMMI and agile, and I expect, between the PMBOK and agile as well. More germane to my interest though, my tagline on LinkedIn states “Have you ever asks, ‘How can I get the accounting department fired up about agile?’ I have.” and I have. And what I have learned is that, out side of the technology department, most companies think and speak in PMBOK terms.

So my three-fold reason for taking the PMP is this. First, I really believe there is useful information in there that is going to help me run my lean projects better. Second, I want to be conversant in the terminology of those I am looking to win over, and third, having PMP after my name will help me get my foot in the door with certain people to have those conversations.

That is not what this article is about however. That is just the context. What I want to throw out there is this idea that is percolating in my head as I sit in these classes and think, how do I get the accounting department fired up about agile?

My biggest objection to the class is just how impractical it is. It is (understandably) teaching to a test. Its an attempt to cram into the heads of up-and-coming project managers a high level understanding of everything they might ever need to know about project management. So here I am, working with people some of whom have never run a project that ran longer than a few months, never had a formal charter nor budget, etc. And they are trying to get their heads around scheduling, budgeting, command and control and every other knowledge area that you might need if you were building the next big thing in Abu Dhabi.

There is this disconnect. To pass the PMP exam, what we are getting is a cram course, a survey if you will, of the depths and riches of the PMBOK. But the expectation is, or seems to be, that if you pass the PMP, you actually know something at the practical level about how to run a project along PMBOK lines. My experience to date is that this will not be the case, nor does the remainder of the syllabus suggest differently.

I have a plan to address this. Lets get our PMP, but lets not stop there. We need a mentoring program for newly minted PMs that starts with the one or two PMBOK processes most applicable to the project at hand and helps the mentee to tailor those processes for and learn to use them on their project. Once they have begun to show mastery at using and tailoring those processes, and as they move on to bigger more complex projects, the mentoring process will assist them in identifying, tailoring and integrating other processes.

And, lest you forget that I am an agilist–the company’s legion of scrum masters, lean nijas and the like should be deeply integrated into this mentoring program. The goals that the PMBOK processes have are both good and eminently attainable using agile practices. Our implementation of them should be strongly informed by lean and agile principles–our companies “organizational process assets.” In this way we can, across the whole company, PMPs and SCMs alike, tech and accounting, HR and marketing, all develop a common language and understanding of delivering the right thing, on time and on budget to high ROI. That is what it is all about in the end is it not?

And who knows? Maybe by the time I retire, the accounting department will finally accept my iterative annual budget, delivered just in time to spend. Now that I know to present it as “progressively elaborated!” 🙂

Web Development13 Aug 2014 06:01 am

The AngularJS $http service is great for most any communication you need to do with the web services that are likely backing your single-page-application. However one place where it doesn’t quite do what you usually want is in the deserialization of dates.

Using $http to post a blog entry for example is pretty easy:

myPost = 
  id: 123
  title: 'Using HTTP Interceptors to Deserialize Dates'
  status: 'draft'
  creationDate: new Date()
  body: 'TBD'
 
$http.post('/api/blog', myPost)

This results in the following JSON being posted to the server:

{
  "id": 123
  "title": "Using HTTP Interceptors to Deserialize Dates",
  "status": "draft",
  "creationDate": "2014-08-13T10:13:39.399Z",
  "body": "TBD"
}

This is great. Notice that the service has automatically serialized the creation date to an ISO-8601 compliant string. I couldn’t ask for more… or could I?

What if I want to now get that post back:

$http.get("/api/blog/123").success (blog) ->
    console.log blog.creationDate    
    console.log typeof blog.creationDate

Assuming that the endpoint returns the exact same JSON that was just posted, this code will output:

2014-08-13T10:13:39.399Z
string

This is not the end of the world but it may not be what one is expecting. The expectation is usually that if I put a Date instance into a serialization function, then I get a Date instance out of the matching deserialization function.

Fortunately, this situation is easily remedied with a Angular http interceptor. Angular’s $httpProvider service allows one to configure interceptors that can pre-process all out-going requests before they are sent and post-process all received responses before handing them back to the calling application. A response post-processor to find all ISO-8601 date strings and convert them to actual Date objects is easy to implement.

angular.module('myModule', []).config([
  '$httpProvider'
  ($httpProvider) ->
    $httpProvider.interceptors.push [
      ->
        #Matches YYYY-MM-ddThh:mm:ss.sssZ where .sss is optional
        iso8601RegEx = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/
 
        response: (response) ->
 
          convertDates = (obj) ->
 
            for key, value of obj
 
              #If it is a string of the expected form convert to date  
              type = typeof value
              if type is 'string' and iso8601RegEx.test value
                  obj[key] = new Date(value)
 
              #Recursively evaluate nested objects
              else if type is 'object'
                convertDates value
 
          convertDates response.data
 
          response
    ]
])

And there you have it. Happy coding!

Web Development14 Jan 2014 09:03 am

Figuring out load order issues in Require.JS can be a big pain some times. However, if you are using the non-minified version, its easy to add some instrumentation that makes things clear. The Require.JS code is well documented so feel free to look around. I find the following methods most helpful to instrument.

@@ -1517,10 +1517,11 @@ var requirejs, require, define;
              * A load event could be a script load or just a load pass from a synchronous
              * load call.
              * @param {String} moduleName the name of the module to potentially complete.
              */
             completeLoad: function (moduleName) {
+                console.log('Completed load of ' + moduleName);
                 var found, args, mod,
                     shim = getOwn(config.shim, moduleName) || {},
                     shExports = shim.exports;
 
                 takeGlobalQueue();
@@ -1635,10 +1635,11 @@ var requirejs, require, define;
             },
 
             //Delegates to req.load. Broken out as a separate function to
             //allow overriding in the optimizer.
             load: function (id, url) {
+                console.log('Loading ' + id + ' from ' + url);
                 req.load(context, id, url);
             },
 
             /**
              * Executes a module callback function. Broken out as a separate function
@@ -1646,10 +1647,11 @@ var requirejs, require, define;
              * layer in the right sequence.
              *
              * @private
              */
             execCb: function (name, callback, args, exports) {
+                console.log('Initializing ' + name);
                 return callback.apply(exports, args);
             },
 
             /**
              * callback for script loads, used to check status of loading.

F.Y.I. This diff was applied to Require.JS 2.1.10

Next Page »