Showing posts with label Design Principles. Show all posts
Showing posts with label Design Principles. Show all posts

Sunday, November 12, 2006

Way of implementing Dependency Injection

I am working on spring .NET for last of couple of months so thought to put my understanding of idea behind Sring.NET framework in following words.

Any cohesive application made of lots of reusable components. A good designer always dream of reducing the dependency among components in application. Dependency Injection allows coder to get rid of such menial tasks of creating of instances and setting the dependency of objects in code.

Dependency Injection using Factories:

Factories provide centralized approach to handle to instance creation and resolve the dependency among components and hence provide easier way of code maintenance which could have been big mess if such things solved in decentralized way. Using encapsulation Factories shields the information about object creation and it also hides the information about how factored components fit with each other in architecture of the application. All the client code has to do is to call create instance of factory method.

Following is sample code to achieve dependency injection using Factories:

Factory Code:

using System;

namespace DependencyInjectionFactory

{

public interface IFactoredProduct{}

public class ConcreteFactoredProduct:IFactoredProduct{}

public abstract class AbstractProduct

{

protected IFactoredProduct _factoredProduct;

protected AbstractProduct(IFactoredProduct factoredProduct){}

}

public class ConcreteProduct:AbstractProduct

{

public ConcreteProduct(IFactoredProduct factoredProduct)

:base(factoredProduct){}

}

public class ConcreteProductTwo:AbstractProduct

{

public ConcreteProductTwo(IFactoredProduct factoredProduct)

:base(factoredProduct){}

}

public enum AbstractFactoryEnum

{

ConcreteFactory1,

ConcreteFactory2

}

public abstract class AbstractFactory

{

public abstract AbstractProduct Create();

public static AbstractFactory GetFactory(AbstractFactoryEnum enumValue)

{

if(enumValue == AbstractFactoryEnum.ConcreteFactory1)

{

return new ConcreteFactory1();

}

else if(enumValue == AbstractFactoryEnum.ConcreteFactory2)

{

return new ConcreteFactory2();

}

return null;

}

}

public class ConcreteFactory1:AbstractFactory

{

public override AbstractProduct Create()

{

//Object creation and dependecy issue is solved here

return new ConcreteProduct(new ConcreteFactoredProduct());

}

}

public class ConcreteFactory2:AbstractFactory

{

public override AbstractProduct Create()

{

return new ConcreteProductTwo(new ConcreteFactoredProduct());

}

}

}

Client Code:

AbstractFactory factory =

AbstractFactory.GetFactory(AbstractFactoryEnum.ConcreteFactory1);

AbstractProduct product = factory.Create();

//Client code calls Create method of Factory

Console.WriteLine(product.GetType().ToString());

From boilerplate wiring point of view factories has following problems:

1) Instance creation code is hard coded in implementation of factory and thus makes it non extensible. Client code as seen in above code has to know what kind of factory has to be created.

2) All dependencies of objects are well known at compile time.

Dependency Injection using Containers:

