in

 

Ray Houston

February 2008 - Posts

  • A Simple Delegate Example

    I was recently working on a code generator and I made use of some simple delegates and I thought that I would share a few ideas.

    Some folks may be wondering what is a delegate.  You can think of a delegate as a type safe function pointer. It's a type which can be passed around like any other type and it can be invoked which calls the original method that it's pointing to. Lets look at a delegate type declaration:

    public delegate void DoSomething();

    This basically creates a delegate type called DoSomething that can point to a method that takes no arguments and returns void.

    Say you have a method:

    public void HeresSomething()
    {
        //put something here
    }
    

    then you can create a new instance of our delegate and have it point to that method like:

    DoSomething myDelegate = new DoSomething(HeresSomething);

    ReSharper tells me that you can abbreviate this syntax like so:

    DoSomething myDelegate = HeresSomething;

    Now myDelegate can be passed around and then executed just like a method which will call the real method HeresSomething():

    myDelegate();

    This becomes really valuable is when you have delegates that take arguments and return values as you will see in a moment.

    In my particular real life case, I have some .NET data transfer objects (DTOs) which I want to code generate equivalent Flex ActionScript objects so I can move data back and forth via serialization. These DTOs can be complex types (objects within objects) so I will need to unwind the object hierarchy to determine what to generate.

    Let's look at an example without using delegates:

    class TypeUnwinder
    {
        public void Unwind(Type type, List<Type> allTypes)
        {
            if (allTypes.Contains(type))
                return;
    
            allTypes.Add(type);
    
            UnwindProperties(type, allTypes);
            UnwindMethods(type, allTypes);
        }
    
        private void UnwindProperties(Type type, List<Type> allTypes)
        {
            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                Unwind(propertyInfo.PropertyType, allTypes);
            }
        }
    
        private void UnwindMethods(Type type, List<Type> allTypes)
        {
            foreach (MethodInfo methodInfo in type.GetMethods())
            {
                Unwind(methodInfo.ReturnType, allTypes);
                UnwindParameters(methodInfo, allTypes);
            }
        }
    
        private void UnwindParameters(MethodInfo methodInfo, List<Type> allTypes)
        {
            foreach (ParameterInfo parameterInfo in methodInfo.GetParameters())
            {
                Unwind(parameterInfo.ParameterType, allTypes);
            }
        }
    }
    

    This code works ok but my real case is much more complex. I actually have to unwind a couple of different times for different reasons and I have multiple checks for attributes and I ignore certain types. I want to reuse my pattern of unwinding with different logic. I can do this using a delegate. Instead of passing a List around, I can have the UnwindType method simply call a delegate that takes a Type. The calling class supplies the delegate and figures out what to do with the Type when it's called.

    First I create a delegate that returns bool that takes one argument of type Type:

    public delegate bool DoSomethingWithTypeDelegate(Type type);

    Then we modify our class by removing the references to the List and have it take in an instance of our delegate in the constructor:

    class TypeUnwinder2
    {
        private readonly DoSomethingWithTypeDelegate doSomethingWithType;
    
        public TypeUnwinder2(DoSomethingWithTypeDelegate doSomethingWithType)
        {
            this.doSomethingWithType = doSomethingWithType;
        }
    
        public void UnwindType(Type type)
        {
            if(!doSomethingWithType(type))
                return;
    
            UnwindProperties(type);
            UnwindMethods(type);
        }
    
        private void UnwindProperties(Type type)
        {
            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                UnwindType(propertyInfo.PropertyType);
            }
        }
    
        private void UnwindMethods(Type type)
        {
            foreach (MethodInfo methodInfo in type.GetMethods())
            {
                UnwindType(methodInfo.ReturnType);
                UnwindParameters(methodInfo);
            }
        }
    
        private void UnwindParameters(MethodInfo methodInfo)
        {
            foreach (ParameterInfo parameterInfo in methodInfo.GetParameters())
            {
                UnwindType(parameterInfo.ParameterType);
            }
        }
    }
    

    Now a calling class can control what actually happens when a Type is hit (remember, this is just example code):

    class Program
    {
        static readonly List<Type> types = new List<Type>();
    
        static void Main(string[] args)
        {
            TypeUnwinder2 unwinder = new TypeUnwinder2(IndexType);
    
            unwinder.UnwindType(typeof(SomeCustomTypeToUnwind));
    
            foreach (Type type in types)
            {
                Console.WriteLine(type.FullName);
            }
        }
    
        static bool IndexType(Type type)
        {
            if (!types.Contains(type))
            {
                types.Add(type);
                return true;
            }
    
            return false;            
        }
    }
    

    Notice how we pass in IndexType to the TypeUnwinder2 constructor (the delegate is created for you). If we wanted to see the delegate, we could have done:

    TypeUnwinder2 unwinder = new TypeUnwinder2(new DoSomethingWithTypeDelegate(IndexType));

    So adding a delegate allowed me to decouple my unwinding pattern from the work that happens as a result of the unwinding. Yeah!

    Here's a version that uses another delegate to reuse a single foreach loop. It's a bit ridiculous , but it might be fun to decipher.

    class TypeUnwinder3
    {
        private DoSomethingWithTypeDelegate doSomethingWithType;
    
        public TypeUnwinder3(DoSomethingWithTypeDelegate doSomethingWithType)
        {
            this.doSomethingWithType = doSomethingWithType;
        }
    
        public void UnwindType(Type type)
        {
            if (!doSomethingWithType(type))
                return;
    
            UnwindItems(type.GetProperties(), UnwindProperty);
            UnwindItems(type.GetMethods(), UnwindMethod);
        }
    
        private void UnwindItems<T>(IEnumerable<T> items, Action<T> process)
        {
            foreach (T item in items)
            {
                process(item);
            }
        }
    
        private void UnwindProperty(PropertyInfo propertyInfo)
        {
            UnwindType(propertyInfo.PropertyType);
        }
    
        private void UnwindMethod(MethodInfo methodInfo)
        {
            UnwindType(methodInfo.ReturnType);
            UnwindItems(methodInfo.GetParameters(), UnwindParameter);
        }
    
        private void UnwindParameter(ParameterInfo parameterInfo)
        {
            UnwindType(parameterInfo.ParameterType);
        }
    }
    

    Technorati Tags: ,

  • Good Code Is Not Just About Writing Lines of Code

    At work we've been having a few coding sessions where we have one computer and a hand full of developers and work on a couple of tasks from the current sprint. It's sort of like a mini CodingDojo. These meetings have been very educational for learning tips and tricks from each other as well as design and architecture.

    As I observe and participate in these meetings, I'm amazed at the amount of time that is spent renaming and reorganizing the code artifacts. This is good that we're refactoring when it makes sense, but it shows that good code is more about naming and organizing than it is about writing logic (well, the logic has to be correct too). You can write all kinds of goofy code that works, but that doesn't mean it's good code. Creating good code is an art. You can say that a good painting is just putting the right tones in the right spots on a canvas. You can say that a good piece of music is just playing the right notes at the right time. Coding is not just about writing lines of code, but about having a place for everything and putting everything in its place. Of course we all have our opinions as to what is good art. ;)

     
  • A Custom Converter for Json.NET

    I was playing around with Json.NET while trying to move some data back and forth between .NET and Flex. I found that I needed to deserialize a string that looks something like:

    string json = @"{param1:{FirstName:'Jay',Age:2},param2:{FirstName:'Ray',Age:3}}";

    where param1 and param2 are parameters to a method that I want to invoke as a remote service. I have two objects that I want to deserialize within a container object (the outer { }). I really don't care about the container object but I have no way to tell Json.NET to ignore it. I have to have a real concrete to deserialize the container. I didn't want to create specific objects for each call being made (there could be a lot) so I created a simple generic object that looks something like the following (error handling removed for clarity):

    public class ParameterCollection
    {
    private readonly Dictionary<string, object> parameters;

    internal ParameterCollection(Dictionary<string, object> parameters)
    {
    this.parameters = parameters;
    }

    public object this[string name]
    {
    get { return parameters[name]; }
    }

    public int Count
    {
    get { return parameters.Count; }
    }
    }

    In order to deserialize to a ParameterCollection object, I needed to create a converter class that inherits from JsonConverter. It ended up looking like the following (error handling removed for clarity):

    public class ParameterCollectionJsonConverter : JsonConverter
    {
    private readonly Type[] parameterTypes;
    private readonly Dictionary<string, object> parameterInstances;

    public ParameterCollectionJsonConverter(params Type[] parameterTypes)
    {
    this.parameterTypes = parameterTypes;
    this.parameterInstances = new Dictionary<string, object>(parameterTypes.Length);
    }

    public override bool CanConvert(Type objectType)
    {
    return objectType.IsAssignableFrom(typeof(ParameterCollection));
    }

    public override object ReadJson(JsonReader reader, Type objectType)
    {
    reader.Read(); // read past start object token

    for (int i = 0; i < parameterTypes.Length; i++)
    {
    string parameterName = reader.Value as string;

    this.parameterInstances.Add(parameterName, new JsonSerializer().Deserialize(reader, parameterTypesIdea));
    reader.Read();// read past end object token
    }

    reader.Read();// read past end object token

    return new ParameterCollection(parameterInstances);
    }

    public static ParameterCollection Deserialize(TextReader jsonTextReader, params Type[] types)
    {
    JsonSerializer serializer = new JsonSerializer();
    serializer.Converters.Add(new ParameterCollectionJsonConverter(types));

    JsonReader reader = new JsonReader(jsonTextReader);
    return serializer.Deserialize(reader, typeof(ParameterCollection)) as ParameterCollection;
    }
    }

    So now I can deserialize to a ParameterCollection by passing in the types of each parameter like so:

    TextReader tr = new StringReader(@"{param1:{FirstName:'Jay',Age:2},param2:{FirstName:'Ray',Age:3}}");

    ParameterCollection paramCollection = ParameterCollectionJsonConverter.Deserialize(tr, typeof(SomeObject), typeof(SomeObject));

    SomeObject someObj1 = paramCollection["param1"] as SomeObject;

    I'm sure as soon as I post this somebody will let me know of a built-in way to do the same thing. ;)

    Technorati Tags: ,,
  • A Project Walk Through - Defining User Stories

    One of the things that I've learned is that you shouldn't start development until you're ready. You shouldn't start until you have a good idea of what you are building. You shouldn't start until you have some reasonable idea of how long it's going to take. You need to make sure the information is organized and that everyone knows what they're supposed to be working on.

    I think Agile has gotten a bad reputation in some cases because it's been used as a cover for disorganized teams with no process (I've been on one of those teams). Agile software development doesn't mean anything goes software development. If the stakeholder asks "Where are we on the project?" and the answer is "Oh it's agile, you wouldn't understand." then something is wrong.

    I want to attempt to do a walk through of an imaginary project that gives some insight into situations that others may come across in their own projects. This will take me several posts, so bear with me.

    A school district is planning an event for teachers where they can signup for different workshops on various topics. A development team has been asked to write a simple application to manage coordinating the workshops and the registrants.

    This seems like a simple enough application and  a developer might think they know how it should work. Most of the time they would be wrong unless they were the stakeholder as well as the developer. The stakeholder has a lot of information tied up in their brain that developers don't know about. We all take for granted the information we keep in our heads and it's often difficult to present detailed information in a format that is easily understandable to a person that has no background on the particular subject. Even if it's written  down in great detail, someone has to tear it apart, piece by piece and rebuild it into an understanding of the desired goal. Misinterpretation is often the result. To me, understanding requirements is one of the most challenging aspects of software development. Agile methodologies accepts a level of misinterpretation and addresses it by constantly challenging understanding through communication and reevaluation. You can't have Agile without good communication.

    At this point, it would be a mistake to jump right into coding because we haven't talked about the details of what we're building and we don't have a good way to estimate how long it will take. If the event is in three months and development will end up taking six, then it may not be worth the effort to spend three months developing something we can't use.

    The stakeholders have heard a lot of buzz around agile software development and agree that it's the way to go. They go off in a room for a couple of days and then emerge with a set of specifications written on index cards.

    Unless the stakeholders have had experience writing user stories, it would probably be a mistake to start development at this point. More than likely, they have written waterfall type specifications and just put them on index cards and this just doesn't work (been there, tried that). A possible example of a story coming out of this session might be:

    A workshop can have a name, location, and a start date and end date.

    The problem with this sort of story is that it doesn't put the information into a context that helps us to understand how it fits into the system. This information is indeed valuable, but it doesn't belong in that initial story. The story needs to give us just enough information so that we can quickly look at them and understand the feature and the business value.  Dan North's post What's in a Story?, explains a BDD approach to defining stories, which I'm currently using on my projects. Dan implies that acceptance scenarios are a part of a story, but I like to think of them as a separate deliverable because you don't necessarily have to have that much detail up front. I'll post more on this later.

    Writing good stories takes a lot of practice and there will be a lot of questions. Some may be:

    • What goes in a story? - See Dan's post.
    • How big should a story be?  - Keep them as short.
    • How specific should a story be? - Start out general. You can always split a story later into more specific stories.
    • Where do the business rules of a story go? - In Scenarios. See Dan's post.
    • Can I have stories that depend on each other? - Sure. Some features depend on other features.
    • Can I create non feature related stories (like coding framework)? - Sure. But you probably won't have much or any acceptance scenarios.

    The stakeholders go back into a room with a story writing coach and this time they emerge with a set of user stories.

    As an Event Coordinator
    I want to enter event information
    So that it can be published online in order to attract potential registrants

    As an Event Coordinator
    I want to define workshops for an event
    So that event registrants can signup to attend those workshops

    As an Event Coordinator
    I want to define available rooms for an event
    So that workshops may be scheduled in those rooms

    As an Event Coordinator
    I want to schedule workshops in available rooms
    So that I can be sure that two workshops don't occur in the same room at the same time

    ...

    These stories are much better. They are short and have a role, feature, and benefit. A person can read through them quickly without being overwhelmed. Once estimates have been placed on the stories, someone will have to go and prioritize them and you don't want them to have to read a whole paragraph to understand the story. There is enough there to start a conversation and talk about some details so that the developers can come up with a rough estimate. Some of these stories may be too big to fit into a single iteration, but you shouldn't care about that right now. You can always split them later. For now, we need a high level view of our goal and we can always refine it later when we plan an iteration. If a story seems too big to estimate, then go ahead and split it now.

    In order to get a rough estimate on approximately how long the project will take, the team meets and has a Release Planning Meeting. The team goes through each story and gives them a point estimate.

    In this meeting, the goal is to educate the developers just enough on each story so that it can be given a general estimate. You can't make estimates that are more accurate than the information presented, so there's not much point in estimating in terms of time. By estimating in terms of points (size) you can later determine the unit of time that relates to a story point. The key is to estimate consistently and estimate the stories relative to each other. If a story is twice as hard as another story, it should have twice the estimate.

    Initially, to get a rough estimate for the completion of the whole project, you have to take an educated guess of how many story points you will be able to complete within a given iteration. This will be your initial velocity. If you have 1000 points to complete, your iterations are one month long and you can do 100 points per iteration, then you can estimate that you have 10 months of work. You may find that you will not have everything ready by a particular date, but you may have enough completed at an earlier date which will provide enough value to release. Remember this is a educated guess that needs to be refined as the project progresses. You have to do a couple of iterations before you really know your true velocity.

    The team makes an educated guess for the initial velocity and the stakeholders start prioritizing the stories into iterations. There is enough time for three iterations before the event and the estimates show that it will take six iterations to complete everything. It is obvious that everything cannot be completed by the deadline of the event, but it has been determined that there will be enough value coded at the end of the third iteration to have a release. Release 1 will only contain enough features to manage scheduling workshops.

    I'll continue with the first iteration in a future post. Any thoughts, comments or questions on what I have so far are welcome.

    Technorati Tags: ,
  • LosTechies!

    The folks at LosTechies invited me to join their blogging team. I'm not sure why they would want to dilute their blogging talent pool by having me, but I'm honored and I pledge to contribute to the best of my ability. This means that I'm going to have to increase my posting frequency which I've been planning on doing for awhile. Being part of the team is a nice motivator, so I hope they don't kick me off after they get to know me. ;)

    If you've subscribed using my FeedBurner RSS, then you don't have to update anything. My new blog URL is http://www.lostechies.com/blogs/rhouston.  Many thanks to LosTechies for having me.

Copyright Los Techies 2007. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems