Sunday, May 10, 2009

Lazy Initialzation Pattern in C#





Intent:

Delaying the creation of the object until the first time it has been requested.

Lazy initialization is the tactics of delaying the process of creation of object or calculating the value of the object or some other expansive processes until the first time it is needed. Typically it is achieved by maintaining a flag value in the code. Based on the flag value if the object is ready it is served from the available resources. If not available the object is created on the spot and the request is served.

Benefits:


The main advantage of using the Lazy initialization is that it will not consume unnecessary expansive resources for creating the object until it is required for the first time. Also if the object is already created the request is being served from the object created instead of creating a new object.

Software Example & Explanation of Code:

Let us assume that we are building an online Library Management System. One of the pages (aspx page) requires you to create object of different books. Using the Lazy initialization pattern we will see how the construction of object is delayed till it is requested for the first time. Also when we make request for an object which is already existing how the object is being served from the existing object rather than creating a new one.

Typically Lazy initialization is using with either Factory Method pattern or Single ton design pattern. Here in our example the class “LibraryBooks” does the late initialization of LibraryBooks objects and also if any of the book type already exists it serves it from the existing objects rather than creating new object. The client which is our asp.net page (“Default.aspx” in our case) makes request to the “LibraryBooks” class for creating new objects. Below is the code for the pattern



LibraryBooks.cs

using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Collections.Generic;

namespace LazyInitialzation
{
public class LibraryBooks
{
private static Dictionary objLibraryBooks = new Dictionary();
private string strBookType;

//using a Private constuctor to for Factory or Singleton Methos
private LibraryBooks(string _type)
{
this.strBookType = _type;
}
//Here we are passing the book type and the return type is LibraryBook type
public static LibraryBooks GetBooks(string _BookType)
{
LibraryBooks objBooks;

if (!objLibraryBooks.TryGetValue(_BookType, out objBooks))
{
objBooks = new LibraryBooks(_BookType); //Lazy Initialization
objLibraryBooks.Add(_BookType, objBooks);
}
return objBooks;
}

public static string SetBookStrings()
{
string strBookDetails = "";
if (objLibraryBooks.Count > 0)
{
strBookDetails = " Number of Objects requested as of now is " + objLibraryBooks.Count.ToString() +"
"+"Created objects are
";
foreach (KeyValuePair objKvp in objLibraryBooks)
{
strBookDetails += objKvp.Key + "
";
}
}
return strBookDetails;
}
}
}




Default.aspx.cs

using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

namespace LazyInitialzation
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}

protected void btnCreate_Click(object sender, EventArgs e)
{
LibraryBooks.GetBooks(txtBookType.Text);
Response.Write(LibraryBooks.SetBookStrings());
}
}
}

Default.aspx








Enter Book to be Created










To Test the code run the asp.net application. Enter book types you wanted to create in the textbox. When you create a book type which already exist the count of objects in the dictionary object does not get increased and the object request is being served from the existing objects.

The entire code for download is available at http://www.csharppatterns.com/

Builder pattern in C#



Intent:
The Builder pattern separates the construction of a complex object from its representation, so that the same construction process can create different representations.
Non-Software Example:


Builder pattern can be found in Fast Food restaurants, while making a children’s meal. Typically children’s meal item consists of a main item like Burger, a side item like fries, a soft drink like Coke and a toy. Note that there can be variation in the content of the children's meal, but the construction process remains the same. Whether a customer orders a hamburger, cheeseburger, or chicken burger, the construction process of the meal is the same. The cashier at the counter directs the crew to assemble a main item, side item, and toy.



The Children’s Meal concept corresponds to the builder, which is an abstract Interface for creating parts of the Product object.
The restaurant crew corresponds to the ConcreteBuilder, as they will assemble the parts of the meal (i.e. make a hamburger).
The cashier corresponds to the Director, as the cashier will specify the parts needed for the children’s Meal, resulting in a complete Kid’s meal.
The children’s Meal package corresponds to the Product, as it is a complex object created via the Builder interface.

