February 24, 2007

Variable Lucidity

Ok, to say that things have been a wee bit busy is an understatement of such magnitude that I can't describe. Given that the things I write about either require quite a bit of research, for which I had no time, or are inspired by the day-to-day activities at my clients', which, for the last couple of months, would have been inappropriate subject matter, there has been little about which I could write. However, there were a couple of little items that popped up, so as I spend a few minutes trying to figure out how to short out my neighbor's stereo, I'll take the opportunity to mention one.

There is a tendency among programmers to plan the code to implement a particular piece of functionality in their heads. Breakdown of functions, little features to implement, peculiarities that will need to be accounted for, etc.

The difficulty is that your mind tends not to have the same level of lucidity day to day. To compensate for this, I like to put little one-liner comments in the function stubs as I think of the details.

It was not until a conversation with a friend a few weeks back that I realized that most programmers don't do this. I think this is one reason programmers prefer to work long hours once they have the idea in their heads ... to keep the level of mental function that they had when designing on through the coding.

There's this thing called "a life" that I've been trying to acquire for some decades. I've found it very difficult to do so when I have to work long hours to keep a design in my head. A few little comments while designing, and "life" becomes more pleasant.

October 21, 2006

Transactions

I had to track down a series of problems this week, all related to transactions and database interaction. Many of the conclusions I had to make are mere guesses, but they seem plausible, so I thought I'd mention them here (as, once again, I found little on the 'net to support my efforts.)

  • Prior to .Net 2.0, the easiest way to manage distributed transactions was to implement certain functionality from EnterpriseServices and dump your assembly into COM+ component services. However, it would appear that if a class in COM+ calls a method on a class that does not implement EnterpriseServices, the called method is not (may not be?) included in the distributed transaction.
  • If you have an operation that makes one connection to a SQL database, it uses a lightweight transaction. If you have an operation that makes use of two or more connections to a SQL database, the original lightweight transaction is promoted to a distributed transaction when the second connection is opened. Referring to item 1, if this second set of calls is not in COM+, the second DTC transaction will not necessarily join the first. Therefore, any locks and such made by any connection made by any method on any class in COM+ have the possibility of blocking any locks and such made by the connections in the non-COM+ class.
  • If you make database calls from a class that someone has marked as not supporting transactions, it will go through the same process of promoting lightweight to distributed transactions in that class regardless. They will not, however, be incorporated into existing DTC transactions, and, once again, you have the possibility of lock contention.
  • The new .Net 2.0 TransactionScope is, shall we say, your friend. If you use it in the context of a transactional .Net COM+ component, the TransactionScope object will utilize the existing DTC transaction. If you're wanting to move away from COM+, this is a good start.
  • If you have a procedure that writes to temp tables, these operations are transactional. If you're using lightweight transactions, and the number of records is substantial, this can cause unnecessary load on the database. If you're using distributed transactions, you may have real problems. It would appear (although I'm guessing, as I've found no documentation) that information about the operations have to be sent to the DTM or DTC. This is not fast. A procedure that runs in, say, half a second within query analyzer may take a minute or more when run in the context of a distributed transaction. Remember to be aware of the implicit promotion to distributed transactions. And rewrite your procedures to get rid of that many temp table writes!

Oh, and don't forget ... if your connection is timing out, and you're considering increasing the connection timeout (easily done on the connection string), don't forget that there's a timeout on the Command object as well, not to mention global- and component-specific timeouts (timesout?) for the distributed transactions.

Share and enjoy.

October 16, 2006

SQL Interview Questions

Tim Chapman has an article on TechRepublic describing questions you might ask a SQL Server database developer applicant. I think a more accurate title for the article would be "How to Make Sure You Hire a Mediocre SQL Server Database Developer." The questions Mr. Chapman suggests can be answered by anyone who has remained awake for a few of their relational database theory classes or have skimmed one book. And if you want to ensure that your prospects have, at least, heard of relational databases, by all means use these questions.

