<CharlieDigital/> Programming, Politics, and uhh…pineapples

28May/09Off

Visitor Pattern In C# 4.0

Posted by Charles Chen

I've blogged about the Visitor pattern previously and using double dispatch to resolve .NET's inherent inability to resolve methods by parameter type at runtime.

As I was reading about C# 4.0's dynamic types, I started to wonder if this would mean that we could finally get a more concise implementation of the pattern.  My hunch was correct.

Here is the updated code listing (key changes bolded):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace VisitorPatternConsole
{
    public class Program
    {
        private static void Main(string[] args)
        {
            // NOTE: Using dynamic collections.
            Collection<dynamic> visitors 
				= new Collection<dynamic>();
            Collection<dynamic> pets 
				= new Collection<dynamic>();
 
            // Initialize the pets
            pets.Add(new Fish());
            pets.Add(new Dog());

            // Initialize the visitors
            visitors.Add(new Feeder());
            visitors.Add(new Walker());

            // Visit each of the pets.
            foreach (dynamic pet in pets)
            {
                foreach (dynamic visitor in visitors)
                {
                    visitor.Visit(pet);
                }
            }

            // Check the results.
            foreach (Pet pet in pets)
            {
                Console.Out.WriteLine(pet.GetType().Name);
                foreach (String note in pet.Visitors)
                {
                    Console.Out.WriteLine("\t{0}", note);
                }
            }
        }
    }

    /// <summary>
    /// Handles the base cases.
    /// </summary>
    public abstract class AbstractVisitor
    {
        public void Visit(Pet pet)
        {
            pet.Visitors.Add(
                "Not supported for this type of pet...");
        }
    }

    /// <summary>
    /// Concrete visitor, a pet feeder.
    /// </summary>
    public class Feeder : AbstractVisitor
    {
        public void Visit(Dog dog)
        {
            // Feed the dog
            dog.Visitors.Add("Fed the dog");
        }

        public void Visit(Fish fish)
        {
            // Feed the fish
            fish.Visitors.Add("Fed the fish");
        }
    }

    /// <summary>
    /// Concrete visitor, a pet walker.
    /// </summary>
    public class Walker : AbstractVisitor
    {
        public void Visit(Dog dog)
        {
            dog.Visitors.Add("Walked the dog");
        }

        // Fish can't be walked!
    }

    /// <summary>
    /// Base class for pets.
    /// </summary>
    public abstract class Pet
    {
        private readonly Collection<string> visitors;

        public Collection<string> Visitors
        {
            get { return visitors; }
        }

        protected Pet()
        {
            visitors = new Collection<string>();
        }
    }

    /// <summary>
    /// A pet fish.
    /// </summary>
    public class Fish : Pet { }

    /// <summary>
    /// A pet dog.
    /// </summary>
    public class Dog : Pet { }
}

Here is the output:

Wow, just when I thought dynamic was going to suck :-D

What is somewhat interesting is that both collections have to be declared of type dynamic; I'm still mulling this over, but it's not clear why it doesn't work if only one of the collections is declared dynamic (I figured that it should have worked if the visitors collection alone was declared dynamic).

Filed under: .Net, Awesome No Comments
27May/09Off

Random DevTools Entry #017

Posted by Charles Chen

In software development, it's incredibly useful to be able to visualize your code interactions using sequence diagrams and data flow diagrams and what not.  Not only is the visualization a plus, the act of generating one helps tremendously in terms of working out the outline of the logic that you need to implement.  One of the biggest problems I've come across in this area are the tools: they're simply too heavy and too complex for general diagram drawing tasks in addition to being generally rigid as well.


Today, as I was about to download and install Visio, I decided to spend a few minutes checking to see if there was a web alternative.  Enter websequencediagrams.  This is an all around awesome little tool to add to your toolbox.  Not only is it free (free is always awesome), it's text based.  At first blush, this seems terrible; there's a whole syntax to learn and lots of typing.  But the syntax is incredibly easy and simple while powerful and easy to understand.


Here's an example (I've bolded the syntax to make it easier to distinguish):



Browser->App: HandleSearchClickEvent()
App->Service: ExecuteSearch(keyword)
activate Service
Service-->App: (return results)
deactivate Service
App->App: RenderResults(reseults)
note right of App:
    render URL with
    keyword in query string.
end note
App-->Browser: HTML
Browser-->Office: click:
http://../name.docx?term=keyword
Office->AddIn: ThisAddIn_Startup()
AddIn->AddIn: Check for search term
note left of AddIn:
    ActiveDocument.FullName will
    contain the query string.  This
    can be extracted with a regular
    expression
end note
AddIn->AddIn: Execute find


And here is the result:



There are also a variety of pre-defined styles you can choose to render your diagram.  It's all sorts of awesome and a real time-saver compared to traditional tools.  I personally love that it's text based; I've found that when working with Visio (and other such tools), more than half of my time is spent arranging things just to get them to line up.  A text based approach works well for sequence diagrams and gets rid of that layer of unnecessary complexity.

Filed under: Awesome, DevTools No Comments