Benefits:


The construction process is separated from the representation.
The there is a finer control over the construction process and the internal structure of the finished product. Hence two different products from the same builder can be entirely different, but the construction process is the same.

Software Example & Explanation of Code:

Let us take the same above non-software example and try to convert it to a software example. Let us assume that we have got a requirement to build software for a restaurant which serves meals. Once of pages has to be designed for creating a Children’s meal. The Children meal either can be of Vegetarian type or Non-Vegetarian type. The UI (“Default.aspx”) is going to pass the meal type to be created and based on the meal type selected the Director of builder pattern (“Director.cs”) uses the concrete builders (“VegeterianMealBuilder.cs” and “NonVegeterianMealBuilder.cs”) to create the product object (Meal.cs).

UML:




Product: The product defines the type of object to be created by the Builder Pattern. Here in our case since we are creating a Meal object “Meal.cs” will be our product class.

Builder: The builder class defines all the steps that must be implemented to create a final product. Here in our case “MealBuilder.cs” abstract class is the builder and “Meal.cs” class is the product. The “GetMeal” method in the builder class returns the final product.
Concrete Builder: There may be any number of concrete builder classes. These classes inherit from the Builder class. Here in our case “MealBuilder.cs” is the builder class. “VegeterianMealBuilder.cs” and “NonVegeterianMealBuilder.cs” are the concrete builders. The concrete builder classes contain the complexity to build the objects.

Director: The director class controls the algorithm that generates the final product object. A director object is instantiated and its “MakeKidMeal” method is called. The method includes a parameter to capture the specific concrete builder object that is to be used to generate the product.

Following are the code for each of the classes

MealBuilder.cs

namespace BuilderPattern
{
public abstract class MealBuilder
{

public abstract void AddBurger();
public abstract void AddFries();
public abstract void AddDrink();
public abstract void AddToy();
public abstract void SetPrice();
public abstract Meal GetMeal();

}
}

NonVegeterianMealBuilder.cs

namespace BuilderPattern
{
public class NonVegeterianMealBuilder : MealBuilder
{
private Meal _NonVegMeal = new Meal();

public override void AddBurger()
{
_NonVegMeal.BurgerType = "Step 1 : One Chiken Burger";
}
public override void AddFries()
{
_NonVegMeal.FryType = "Step 2 : One Basket of Patato and Chicken Fry";
}
public override void AddDrink()
{
_NonVegMeal.DrinkType = "Step 3 : One Pepsi with out ICE ";
}

public override void AddToy()
{
_NonVegMeal.ToyType = "Step 4 : One Racing car toy ";
}

public override void SetPrice()
{
_NonVegMeal.Price = 4;
}
public override Meal GetMeal()
{
return _NonVegMeal;
}
}
}


VegeterianMealBuilder.cs

namespace BuilderPattern
{
public class VegeterianMealBuilder : MealBuilder
{
private Meal _VegMeal = new Meal();

public Meal Meal
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}

public override void AddBurger()
{
_VegMeal.BurgerType = "Step 1 : One Vegiterian Burger";
}
public override void AddFries()
{
_VegMeal.FryType = "Step 2 : One Basket of Patato and Capsicum Fry";
}
public override void AddDrink()
{
_VegMeal.DrinkType = "Step 3 : One Coke with Ice and Lemon ";
}

public override void AddToy()
{
_VegMeal.ToyType = "Step 4 : One Soft toy ";
}

public override void SetPrice()
{
_VegMeal.Price = 2;
}
public override Meal GetMeal()
{
return _VegMeal;
}
}
}

Meal.cs

