« July 2006 | Main | September 2006 »

August 31, 2006

Shirt Off Your Back

Upper management of IT teams love giving out shirts with the company logo to commemorate some milestone or event. They are usually in whatever color the manufacturer sells the least of.

I've never understood why they did this. If the goal is the usual stated purpose of thanking the development team for putting in so much extra effort in order to achieve the goal, why are they giving out the couture equivalent of a commemorative shot glass of Hoboken, NJ?

If the goal is to build the sense of being a team, isn't the time to do that before the big push to accomplish the milestone? Truly, if you're waiting until the completion of a project requiring extra effort, it's pretty likely that a sense of being part of a team has already been established ... based on shared contempt of management. Probably something to avoid.

August 29, 2006

TFS, VS, and Users

I ran into a problem today as we were trying to get a build out with our new implementation of Team Foundation Server.

The problem was that there was a reference path set in each project of the solution (some 30+ projects) that pointed to some directory that didn't actually exist on my machine, but did on most other machines. Since the paths for all the libraries specified as project references are merely "hints" (having been converted to relative paths) that Visual Studio may or may not pay attention to during the build process, every time someone else (who had the reference path directory) tried to build the solution, they used the wrong version of a particular library.

No big deal ... just clear out the reference paths for each project. Unfortunately, the reference path information is not actually part of the project. It is part of the user-specific information about the project, stored in (for a vb project) the *.vbproj.user file. As such, it's not technically part of the project, so changes to it are not pushed up into TFS. Which shouldn't be an issue, since these are user specific. So where was this information coming from?

The actual problem was that someone's *.vbproj.user files had been included as part of the projects when they were added to TFS. Whoever set things up probably had to do an "add folder" from the source control interface, because the "add to source control" context menu seems to be fickle about showing up in VS 2005.

Be aware of this scenario when setting up your own projects in TFS based on existing code.

August 25, 2006

Aspiring to Mediocrity

Exceptional companies pursue values.

Struggling companies pursue competitors.

It's reasonable to pursue competitors when the market is saturated, and any increase in market share can reasonably be considered part of a zero-sum game.

August 22, 2006

Intensity and Accountability

Most software development shops view the development team as entirely separate from the QA team. Hence you have sayings such as "throw [your code] over the wall" and "hand it off to QA". These teams are frequently managed by two entirely different people or departments. There are many consequences to this, a few of which I'll mention ...

  • An adversarial relationship, of varying degrees, is created between dev and QA.
  • The dev team views the delivery of their code to QA as the completion of their responsibility, and subsequently go into reaction mode with all their actions driven by unplanned and unexpected directives from QA (which means the dev team's pre-release "intensity" is often too low for management's taste).
  • The process defined for handing off code to QA is usually either inadequate, or excessively bloated, if any process is described at all.
  • The responsibility for actually getting code deployed bubbles up to the lowest level under which both dev and QA (as well as configuration management, deployment, support, etc.) are managed. As is true of all general staff structure organizations, bubbling the responsibility of making front-line decisions to a higher authority increases risk and decreases efficiency.

When this situation occurred in one of my recent contracts, I recommended that the developers retain ownership of their code until the final phase prior to release. The DBAs responsible for reviewing data model and stored procedure changes, as well as the QA department itself, become tools the developer uses in order to get his code delivered. This has quite a number of consequences, many of which are subtle or psychological in nature. A few of them are:

  • A single, front-line individual is responsible for the entire effort.
  • Availability of the DBAs or QA department must be planned on ahead of time, giving greater predictability and reduced risk to the process.
  • The developers will initially be "cracking the whip" over the assigned tester in an annoying and distracting manner. Therefore, the QA department will be forced to design process and procedure that is practically defensive in nature, rather than whimsically idealistic.
  • Since QA is just a tool for the developer to use, no longer a separate department, the developer is more likely to monitor, actively participate in, and facilitate the testing process. No more surprise demands.
  • Since someone who is focused on task is less able to evaluate the overall set of tasks being performed, the close association of the developer with the assigned tester will provide a "super-ego" to the process, who is more likely to evaluate the overall process and identify risk (as opposed to QA telling the project manager the night before the release that they still have 50% of the project to test).
  • The change in situation also has psychological implications on the team with regard to responsibility, focus, pressure, etc. that I consider desirable.

The company is in the process of making the change along the lines I suggested, so I'll let you know how it works out. So far, everyone up and down the management chain (including the testers themselves) finds the idea appealing.

August 16, 2006

Collaborative Protocol

