CodeProject

It’s Our Code

Background

I’m sure what I’m about to talk about here doesn’t just relate to programming–it relates to any team-based project where everyone works on a small portion of the big picture. My experiences are primarily geared toward writing code in teams, so try to find parallels in your own work/experiences if you’re not a programmer. Anyway, enough of that.

When someone puts a lot of effort into something, they’ll often take great pride in the finished product. Of course, it’s great that they do! They’ve slaved away at something at work for days, weeks, or months, and it’s finally working/implemented. Other people are using it and it’s doing its job as expected. Awesome!

What kinds of things could possibly go sour here? If you have experience working in teams to complete a project, you might have some ideas.

Ownership

You don’t own anything. You don’t own a single sentence or character you type and share with your team. You don’t own the title you came up with for the document, the name of a class or interface in your code, the conventions for indenting your variable declarations, the overall file & folder structure of your code, or even the Powerpoint you want to show to the sales and marketing department. If you’re on a team, you’re creating content for your team and your team assumes ownership of it (technically, I guess your company owns everything you do… but… stick with me on this one for a bit).

Ownership becomes a big problem in team environments. Person A worked on Item X, so Person A is assumed to be the owner of Item X. Now every time someone wants to use Item X, they need Person A. Simple? Yeah, that’s a simple system, but it’s absurd. Why don’t I just work on the most important part of the project, encrypt it, and secure my job for the rest of eternity? It’s hard to swallow sometimes, especially after pouring a lot of time and effort into something, but when you’re part of a team you should always be working in order to create things for your team. This has two major benefits:

  • You’ll adjust your perspective to be that of your entire team when you’re making something. (i.e. Am I working to their standards? Am I using their conventions? Can someone else understand what I’m writing here? Will this be easy for them to use? Can someone easily come along and modify my work to improve it in the future? etc…)
  • You remove the people bottleneck.

Ask the Experts

Instead of ownership, people should be considering “expertise”. What’s the difference? Well, someone who owns something is entirely responsible for it. If you want to use it, you ask the one owner. If you want to change it, you ask the one owner. If someone asks you about it, you better direct them to the one owner. The one owner becomes the bottleneck for whatever they own.

An expert is someone who has extensive knowledge in the area and there can be more than one. If you want to use something, you consult one of the experts for proper usage. If you want to modify it, you consult the experts. If someone asks you about it, you can direct them to any of the experts. See the difference? You widen (or eliminate?!) the bottleneck. You increase how robust your team is in terms of responsibilities.

What happens if Bob is sick for a week and he’s the only one who knows how to use the data layer when a big customer bug comes in? What happens when your co-op student who wrote your patented fizz-buzz algorithm leaves to go back to school and no other developer knows how to maintain the code? If there’s only one owner in each of these situations, you’re in a bad spot. If there are several experts who are knowledgeable in the area of code in question, you’re laughing.

Keep in mind, there aren’t only changes in your development staff–your code base is dynamic too.

Code Changes

One huge benefit that software has over almost any other product is that it’s dynamic. You can build something now that works, that may not work next week, that can be fixed the week after, and then later completely rewritten the week after that… and… well… you get the idea. Sure. I know you’re capable of thinking of situations where this doesn’t work with software or products that can somehow get the same benefit, but I’m not contesting that. The point is that software is (usually) flexible and dynamic and you need to treat it like that.

When a group of people has control over software, they can guide the direction it grows in. You get multiple people who are knowledgeable in the direction that the software can take and you leverage the group’s knowledge and experience collectively. Obviously consulting every single person on the team to change a single line of code is overkill, but at least you can find a happy medium in terms of architectural and API changes.

Your code changes because unless you executed the waterfall approach to programming 100% perfectly, your architecture is likely going to change. It’s just a fact of life. But there’s absolutely no reason to freak out. Embrace it. You’ve written unit tests for a reason, right? You’ve used interfaces and designed a nice clean API to decouple your code and make such changes easy. Duh! So don’t worry! You have a couple experts in the area of code that needs to change, so either they can tackle the changes or guide one of your more junior developers.

The same thing should hold true for any process or on-going project that is dynamic. Take measures to ensure that changes in the project or workflow can be done by anyone and don’t jeopardize the whole operation.

Tips

Here’s an assortment of tips (and hopefully some parallels for the non-programming types):

  • Use some sort of revision control. When something bad happens with your work, you always want the ability to press a figurative undo button. Look into something like Git, Subversion, or Mercurial. There are others out there too! Source control software isn’t just great for programmers… If you’re collaborating on a document of any kind, you can leverage source control to manage the revisions of the document.
  • Use tools that allow working on things in parallel. Again, source control helps here for programmers… but find solutions that mirror this. Look at Google Docs! You can literally work with people at the exact same time!
  • Practice and embrace the fact that you don’t own anything… It all belongs to your team, collectively. Keep that in mind or your team may start finding better team players! You want everyone to feel like what they are working on is for the team.
  • When you have something that’s dynamic and changes (like code), take the necessary steps to facilitate and embrace changes. Take precautions to ensure changes don’t mess everything up (unit test & code review!)

Summary

When you’re working in a team, you need to be thinking about your team. What you’re working on belongs to your team and shouldn’t be treated as your personal pet project that you control. This works best when you have multiple “experts” that have knowledge in a given area that can make changes or guide others to make the required changes. If you’re working on something that is dynamic or changes often, you can ease some pains by planning for change. Don’t resist it and fall apart when changes finally happen.


Dependency Injected Singletons… What?

Background

Previously I wrote a bit about singletons. I’m not afraid to say that I think singletons have a time and a place… Okay, I’m afraid to say it, but it’s actually how I feel 🙂 After learning more and more about inversion of control design patterns and programming by interfaces, I started to notice just how inflexible singletons are. When you consider using a singleton, you should be considering both the pros and cons without jumping right into it. Here’s an example of my approach for mixing singletons, programming by interfaces, and a bit of inversion of control.

The Setup

I’m actually surprised you got this far. I’m sure you’re probably just sticking around to see how messed up this could possibly be. I’m actually proud that this little pattern has worked out so well when I’ve used it, so it can’t possibly be that bad.

One major drawback to singletons is that they are often implemented as concrete classes. That is, you ask some class X for it’s instance (via a static property/method) and it provides you it. This doesn’t mix very well with programming by interfaces. So, the first step is to have your singleton return an interface instead of a concrete class. Unfortunately, this on it’s own only provides a few benefits, and it’s really only a minor abstraction layer. You can change your singleton class around all you want, but the only dependencies people are going to see are what’s exposed on the interface. As long as your interface isn’t changing, you’re in a good position. With this change alone, we’ve managed to tackle a bit on programming by interfaces, which makes me just a bit happier.

So, what’s the problem now then? Well, now that I have my singleton returning an interface, the unfortunate truth is it’s always going to be the same class backing that interface. It’s incredibly risky if I start putting some sort of logic in my singleton’s property to get the instance that will return different references that could implement the interface. I mean, once your code is running, you want to make sure you’re always getting the same reference back… or else you’re not using a singleton! The drawback to this is that it completely ruins inversion of control and dependency injection!

 

An Example

Consider that I have a singleton that has information about my application. (If you don’t like my example, then you’ll surely hate using WinForms, because Microsoft does it with their Application class. So, it’s a fair example!) Okay, so if we pretend that we need something just like the Application class in our project, we might create some interface IApplication and create a singleton that returns an instance of an IApplication.

Suppose in one implementation we have, we really want to be using reflection and the assembly information to figure out our application’s information. Our concrete class would implement the IApplication interface but the methods would revolve around using reflection and querying the assembly for what it wants. If we built up a whole framework that used this singleton… We’d be tied to that implementation!

What happens if we go to make another application that wants to use this same framework, but it needs to be able to provide the application information through a configuration file? Well… We’d be pooched! Our singleton that’s used everywhere (and yes, please continue crying about the use of the singleton… Just remember Microsoft’s Application class) and we can’t really do anything about it!

Or can we?

The “Solution”

Okay, so here we are. I’ve demonstrated the problem with a scenario that isn’t too far fetched. How do we fix this crappy situation we’ve got ourselves in by using the dreaded singleton pattern? We use my other best friend: events. Except we use them in a way that makes me cringe. Static events.

Here’s my solution the the above problem:

The Interface:

    public interface IApplication
    {
        string Name { get; }

        string Version { get; }
    }

The Singleton:

    public static class Application
    {
        private static readonly object _instanceLock = new object();
        private static IApplication _instance;

        public static event EventHandler<QueryTypeEventArgs> QueryType;

        public static IApplication Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_instanceLock)
                    {
                        if (_instance == null)
                        {
                            _instance = CreateInstance();
                        }
                    }
                }

                return _instance;
            }
        }

        private static IApplication CreateInstance()
        {
            var handler = QueryType;
            if (handler == null)
            {
                throw new InvalidOperationException(
                    "Cannot create an instance because the QueryType event " +
                    "handler was never set.");
            }

            var args = new QueryTypeEventArgs();
            handler.Invoke(null, args);

            if (args.Type == null)
            {
                throw new InvalidOperationException(
                    "Cannot create an instance because the type has not been " +
                    "provided.");
            }

            // NOTE: here's where things get weird. you need to define your own
            // sort of "contract" for what type of constructor you will allow.
            // you might not even use a constructor here... but you need to
            // define what mechanism the provided type must have to provide
            // you with a singleton instance. i'm a fan of providing a type
            // with a private parameterless constructor, so i'll demonstrate
            // with that. your requirements will change what this section of
            // code looks like.
            if (!typeof(IApplication).IsAssignableFrom(args.Type))
            {
                throw new InvalidOperationException(
                    "Cannot create an instance because the provided type does " +
                    "not implement the IApplication interface.");
            }

            const BindingFlags FLAGS = 
                BindingFlags.CreateInstance | 
                BindingFlags.Instance | 
                BindingFlags.NonPublic;

            var constructors = args.Type.GetConstructors(FLAGS);
            if (constructors.Length != 1)
            {
                throw new InvalidOperationException(
                    "Cannot create an instance because a single private " +
                    "parameterless constructor was expected.");
            }

            return (IApplication)constructors[0].Invoke(null);
        }
    }

The Program (With two types to inject!)

    internal class Program
    {
        private static void Main(string[] args)
        {
            Application.QueryType += (sender, e) =>
            {
                e.Type = typeof(ApplicationB);
            };

            Console.WriteLine(string.Format(
                "Application Name: {0}rnVersion: {1}",
                Application.Instance.Name,
                Application.Instance.Version));

            Console.WriteLine("Press enter to exit.");
            Console.ReadLine();
        }
    }

    internal class ApplicationA : IApplication
    {
        private ApplicationA()
        {
        }

        public string Name
        {
            get
            {
                return "Application A (Pretend this was from the assembly info)";
            }
        }

        public string Version
        {
            get { return "1234"; }
        }
    }

    internal class ApplicationB : IApplication
    {
        private ApplicationB()
        {
        }

        public string Name
        {
            get
            {
                return "Application B (Pretend this was from an XML file)";
            }
        }

        public string Version
        {
            get { return "9876"; }
        }
    }

So, if you were to run the program, what outputs would you expect in either case? What happens when you forget to set your event handler? What happens when you set your event handler and don’t provide a type? What if it’s a bad type?

 

Summary


I’m not claiming this is the best approach to solve this problem, and I’m not even encouraging that everyone go ahead and use it. Some of the pros of this are:

  • Advantages of programming by interfaces! You’re only exposing interface definitions to others.
  • Dependency injection capabilities. Inject your “singleton” into other applications.
  • All the goodies related to singletons
  • Easy to use. Just hook up your type to a event handler when your program initializes.

Some of the cons are:

  • All the things people hate about singletons. All of them.
  • Static events are absolutely hideous.
  • You’re giving some other class control of creating your singleton instance.
  • There is no compile time checking or contracts for how your singleton needs to be created.

And now that you know some of the good and some of the bad, can you leverage a design like this? You can check out a working solution I put together for the code and example I described above over at Google Code. Hope you were able to learn something (either good or bad)!


  • Nick Cosentino

    Nick Cosentino

    I work as a team lead of software engineering at Magnet Forensics (http://www.magnetforensics.com). I'm into powerlifting, bodybuilding, and blogging about leadership/development topics over at http://www.devleader.ca.

    Verified Services

    View Full Profile →

  • Copyright © 1996-2010 Dev Leader. All rights reserved.
    Jarrah theme by Templates Next | Powered by WordPress