namespace BuilderPattern
{
public class Meal
{
private string _BurgerType;

public string BurgerType
{
get { return _BurgerType; }
set { _BurgerType = value; }
}
private string _DrinkType;

public string DrinkType
{
get { return _DrinkType; }
set { _DrinkType = value; }
}
private string _ToyType;

public string ToyType
{
get { return _ToyType; }
set { _ToyType = value; }
}
private string _FryType;

public string FryType
{
get { return _FryType; }
set { _FryType = value; }
}
private int _Price;

public int Price
{
get { return _Price; }
set { _Price = value; }
}
}
}

Now the director class

Director.cs

namespace BuilderPattern
{
public class Director
{
public void MakeKidsMeal(MealBuilder objMealBuilder)
{
objMealBuilder.AddBurger();
objMealBuilder.AddDrink();
objMealBuilder.AddFries();
objMealBuilder.AddToy();
objMealBuilder.SetPrice();
objMealBuilder.GetMeal();
}
}
}

The button click method can be represented as

Default.aspx

protected void btnPrint_Click(object sender, EventArgs e)
{
Meal objMeal = null;
Director objDirector = new Director();

if (ddlMealType.SelectedValue == "Veg Meal")
{
VegeterianMealBuilder objVegMeal = new VegeterianMealBuilder();
objDirector.MakeKidsMeal(objVegMeal);
objMeal = objVegMeal.GetMeal();
}
else if (ddlMealType.SelectedValue == "Non Veg Meal")
{
NonVegeterianMealBuilder objNonVegMeal = new NonVegeterianMealBuilder();
objDirector.MakeKidsMeal(objNonVegMeal);
objMeal = objNonVegMeal.GetMeal();
}

Response.Write("======================================================
");
Response.Write("Welcome To New Restruant
");
Response.Write("======================================================
");
Response.Write(objMeal.BurgerType+"

");
Response.Write(objMeal.FryType + "

");
Response.Write(objMeal.DrinkType + "

");
Response.Write(objMeal.ToyType + "

");
Response.Write("Total Meal price is $"+objMeal.Price.ToString() + " only

");
}

Happy Coding :)


The entire code for download is available at
http://www.csharppatterns.com/

References:
Non-Software examples of these patterns were published by Michael Duell in Object Magazine in July, 1997.

Factory Method in C#



Intent:

The Factory Method defines an interface for creating objects, but lets subclasses decide which classes to instantiate.

Non-Software Example:


The factory method pattern can be found in the injection moldings manufacturing process. The manufacturer processes the plastic molding powder and injects plastic into the molds of desired shapes. Like the Factory Method, the subclasses (in this case the molds) determine which classes to instantiate. In the example, the ToyHorseMold class is being instantiated.



To know what a plastic molding process is please visit
http://www.ider.herts.ac.uk/school/courseware/manufacture/plastic_forming/injection_moulding.html

The Injection Mold corresponds to the Product, as it defines the interface of the objects created by the factory.

A specific mold (ToyHorseMold or ToyCarMold) corresponds to the ConcreteProduct, as these implement the Product interface.

The toy company corresponds to the Creator, since it may use the factory to create product objects.

The division of the toy company that manufactures a specific type of toy (horse or car) corresponds to the ConcreteCreator.

Benefits:


Creating objects with an injection mould is much more flexible than using equipments that creates only toy horses. If racing car toys become more famous tomorrow injection mould can be easily extended to make racing cars.

Software Example & Explanation of Code:

Let us assume that we have a requirement to display mobile information on an aspx page based on the values selected in the dropdown (assume that we have two different mobiles Nokia and Samsung). Let us see with the below code how can we apply factory pattern to this scenario.

As the factory method stats it defines an interface to create objects but the sub class decides which object to create. Here in our example we have two different varieties of objects to be created, the “NokiaMobile” class object or the “SamsungMobile” Class object. The “MobileFactory” class decides which of these two objects to be created based on parameter provided to it. The default.aspx which is a client passes the parameters to the “MobileFactory” class, based on which the objects are being created. Below is the code of each of these classes

UML:



MobileClass.cs

namespace FactoryMethod
{
public abstract class MobileClass
{
private int _Price;

public int Price
{
get { return _Price; }
set { _Price = value; }
}
private string _ModelName;

public string ModelName
{
get { return _ModelName; }
set { _ModelName = value; }
}
private string _HasMp3;

public string HasMp3
{
get { return _HasMp3; }
set { _HasMp3 = value; }
}
private int _StorageCaparity;

public int StorageCaparity
{
get { return _StorageCaparity; }
set { _StorageCaparity = value; }
}
private string _HasCamera;

public string HasCamera
{
get { return _HasCamera; }
set { _HasCamera = value; }
}


}
}

SamsungMobile.cs

public class SamsungMobile:MobileClass
{
//Setting All the base class values in the constructor
public SamsungMobile()
{
base.Price = 125;
base.HasCamera = "Yes";
base.HasMp3 = "Yes";
base.ModelName = "New Samsung ABC Model";
base.StorageCaparity = 4;
}
}





NokiaMobile.cs

public class NokiaMobile:MobileClass
{
//Setting All the base class values in the constructor

public NokiaMobile()
{
base.Price = 100;
base.HasCamera = "Yes";
base.HasMp3 = "No";
base.ModelName = "New Nokia XYZ Model";
base.StorageCaparity = 2;
}

}

MobileFactory.cs

namespace FactoryMethod
{
public class MobileFactory
{
public static MobileClass CreateMobile(string _mobileTypes)
{
switch (_mobileTypes)
{
case "NOKIA":
return new NokiaMobile();
break;

case "SAMSUNG":
return new SamsungMobile();
break;

default:
throw new NotSupportedException("This format is not supported");
}

}

}
}

Here is the clinet code Default.aspx and Default.aspx.cs which uses the MobileFactory Class.

Default.aspx
















Default.aspx.cs

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Response.Write("Welcome to Model Selector");
DropDownList1.Items.Add("SAMSUNG");
DropDownList1.Items.Add("NOKIA");
}
}

protected void Button1_Click(object sender, EventArgs e)
{
MobileClass objNewMobile = MobileFactory.CreateMobile(DropDownList1.SelectedValue);

Response.Write(" "+"Welcome to new model of "+DropDownList1.SelectedValue.ToString()+"

");
Response.Write("Mobile Model is: "+objNewMobile.ModelName+"
");
Response.Write("Mobile Price is: $"+objNewMobile.Price+".00
");
Response.Write("Mobile Has MP3 : "+objNewMobile.HasMp3+"
");
Response.Write("Mobile Has Camera is: "+objNewMobile.HasCamera+"
");
Response.Write("Mobile Supports : "+objNewMobile.StorageCaparity.ToString()+"
"+"Thank you");
}
}

The entire code for download is available at
http://www.csharppatterns.com/

References:
Non-Software examples of these patterns were published by Michael Duell in Object Magazine in July, 1997.


What are different types of Design Patterns



Design patterns are mainly of three different types

1. Creational Patterns: Helps you in creation of objects rather then you instantiating objects directly.
2. Structural Patterns : Helps you to compose or build groups of objects into larger structures, such as complex user interfaces or accounting data
3. Behavioral Patterns: Helps you in establishing communication between objects.


When to use Design Patterns?


Of course we should think of design patterns while designing the application, but the question is what pattern to use when.

Creational design patterns:

When your design needs to create objects in the system you should think of creational patterns. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation.
Some examples of creational design patterns include:
Abstract factory pattern: centralize decision of what
factory to instantiate

Factory method pattern: centralize creation of an object of a specific type choosing one of several implementations

Builder pattern: separate the construction of a complex object from its representation so that the same construction process can create different representations

Lazy initialization pattern: tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed

Object pool: avoid expensive acquisition and release of resources by recycling objects that are no longer in use

Prototype pattern: used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects

Singleton pattern: restrict instantiation of a class to one object

Structural Patterns: When you design complex objects on top of the existing objects you can think of any of the structural patterns.

Some of the examples of Structural Pattern include
Adapter pattern: 'adapts' one interface for a class into one that a client expects

Aggregate pattern: a version of the Composite pattern with methods for aggregation of children

Bridge pattern: decouple an abstraction from its implementation so that the two can vary independently

Composite pattern: a tree structure of objects where every object has the same interface

Decorator pattern: add additional functionality to a class at runtime where subclassing would result in an
exponential rise of new classes

Extensibility pattern: aka. Framework - hide complex code behind a simple interface

Facade pattern: create a simplified interface of an existing interface to ease usage for common tasks

Flyweight pattern: a high quantity of objects share a common properties object to save space

Proxy pattern: a class functioning as an interface to another thing

Pipes and filters: a chain of processes where the output of each process is the input of the next

Private class data pattern: restrict accessor /mutator access

Behavioral Patterns: Behavioral patterns define the communication patterns between objects. These objects

Examples of this type of design pattern include:
Chain of responsibility pattern: Command objects are handled or passed on to other objects by logic-containing processing objects

Command pattern: Command objects encapsulate an action and its parameters

Interpreter pattern: Implement a specialized computer language to rapidly solve a specific set of problems

Iterator pattern: Iterators are used to access the elements of an aggregate object sequentially without exposing its underlying representation

Mediator pattern: Provides a unified interface to a set of interfaces in a subsystem

Memento pattern: Provides the ability to restore an object to its previous state (rollback)

Null Object pattern: designed to act as a default value of an object

Observer pattern: aka Publish/Subscribe or Event Listener. Objects register to observe an event which may be raised by another object

State pattern: A clean way for an object to partially change its type at runtime

Strategy pattern: Algorithms can be selected on the fly

Specification pattern: Recombinable Business logic in a boolean fashion

Template method pattern: Describes the program skeleton of a program

Visitor pattern: A way to separate an algorithm from an object

Single-serving visitor pattern: Optimize the implementation of a visitor that is allocated, used only once, and then deleted

Hierarchical visitor pattern: Provide a way to visit every node in a hierarchical data structure such as a tree.

Origin of Design Patterns



Years ago, an architect named Christopher Alexander (a civil Architect) postulated some of his thoughts in designing some of the buildings, towns and roads planning. Alexander studied this problem by making many observations of buildings, towns, streets, and virtually every other aspect of living spaces that human beings have built for themselves. He discovered that, for a particular architectural creation, good constructs had things in common with each other.

Alexander understood that structures couldn’t be separated from the problem they are trying to solve. Therefore, in his quest to identify and describe the consistency of quality in design. Alexander realized that he had to look at different structures that were designed to solve the same problem. For example, below Image illustrates two solutions to the problem of demarking an entryway.


Although the structure in the above image looks different, but they solve the same problem.

Design Pattern in Software Designs

In the early 1990s, some smart developers looked at Alexander’s work in patterns. They wondered whether what was true for architectural patterns would also be true for software design.

• Were there problems in software that occur over and over again that could be solved in somewhat the same manner?
• Was it possible to design software in terms of patterns, creating specific solutions based on these patterns only after the patterns had been identified?

The group felt the answer to both of these questions was “unequivocally yes.” The next step was to identify several patterns and develop standards for cataloging new ones. Although many people were working on design patterns in the early 1990s, the book that had the greatest influence on this fledging community was Design Patterns: Elements of Reusable Object-Oriented Software6 by Gamma, Helm, Johnson, and Vlissides. In recognition of their important work, these four authors are commonly and affectionately known as the Gang of Four.

The Liskov Substitution Principle in C#.Net (LSP in C#.Net)




The Liskov Substitution principe was coined by Barber Liskov in her work regarding data abstraction and type theory. In simple english the principle can be stated as
“ Any derived class should be substitutable for their base classes”
That is, a user of a base class should continue to function properly if a derivative of that base class is passed to it.
Let us say consider the above example. “SavingsWithDrawform” class has a method which accepts the “Accounts” class object as shown below.
public void WithDraw( Accounts objAcc)
{
//Code Implementation of Account objects
}
The principle of LSP states that it should be legal to pass the the “SavingsAccount” object to the same method, which is as shown
public void WithDraw(SavingsAccounts objAcc)
{
//Passing the derived type should be legal
}

This looks prety obvious. But let us consdier the follwing code example
Let us say we have rectangle class with the following code
public class Rectangle
{
protected int _Height;
protected int _Width;

public int Height
{
get { return _Height; }
}


public int Width
{
get { return _Width; }
}

public virtual void SetHeight(int intHeight)
{
_Height = intHeight;
}
public virtual void SetWidth(int intWidth)
{
_Width = intWidth;
}
}
Now let say we have one more class which is derived from “Rectangle” class is Square class
public class Square:Rectangle
{
public override void SetHeight(int intHeight)
{
_Width = intHeight;
_Height = intHeight;
}
public override void SetWidth(int intWidth)
{
_Height = intWidth;
_Width = intWidth;
} }


Now let say you have a method to calculate area and below is the code for this
Rectangle objRect = new Square();

objRect.SetHeight(2);
objRect.SetWidth(5);

int area = objRect.Width * objRect.Height;

When the area is calcualted it will show as 25, but actually we have expected the value to be 10. So here in this case the derived class is not substitutable for the base class.
References
http://www.objectmentor.com/resources/articles/lsp.pdf

The Open Closed Principle in C# (OCP in C#)



To improve and succeed in market every software needs “Change”. All software change during its life cycle. So it is very important for the developers to design software in a way which can accommodate changes with minimal impact. One of the design principles which help us in designing this kind of software is “Open Closed Principle (OCP)” suggested by Robert Martin. The OCP stats that
“Software entities (Classes, Modules, Functions etc) should be open for extension, but closed for modification”
Software entities that implement the OCP principle will have two big benefits. First they are open to extension which means that we can achieve new business needs with out changing the existing code much. Second they are closed for modification which means that they code itself will not change.
Let us consider an example. Let us say you are designing software for resource allocation. You have two option of resource allocation the “Time slot” and “Space slot”. The below code is implemented without the OCP. The disadvantage with the code is that every time there the new resource type added there need to a lot of changes to the code. Please note the number of comments in below code where the changes are required whenever there is an addition of resource type

Code without OCP


public class ResourceAllocator
{
public string Allocate(int intResourceType)
{
int intRes=0;
switch (intRes)
{
case 1:
return AllocateTimeSlot(intRes); ;
break;
case 2:
return AllocateSpaceSlot(intRes);
break;
//new Case has to be added for a new Allocation Type
default:
throw new Exception("No slot defination");
}
}
public string Free(int intResourceType)
{
int intResFree = 0;
switch (intResFree)
{
case 1:
return FreeTimeSlot(intResFree);
break;
case 2:
return FreeSpaceSlot(intResFree);
break;
//new Case has to be added for a new Allocation Type
default:
throw new Exception("No slot defination");
}
}

//New methods has to be created for the new allocation Type

public string AllocateTimeSlot(int intTimeSlot)
{
//Put the logic to Allocate the time slot
return "";
}
public string AllocateSpaceSlot(int intSpaceSlot)
{
//Put the logic to Allocate the Space slot
return "";
}

public string FreeTimeSlot(int intTimeSlot)
{
//Put the logic to Allocate the Space slot
return "";
}

public string FreeSpaceSlot(int intSpaceSlot)
{
//Put the logic to Allocate the Space slot
return "";
}
}
.
Now let’s take the same example and apply OCP to it.

Below is the code for the resource allocation with OCP

public abstract class ResourcePool
{
public abstract string Allocate(int IntRes);

public abstract string Free(int intRes);

}

public class SpaceSlot:ResourcePool
{

public override string Allocate(int IntRes)
{
//put the logic to allocate space slot
return "";
}

public override string Free(int intRes)
{
//put the logic to free space slot
return "";
}
}

public class TimeSlot : ResourcePool
{
public override string Allocate(int IntRes)
{
//put the logic to allocate time slot
return "";
}

public override string Free(int intRes)
{
//put the logic to Free time slot
return "";
}
}


Now you can have the logic for creating type of object in the resource manager class. Any addition of new code resouce type will not involve much code changes.

Deadly sins of Design (Symptoms of rotting Design)



Every software is designed for a business need. When software is designed it starts with a clear thought process in mind of the developers. At this point the software is in its best shape and in a condition which can be maintained very easily. But there are always changes in business needs and business plans. Your software should be able to meet the business needs and business plans. You start making changes to the code. Slowly you realize that the code is not that maintainable which found earlier and it is not very easy plug new thing into the code. Then your software starts rotting. It continues to a point where it fails completely and you think of re-designing the entire software again. In reality you really get a chance to re-design the entire software and also these re-designs hardly succeeds. So what is the thing which causes the software to rot? Well there are four design symptoms which rots the software if not taken in to consideration from the beginning. They are

• Rigidity
• Fragility
• Immobility
• Viscosity


Rigidity

A software can be called a rigid when it is difficult to change even in a sample way. Every change causes subsequent changes in all the other dependent modules. What begins with a simple two days change in one module grows into changes for weeks as the engineer changes module after module.
Let us consider a defect tracking system. Let us say it is an N-tier architecture product. Let’s say the defect tracking system has a severity dropdown having values like “Critical, Major and Minor”. Now it was decided by the client that there can not be any other values for severity other then “Critical, Major and Minor” The developers have decided to hard cord the values in the UI layer. So every layer has been hard cored with the values and the product has been released to the client. The first release was successful and the client it happy with it.
After a year the client has decided to add “Normal” as one category and remove “Minor” from the category list. The manager felt that this is a simple label change and can be done very easily and has made the commitment accordingly. This has been communicated to the new developer and the developer started looking into the issue. Now the developer realized that since the values have been hardcoded he/she has to go and change each and every layer. Also the developer started exploring all the places where the values have been hard coded. So the commitment to the client can not be met. So what has started with a small change has become an ocean of changes now.
So while designing software it is the responsibility of the architect to make sure that the software is not rigid.


Fragility


Fragility is very closely related with rigidity. Fragility is the tendency of the software to break in many places every time there is change in the software. Often the breakage occurs in areas that has no conceptual link with the changed area. As the fragility of the software increases the chances of breaking increases with time. Such software is difficult to maintain. Every fix that has been introduced will cause more problem than solved.


Immobility


Immobility is the inability to reuse the software from other projects or parts of the same project. This comes when the system engineer finds that the same functionality which needs to be implemented is already available in a different part of the same project or in a different project. However often the modification to make it generic comes with a heavy price. So the engineers decide to re-write the entire code instead of reusing.

Viscosity
Viscosity of software comes in two forms 1. Viscosity of the design 2. Viscosity of environment. Whenever a change is being requested for a software engineers has multiple ways to implement it. Some of the ways preserver the existing design and some do not. Implementing in a way to preserve the design difficult and hence the viscosity is very high. Implementing without preserving the design is very easy and hence has low viscosity.
Viscosity of environment comes when the engineers compromise the design with development environment. For example when the engineers find that the recompiling the entire code takes time, the skip the recompiling of code compromising the design.
The four systems Rigidity, Fragility, Immobility, and Viscosity are the signs of a poor architecture. Software starts rotting after sometime if these points has not been covered properly while designing the software. What causes the software to rot? Well one of the main reasons for the software to rot is change in requirement.