Sunday, October 28, 2012

Software Development Roles

In software development, there are four major stakeholders, or roles to play: the customer, the architect, the engineer, and the operator.
  • The Customer: The customer is most typically the business analyst, executive, or client that is driving the production of software. They are the people who write the checks.
  • The Architect: The architect is the person or persons responsible for designing how the system(s) work. They must take a holistic view and are responsible for guiding software to a place that is reliable, testable, efficient, and de-coupled.
  • The Engineer: The engineers are those who actually build the software, who sit down and write code based on the customer's needs and the architectural designs.
  • The Operator: Operators come in two very different classes: end-users and operations groups. If you release software for public consumption, your operator is the end-user. If however your software runs on company servers and/or workstations, then the systems personnel are the operators.
The ideal scenario, the sweet-spot where quality, sustainable software is developed, is where each of these different roles work in concert with all the others. The problem of course is that they often don't. The customer is impatient or bombastic, demanding features and deadlines that turn the architects and developers into slaves to his whims, too harried to do their jobs correctly. The architect is overbearing and tyrannical, over-planning the system to the point that it can never be completed and insisting all development pass through him. The engineers are slap-dash, churning out code without regard to system performance, readability, or bug count. The operators are too cheap, unwilling to provide enough servers to handle the load gracefully.

Hopefully no one has ever been in a position where all four of these sentences were true (or at least didn't have to work there long), but everyone's been involved in a job or project where at least one of them was. When one group wields too much say over the software development cycle, problems ensue. Each role should have autonomy in their own domain - their working environment should not be dictated to them by another role. However, for each role to enjoy such independence, there has to be a certain amount of give and take between them. For instance, if your engineers want to develop ASP.NET websites, the operators can't very well insist on Apache servers. If your operators are largely iMac owners, it would be unrealistic for the engineers to decide to write C# desktop apps. If the architect thinks it would be swell to use SharePoint, it's not his/her place to demand that the customer abandon the current CMS system they've come to know and love. Deciding how a piece of software (or software system) comes together requires negotiation and collaboration between the different groups.

One mistake commonly made is to assume that these roles have to be separate people. Naturally, in small companies, particularly start-ups, a small group of IT people will wear multiple hats. Freelancers, consultants, and one-man-IT-shops will often wear the architect, developer, and operator hats simultaneously and exclusively. There is a tendency, though, as the company grows, for these roles to become different departments. There's not necessarily anything wrong with that. But how a company sets up its reporting relationships should not determine how software development roles are filled. Software quality is improved and innovation is fostered when individuals who are engineers 90% of the time are allowed to be architects when the time is right. Architects who step into developer shoes produce more realistic systems. Operators who can be the customer sharpen system requirements. Fostering an environment where this kind of 'cross-pollination' is looked on favorably should certainly be a priority for all involved parties.

I once worked in the Information Systems Division of a Fortune 100 company. They had a lot of clumsy processes and a lot of the folks who worked there weren't standouts in their fields. But their environment was set up in such a way that each role had the autonomy they needed. An architectural group had created an overall vision for how the various systems should fit together, and the development groups were expected to follow that vision. However, inside their own domains, development teams had enormous flexibility in choosing the programming language, OS platform, and design patterns to use. The operators, the infrastructure teams that maintained the servers and terminals that ran this software, had a finite list of platforms and runtimes they would allow, but it was a long list, and anything on that list they would fully support.

My current job employs a much higher caliber of person, and has a much better development life cycle. They have, however, struggled with finding this correct balance between the stakeholders. Despite the flaws of that previous position, I find myself looking back at how they did things as a guide in this area. On paper, this sounds like a rather abstract and theoretical discussion, and in some IT shops it might be. But when this balance is off and/or these roles are not clearly defined, your workday can quickly transform into a series of turf wars. If you find yourself getting into that kind of situation, it's time to take a step back, define, and balance. We didn't, and it went badly: we thought we'd 'won' the turf war, only to have the problem come back at us sideways and make things worse. Don't let this happen to you!

Friday, October 5, 2012

MVC View Compile Workarounds, or the SDK Strikes Back

I have resisted learning/using ASP.NET MVC for a while now, for several reasons. One, I'm a cranky old codger who doesn't like to change. Two, I don't hate the viewstate or the page life cycle, so when Microsoft proclaims that MVC will save us from those two pains, I go, "what pains?" Third, when I look at MVC code, I find myself grumbling, "If I wanted to be a PHP programmer, I would have stuck with that."

But time and upper management marches on, and recently I was pulled onto a project where the primary deliverable is an MVC 4 website. So I had to finally bite the bullet and get started. After installing the necessary components and add-ins and actually getting all the projects to load, I tried to build the solution, and got a compile error. The message was of the standard "The type or namespace name '...' does not exist in the namespace '...' (are you missing an assembly reference?)" variety; the breaking files, however, were entries like this:

c:\Users\nirvin\AppData\Local\Temp\
Temporary ASP.NET Files\temp\0260edc4\5834db2c\App_Code.q2tzfscm.0.cs

What? Why was Visual Studio generating code and then blaming me that it didn't build it right? Why should I care about the temporary ASP.NET files at this stage? I was trying to build, not run. I did some digging and found that Visual Studio attempts to compile the MVC views at build-time, instead of waiting until run-time (as standard ASP.NET does).

I consulted with my co-workers and determined that the issue was partially with my machine and partially with the solution. I could create an MVC 4 project from scratch and build it just fine, but this existing solution would fail consistently. However, other developers on the team were able to build the solution just fine on their machines. After more consultation and Googling, the following solutions were proposed:
  • Install Visual Studio 2012.
  • Uninstall MVC 2, 3, and 4 from my machine and then re-install them.

Neither of these options were appealing to me. I had not yet installed Visual Studio 2012 on my machine, and I knew that such a process would be time-consuming. The base install would take forever (after I found the right ISO that is), and then several of the critical add-ins and packages I use for daily development would have to be upgraded and reconfigured (e.g., ReSharper, dotCover, NuGet). Plus, I knew some of my teammates were using Visual Studio 2010 and building just fine, so I was somewhat skeptical of the proposed solution anyway.

The uninstall/re-install option, though, just rankled me. Ever since my my bad experience with Silverlight, SDK versions that refuse to play nice with one another (or, to put it another way, aren't properly isolated from one another) are a pet peeve of mine. Just as with the Visual Studio 2012 option, I didn't want to spend hours re-configuring my machine, and I certainly was not willing to play the install dependency guessing game.

After hours of trying to resolve the error, I finally found that you can actually turn off this "compile views" step.  While I didn't like this option, I needed to get back to actual work (particularly since my assigned tasks were all down in the data layer) so I decided to give this a shot. (I realize this might seem stupid; please keep reading, an endnote addresses the paradox here.) This particular setting is not accessible through Visual Studio 2010's UI, but can be toggled by editing the project file. Inside the project file there is a line that reads:

<MvcBuildViews>true</MvcBuildViews>

I switched it to "false", reloaded the project file, and built. Success! Well, not quite. I didn't want to check this change into source control; this was a personal choice/setting, and I didn't feel right imposing it on the rest of my team. It is, after all, a hack: telling the compiler to skip certain steps is not exactly advisable. I also didn't want to leave the project file checked out all the time; eventually I would accidentally check-in the hack, or have to make a legitimate change to the project file. Plus seeing stuff in the Pending Changes window at the end of the day just bothers me.

Now, the same variables/expressions that are available in pre- and post-build events are available in the project file markup and get evaluated at build-time. At first I looked into creating some rule/exception based on my machine name, but that variable wasn't readily available. So I hit on the idea of creating a separate build configuration instead.

I created a solution build configuration called "DevNoViewChecks" (emphasis on solution; the "Create new project configurations" option was not selected). This build configuration was copied from Debug, and so upon first creation it had each project set to "Debug". I then went to the MVC project, and created a new project build configuration for it with the same name (again with the emphasis; the "Create new solution configurations" option was not checked). This gave me a solution configuration "DevNoViewChecks" with each project set to "Debug", except for the MVC project, which was set to "DevNoViewChecks". I then went into the MVC project file, and edited the afore-mentioned line to read:

<MvcBuildViews Condition="'$(Configuration)' != 'DevNoViewChecks'">true</MvcBuildViews>

I then changed my build configuration in the Visual Studio toolbar to say "DevNoViewChecks", and built. No compile errors! Success! Actual Success!

I don't love that I had to hack this, and I'm not exactly warming to MVC here. But I do love that with this approach, no one has to think about it. I keep my solution set to "DevNoViewChecks", everyone else keeps themselves set to "Debug", and everyone's solution just works. No one has to care about what the other is doing and I don't have to think about what's going on with my project file all the time.

Someday I hope to actually resolve this issue with a deterministic approach that actually makes sense. But until then, this keeps me going.

(It is important to note that the website runs perfectly in the "DevNoViewChecks" build. There seems to be some inconsistency between how Visual Studio (attempts to) compile the views, and how the ASP.NET runtime actually compiles them. This compile error feels like a false negative.)