Tuesday, December 11, 2012

Use technologies as tools, don’t let them drive your design





Many problems on software development are due to which I call technology driven design obsession. Don’t let technologies and stacks dictate your design, keep it as simple as possible. Many developers try to use new technologies on their projects (because they are cool :P or have cool names like Marionette.Js I love that name) and forget about the business value and what they are trying to achieve. Instead of focusing on the use case and the goal of the application, they try to fit the problem to technology and suddenly they become slaves to these tools. 


Focus on the value of your software, don't limit yourself by technology obsessions. Fit the technology to the problem not the problem to the technology.

In my career so far, I have been lucky to work on projects from scratch, some of them with limited resources and budgets, every time I start a new project i try to forget about all I know about tools and design patterns and I focus on what im trying to achieve then I pickup the best  tools that fit the job. Picking the right tool depends on many factors, time and deadline, friction, familiarity of your team with the tool, and the most important thing : does it fit the job ?.
 For example, entity framework is the defacto ORM that comes with visual Studio, but if I don’t need state tracking and I’m just doing some mere CRUD I will opt for a more simple tool like Massive, in the other hand If I’m trying to achieve more advance scenarios (Read/Write batching, some extensions) I will opt for Nhibernate.  Same thing for choosing (or even use them together for different senarios) with MVC and Webforms sometimes I even opt for NancyFx (lightweight web framework). For dependency injection or IOC, I prefer to use some convention over configuration or make my intentions explicit and by limiting my abstractions usually I don’t need to use an IOC at all. (maybe I will write a post about how to do this).

After picking your tools wisely, the most important thing is to use them right, if you find some friction (if you are doing TDD, a good sign is having difficulty to write the tests) than this means that you have a problem in your design or you are misusing (abusing) a tool, you should start refactoring before things get worst. For example using an ORM many people forget about session management ( you will find many using var context = new DbContext) and this results in a poor performance and you lose all the benefits of using the ORM (on a web usually it is one session per request, on desktop app it can be one per form). When you use an IOC try to centralize the using of the container and don’t access the container directly in your classes (in big projects you will really regret it). General rule:

Design patterns and technologies are tools to resolve a problem if you don’t have that problem at first place, don’t use them

otherwise you are creating more problems and you will finish by hurting yourself.
Last thing, try to focus on the concept behind the tool and what it is trying to achieve not the tool itself some concepts can be achieved simply by using some delegates or some conventions or Marker interfaces, this is important to keep in mind, tools always imply a learning curve specially for juniors, and it adds a dependency to your project (eventually make it a slave to it).

The example below shows how to achieve  AOP with delegates (just proof of concept not production code) this can be simply understood by juniors no learning curve and no friction:

public Action<T> Before (Action<T> method, Action<T> before)
{
        return delegate
        {
               before();
               method();
        };
}

public Action<T> After (Action<T> method, Action<T> after)
{
        return delegate
        {
               method();
               after();
        };
}

public class ClassHavingAspects
{
        public Action<string> PrintSomeText = delegate(string message)
        {
               Console.WriteLine(message);
        };
}
 
ClassHavingAspects clazz = new ClassHavingAspects ();
        cut.PrintHello = Before(cut.PrintSomeText, delegate { Console.WriteLine("Hi im before") } );
        cut.PrintHello =After(cut.PrintHello, 
delegate { Console.WriteLine("Hi im After") } );
        cut.SomeText();

I will let you meditate on that.
Technically yours :)

0 comments :

Post a Comment