Worst. Best Practices Book. Ever.

As you may or may not know, I generally critisize things on a daily basis. But this post is much different than my normal (hopefully witty) commentary on bad code. Today I'm pointing out some serious flaws in a book I came acrossed called Practical Guidelines and Best Practices for Microsoft Visual Basic and Visual C# Developers that make the book not only bad (which I can live with) but dangerous for an inexperienced developer. Not only does it fall short of "best practices," but it actually advocates bad practices. In summary, DO NOT BUY THIS BOOK. And if an enlarged & emboldened statement isn't enough, read on ...

Although Balena and Dimauro are MSDN Regional Directors (a prestegious title, I think), they are no where near "IT legend" status (unlike Don Knuth [pdf], Andrew Tanenbaum, Ed Yourdon, etc.). You would think they would supplement their lack of credibility with cold hard facts and research, but no, they just seem to make up arbitrary figures (pp 139, "avoid methods longer than 50 executable statements") and shove them in the book. And what's with 50? Why not 60? Why not 45? Look at a good book (Code Complete by Steve McConnell') and see that Steve backed up his best practice on method length with six different studies. SIX!! You won't find a single reference in this book.

On to the content, the authors use the words "always" and "never" way too much. The architects behind the .NET Framework didn't put in "forbidden fruit" that looks tempting but should never be used. For example, on page 325, they say that you should never catch the ThreadAbortException. What they don't mention is that catching ThreadAbortException (and ThreadInterruptedException for that matter) is the *only* way to gracefully clean up and exit from a sleeping background thread using unmanaged resources. This happens more often than you'd think; if you're interfacing directly with specialized hardware that takes a long time to do process (like a printer), you would put that in a background thread that waits for the printer to finish. If the user closes the application (and the background thread doesn't catch the Thread exceptions), you're hardware could be hung up.

Another example, on page 191: "All events must define two parameters. The first parameter is an Object named sender; the second parameter is an instance of the EventArgs type (or a type that derives from EventArgs) and must be named e." Wrong, wrong, wrong! An event can have any number parameters of any type with any name. That may be the way *most* events are handled, but it's certainly not what you *must* handle events. A lot of times there is no need for a sender reference or event arguments.

They also seem to really like the words "right"/"wrong" and "correct"/"incorrect". Let's take a look at page 140:
  ' *** Wrong: uses incorrect casing, type is embedded in parameter name.
  Sub PerformTask(ByVal UserName as String, ByVal boolIsAdmin as Boolean)
  ' *** Correct
  Sub PerformTask(ByVal userName as String, ByVal isAdmin as Boolean)
Their way is neither correct nor incorrect. It's simply a preference, it also happens to be the same preference that Microsoft spells out in MSDN, but they actually use the term "preference." Ironically, on the very next page (pp 141), they use a class named "frmMain." This is one of many examples where their preference doesn't line up with Microsoft's preference. MSDN prefers MainForm.

Next, the authors focus on "speed and efficiency" as if it's 1963 and a few CPU hours cost as much as a car. In the world of BILLIONS (1,000,000,000's) of cycles per second (Ghz), it really is ok to "waste" a few cycles on making sure your code is easier to read and maintain. You wouldn't get that impression from reading this book as a beginner:
pp 127: "the as operator ... speeds up execution"
pp 149: "Return keyword enables the compiler to optimize your code more efficiently."
pp 251: "language specific functions perform worse"
pp 253: "the ChrW function is faster"
pp 257: "the CompareOrdinal static method ... is typically faster"
They did not drive the point of maintainability over speed. 100 clock cycles will make ZERO difference on a 10 millisecond request.

I've also found that some parts of the book are hopelessly out of date. It would appear that the authors have not yet fully entered the world of .NET themselves. Take for example page 408, where they provide a rather "Classic ASP" method of setting the page title: <title><%=GetTitle()%></title>. The ".NET" way of doing this would be either using a literal <title><asp:literal id=pageTitle runat=server></title>) or making the title tag a server tag (<title runat=server id=Title/>).

It would also appear that the authors have little to no knowledge of relational database design. On page 380 they say "Don't use primary keys that have meaning for the end user, such as invoice number or the ISBN value." This is beyond absurd and defeats the whole purpose of "relational databases". Don't take my word for it, of course; ask any "Database 101" student or read it straight from the creators of relational databases (EF Codd and CJ Date). The authors' technique is as close to a COBOL-mainframe-flatfile method of development you can possibly get and is, ironically, what relational databases were designed to fix.

And on top of all of this, they're inconsistent in following their own "best practices." On page 251 they say "don't use Visual Basic-specific string functions, such as Len, Left, and Mid." Flip the page (pp 253) to another tip and see "favor the ChrW function over the Chr function." No mention about using "Convert.ToInt16," which they suggested as a replacement just on the previous page. And speaking of using "Int16", they didn't follow their own advise of "Use 32-bit integer variables" as suggested on page 240. And why int32? Because they're faster!

I really do hate to be so negative about this book. Yes, it does have some decent tips that will help an inexperienced developer. But at the same time it has some absolutely horrendous tips and there is absolutely no way that an inexperienced developer could distinguish between the good and bad. Stay clear of this book. Buy McConnel's Code Complete instead.

Published Tuesday, March 15, 2005 9:57 AM by Alex Papadimoulis

Comments

Tuesday, March 15, 2005 10:47 AM by el Nino

# re: Worst. Best Practices Book. Ever.

I agree with all your criticisms but one. The issue of primary keys being meaningful or meaningless is a real debate and I fall on their side.

The issue is that ideally, primary keys should be immutable for a record (because it is referenced in many other tables with foreign keys.) If it is meaningless (i.e. a numeric counter), then that should be the case.

However, if you use a meaningful primary key like SS#, invoice# or ISBN value; it is possible that a user may mistype those values when entering records in the database. At some point in the future, someone needs to go back to that record, and want to correct the mistake. If there are a ton of references to this primary key, that could be a very expensive task (e.g. you have to go through all dependent tables and make the same update.)

In general, I like to use a meaningless primary key like "BOOK_ID" which is just a sequence type, and have a unique key for ISBN value so that uniqueness is still enforced, but there is no expense of updating that field.

There are exceptions--so they should not use the word never, but I believe it is good practice.
Tuesday, March 15, 2005 11:25 AM by The REAL Josh Anderson

# re: Worst. Best Practices Book. Ever.

I totally concur with el Nino. I find myself searching for other ideas to back him up, but there is no need. Top notch, el Nino!!!

Perhaps someone should write a scathing article about the "credibitliy" of this article... :)

Tuesday, March 15, 2005 11:33 AM by Barry Kelly

# re: Worst. Best Practices Book. Ever.

"Don't use primary keys that have meaning for the end user, such as invoice number or the ISBN value."

For relational DBs which are mapped to OO classes with some kind of business object mapping layer, there isn't much value in primary keys with business meaning, while there are drawbacks.

Business meanings (and codes) can and do change. Depending on what kind of tools you have available to change all your primary keys this may or may not be a big burden.

Not disagreeing with the overall jist of the review of the book (which I haven't read), just a point to consider.
Tuesday, March 15, 2005 11:48 AM by Stefano Demiliani

# re: Worst. Best Practices Book. Ever.

I had received in october a first preview of this book (written in italian language) and what I can say is that the preview I have in my hand is a good book, with lots of useful optimization tips.
I'm shocked to listen this opinion.
Tuesday, March 15, 2005 12:01 PM by Ian Cooper

# re: Worst. Best Practices Book. Ever.

I also fall in the 'avoid using natural primary keys' camp, if only because too often natural primary keys often turn out not to be so, or are incorrect and need changing. My, bitter experience, rule here would be to avoid natural primary keys or in the worst case avoid natural primary keys that you do not manage.
Tuesday, March 15, 2005 12:23 PM by Karl

# re: Worst. Best Practices Book. Ever.

I haven't seen the book, but this type of stuff really makes my blood boil. Assuming your description is modestly accurate I'm totally with you...
Tuesday, March 15, 2005 12:51 PM by Scott

# re: Worst. Best Practices Book. Ever.

+1 on not using PK's that have a business meaning. IMO you always want a PK that doesn't related to the data in the row in any way. Whether you use an int or a GUID is up for debate, but not picking a business value for a PK isn't.

At the very least, if you are going to use a buisness value for a PK, use it in a compound PK with an arbitrary value.
Tuesday, March 15, 2005 2:22 PM by Joe

# re: Worst. Best Practices Book. Ever.

Your comments seem harsh: I haven't seen the book, but I would for example expect a "best practices" book to recommend using the standard capitalization styles and the standard sender/EventArgs pattern for events -I'd interpret "right/wrong" in a "best practice" book as meaning "should/shouldn't", rather than being dogmatic.
And I don't see anything wrong with "<title><%=GetTitle()%></title>." - I've seen "<% %>" recommended by Scott Guthrie as an optimisation technique, and it might save a picosecond here. "runat=server" would be better if the VS.NET designer didn't keep deleting it (fixed in VS 2005 I believe).

However I won't get sucked into the tired old Surrogate vs Natural PK debate.
Tuesday, March 15, 2005 3:11 PM by Ian Smith

# re: Worst. Best Practices Book. Ever.

I find it somewhat ironic that somebody who nitpicks about words like "right" and "wrong" has the cheek to call this the WORST book EVER!

I thought the book was excellent. Too many shops don't have standards or guidelines and the Microsoft Design guidelines are impossible to print or get in any sort of cogent form.

The great thing about this book is it explains the reasoning behind its guidelines. It sometimes suggests alternatives that are the opposite of its recommendations, but explains why you should choose one solution over another.

Having given a guidelines or rule AND explained the reason for it it gives concrete code examples to illustrate (the "right" and "wrong" you so strongly object to).

I've bought a lot of rubbish books in the past (mainly from Wrox or Microsoft Press) but this is NOT one of them.

Your personal attack on the authors (are we supposed to think that while they are not in the "IT legend" league of Don Knuth - YOU are???!!!) smacks of some sort of personal grievance rather than an honest review of a book that will prove extremely useful in many shops. It's readable by the average developer (which I would argue Knuth's dry academic work isn't) I don't know the authors and have no idea whether they are industry guru's or not. I DO know that their book will save a lot of people time and effort in drawing up standards. And it's easy to read and reasonably priced too.

I, too, like "Code Complete" but it, too, can be rather dry at times and is a long read. This book makes a handy read for those trying to get up-to-speed on agreeing standards within a typical .Net shop on tight timescales. I highly recommend it.
Tuesday, March 15, 2005 3:33 PM by Alex Papadimoulis

# re: Worst. Best Practices Book. Ever.

The title was a bit of a pun, ala Simpons' comic book guy.

Guidelines are great, but this book falls short of explaining the difference between preference and correctness. And for many explanation, there is a poor reason WHY. "It's optimizes better" is a bad excuse for their belief.

I did not intend my review to be perceived as a personal attack on the authors. The fact of the matter is they have no established credibility. Nor do you, nor do I, nor do the vast majority of us. This is why most people who write books use references from either people with credibility or from research. The authors did neither.

The book as potential. But as I see it, it's hardly of "beta" quality. One incorrect paragraph outweighs twenty correct pages.
Tuesday, March 15, 2005 6:23 PM by (luKa)

# re: Worst. Best Practices Book. Ever.

I've attended Balena and Dimauro talks, I've read Balena and Dimauro articles and used Balena and Dimauro sample code and after that can say that I can really trust their work: they are great!!!

No book, talk, article always tell *all* the true with *all* the details, some semplification is *always* necessary to focus on the main topic and to reach the target readers. Probably you just misunderstand the book topic and just focused on irrelevant details ;-)

