Latest Posts
So there I am browsing a couple of internal sites suddenly IE7 switches into a mode where it shows me thumbnails of all my open tabs.
"Wha happan??"
I pressed ESC and it went away. But then I couldn't figure out what did it. No combination of Shift, Ctrl, Alt + Tab would do it. Hmmm... Oh well... Back to work.
Five minutes later it happened again. Twice was enough for me to find the pattern.
I was using Outlook Web Access (aka OWA). For a long time I've been a stickler for keeping track of which messages I've really read and which I haven't. So in regular Outlook, I turn off the "auto mark as read" feature of the preview pane and manually mark as read or unread using Ctrl+Q and Ctrl+U.
A thought that back in IE6, Ctrl+Q behaved that way in OWA too, and for all I know the code is still there. But now, in IE7, when I press Ctrl+Q I get the thumbnail view:
Very cool! Not sure how much I'll use it, but it is neat. It also got me wondering about other shortcuts. I'm sure there are more, but I also found that it support Ctrl+1, Ctrl+2, etc. for direct selection of tabs. (Firefox does this too.)
I'm surprised how often I have to say this to other developers and engineers, but violations of this simple object-oriented mantra seems to be everywhere. Almost every time I look at a class inheritance hierarchy, I find this principle violated.
Why is this use of inheritance bad? First of all, let's talk about what inheritance is good for:
- Polymorphism - In OOP, this means that you can treat derived classes as if you had been passed an instance of the parent. This was formalized by Barbara Liskov in her 1988 paper "Data Abstraction and Hierarchy". Another way to say is is, "Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it." [Martin-96]
- Categorization - The process in which ideas and objects are recognized, differentiated and understood. Categorization implies that objects are grouped into categories, usually for some specific purpose. Ideally, a category illuminates a relationship between the subjects and objects of knowledge.
Let me refer you to the wonderful book, C++ Coding Standards: 101 Rules, Guidelines, and Best Practices
by Herb Sutter and Andrei Alexandrescu:
Despite two decades of object-oriented design knowledge, the purpose and practice of public inheritance are still frequently misunderstood, and many uses of inheritance are flawed.
Public inheritance must always model "is-a" ("works-like-a") according to the Liskov Substitution Principle: All base contracts must be fulfilled, and so all overrides of virtual member functions must require no more and promise no less than their base versions if they are to successfully fulfill the base's contract. Code using a pointer or reference to a Base must behave correctly even when that pointer or reference actually points to a Derived.
...
Public inheritance is indeed about reuse, but not the way many programmers seem to think. As already pointed out, the purpose of public inheritance is to implement substitutability. The purpose of public inheritance is not for the derived class to reuse base class code to implement itself in terms of the base class's code. Such an is-implemented-in-terms-of relationship can be entirely proper, but should be modeled by composition—or, in special cases only, by nonpublic inheritance (see Item 34).
Let me call out one of the more importance sentences in that quote:
The purpose of public inheritance is not for the derived class to reuse base class code to implement itself in terms of the base class's code.
The inheritance relationship is one of the strongest coupling relationships we can have in OOP. Everyone knows that coupling is bad and cohesion is good, but we still couple like mad via inheritance. We do this for a number of reasons, but one of the big ones is that very few college grads seem to get taught this in school. It makes me wonder how many undergraduate compsci teachers actually get it. Daniel Pietraru wrote a bit about this and how he has used inheritance questions as interview questions.
The other reason I think it is so common is that our languages and tools make it look so easy and so proper. Even Fowler-esque Refactoring has refactorings called "Pull Up Method/Field/etc." that seem to be all about putting shared code into the base class. There is also the Abstract Test Pattern in TDD which specifically describes using base classes as "a way to reuse test cases".
Whenever possible, you should look to use composition instead of inheritance in your designs. The problem is that composition is harder to do, even though it results in cleaner more modular designs. Despite that, composition has a number of benefits over inheritance. Again, I'll let Messrs. Sutter and Alexandrescu tell it (remember that some of the techniques for pointers and such are very C/C++ centric and aren't relevant here, but the underlying meaning is still true):
Composition has important advantages over inheritance:
- Greater flexibility without affecting calling code: A private data member is under your control. You can switch from holding it by value to holding by (smart) pointer or Pimpl (see Item 43) without breaking client code; you would only need to change the implementations of the class's own member functions that use it. If you decide you need different functionality, you can easily change the type of the member or the manner of holding it while keeping the class's public interface consistent. In contrast, if you begin with a public inheritance relationship, it is likely that clients have already come to depend on the inheritance; you have therefore committed your class to it and cannot easily change your base class decision later on.
- Greater compile-time insulation, shorter compile times: Holding an object by pointer (preferably a smart pointer), rather than as a direct member or base class, can also allow you to reduce header dependencies because declaring a pointer to an object doesn't require that object's full class definition. By contrast, inheritance always requires the full definition of the base class to be visible. A common technique is to aggregate all private members behind a single opaque pointer, called a Pimpl.
- Less weirdness: Inheriting from a type can cause name lookup to pull in functions and function templates defined in the same namespace as that type. This is very subtle and hard to debug.
- Wider applicability: Some classes were not designed to be bases in the first place. Most classes, however, can fulfill the role of a member.
- Great robustness and safety: The tighter coupling of inheritance makes it more difficult to write error-safe code.
- Less complexity and fragility: Inheritance exposes you to additional complications, such as name hiding and other complications that can arise in the presence of later changes to the base class.
In essence, inheriting for code reuse makes your design brittle. Changes in strange places manifest themselves in even stranger places. If your language doesn't support multiple inheritance (like C# and Java), then if you use an form of class-based inheritance in your code, you are effectively preventing good Liskov-style inheritance by people who consume your code. Bad bad bad bad.
When you do use inheritance from a base class in your design, look for these gotchas:
- Protected methods in the base class - This is the stink that is the smell that Herb talks about above.
- Calling public methods in the base class from the derived class - Slightly less smelly, but still not good.
Honestly, it makes me want to try to eliminate all nonabstract inheritance in my code. In languages with good duck typing, I'd say eliminate inheritance entirely, because in those systems the only good reason to use inheritance is for derived class code reuse. I know this is an over aggressive reaction but I do wonder what our code would look like if we had good composition constructs in the language (we don't) and if we either went with pure duck typing (ala Ruby) or interface-only inheritance.
Like that's gonna happen...
Jim Newkirk, Brad Wilson and I have been in agreement about the evils of ExpectedException for a long time. When Jim and Brad wrote xUnit.net, in fact, they left it out and opted instead for a new Throws method that lets you be a lot more precise about what and when you are testing the exception.
But NUnit 2.4.x doesn't have this feature (2.5 will). Fear not! Jim has written a nice little sample of the Throws method for NUnit 2.4.x that provides this same experience in his new post Replacing ExpectedException in NUnit.
If you are using NUnit today, I would really suggest you read the post and consider changing the way you test exceptions in your unit tests.
Time for another trip home to the mother ship for my monthly dose. I'll be in building 25 all week and staying at my (still unsold) house in Sammamish. Looking forward to some quality face time with my team.
I used to use the Microsoft Virtual CD-ROM tool, but the public one doesn't work in Vista. I also used Daemon Tools, but apparently it now bundles some SpyWare so I won't touch it.
After a bit of digging today, I found this: Mount and ISO Image in Windows Vista :: the How-To Geek
It works perfectly and is free.
PS. I still don't understand why this isn't baked into the OS, but it isn't.
Found this little gem while looking for something else... thought I'd share it.
When you have a computer with a recent model CPU, chances are it's a dual-core CPU. Both Intel & AMD have been producing dual core CPU's for a few years now. By default, Windows Vista will only use a single core during boot-up. You can easily change this from the System Configuration utility:
- In Vista's Start Search type msconfig & hit the [Enter] key on your keyboard
- Once System Configuration has started, select the Boot tab and click the Advanced Options button