On the other hand ... well, let me give you a few examples of my interview questions:

  • What is the difference between a table variable and a temp table, their intrinsic and situational drawbacks, and some of their uses? What happens if you do a "select into" a temp table without defining the table ahead of time?
  • What constraints are there on calling stored procedures from user defined functions?
  • If you're doing a left outer join against a large table with 0:1 cardinality (hey, what is cardinality?), how might you rewrite the operation to be more efficient?
  • With regard to indices, what's one of the benefits of using integer primary keys as opposed to guids?
  • What are some of the techniques for managing record change audit trails and their drawbacks/benefits?
  • Suppose you're considering changing the parameter list on a stored procedure. How might you determine if any other stored procedures call the one you're wanting to change?
  • What should you worry about if you're using more than one SQL connection in the same operation? Does the operating system matter?
  • What's a two-phase commit? When is it used? What does it mean to have a transaction "in doubt"?
  • You have a procedure that you've been told is running too long. What steps would you go through to track down and resolve the issue?

And these are just the questions for SQL 2k. The ones for 2k5 get even more fun.

Causal Awareness

One of the companies I worked with in the past once had fits because a significant portion of the internal user base failed to change their passwords from the system default. They implemented a nicely complex process by which you register, validate, and are then forced to change your password. Which is all very well and good ... you've reduced the risk caused by that one security hole.

But to me, this was a sign that the company needed to take some serious effort raising the awareness of its internal users about security risks. Seriously, if your users aren't aware that a default password is a bad idea, they certainly aren't going to be cognizant of the risks of, for instance, "social engineering".

October 08, 2006

Effective Teams

Busy, busy ... on top of the things that were previously causing me to be too busy to write, I'm now looking into the Netflix contest, as well as considering some things that could be done on my current contract.

I'm trying to come up with some team-building techniques. Not the goofy feel-good things that some managers, HR, and other examples of ESFx embrassingly foist upon us, but legitimate things. I've got a situation in which we've got 5 small teams in IT, handling development, maintenance, infrastructure, DB work, and QA. They aren't physically isolated, but they may as well be for all the communication that goes on. Also, IT is the red-headed stepchild of the company. There are other issues as well ... age disparity, high turnover (both voluntary and involuntary), an absence of process, etc.

I've got quite a number of ideas I'd like to try to introduce, such as employee-driven presentations across departments, little applications that the developers can run to watch things as the happen in ops, daily online natural language lessons by various employees, etc. I've been kind-of assuming the role of a team lead, of a sort ... more of a first sergeant to the platoon. Someone who can help them work through difficult problems, coordinate emergency reaction, keep them focused or, when necessary, distract them, etc., all without having to evoke the natural animosity the troops have for the officers. But the squads aren't working as a platoon, and the platoons aren't working as a, err, company. That needs to be fixed. I have no illusions that I know best how to do this ... I'm sure my list is far from complete ... so, any other suggestions of methods?

September 30, 2006

New Things to Read

I've added a few links to the list of things to read. I'll just mention a few of the articles I found worth noting...

Making Developers Cry Since 1995, which gave me the link to The Braidy Tester, mentions a number of things that testers and, therefore, application developers should be testing. There were a number of things I had not considered and did not know ... for instance, the fact that Windows has filesystem reserved words allowing access to, for instance, com ports. And the picture is particularly disturbing. The prior entry's reference to James Shore's Change Diary, a nineteen week effort to introduce aspects of Agile development in to a waterfall environment, is also an illuminating read. My own efforts toward this end have been more subtle and even more indirect, so it's reassuring to see some success documented.

CIO Magazine also has quite a number of good articles, and should be read if for no other reason than that it's reasonable to assume your CIO is reading it. Some of the items I found useful were How to Hook the Talent You Need, which describes both a shift in skill preferences for IT staff (a little overly optimistic, I think), as well as some of the things companies can be doing to acquire and retain good staff, and Tracks in the Snow describes other interpretations of failure and success with regard to software projects (although I'm not sure why we needed an article for this ... if you're in a waterfall shop, look at each step and figure out what failure in any one step looks like at the end.)

In other news, as a round-the-clock coffee drinker who has recently been introduced to the possibility that most commercial coffee is stale, and who enjoys the lack of effort necessary, during my somnambulant mornings, to use espresso pods, I am considering an automatic espresso machine. Any recommendations?

September 01, 2006

Notes on MSMQ

I've used MSMQ many times in the past. However, it's always been on my own systems, so I always exhibited the programmer's virtue of laziness and assume that I have correctly created the message queue and set its transactional state to what I expect it to be, and write my program accordingly.