Above problems can be solved by containers. Containers provides one layer of abstraction through allow client code to get rid of life cycle management and dependency issues. Containers are not new concept and have been in MS platform for long time now. MTS, CLR are some of the examples of heavy weight containers. In .NET world Spring.NET (http://www.springframework.net/) allows you to create custom light weight containers.

Following is the code which solves same problem described above (DI using factories) in bit different way.


Source Code:

using System;

namespace DependencyInjectionContainer

{

public interface IFactoredProduct{}

public class ConcreteFactoredProduct:IFactoredProduct{}

public abstract class AbstractProduct

{

protected IFactoredProduct _factoredProduct;

protected AbstractProduct(IFactoredProduct factoredProduct){}

}

public class ConcreteProduct:AbstractProduct

{

public ConcreteProduct(IFactoredProduct factoredProduct)

:base(factoredProduct){}

}

}

In Container approach instance creation and object plumbing is done thorough configuration file and thus avoid any hard coding like Factories approach.

xml version="1.0" encoding="utf-8" ?>

<configuration>

<configSections>

<sectionGroup name="spring">

<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />

<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />

sectionGroup>

configSections>

<spring>

<context>

<resource uri="config://spring/objects" />

context>

<objects>

<object id="concreteProduct" type="DependencyInjectionContainer.ConcreteProduct,DependencyInjection">

<constructor-arg name="factoredProduct" ref="factoredInstance" />

object>

<object id="factoredInstance" type="DependencyInjectionContainer.ConcreteFactoredProduct,DependencyInjection">object>

objects>

spring>

configuration>

Client Code: The way Client code consumes created object is:

IApplicationContext appContext = ContextRegistry.GetContext();

Console.WriteLine(appContext.GetObject("concreteProduct").GetType().ToString());

More on “Dependency Injection” can be found in interesting article from Martin Fowler @ http://www.martinfowler.com/articles/injection.html#FormsOfDependencyInjection

Thursday, October 12, 2006

Writing Zero Defect software

Yesterday I was listening an Arcast with title "Writing zero defect software" from http://www.skyscrapr.net/blogs/arcasts/default.aspx?ID=340. Dr. Neil talks about attitude (psychological part) of developer, how to tackle when bug is found, quality, TDD and discoverability of feature. He says that our software development should be done in such way that it should be always ready for shipped (may not be always with all feature, a typical agile value). He also explained one interesting fact that “why developer go for complex solution” and explanation seems to be a big truth. He says that we should have feeling of pride whatever piece of code we deliver and that feeling can only come if we strive to ship zero defect software. He is really concerned about fact our expectation for software are very low, clients always expect that software can not be developed without bugs and bugs are inevitable. He says that we need to set our standard high from software development industry and it should be on par with other industry like Car, Aero plane manufacture.

I am not sure whether we can really make “Zero defect software” or not but, if we implement his idea in our day to day activities of software development then we can definitely reduce the number of bugs in our system drastically. So, I would request you to listen the Arcast mentioned in above link.

Friday, September 29, 2006

Questions Every Designer Should Ask

Here is the much awaited task for you. You got to come up with a design for the given module. I guess this is how we all get our first design assignment. With the slight variation in the situation everybody goes through this sometime or other in their career.

While Design related tasks are much awaited for every programmer. Its every (most if not all) programmer's wish to become a designer. But when the first assignment comes they kind of get nervous and start looking at books to find a Quickest Way to produce the artifact. There are few books which can help you do the design and draw models etc but as a Designer there are few questions which needs to be asked before we start drawing design models.

1. What is the Functional Requirement?
2. What are the steps involved to meet the functional requirement.
3. What is Already Existing? Find out from other team members/designers as which of the functionality already exists.
4. What is the Design Guideline?
5. Are there any design constraints?
6. How much is enough? There is no limit on amount of details one can put in a design document but somewhere a line must be drawn where one says "This much detail is Enough".
7. What are the dependencies (both Internal and External)?
8. How is other parts of the system depend on yours?
9. What are the entities who play a role here? List all the entities from the system involved in the activity.
10. What are the artifacts to be produced?
11. What are the non-functional requirement eg Speed, Transaction Control etc.

If we ask these questions in the beginning then rest becomes easy. That's why designer love their work :)

Until Next Time...:)

Monday, September 18, 2006

Power of Simplicity

More often I come across people who think that a Powerful system has to be complex. Or if the system is powerful it must have lots and lots of complex logic in it. Somehow this amuses me to a greater extent. Quite oftent I end up asking these question to myself:
1. Why a Powerful System has to be complex?
2. What makes a System Powerful?
3. Is Simplicity not a powerful feature in itself?
4. Is it not a fact that if a Complex System is analysed properly, it consists of many simple systems?

The list of questions are endless and I rarely meet a person who can think through in these lines and try to implement a system in the most simplistic possible way.

Next time will discuss about why we need a simplistic approach.. Until next time...