Once again I skim down my list of subjects to write about, and find that Mr. Phillips at Thinking Faster has already written about one of the same subjects.

What he describes is the aggregate of proscriptions, declared procedure, custom, and common sense that become a set of "rules" or protocols by which interactions between people (whether collaborations toward mutual goals or efforts to mitigate contention of shared resources, e.g., an intersection) can take place both efficiently and safely. I call this the "framework of expectation".

In the programming world, this framework might be comprised of (in part), the corporate mission statement, the project statement of work, the requirements document, the coding style guide, and a firm understanding of the personnel hierarchy, their roles and responsibilities, and the appropriate means of interacting with them. Defining a clear and unambiguous framework of expectation is essential for completing a project in the most efficient and stress-free manner while controlling unnecessary risk.

But be aware of one problem ... people will sometimes think they know better than the framework, or think it would be nicer or more polite or more diplomatic to violate the protocol. For example, take the four-way stop-sign intersection. Every driver's handbook in America states that the first person to the intersection proceeds first, followed by any others in their arrival order. In the case of simultaneous arrival, the car to the right proceeds first. Most drivers know this and follow this, and in this way efficiency is maximized and risk of a fender-bender minimized.

But you sometimes have people who think they'll be "nice" and let someone proceed ahead of them, despite the fact that, by the stated protocol, they are to go first. Now things are broken. Who goes next? Who is to be considered "first"? Questioning looks go all around, tentative, simultanous starts and stops, hand gestures ... everyone's time is wasted, and the possibility of a small accident is increased.

All violations of the framework of expectation decrease efficiency and increase risk. Deal with them accordingly, no matter what the underlying reason for the failure.

August 15, 2006

Language Selection

Creating Passionate Users has a discussion on tool selection that I mostly agree with, and promote in all the companies I consult with. My only contention with the piece would be a semantic issue ... the use of the phrase "best tool".

"Best" is the superlative of "good", and if you hit the dictionary to look at the term, "good", you will see that it mostly deals with the nature of a thing. So describing a tool as "the best" implies an evaluation of its inherent quality. And this is why you get the religious wars about programming tools, because a thing is not intrinsically good or bad, just good or bad in a specific context for a specific purpose (a computer might be designed so poorly as to be totally useless for coding, but might make a wonderful and truly artistic doorstop.) The only way to argue about a thing being intrinsically good or bad is to fabricate an abstract ideal, and compare the item being debated to that manufactured ideal.

I would prefer the term, "appropriate" ... suitable for a particular person, condition, occasion, or place.

Selection of a tool (or language, or platform, or whatever) involves a multitude of issues. Not merely the obvious ones that were mentioned, or the subtle ones that a manager must consider such as (as mentioned in the comments) retaining talented programmers by giving them greater variety, but also the far more indirect issues such as tool longevity, likelyhood of the producing company being acquired, demand for the appropriate knowledge in the marketplace, etc.

For instance, when I was working in Baltimore, the marketplace was transitioning from VB.Net to C#. Why? I could never get a straight answer. The consequence was that there were suddenly a lot of VB programmers who either had to learn C# (starting at the bottom of the experience curve again) or find the rare VB gig. If I were a manager in Baltimore, I'd probably lean heavily toward using VB rather than C# if I could get a senior VB developer for the same price as a novice C# developer.


The Ivory Skyscraper

Jeffrey Phillips at Thinking Faster discusses the fact that product developers frequently forget that they are working from an aggregate, generalized, abstract "customer" when developing their products. The problem is that companies will sometimes (or, in my experience, frequently) fabricate this abstract customer out of thin air, making it about as useful for determining if your product will be successful as any other standard of evaluation that could be described as falling in the range of "fantasy" to "wishful thinking".

As an employee, go to your marketing people. Ask them what are the attributes of your customers. Ask them why the customers have the problem you're trying to solve for them, and how important it is for them to have it solved. Don't just ask them about the high-level generalizations, ask about specific items you're adding to the product. Have them show you the hard data. If they can't, better evaluate if your company is producing a solution in search of a problem or unnecessarily spending money to produce something that exceeds the basic requirements. Determine if this information has been conveyed to the management of the product development teams. If not, you're probably working for a company that can not scope down a project to the most effective essentials to solve the problem, opening the door for a more efficient and effective competitor.