However, this time I'm writing code that will set the standard for other programmers' work, and I don't maintain the infrastructure myself, so I thought I'd be thorough and do things like check for the existence of the queue and check to see if it was created to be transactional and behave accordingly. This all worked perfectly in my local development environment with its local queues.

But when I went to test the installation in the QA environment, I ran into all kinds of trouble. Specifically, all the properties and methods I was trying to use, with the exception of Send(), were throwing exceptions. 6 hours, lots of Googling, and 5 bodies later, I discovered the problem.

The functionality available in the MessageQueue object changes based on whether the queue being specified is local or remote, and which of the many queue path syntax you use. If you can't code for a specific environment (e.g., if the queue path is a configurable value) there is no way of knowing what functionality is available at run time other than trying to use a method or property and trapping the resulting exceptions.

This behavior is so incredibly bad in an infrastructure mechanism that it never occured to me that it would be coded this way, so I didn't even think of hitting the documentation of each failing method and property to see if it was actually available in any given context until I had exhausted every other possibility and scenario. And there were no googled pages that led me to conclude that that would be a good thing to do, despite other people obviously having the same problem.

So I'm putting this out there to prevent others from going through the same thing.

As an aside...
index -> indices
syntax -> syntices?

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 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.


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 04, 2006

Analysis and Accomplishment

Scientific American has an article out on the expert mind, which I found on a blog post here. Just a few quick comments on both articles...

Be sure to make a distinction between the mental tools of knowledge and those of analysis. Most people focus on the former, but it's the latter that make you expert, if for no other reason than the fact that the results of analysis themselves become knowledge, usually of a more useful nature (abstractions, relationships, etc.)

The article asserts that "success builds on success, because each accomplishment can strengthen a child's motivation." The phrasing of this statement makes it sound like speculation based on observation, not science. In my experience, it is more likely that the mental and physical tools that have been so well trained to accomplish one task find other tasks requiring similar techniques to be less difficult. If the difficulty reduces while the reward increases, you have motivation. Risk/effort -> reward analysis.

The case of D.H, who improved his chess skill by acquiring the knowledge of chess positions and associated strategies, but who did not exhibit additional analytical skills, is worth noting. This is a useful technique, and can be advantageous to a degree. An analogous situation in the IT world would be the definition of programming patterns ... defined techniques used to solve a particular large-scale problem. It's useful to have programmers on staff who know their patterns. However, don't ever mistake them for analysts. When the problems get particularly difficult, you want someone around who can define new patterns or not be limited in their creativity to what fits into a particular structure.

With regard to the chunking theory, please keep in mind your math theory lessons. A symbol can be viewed as equivalent to a function. Also, a symbol for a function can look exactly like the function. A collection of chess pieces in a particular pattern is not merely the data being stored in your head, but is also the visual, spacial, sequential, whatever pattern being used as the referent. Nifty thing ... a manipulated pattern of the knowledge resulting in a new pattern can then be used as a referent for another pattern.

July 31, 2006

Doing Things Wrongly

Our DBA had a problem. He was trying to figure out the best way to populate a bridge table with the full set of keys from two source tables. The answer was to do a simple Cartesian product. It hadn’t occurred to him. The problem was that he had it classified as the wrong way to do things. Not surprising, I guess … this site describing such joins points out that Cartesian joins are “usually done by mistake.”

Be sure not to exclude things from your arsenal of solutions by classifying them as “the wrong way to do things.” Sometimes the wrong thing is precisely what you need.

July 30, 2006

Design and Ambiguity

Eide Neurolearnings has an article on “ambiguity” and how developing minds deal with it. I disagree with many of their implications (for instance, that the difficulty children have in dealing with ambiguity is a discrepancy between the development of the reasoning and communicating abilities), not to mention the very … err … ambiguous use of the term, “ambiguity” in each of the associated articles.

So I will limit myself to discussing ambiguity in brainstorming.

There’s no such thing.

Oh, fine, I’ll elaborate.

This referenced article describes the tolerance of ambiguity as “the ability to live in a universe where there are no right or wrong answers, where ideas or thoughts are vague and yet unformed.” These are two very different things. The former phrase is an assertion that, epistemologically, concepts have little or no relation to reality and, therefore, can not be used to determine truth or validity in relation to reality (alternatively, it could just be embracement of the same old tired subjective reality beliefs … yawn.) The latter phrase, on the other hand, is useful ... a statement that concepts can be incomplete. In other words, a statement of “insufficient data”.

What does this mean for us in a design situation … how do we minimize ambiguity, identify it, resolve it, and keep it from causing problems in our projects? (Note that this is not an exhaustive list … I don’t describe, for instance, the things that must be done in the process of mapping abstracts to concretes.)

  1. Thoroughly define your context.
  2. Identify constraints (typically concretes, so be aware of how these are reflected abstractly.)
  3. Take measures to know what you know about every concept (attributes, intrinsic behavior, relationships, classifications, and methods of interaction), both in terms of completeness and confidence.
  4. Take measures to know what you don’t know, both in terms of requirements to accomplish the specified goal as well as deficiencies implied by context, interaction, relationship, and      methods of implementation.
  5. Figure out if the things you don’t know are relevant to the individual step in the chain of reasoning.
  6. Figure out if a later reasoned step mitigates a lack of information in a former step.
  7. Describe the efforts necessary to resolve each deficiency.
  8. If you choose not to break up the brainstorming session in order to resolve the deficiencies, figure out what you think the conclusion will be, give it a degree of confidence, a      significance with regard to subsequent conclusions, and a description of risk to the entire solution if your conclusion is wrong.
  9. Figure out if you can design out the risk (i.e., if a deficiency in knowledge has two ways in which it can resolved, determine if you are able to implement your solution in such a way that either case can be handled).

Omniscience is a fantasy. Beware anyone who never says, "I don't know." Train anyone who acknowledges ignorance, but doesn't yet deal with it in a structured manner. Embrace anyone who can describe for you a solution that compensates for ambiguity. Fire anyone who says, "You can't know."

July 28, 2006

Bathroom Code

I've worked in office buildings across this country, and there's something that can always be said, without fail. The bathrooms are always poorly designed.

In the building I'm currently working in, for instance, there's a narrow lane between the side of a stall and the sinks, which, in and of itself, isn't a big deal ... except that the paper towel dispenser and trash receptacle are positioned at the closed end of that narrow lane, so anyone washing their hands in any but the leftmost sink must get paper towels by crossing anyone to his left, dripping water on the floor and, possibly, his impediment's clothes. Also, the door is on the opposite side. Which means that those people who like to open the door with a paper towel protecting their hands (not that any of you fail to wash your hands thoroughly, you vectors) will frequently just throw the used paper towel on the floor. How tidy.

I have no idea why this would be the case. My only guess is that bathrooms are boring, so the job of designing bathrooms is given to the most junior people in the architect's office. Probably fresh out of school, rarely having worked in office buildings, not yet having trained themselves (or been trained) to design for practical use. Form follows function, but function includes actual use, not just theoretical, ideal use.

What's the equivalent of designing bathrooms on your project? Who's got the job, and what instruction did you give them?

A Little More On Exceptions

I've found a number of good links describing various aspects of exception/event logging:

Exception Handling Best Practices in .Net

Handling and Throwing Exceptions (MSDN)

Daniel Turini's Lair (Exception Handling Best Practices in .Net)

and then here's an IBM Redbook that provides some nice theory on the subject of Event Management and Best Practices.

And then there's this one here that I think needs some clarification and warning ...
he speaks of handling the errors "centrally", and what he appears to mean by that is to use a single uniform method (or collection of methods). No problem, provided you remember his other statement about using available context, and design your application infrastructure accordingly (i.e., if you have an exception way down at the bottom of your process stack, make sure you can convey all the relevant information you need to report, identify, and (hopefully) resolve the problem all the way back up, and that it can be handled correctly by that central event handler. This may mean defining a serializable wrapper class to encapsulate a set of contextual properties that can then be passed back up the chain, possibly across remoting boundaries, etc.

He also suggests reporting errors to the Windows Event Logs. "I'm going to have to go ahead and sort of disagree with [him] there."

There are many issues I have with writing to the event logs:

  1. For the most part you're stuck with text. It's nice if you can serialize objects that are relevant to the event/exception context and have them available for automated analysis. Sure, you could serialize them up as XML instead of binary, if you want to take the performance hit, but you still don't have a good way of deserializing and accessing them programmatically.
  2. If your application is running on one machine, no problem. If you're on a web farm, do you really want to have to check every machine's event log to get the information for whatever exception a specific customer is screaming about? And that's assuming you actually did use a centralized handler and don't also have to look on multiple tiers ... application servers, database servers, whatever. Sure, you can use a third party app like Rutherford suggests to monitor them all for you, but quis custodiet ipsos custodes?
  3. If your centralized exception handler is at the web level (as it probably has to be unless you don't care about web-level exceptions), are you really dumping your exception information to the web server's event log? With as much context information as possible so the exception can be tracked down? To a machine in your security DMZ?

July 27, 2006

Programming: Language and Thought

Programming is a difficult art to do well. I don’t mean the high level design or the specification of implementation patterns to use, I mean the actual “let me type up the implementation of this single procedure” effort. The problem lies in the need to have both structured, repeatable, consistent patterns of consideration and thinking, while simultaneously having a set of mental processes that lend themselves to innovation and unconventional insight. There’s the added difficulty caused by the fact that programming is often iterative in nature … you might add the portions of the code here, expect there to be interaction over there, and have to come back here to change things around based on behavior and expectation there.

Setting up a template of things to consider doesn’t work for many reasons, not the least of which is that, for the template to be useful across the board, it would have to be so generic and abstract that the concrete specifics of how to use it in a particular circumstance would allow the programmer so much flexibility that he’d dismiss the template entirely (which he would be inclined to do, since a template of what to think about would be offensive to him and his expensive training). Besides, if you have a template of steps to consider, you allow yourself to be constrained by that template, and innovation suffers.

Frankly, there is no solution. However, there are things that can be done to improve the situation by nudging the programmer’s mind in such a way that he considers certain aspects as part of his normal (and possibly unique) programming manner. The key is language and its use.

Words are referents that point to concepts. When you use a word, you’re indicating to a person that they should consider aspects of the concept. Multiple words might refer to the same concept, but indicate that different aspects of the concept should be considered relevant (this is one of the reasons that accurate use of language is important to unambiguous communication.) The structure of the language can also indicate a particular contextual framework in which the referred concepts should be evaluated.

Similarly, if you force a programmer to consider the language he is to use, or the structure he is to use, you can nudge his thought processes in such a way that he considers a particular necessary aspect of coding that he might otherwise overlook. As such, the person responsible for establishing a company’s (or API) coding style must consider areas in which he can provide this nudge. I’ll provide a few examples (please note that these are _examples_, and I will not enter into a debate about whether my particular example is the right or wrong way to do things.)

Classes, in general, reflect a conceptual entity. Therefore, classes should be named with the noun or noun phrase part of speech. By doing so, the programmer is forced to envision the thing and its intended context. Not only does this cause the programmer to more thoroughly evaluate that context (project business processes) allowing the team to identify deficiencies in specification, and also allows him to identify a meaningful hierarchy of related concepts such that a class hierarchy can be defined, but it also makes it easier for him to keep a mental image of the entity being modeled in mind as the coding proceeds.

Properties and methods have their own requirements and naming styles that can lend themselves to better development style. I’ll address these in the comments if necessary, but otherwise I’ll leave it as an exercise to the reader.

The Microsoft Visual Studio environment allows a developer to construct code “regions”, which are just delimited areas of code identified by a common name (with the ability to collapse everything down to a single node identified by that name.) If the coding standards require regions based on the access type of a particular property or method (e.g., #region Protected Methods), that reminds and encourages the programmer to evaluate what access level is actually appropriate, since recommended practice requires that you use the most restrictive that is reasonable.

There are times when resources must be closed or explicitly released (in the case of interacting with unmanaged code or GDI objects, given a few Microsoft GDI leaks), but programmers will frequently forget to consider this. If your coding style always requires that every code block be put in a Try … Finally structure (given that the Finally block is usually where you want to do that kind of clean-up), then the programmer is reminded in every procedure that he should evaluate whether that kind of clean-up is necessary. You don’t want it to be a Try … Catch or Try … Catch … Finally block, because this would encourage the programmer to unnecessarily handle exceptions, and this is not recommended practice.

Keep these techniques in mind, and consider them when documenting your own coding standards guides. Comments of other suggestions welcome, of course.