I do not agree with your review and I think that make no sense to compare
Wednesday, March 16, 2005 8:25 AM by Francesco Balena

# Worst. Best Practices Book. Ever. - Some notes from the authors


Being one of the authors of the "Practical Guidelines and Best Practice ..." book, I guess I ought to jump into the discussion. Needless to say, I respect your opinion. Actually, I am very impressed by how carefully you read the book and weighed each of our sentences... and I am equally impressed by how cleverly you quote them out of their context to support your line of reasoning. Just because you proved to be such a careful reviewer, it's really odd – so to speak – that you omitted so many important points. I assume that you are too ethical to do it maliciously and on purpose, and I am glad I have the opportunity to make your review more complete and useful.

Let me begin with the first inaccuracy in your post. Being a MSDN Regional Directors isn't a volunteer position, at least not in the sense you subtly imply. Your readers might believe that everybody can become and RD if only he or she wishes so, but this isn't the case. Microsoft Corp. carefully selects one or two RDs among recognized expert developers in each US state and foreign country: as a matter of fact there are only 140 RDs all over the world.

Giuseppe and I are the only two Regional Directors for Italy and we are very, very proud to be part of this team. It is true that we all are volunteers, in the sense that we aren't Microsoft employees and aren't paid by Microsoft just to be RDs. On the plus side, our RD status gives us the opportunity to train and consult for large MS customers (and for MS itself), and work at many complex software projects. What we learned in the process lead us to the idea to gather our *practical* experience in a book.

Of course, being just an RD doesn't make us software legends and for sure we aren't in the same league as the gurus you name. Unfortunately, a casual reader of your blog might conclude that we dare to compare ourselves to those living myths, but this isn't the case. We neither claim nor imply anything like that. More simply, we have written software for two decades and believe that we have something interesting to say on the topic. Period. That entire paragraph is a product of your imagination.

You're correct: we often use "always" and "never" adverbs. However, you curiously omit to mention that we complement all controversial guidelines with an explanation of when you should apply them, why you shouldn't, if there are exceptions, and so forth. We believe these additions largely compensate for those strong adverbs. By the way, most guideline collections – as well as Microsoft's own FxCop tool – use sentences beginning with "Do" and "Don't", so at least we are in good company. As one of your readers suggests, in this context "right/wrong" is to be interpreted as "should/shouldn't", and it's a convention used in many guideline collections. Thank you very much for your notes, though: If I ever write an English grammar textbook I'll surely keep them into due account.

You're also correct about a 50-lines-per-method guideline. In the hurry to post your review, however, you forgot to quote the entire paragraph, which reads as follows:
"Try to avoid methods longer than 50 executable statements. If necessary, split the method into multiple procedures. Shorter methods improve code readability. In addition, the JIT compiler can inline short non-virtual methods (fewer than 32 bytes of IL code) that don’t contain Try (Visual Basic) or try (C#) blocks, or conditional or loop statements, and that don’t receive a structure as an argument."

An unbiased reader would probably agree that the complete text is much less generic or rigid than your cleverly-clipped quote suggests. As for me, the omission of the leading "Try to" provides interesting hints about the selection criteria you adopted when excerpting our guidelines.

I won't even try to defend our guidelines, except to notice that, coincidentally, all the ones you mention have appeared, in one form or another, in MSDN articles and are normally regarded as official Microsoft guidelines. In other words, you just picked up the wrong target for your criticism, even though I understand that it's easier to criticize us rather than the people who actually created the .NET Framework and that know it better than everyone else. You can surely argue about the exact wording we use, but the substance is the same.

An unbiased review would mention that the book contains over 700 rules for 600 pages, that the "questionable" rules are therefore a small portion of the overall contents, and that nearly all of them belong to the "coding guideline" portion (less than half of the book). The bulk of the book, in fact, is about best practices in Windows Forms, ADO.NET, ASP.NET, COM+ and remoting-based applications.