One of the commenters mentioned that Unilever in India has a policy that you can't participate in a discussion about customers if you haven't spent some minimum time interacting with customers (and Mr. Phillips made a statement supporting the idea that everyone in the company interact with customers.) I'm not sure what he (the commenter) meant by "discussion about customers" unless he's referring to account managers or marketing people. Everyone else should be talking about problems. And having everyone dealing with problems interact with the customers is a bad idea, because it widens their focus from the targeted problem. If you're working on project X, don't even consider designing solution X' because it happens to address other issues the customers also have. Your architecture should be flexible enough that you can do easy additions, but considering those additions should not be on the product developers' radar at all. They didn't do the cost/effort->value analysis of the project, and are not in a position to accurately evaluate whether it is worth it to the company to do X'. Doing it anyway opens the door for competitors. Cultivating an environment in which scope creep is facilitated is dangerous.

Summary:

  • Do build abstract customers, but based on hard data.
  • Validate all assumptions about that abstract customer that aren't directly stated. Identify the person in the company responsible for managing the "customer" definition.
  • Don't go overboard with customer interaction ... marketing, business analysts, architects, and project managers to the extent that they need to address specific issues of the specific problem being addressed.
  • A product that provides slightly more for a slightly higher price may price itself out of the market if all people want is slightly less at slightly cheaper.
  • Ask the questions. Protect yourself.

Underwhelmed


I just tried signing up for the local Visual Studio User's Group. Their site has a location in which you enter your email address and click a "sign up" button. Which promptly returns an error.

Needless to say I am eager ... nay, inspired ... to become an an enthusiastic participant in this group.

It would take me, at most, 3 hours to write a highly configurable, robust (the criteria requiring most of those 3 hours) service to validate all the pages and operations in a web site. If your choice is to risk letting your company or group look foolish, why would you not spend the 3 hours? Why would you not spend a week? Why would you not spend a month?

Too expensive?

Companies that place little value on their public reputations should be avoided because they have no reason to produce exceptional products. Good companies know this, and smart consumers know this. You should have just two interactions with companies that obviously don't value their reputations ... short their stock, and open a competing service.

How expensive is it looking now?

August 14, 2006

Asynchronous vs. Parallel

I'm having to do some funky things with (among other things) reporting incremental information back to a caller from a processor class running on a worker thread. What I was looking for was a call-and-forget method that would allow a process on the managing object to run completely independently of the processor object. I was hoping to be able to do this with asynchronous delegates.

I was apparently confused by the term, "asynchronous", that Microsoft uses to refer to this functionality ... they really should have called it "parallel". The distinction (that I make in my messy little mind) is that an asynchronous process can run concurrently and/or independently of the calling process, while a parallel process can only run concurrently. For instance, a parallel process must rejoin the calling thread when it has completed (which, if the calling process has finished earlier, means that the calling process is blocking while waiting for the called process to complete), whereas an asynchronous process is entirely independent and could be run after the calling process has completed entirely.

On the other hand, that term, "concurrently", is a problem. It means one thing in a single-processor environment and another in a multi-processor environment, and parallelism has usually been associated with the latter (therefore, its use might imply a multi-processor environment.) Do we need a new term? Or can we get by with assuming Microsoft meant asynchronous invocation, not processing, and just live with the fact that the processing behavior is not currently described by any term?

As an aside (since I had trouble finding this documented) ...
the delegate BeginInvoke and EndInvoke methods are automatically emitted by the CLR with signatures tailored to the signature of the delgate being called. Since they aren't "real" method calls, there's no documentation in MSDN about them. Be forewarned before you waste your time hunting. If you're curious, the BeginInvoke signature is (x, y, z, callback, delegate) where "x, y, z" are the parameters the delegate is expecting.

August 10, 2006

Big Tobacco

I once heard a CEO say, after the most recent in a series of layoffs, that “we’ve got a healthy company, now.”

A little clue for all the other CEOs out there: never, ever say something like that.

True, half the people will blithely nod and say, “Yep, we surely do,” grateful that they were able to keep their jobs, if for only a little while longer. Their families are still supported, they don’t have to deal with the relationship turmoil of less money coming into a marriage, and they don’t have to see what the job market is like. They’ll be pleased that their stock options for which they put in all that past effort are still good and vesting if the real goal of the layoffs was to make an IPO more feasible.

Unfortunately, a portion of the people will actually evaluate the adjective. Do you actually have a healthy company? A more accurate metaphor might possibly be that you have a lung cancer patient, fresh out of surgery, looking forward to a term of chemotherapy, hoping desperately to live long enough to see his daughter married. And they'll figure this out.

There will be two themes in this group of people … those pensively waiting to see if the cancer has metastasized, and those wondering when upper management is going to quit their 3-pack-a-day habit. These are not the mental states you want to cultivate in your "healthy" company.

Don't choose your metaphors frivolously.