- In the BOOT Advanced Options dialog, check the "Number of processors" check box, and choose 2 (or 4 if you have quad core) for the number of processors.
- Click OK twice.
Done and done. :)
I've been a tequila sipper for years. When I was young I had an incident with whiskey that put me off it, possibly for life, and tequila has nicely filled that gap.
I know the difference between good tequila and bad tequila. Good tequila is 100% blue agave and has a little number on the label that say NOM ####. That number if the distillery registration number. Look for it.
My good friend and fellow tequila sipper Aaron Mikulich sent me this great article today that sums up good tequila better than I ever could:
bbum’s weblog-o-mat » What is good tequila?
A choice quote from the beginning:
First, Cuervo Gold is not good tequila. It is actually a really terrible product, quality wise, backed by some brilliant market. Sadly, most of the tequila consumed in the United States is Cuervo Gold or something equally as bad. And by “bad”, I mean bad taste and vicious hangover.
Amen brother!
We use OneNote a LOT at work. Once you get used to it, it is basically an offline Wiki. You can link all over the place easily, store it on a server to share, and work offline. I love it.
But once you get to using it this way, you end up with a whole bunch of notes. It can be hard to find something when you need it.
Enter OneNote Instant Navigator...
Assign a hotkey (I use Win+I) and now you can very quickly get to any note you want. I love it.
UPDATE: Forgot the link: http://i-navigator.hut2.ru/
Cameron Skinner, the Product Unit Manager for VSTS Architecture Edition, has returned to the blogging world by announcing (a little bit late) his new role.
Skinner's Blog : New role running the VSTS Architecture Edition team
Hopefully he'll keep blogging more!
I know Chris Tavares mentioned this at work one day when I was at P&P, and I'm very excited that he blogged it and made it so easy to do.
The last vsvars32.ps1 I'll ever need
I made one tiny modification, which is to default to 9.0 instead of 8.0 since that is the environment I use, but other than that it seems to work great.
Thanks Chris!
Not sure how I missed this, but a few weeks ago the patterns & practices team released Enterprise Library for VS 2008 (aka EntLib 4.0).
Grigori Melnik has blogged all about it here:
http://blogs.msdn.com/agile/archive/2008/05/16/enterprise-library-4-0-for-visual-studio-2008-released.aspx
Check it out! Lots of good stuff in there!
I'm always digging around looking for people talking about our stuff. FOund another one today by Willy-Peter Schaub, an MVP. He does a pretty good job, with screenshots and all that, of talking about the features in the CTP.
Rosario April 2008 CTP Investigation (Part 3) - Architecture - Willy-Peter Schaub's Cave of Chamomile Simplicity
Enjoy!
I'm back from TechEd 2008 Developer where we showed off not only our VSTS 2008 stuff but spent a lot of time talking about our Rosario features and in particular our UML support.
We got some time in the Billg keynote which was great, had thousands of excited customers come by our booth and I did a session all about Team Arch Rosario on Friday.
Feedback has been continuously positive and we're all very excited about what we're doing and about how customers are feeling about it. The UML direction seems to be very positive so far.
Also, via Mark Groves I found another blogger talking about our stuff, this time with a demo video of Reverse Engineering UML Sequence Diagrams from code. I've yet to do a demo of this where people don't get excited.
http://theumlguy.spaces.live.com/blog/cns!B4665B67C2981533!136.entry
Enjoy!
I see this get discussed all the time on some of the agile aliases I'm on.
I care how much time is left, not how much time you spent on it.
I know people like to talk about “using the data to make our estimating better” but there are flaws in that argument that just can’t be ignored:
- Nobody ever does it. In fact, I don’t even know of a process to achieve this. Hollering at people who over/under estimate is not an improvement process.
- It assumes you can make developer estimates better. More experienced developers estimate better, that I’ll take as a given, but can you accelerate this with novice/junior developers or testers? I don’t think so.
- Software is NOT like mechanical engineering. It is a craft. Every activity you do is very likely the first time you’ve done it exactly that way. So our inability to accurately and precisely estimate shouldn’t be all that surprising.
At least that’s how I see it. :)
Jeff Levinson's has followed up his last column on the April 2008 VSTS CTP with a new one called The Joy of Sequence Diagrams.
In this article Jeff reviews the Logical Class Diagram and the Sequence Diagram.
My favorite bit:
The benefit of the revamped diagrams is that not only can the represented information be semantic, but it can also be non-semantic. That is, it can be used to communicate ideas and thoughts without adding any particular constraints to a solution. This makes the new suite of diagrams in the Architecture Edition particularly powerful and useful.
Hopefully Jeff will cover more in his upcoming articles.
Today on an internal agile alias, a discussion came up about simulating agile team rooms for disbursed teams. I've played around with this for years and had some suggestions for them:
It can be simulated, but it is hard and requires extra discipline by the team. A few key things:
- Think about how to simulate the “in the room” experience where you can overhear and participate in conversations going on around you? Team void chat software like Ventrilo, Team Speak or our own Corporate Conference Calling system can work. Can you have an “open mic” in the team room? You also can give up on audio and use team room chat software like IRC. I’ve used them all. There are plusses and minuses to each.
- Think about the changes you may need to make to development practices. Do you use Pair-Programming and TDD? If so, you may want to take a look at Micro-pairing as a technique for coordinating the TDD/Pair handoffs. (Micro-pairing was actually created in response this exact scenario. I was pairing with another developer who was remote.)
- In addition to practice changes, think about how to deal with remote desktop sharing. Live Meeting works, but can be a bit heavy. Virtual Server and the standalone Virtual Server client actually let two people connect to the same desktop. I know that VNC, an open source remoting tool, also allows this, but I would recommend you to be cautious with that tool. It has some known security bugs and your network admins may not allow it. Check with them first.
- Make sure everyone on the team has all the necessary access they need to be a full team member. Access to version control, portals, file shares, email aliases, etc. all must be available.
- Think carefully about how you do your team meetings. When you have only 1 or 2 people who are remote and the rest of the team is in a room, the person on the far side WILL feel out of the loop unless you run the meeting as if everyone were remote. One thing I’ve heard of is to actually have everyone go into their individual offices and dial-in to the meeting so everyone is on an equal footing.
- Drastic time zone differences can make this very very hard on some team members. Ultimately this can be make-or-break for successful disbursed teaming. If people are 8 hours apart, when do you schedule standups and IP meetings? My rule of thumb is that more than 3-4 hours apart will kill you and you should split it into two teams that are closer in time to each other.
These are based on 3-4 years of playing around with these concepts at P&P. YMMV.
I know I've been kinda quiet since moving to VSTS Team Architect, but getting settled into a new job and moving your family can be a bit time consuming.
However, I was taking a break looking at some blogs and stuff and found a few people talking about some of the new stuff in our most recent CTP!
Very cool indeed and I wanted to share them with you.
It got me excited to see people talking about our new stuff. I promise I'll be writing more about it soon... just give me some time.
I ran across this post by Jeff Certain on his blog talking about the Rosario release of VSTS Architect Edition. Sounds like we're moving in a positive direction:
I attended the Rosario Architecture Edition preview yesterday. Frankly, I'm two orders of magnitude more excited about this than I am about anything else I've seen here at the summit yet.
Woot!
Technorati Tags:
VSTS,
Architect,
MVP
I never thought I'd see the day, but my good friend AaronX has finally started blogging. He and used to have a blog-like site that was just cool links that we found, little or no commentary and this this his new take on that idea.
http://denversurfreport.blogspot.com/
Enjoy!
My good friend Eduardo Jezierski has returned to the blog-o-sphere. His new blog is up and running and his first post explains what he's been doing at InSTEDD since leaving Microsoft.
He's promised me that he'll blog about all kinds of interesting technology and how they're using it for really cool humanitarian efforts around the world.
Good to see you Ed and good luck on your mission!
Technorati Tags:
edjez,
instedd
Haha... I love the Internet sometimes. I was sitting here in my office listening to the Tool song Jambi, tapping my foot along, counting the beats on a background thread as I am wont to do...
"Hmm... this is in 9/4 time signature. COOL!"
You see, I've always loved finding songs that have unusual time signatures. One quick search later and I found this little page over on Answers.com:
List of musical works in unusual time signatures
Cool. I'm gonna have to dig through my music for some of those.
I found this nice article today in this month's Agile Chronicles:
Agile Chronicles: Leading Volunteers with Agility
I found it particularly relevant because I am an officer in a club and have often felt that I could better apply some of the agile values to that organization and not just to my work as in software development.
Enjoy!
Someone pointed out today that I hadn't been blogging lately (guilty as charged) and that I hadn't blogged anything at all about recent changes in my work life.
A year ago, various personal and family issues led me to make a promise to my wife that I would move her back to Denver. We've enjoyed Seattle a lot, but with her Lupus and other things, she needed to be closer to her family. This led me to start looking around for opportunities that would let me get back to Denver.
Long story short, I have moved on from P&P and am now working as a Program Manager on the Visual Studio Team System Architect Edition product. This role will allow me to live in Denver and work remotely most of the time. I still plan to be back in the Redmond area every month or two, though.
We're doing some really exciting stuff on the VSTS-AE product at the moment that I'm really looking forward to sharing with you all soon, so please stay tuned. I think I feel my blogging genes firing up again. :)
Not sure how I missed this before, but I was looking for something today and this popped up in my search engine.
Channel9 Wiki: Windows PowerShell Quick Start
Perfect!
Technorati Tags:
PowerShell
Agileprogrammer's been a good home for a number of years, but I've been getting the itch to host my own content again, so I've
moved my weblog back to eighty-twenty.net; the
archives of this site are located there too. If you're subscribed to the feedburner feed, you should be picking up the new feed already, if not, you'll have to
resubscribe - sorry for the hassle!
I have come full circle in my career. I have recently joined the p&p team again this time as a PM. I really enjoyed my time at CodePlex and those guys are on the right path. Given this, I have decided to move my blog back to MSDN. Hey why not go full circle all the way. Check me out over here.
Technorati Tags: CodePlex, Enterprise Library, p&p
Happy Birthday to my wonderful sister Michelle. You are a great sis, a great mom, smart business woman and a good friend. Hopefully we can all get back together soon. Love you.
--Peter
Recently I was involved in a discussion of teams and roles and whether the 'hero model' is healthy.
In general parlance, the hero model is one where we encourage people to be superstars, to stand out, and to save the day. This is a common model in many companies and many people attribute individual compensation models as being the culprit.
Here is how the thinking goes. When you recognize and reward people for standout, rock-star, save-the-day behaviors, what you are really doing is rewarding people for not being team players. Or perhaps they are team players, but they are on a team that is more like a figure skating team than a basketball team. On a figure skating team, each person is individually judged and the scores are combined to create the team score. The 'team' doesn't actually work together to achieve their final score.
A basketball team, however, doesn't work this way. It is more like a machine where each moving part tightly meshes with the other pieces in the system. When one part fails or under performs, the entire team fails or under performs. As the old saying goes, "A chain is only as strong as its weakest link."
Most agile-minded folks like the idea of basketball teams and don't really like the idea of figure skating teams. Most agilists will talk about teams as if they are organisms. They will use metaphors like family, system, machine, and others, that show how the parts are all working together. Many non-agile folks will talk about team members as resources and describe the team in language that make it sound like the component parts are replaceable and interchangeable.
Now, lets get back to the idea of Heroes. The gymnastics team loves heroes. In fact, they depend on heroes. The team may all be made up of heroes in the ideal case, but there is always the poor schmuck who doesn't have a good day, who falls, or who gets hit in the kneecap by an opponent's boyfriend.
Let's look at that a bit closer. The opponent in the famous kneecap case was a fellow team member. Was a Hero. She was heralded, along with the kneecapped skater, as one of the next great skating Heroes of her generation. But I would propose, and most would agree, that she was not a Hero. She wasn't one before the kneecapping and she obviously wasn't one after the kneecapping. She was a Villain.
If you think back to your comic book lore, there are some interesting characteristics of Heroes and Villains. Heroes are almost always reluctant. They don't want to have to do what they want to do. For the most part, they just want to be regular folks. They don't want to be different, or shining; they want to be just like everyone else. They'd rather be on the team of humanity than outside it.
Villains in the other hand love to light up. Love to be noticed and get attention. In fact, for most of them, that is their number one goal. They will engineer situations to get attention, to look better than the other guy and.. to get paid.
So here's my assertion as it related to software development teams: The Hero Model doesn't exist. What does exist is more properly named the Villain Model. Organizations that recognize, reward and encourage people to stand-out will create a system on Villains. We are engineers, and it is our nature to want to hack our way around obstacles to success. It is what we do. Presented with a system like we're discussing here, some folks will eventually figure out that to 'get ahead' you have to compete with your team members. You have to stand-out, be a Hero, save-the-day, get the bonus, the gold star, the promotion.
But as I said, when you set out to be a Hero, you are almost always a Villain! You will go after the best projects, leaving the trash for others. You'll sign up for the best work items, leaving the bugs for lesser mortals. You'll avoid pair programming, because that is sharing the glory. You'll try to 'own' key pieces of the system to protect your asset base. Some people, as we have seen in the figure skating story, will actually attempt to undermine their competitors by kneecapping them. Remember, Heroes are reluctant.
So... are you in an organization that rewards kneecapping villains? Are you a kneecapper yourself? If you aren't, do you know who is?
I recently finished 6 weeks of coding for a client, and it was heaven! I actually got a chance to code every day, for 6 solid weeks. It was a chance for me to learn C# 3.0, and a chance to work on testing things that are hard to test. It was great!
Out of the work, came several interesting observations and coding techniques, all rooted in C# 3.0. Since no one at work has any experience with these new idioms I "invented", "discovered", or just "copied", I'd love to get some reader feedback. I'll start with this one trick I tried, and follow on with more as the mood strikes me over time.
Trick 1: Using extension methods and a marker interface in place of implementation inheritance
I had an instance of code duplication in two parallel hierarchies of classes, and I wanted to find a way to share the code. One option would be to use inheritance, factoring out another base class above BaseResponse and BaseRequest. This is where methods common to requests and responses could both live. Using inheritance as a way to reuse code in a single inheritance language is a pretty heavyweight thing to do. I'd rather find a way to use delegation, since that preserves the SRP in my class hierarchy. Instead, I decided to try an extension method, and just use that method where I needed it. To avoid polluting Object with unnecessary methods, however, I came up with the idea of using a marker interface on the classes I wanted to have these extension methods, limiting the scope where these extra methods were visible. (No idea if anyone else has done this yet or not)
For each request and response class, in the two parallel hierarchies, my client requirements made it necessary to add an XmlRoot attribute to tell the XmlSerializer that this object was the root of an XML document and to specify the runtime name of this element. To let me get the runtime name of each request and response object, for auditing and logging purposes, both hierarchies had a CommandName property, containing the exact same code. This was the code in question that I was trying to share.
As a simple exercise, I created an extension method to deal with this:
internal static class SssMessageExtensionMethods
{
public static string GetCommandNameFromXmlRootAttribute(this object message)
{
object[] attributes = message.GetType().GetCustomAttributes(typeof(XmlRootAttribute), true);
if (attributes.Length == 0) return message.GetType().Name;
XmlRootAttribute xmlRootAttribute = attributes[0] as XmlRootAttribute;
return xmlRootAttribute.ElementName;
}
}
This solution worked just fine, and the code ran correctly, but I still wasn't happy with my solution. The problem I was sensing was that I was adding yet another extension method to Object, and Object's neighborhood was already pretty crowded with all the Linq methods in there. I wanted my extension methods to show up only on those classes to which I wanted to apply them.
The solution that I came up with was to use a marker interface whose sole purpose is to limit the visibility of the extension methods to classes that I intend to apply them to. In this case, I made BaseRequest and BaseResponse each implement IMessageMarker, an interface with no methods. And I changed the extension method to be:
internal static class SssMessageExtensionMethods
{
public static string GetCommandNameFromXmlRootAttribute(this ISssMessageMarker message)
{
object[] attributes = message.GetType().GetCustomAttributes(typeof(XmlRootAttribute), true);
if (attributes.Length == 0) return message.GetType().Name;
XmlRootAttribute xmlRootAttribute = attributes[0] as XmlRootAttribute;
return xmlRootAttribute.ElementName;
}
}
Now I have the same extension method defined, but it only appears on those classes that implement the marker.
What do you think of this technique? In a more powerful language, like Ruby or C++ (ducking and running for cover!), this kind of trickery wouldn't be needed. But C# can only get you so far, so I felt this was a good tradeoff between adding the methods for needed functionality and making the most minimal change in my classes to hide these methods so that only those places that needed them could see them.
-- bab
This post has moved: The Great Debaters
This post has moved: Who's in the Lead?