Here's another (causal?) omission in your review. In the intro, we explain that we sorted our guidelines according to the goals each one is meant to reach: robustness, security, scalability, efficiency, usability, code reuse, extensibility, maintainability, interoperability, ease of development. In other words, we recommend a guideline that buys you faster execution only if it doesn't affect the robustness, security, and scalability of your applications. We aren't obsessed by speed and we do our best to illustrate the trade-offs of all the recommendations we make. Our goal is to enable readers to make informed decisions. We deem our peers to be smart enough to understand when a guideline should be applied, once they know its pros and cons.

While on the topic of execution speed: most of the techniques you consider as questionable can make your code run faster by at least 50%, or more. If the offending statement appears in a tight loop they can save you a significant amount of time, not just a few CPU cycles. In a server-side component this sort of optimization makes the difference and can positively affect scalability - I am surprised you missed the point.

Also, you mention the "as" operator, the String.CompareOrdinal method, and VB's ChrW function (and others) as factors that can decrease code readability. Granted, not all developers are familiar with the advantages of these *standard* and *documented* techniques, and this is precisely why we wrote these guidelines. Please notice the emphasis on "standard" and "documented": we aren't advocating any undocumented and obscure code technique that might undermine the readability of your code. It's just plain C#, VB, and .NET stuff! Where is the danger you mention at the top of your review?

In case you haven't noticed, programmers usually buy books to improve their skills and learn about features of the language or the .NET framework they aren't already familiar with. If you weren't so biased, you'd probably see that it's the most laughable argument in your review.

ironically yours,

Francesco Balena
Wednesday, March 16, 2005 3:31 PM by TrackBack

# Author responds to

Wednesday, March 16, 2005 3:54 PM by TrackBack

# La risposta di Francesco Balena e la replica...

Wednesday, March 16, 2005 4:05 PM by TrackBack

# Picking a fight with a book author

Wednesday, March 16, 2005 6:33 PM by Free Beer

# re: Worst. Best Practices Book. Ever.

The world is full of mixed messages.

I do try to follow best practices but there in no chance I would have bought this book. I use MSDN and FxCop and I try to understand.
I believe that premature optimization is bad, I think that coding based on what the JIT might optimize is often premature.

I like my RD a lot, but before he starts telling me what best practices are he better sit down and start working in some projects, not just training and consulting.

The primary key thing is a burning issue. Burning issues should be expressed as such.

Just today I caught and swallowed a ThreadAbortException, it was the right thing to do, it was from a response redirect and it was poluting the event log.

I use the "as" operator all the time. I find it easier to understand and cleaner than catching invalid casts.
Wednesday, March 16, 2005 7:56 PM by WilliamT

# re: Worst. Best Practices Book. Ever.

Dar Alex,

While I would reserve my judgement about the book and your comments, there is one statement you made which I find rather unfair and unprofessional and crossing the lines of a personal attack

> Don't let the "MSDN Regional Director" title fool you: it's a volunteer position. You would think they would supplement their lack of credibility

How (well) an author writes a book is not dependent on his title as such...and vice versa, a person's title/appointment/award is has no bearing on how (well) he writes a book or treats his dogs, etc etc.

Going by your token, one can easily imply that someone who works in MS is bound to churn out a classic ? How a person carries out his duties should have no relative bearing on what he is awarded or appointed.

That statement you made is also a "blanket" statement because you are effectively making a public statement against 140+ folks who are appointed their positions based on a number of (selfless) activities they have done that have contributed greatly to the dev communities. Writing a book is one, BUT knowing how to write a good book THAT statisfies everyone is definitely NOT one of the criteria.

Now, I wonder what kind of flames you would incur if you substituted the Regional Director role with that of a Microsoft Valuable Professional one. (Both are voluntary as well) Now you deal with thousands more people.

