Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Christopher Bennage

Our WPF book is now available!

March 2008 - Posts

  • The Roots of Best Practices

    I've been asked about best practices and good design several times over the last few months. A few questions have been from students, or newcomers to .NET, and I have found their questions very insightful. They ask questions I remember asking myself. One good example was "I know I should separate my app into three layers, but how should I do it?"

    Getting to the RootsI'm rather to sensitive to the idea of "answering the wrong question". I believe that it's easy to do that when talking about best practices.  My intention with this post is build a foundation for discussing good design. A starting point to make sure we are solving the right riddle. I certainly don't consider myself a master on this topic, but I do have a lot of thoughts.

    Acknowledging My Bias

    I'm a fan of Object Orient Programming, Domain-Driven Design, Design Patterns, Test Driven Development, and agile methodologies. I use a lot of open source software, and I'm ALT.NET. Foremost, I like to think that I am pragmatic.   I'm motivated by getting stuff done.

    The Point of Best Practices

    There are a long list of principles out that are generally acknowledged as best practices. They range from generalities like "your code should be well commented" to very specific and named rules such as the Liskov substitution principle. Regardless of the type, I think it's important to know why a given principle is better than its alternatives.

    I'll use the Law of Demeter (LoD) as an example. Overly simplified, the law says that an object should only invoke methods that it owns.  In other words, you'll break the law with something.child.Method() whereas something.Method() does not. 

    Why is LoD good? One quick answer is that you never know when something.child might be null, and applying LoD helps you avoid the nasty NullReferenceException. Wikipedia has a nice summary the benefits:

    The advantage of following the Law of Demeter is that the resulting software tends to be more maintainable and adaptable. Since objects are less dependent on the internal structure of other objects, object containers can be changed without reworking their callers.

    Now we are approaching the real heart of the matter, we want software that is easy to maintainable, and easy to extend. LoD promotes those values. In facts, most of the generally accepted principles are meant to produce software that is maintainable and extensible. Here is my Grand Unification Theory of software best practices: the guiding, or root, principles are Maintainability and Extensibility. (These two are close cousins, and you might arguably combine them.)

    The Root of the Matter

    Now, let's deconstruct further.  Why do we care about Maintainability and Extensibility? We care because they result in reduced costs.  The bulk of cost with custom software is not building it, but maintaining it. If you are in business, reduced costs equals more money; if you are a hobbyist or open source developer then reduced costs means getting to the desired result in less time.  That's the bottom line: time and money. We employ best practices to save ourselves time and money.

    Okay, well, nothing new here. You probably already knew this.  I emphasize it though because I've found that "best practices" have a tendency to degrade into a set of arbitrarily applied rules, enforced without exception, irrespective of whether or not they are useful. A great example is "always comment your code". The intention of this rule is improve maintainability.  We've all seen the end result.

    //open the file 
    FileStream stream = File.Open(pathToFile, FileMode.Open);

    Does this improve maintainability? Perhaps if you can't read C#, but even then it seems unlikely. Does one extraneous little comment hurt? Not by itself. A poppy flower is beautiful, a thousand poppies is dangerous. If 50% of your source is extraneous comments, it's nothing but noise and it's reducing maintainability.

    My Point

    Let's take a look at the question I was asked again:

    "I know I should separate my app into three layers, but how should I do it?"

    To answer this correctly, we need to start with the motivation for layering an application in the first place. "Three-tier architecture" has a good intention, just as "well commented code" does. However, the principle has can easily be lost in the arbitrary application of the rule.

    In a soon-to-follow post, I'll examine this specific question of layering an application from its roots.

    Epilogue

    For some reading in the meantime, check out the series of posts over at Los Techies on SOLID Principles. There is some great discussion in the comments too.

    What do you think?

  • Thoughts on ALT.NET

    I just listened to Scott Hanselman interviewing Dave Laribee regarding ALT.NET. I really like what Dave had to say, and I encourage everyone to go and listen.  I've been reticent about the ALT.NET movement (aside from my initial surge of enthusiasm.) I'm a bit shy when it comes to controversy, and even though I have strong evangelistic tendencies, I am also quick to shut up. ALT.NET has had its share of controversy.

    Now we're an institution!I really like that Dave said it's not about the tools, it's about the principles.  I am frequently asked about "good design" and "best practices".   This is why I'm ALT.NET. (In fact, I have a series of posts on this topic that I intend to start after we're done with the book.)

    There's an item in the interview that I'd like to comment on.

    Scott asks (pardon my paraphrasing) why would the hypothetical Chief Architect of the Nebraska Department of Forestry have any interest in ALT.NET? The mythical Mort has pressing concerns, he just needs to get work done, why would he care about these conversations, discussions, and principles? Listen to the podcast for Dave's answer.  However, my answer is this: he probably doesn't care and that's okay. I think that ALT.NET is about bringing good design and principle to the forefront.  However, good ideas take a while to be adopted, to be democratized.  Those who are hungry, we'll feed.  Those who aren't, we'll wish them well.  No hard feelings. Eventually, the good ideas will be institutionalized and they'll trickle down. (Have you noticed the "refactor" menu in Visual Studio?) I'm more concerned about convincing the institutions and the thought leaders.  (Perhaps "convincing" is the wrong word, ALT.NET is more about "conversing" to me.) That's why it's good that ALT.NET is conversing with Microsoft, and that's also why I'm encouraged to see Microsoft paying attention to things like open source (though I know many people are angry about the kind of attention being paid).

    Now go learn Ruby!  :-)

  • Identifying Control Templates Parts in WPF

    I'm currently writing the chapter about control templates in our WPF book, and I wanted to include a list of all of the named parts that are hidden away in the dark recesses of the various controls.  Before I even started googling, I had an idea that I thought I'd share.

    For those of you not yet familiar with control templates, WPF allows you to redefine the visual appearance of controls. The problem is that some of the controls have special named parts, that is, there are visual elements with specific names that the code expects to be there.  Luckily, there is the TemplatePartAttribute that's meant to decorate controls with named parts. If you look at the documentation for a given control, the attributes are listed and you'll know what named elements a new template requires.

    Given an assembly though, it's quite easy to identify the controls programmatically. Here's some C# that does just that:

    using System;
    using System.Linq;
    using System.Reflection;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace TemplatesParts
    {
        class Program
        {
            static void Main()
            {
                var assembly = Assembly.GetAssembly(typeof (Control));
                var attributeType = typeof (TemplatePartAttribute);
    
                var controls = from c in assembly.GetTypes()
                               where c.GetCustomAttributes(attributeType, false).Length > 0
                               orderby c.Name
                               select new {c.Name,Parts=c.GetCustomAttributes(attributeType, false)};
    
                foreach (var control in controls)
                {
                    Console.WriteLine(control.Name);
                    foreach (var part in control.Parts)
                    {
                        Console.WriteLine( "   " + ((TemplatePartAttribute)part).Name);
                    }
                }
                Console.ReadLine();
            }
        }
    }
    

    Now, if I can just look this up in the documentation, why bother with this code? It was fun, what can I say?

More Posts

Red-Gate!