Having said that, my point is that personal statements like that can be sometimes viewed as personal and discriminatory. While I agree that having an appointment or title, regarless whether it is voluntary or not, does hold some weight in the public's eye; it should not be used as part of a basis of attack against someone's work just because you do not like it.
Thursday, March 17, 2005 3:12 AM by TrackBack

# La risposta di Balena

Thursday, March 17, 2005 4:17 AM by Carl Franklin

# re: Worst. Best Practices Book. Ever.

> Today I'm pointing out some serious flaws in a book I came acrossed called <

Just when did you come acrossed this books?
Friday, March 18, 2005 6:47 PM by Martin

# re: Worst. Best Practices Book. Ever.

Umm, have you ever worked on a website with 15 million members, and an average of 3 million visitors a day, that spend more than 2 hours on average? You see, in situations like that speed is very important. A single try statement, when repeated billions of times, can brake your application.

When I was working on measly sites back in the day I was thinking the same way about processors and memory... Fortunatly, as I've found out speed and memory is very much important unlike human readibility which doesn't really make a shred of difference once a project is finished and encapsulated in the right way, which seems to be lacking with you.

As far as 'right' and 'wrong' go... It really is wrong.

' *** Wrong: uses incorrect casing, type is embedded in parameter name.
Sub PerformTask(ByVal UserName as String, ByVal boolIsAdmin as Boolean)
' *** Correct
Sub PerformTask(ByVal userName as String, ByVal isAdmin as Boolean)

You see, it is wrong because the two parameters have different names. I've never seen a standard or preference where one parameter will be lower case first letter, and the next one upper case first letter. What are you? Retarded? Learn how to critisize, learn how to program, and then make a blog.
Monday, March 21, 2005 6:29 AM by heinzkunz

# re: Worst. Best Practices Book. Ever.

"You see, it is wrong because the two parameters have different names. I've never seen a standard or preference where one parameter will be lower case first letter, and the next one upper case first letter. "

True, but these are standards, or preferences. It is not "wrong" to use or not use them, while it certainly is wrong to label them "wrong" or "right".
Wednesday, March 23, 2005 1:18 AM by Entropian

# re: Worst. Best Practices Book. Ever.

It's a good thing that they don't engineer bridges the way software is "engineered", otherwise all the effort would go towards things like inventing the "Gravity Makes Things Fall - Pain Hurts" pattern rather than focusing on keeping the damn thing standing.


Let's be honest, we are just making this up as we go along - maybe in a couple hundred more years of doing it there will be some 'right' answers, but current "Best Practices" of software development are really more like "Practices That May Lead To Deliverables Other Than Heat, Or At Least Have For Me More Than Once"
Monday, April 04, 2005 1:02 PM by George Handlin

# re: Worst. Best Practices Book. Ever.

I'm in the camp of not making the PK meaningful. I was bitten by that one when I was starting out. Suppose the original thought was the invoice number would be the PK and it would just increment up like a checkbook. So you make the PK a int. Then the rule changes and the invoice number now needs to be coded to show the department that it's primarily from. So 1234 now becomes 1234-REC. Trouble. My belief and what I teach people is the PK should never be a meaningful piece of data.
Wednesday, April 13, 2005 6:52 PM by TrackBack

# Practical Guidelines and Best Practices for Microsoft Visual Basic and Visual C# Developers

Monday, December 18, 2006 3:00 AM by tina helen

# re: Worst. Best Practices Book. Ever.

I've found out speed and memory is very much important unlike human readibility which doesn't really make a shred of difference once a project is finished and encapsulated in the right way.

Tuesday, March 27, 2007 2:49 AM by Alisya

# hi

snowgirl_814@hotmail.com

I suspect that's thereason general public want to read blog....Internet visitors generally create blogs to declare themselves or their secret views. Blog grant them same matter on the monitor screen what they specifically needed,so as the above stuffs declared it.

Leave a Comment

(required) 
(required) 
(optional)
(required)