Sunteți pe pagina 1din 62

1.

Introduction

I have noticed an increase in the number of articles published in the Architect category in code-project during the last few
months. The number of readers for most of these articles is also high, though the ratings for the articles are not. This
indicates that readers are interested in reading articles on Architecture, but the quality does not match their expectations. This
article is a constructive attempt to group/ define/ explain all introductory concepts of software architecture for well seasoned
developers who are looking to take their next step as system architects.

One day I read an article that said that the richest 2 percent own half the world's wealth. It also said that the richest 1
percent of adults owned 40 percent of global assets in the year 2000. And further, that the richest 10 percent of adults
accounted for 85 percent of the world's total wealth. So there is an unbalanced distribution of wealth in the physical world.
Have you ever thought of an unbalanced distribution of knowledge in the software world? According to my view point, the
massive expansion of the software industry is forcing developers to use already implemented libraries, services and
frameworks to develop software within ever shorter periods of time. The new developers are trained to use (I would say more
often) already developed software components, to complete the development quicker. They just plug in an existing library and
some how manage to achieve the requirements. But the sad part of the story is, that they never get a training to define,
design the architecture for, and implement such components. As the number of years pass by, these developers become leads
and also software architects. Their titles change, but the old legacy of not understanding, of not having any architectural
experience continues, creating a vacuum of good architects. The bottom line is that only a small percentage of developers
know how to design a truly object oriented system. The solution to this problem is getting harder every day as the aggressive
nature of the software industry does not support an easy adjustment to existing processes, and also the related online
teaching materials are either complex or less practical or sometimes even wrong. The most of them use impractical, irrelevant
examples of shapes, animals and many other physical world entities to teach concepts of software architecture. There are only
very few good business-oriented design references. Unfortunately, I myself am no exception and am a result of this very same
system. I got the same education that all of you did, and also referred to the same resource set you all read.

Coming back to the initial point, I noticed that there is a knowledge gap, increasing every day, between the architects who
know how to architect a system properly and the others who do not know. The ones, who know, know it right. But the ones,
who do not know, know nothing. Just like the world’s wealth distribution, it is an unbalanced distribution of knowledge.

2. Background

This article began after reading and hearing the questions new developers have, on basics of software architecture. There are
some good articles out there, but still developers struggle to understand the basic concepts, and more importantly, the way to
apply them correctly.

As I see it, newcomers will always struggle to understand a precise definition of a new concept, because it is always a new
and hence unfamiliar idea. The one, who has experience, understands the meaning, but the one who doesn’t, struggles to
understand the very same definition. It is like that. Employers want experienced employees. So they say, you need to have
experience to get a job. But how the hell is one supposed to have that experience if no one is willing to give him a job? As in
the general case, the start with software architecture is no exception. It will be difficult. When you start to design your very
first system, you will try to apply everything you know or learned from everywhere. You will feel that an interface needs to be
defined for every class, like I did once. You will find it harder to understand when and when not to do something. Just prepare
to go through a painful process. Others will criticize you, may laugh at you and say that the way you have designed it is
wrong. Listen to them, and learn continuously. In this process you will also have to read and think a lot. I hope that this
article will give you the right start for that long journey.

“The knowledge of the actions of great men, acquired by long experience in contemporary affairs, and a continual study of
antiquity” – I read this phrase when I was reading the book named “The Art of War”, seems applicable here, isn’t it?
3. Prerequisites

This article is an effort to provide an accurate information pool for new developers on the basics of software architecture,
focusing on Object Oriented Programming (OOP). If you are a developer, who has a minimum of three or more years of
continuous development experience and has that hunger to learn more, to step-in to the next level to become a software
architect, this article is for you.

4. The Main Content

4.1. What is Software Architecture?

Software Architecture is defined to be the rules, heuristics and patterns governing:

• Partitioning the problem and the system to be built into discrete pieces
• Techniques used to create interfaces between these pieces
• Techniques used to manage overall structure and flow
• Techniques used to interface the system to its environment
• Appropriate use of development and delivery approaches, techniques and tools.

4.2. Why Architecture is important?

The primary goal of software architecture is to define the non-functional requirements of a system and define the
environment. The detailed design is followed by a definition of how to deliver the functional behavior within the architectural
rules. Architecture is important because it:

• Controls complexity
• Enforces best practices
• Gives consistency and uniformity
• Increases predictability
• Enables re-use.

4.3. What is OOP?

OOP is a design philosophy. It stands for Object Oriented Programming. Object-Oriented Programming (OOP) uses a different
set of programming languages than old procedural programming languages (C, Pascal, etc.). Everything in OOP is grouped as
self sustainable "objects". Hence, you gain re-usability by means of four main object-oriented programming concepts.
In order to clearly understand the object orientation, let’s take your “hand” as an example. The “hand” is a class. Your body
has two objects of type hand, named left hand and right hand. Their main functions are controlled/ managed by a set of
electrical signals sent through your shoulders (through an interface). So the shoulder is an interface which your body uses to
interact with your hands. The hand is a well architected class. The hand is being re-used to create the left hand and the right
hand by slightly changing the properties of it.

4.4. What is an Object?

An object can be considered a "thing" that can perform a set of related activities. The set of activities that the object
performs defines the object's behavior. For example, the hand can grip something or a Student (object) can give the name or
address.

In pure OOP terms an object is an instance of a class.

4.5. What is a Class?

A class is simply a representation of a type of object. It is the blueprint/ plan/ template that describe the details of an object.
A class is the blueprint from which the individual objects are created. Class is composed of three things: a name, attributes,
and operations.
Collapse | Copy Code

public class Student


{
}

According to the sample given below we can say that the student object, named objectStudent, has created out of the
Student class.
Collapse | Copy Code

Student objectStudent = new Student();

In real world, you'll often find many individual objects all of the same kind. As an example, there may be thousands of other
bicycles in existence, all of the same make and model. Each bicycle has built from the same blueprint. In object-oriented
terms, we say that the bicycle is an instance of the class of objects known as bicycles.

In the software world, though you may not have realized it, you have already used classes. For example, the TextBox control,
you always used, is made out of the TextBox class, which defines its appearance and capabilities. Each time you drag a
TextBox control, you are actually creating a new instance of the TextBox class.

4.6. How to identify and design a Class?

This is an art; each designer uses different techniques to identify classes. However according to Object Oriented Design
Principles, there are five principles that you must follow when design a class,
• SRP - The Single Responsibility Principle -
A class should have one, and only one, reason to change.
• OCP - The Open Closed Principle -
You should be able to extend a classes behavior, without modifying it.
• LSP - The Liskov Substitution Principle-
Derived classes must be substitutable for their base classes.
• DIP - The Dependency Inversion Principle-
Depend on abstractions, not on concretions.
• ISP - The Interface Segregation Principle-
Make fine grained interfaces that are client specific.

For more information on design principles, please refer to Object Mentor.

Additionally to identify a class correctly, you need to identify the full list of leaf level functions/ operations of the system
(granular level use cases of the system). Then you can proceed to group each function to form classes (classes will group
same types of functions/ operations). However a well defined class must be a meaningful grouping of a set of functions and
should support the re-usability while increasing expandability/ maintainability of the overall system.

In software world the concept of dividing and conquering is always recommended, if you start analyzing a full system at the
start, you will find it harder to manage. So the better approach is to identify the module of the system first and then dig deep
in to each module separately to seek out classes.

A software system may consist of many classes. But in any case, when you have many, it needs to be managed. Think of a
big organization, with its work force exceeding several thousand employees (let’s take one employee as a one class). In order
to manage such a work force, you need to have proper management policies in place. Same technique can be applies to
manage classes of your software system as well. In order to manage the classes of a software system, and to reduce the
complexity, the system designers use several techniques, which can be grouped under four main concepts named
Encapsulation, Abstraction, Inheritance, and Polymorphism. These concepts are the four main gods of OOP world and in
software term, they are called four main Object Oriented Programming (OOP) Concepts.

4.7. What is Encapsulation (or information hiding)?

The encapsulation is the inclusion within a program object of all the resources need for the object to function - basically, the
methods and the data. In OOP the encapsulation is mainly achieved by creating classes, the classes expose public methods
and properties. The class is kind of a container or capsule or a cell, which encapsulate the set of methods, attribute and
properties to provide its indented functionalities to other classes. In that sense, encapsulation also allows a class to change its
internal implementation without hurting the overall functioning of the system. That idea of encapsulation is to hide how a class
does it but to allow requesting what to do.
In order to modularize/ define the functionality of a one class, that class can uses functions/ properties exposed by another
class in many different ways. According to Object Oriented Programming there are several techniques, classes can use to link
with each other and they are named association, aggregation, and composition.

There are several other ways that an encapsulation can be used, as an example we can take the usage of an interface. The
interface can be used to hide the information of an implemented class.

Collapse | Copy Code

IStudent myStudent = new LocalStudent();


IStudent myStudent = new ForeignStudent();

According to the sample above (let’s assume that LocalStudent and ForeignStudent are implemented by the IStudent
interface) we can see how LocalStudent and ForeignStudent are hiding their, localize implementing information through the
IStudent interface.

4.8. What is Association?

Association is a (*a*) relationship between two classes. It allows one object instance to cause another to perform an action on
its behalf. Association is the more general term that define the relationship between two classes, where as the aggregation
and composition are relatively special.
Collapse | Copy Code

public class StudentRegistrar


{
public StudentRegistrar ();
{
new RecordManager().Initialize();
}
}

In this case we can say that there is an association between StudentRegistrar and RecordManager or there is a directional
association from StudentRegistrar to RecordManager or StudentRegistrar use a (*Use*) RecordManager. Since a direction is
explicitly specified, in this case the controller class is the StudentRegistrar.

To some beginners, association is a confusing concept. The troubles created not only by the association alone, but with two
other OOP concepts, that is association, aggregation and composition. Every one understands association, before aggregation
and composition are described. The aggregation or composition cannot be separately understood. If you understand the
aggregation alone it will crack the definition given for association, and if you try to understand the composition alone it will
always threaten the definition given for aggregation, all three concepts are closely related, hence must study together, by
comparing one definition to another. Let’s explore all three and see whether we can understand the differences between these
useful concepts.

4.9. What is the difference between Association, Aggregation and Composition?

Association is a (*a*) relationship between two classes, where one class use another. But aggregation describes a special type
of an association. Aggregation is the (*the*) relationship between two classes. When object of one class has an (*has*)
object of another, if second is a part of first (containment relationship) then we called that there is an aggregation between
two classes. Unlike association, aggregation always insists a direction.
Collapse | Copy Code

public class University


{
private Chancellor universityChancellor = new Chancellor();
}

In this case I can say that University aggregate Chancellor or University has an (*has-a*) Chancellor. But even without a
Chancellor a University can exists. But the Faculties cannot exist without the University, the life time of a Faculty (or Faculties)
attached with the life time of the University . If University is disposed the Faculties will not exist. In that case we called that
University is composed of Faculties. So that composition can be recognized as a special type of an aggregation.

Same way, as another example, you can say that, there is a composite relationship in-between a KeyValuePairCollection and a
KeyValuePair. The two mutually depend on each other.

.Net and Java uses the Composite relation to define their Collections. I have seen Composition is being used in many other
ways too. However the more important factor, that most people forget is the life time factor. The life time of the two classes
that has bond with a composite relation mutually depend on each other. If you take the .net Collection to understand this,
there you have the Collection Element define inside (it is an inner part, hence called it is composed of) the Collection, farcing
the Element to get disposed with the Collection. If not, as an example, if you define the Collection and it’s Element to be
independent, then the relationship would be more of a type Aggregation, than a Composition. So the point is, if you want to
bind two classes with Composite relation, more accurate way is to have a one define inside the other class (making it a
protected or private class). This way you are allowing the outer class to fulfill its purpose, while tying the lifetime of the inner
class with the outer class.

So in summary, we can say that aggregation is a special kind of an association and composition is a special kind of an
aggregation. (Association->Aggregation->Composition)
4.10. What is Abstraction and Generalization?

Abstraction is an emphasis on the idea, qualities and properties rather than the particulars (a suppression of detail). The
importance of abstraction is derived from its ability to hide irrelevant details and from the use of names to reference objects.
Abstraction is essential in the construction of programs. It places the emphasis on what an object is or does rather than how it
is represented or how it works. Thus, it is the primary means of managing complexity in large programs.

While abstraction reduces complexity by hiding irrelevant detail, generalization reduces complexity by replacing multiple
entities which perform similar functions with a single construct. Generalization is the broadening of application to encompass a
larger domain of objects of the same or different type. Programming languages provide generalization through variables,
parameterization, generics and polymorphism. It places the emphasis on the similarities between objects. Thus, it helps to
manage complexity by collecting individuals into groups and providing a representative which can be used to specify any
individual of the group.

Abstraction and generalization are often used together. Abstracts are generalized through parameterization to provide greater
utility. In parameterization, one or more parts of an entity are replaced with a name which is new to the entity. The name is
used as a parameter. When the parameterized abstract is invoked, it is invoked with a binding of the parameter to an
argument.

4.11. What is an Abstract class?

Abstract classes, which declared with the abstract keyword, cannot be instantiated. It can only be used as a super-class for
other classes that extend the abstract class. Abstract class is the concept and implementation gets completed when it is being
realized by a subclass. In addition to this a class can inherit only from one abstract class (but a class may implement many
interfaces) and must override all its abstract methods/ properties and may override virtual methods/ properties.

Abstract classes are ideal when implementing frameworks. As an example, let’s study the abstract class named LoggerBase
below. Please carefully read the comments as it will help you to understand the reasoning behind this code.

Collapse | Copy Code

public abstract class LoggerBase


{
/// <summary>
/// field is private, so it intend to use inside the class only
/// </summary>
private log4net.ILog logger = null;

/// <summary>
/// protected, so it only visible for inherited class
/// </summary>
protected LoggerBase()
{
// The private object is created inside the constructor
logger = log4net.LogManager.GetLogger(this.LogPrefix);
// The additional initialization is done immediately after
log4net.Config.DOMConfigurator.Configure();
}

/// <summary>
/// When you define the property as abstract,
/// it forces the inherited class to override the LogPrefix
/// So, with the help of this technique the log can be made,
/// inside the abstract class itself, irrespective of it origin.
/// If you study carefully you will find a reason for not to have “set” method here.
/// </summary>
protected abstract System.Type LogPrefix
{
get;
}

/// <summary>
/// Simple log method,
/// which is only visible for inherited classes
/// </summary>
/// <param name="message"></param>
protected void LogError(string message)
{
if (this.logger.IsErrorEnabled)
{
this.logger.Error(message);
}
}

/// <summary>
/// Public properties which exposes to inherited class
/// and all other classes that have access to inherited class
/// </summary>
public bool IsThisLogError
{
get
{
return this.logger.IsErrorEnabled;
}
}
}

The idea of having this class as an abstract is to define a framework for exception logging. This class will allow all subclass to
gain access to a common exception logging module and will facilitate to easily replace the logging library. By the time you
define the LoggerBase, you wouldn’t have an idea about other modules of the system. But you do have a concept in mind and
that is, if a class is going to log an exception, they have to inherit the LoggerBase. In other word the LoggerBase provide a
framework for exception logging.

Let’s try to understand each line of the above code.

Like any other class, an abstract class can contain fields, hence I used a private field named logger declare the ILog interface
of the famous log4net library. This will allow the Loggerbase class to control, what to use, for logging, hence, will allow
changing the source logger library easily.

The access modifier of the constructor of the LoggerBase is protected. The public constructor has no use when the class is of
type abstract. The abstract classes are not allowed to instantiate the class. So I went for the protected constructor.

The abstract property named LogPrefix is an important one. It enforces and guarantees to have a value for LogPrefix
(LogPrefix uses to obtain the detail of the source class, which the exception has occurred) for every subclass, before they
invoke a method to log an error.

The method named LogError is protected, hence exposed to all subclasses. You are not allowed or rather you cannot make it
public, as any class, without inheriting the LoggerBase cannot use it meaningfully.

Let’s find out why the property named IsThisLogError is public. It may be important/ useful for other associated classes of an
inherited class to know whether the associated member logs its errors or not.

Apart from these you can also have virtual methods defined in an abstract class. The virtual method may have its default
implementation, where a subclass can override it when required.

All and all, the important factor here is that all OOP concepts should be used carefully with reasons, you should be able to
logically explain, why you make a property a public or a field a private or a class an abstract. Additionally, when architecting
frameworks, the OOP concepts can be used to forcefully guide the system to be developed in the way framework architect’s
wanted it to be architected initially.

4.12. What is an Interface?

In summary the Interface separates the implementation and defines the structure, and this concept is very useful in cases
where you need the implementation to be interchangeable. Apart from that an interface is very useful when the
implementation changes frequently. Some say you should define all classes in terms of interfaces, but I think recommendation
seems a bit extreme.

Interface can be used to define a generic template and then one or more abstract classes to define partial implementations of
the interface. Interfaces just specify the method declaration (implicitly public and abstract) and can contain properties (which
are also implicitly public and abstract). Interface definition begins with the keyword interface. An interface like that of an
abstract class cannot be instantiated.

If a class that implements an interface does not define all the methods of the interface, then it must be declared abstract and
the method definitions must be provided by the subclass that extends the abstract class. In addition to this an interfaces can
inherit other interfaces.

The sample below will provide an interface for our LoggerBase abstract class.
Collapse | Copy Code

public interface ILogger


{
bool IsThisLogError { get; }
}

4.13. What is the difference between a Class and an Interface?

In .Net/ C# a class can be defined to implement an interface and also it supports multiple implementations. When a class
implements an interface, an object of such class can be encapsulated inside an interface.

If MyLogger is a class, which implements ILogger, there we can write

Collapse | Copy Code

ILogger log = new MyLogger();

A class and an interface are two different types (conceptually). Theoretically a class emphasis the idea of encapsulation, while
an interface emphasis the idea of abstraction (by suppressing the details of the implementation). The two poses a clear
separation from one to another. Therefore it is very difficult or rather impossible to have an effective meaningful comparison
between the two, but it is very useful and also meaningful to have a comparison between an interface and an abstract class.

4.14. What is the difference between an Interface and an Abstract class?

There are quite a big difference between an interface and an abstract class, even though both look similar.

o Interface definition begins with a keyword interface so it is of type interface


o Abstract classes are declared with the abstract keyword so it is of type class
o Interface has no implementation, but they have to be implemented.
o Abstract class’s methods can have implementations and they have to be extended.
o Interfaces can only have method declaration (implicitly public and abstract) and fields (implicitly
public static)
o Abstract class’s methods can’t have implementation only when declared abstract.
o Interface can inherit more than one interfaces
o Abstract class can implement more than one interfaces, but can inherit only one class
o Abstract class must override all abstract method and may override virtual methods
o Interface can be used when the implementation is changing
o Abstract class can be used to provide some default behavior for a base class.
o Interface makes implementation interchangeable
o Interface increase security by hiding the implementation
o Abstract class can be used when implementing framework
o Abstract classes are an excellent way to create planned inheritance hierarchies and also to use as
non-leaf classes in class hierarchies.

Abstract classes let you define some behaviors; they force your subclasses to provide others. For example, if you have an
application framework, an abstract class can be used to provide the default implementation of the services and all mandatory
modules such as event logging and message handling etc. This approach allows the developers to develop the application
within the guided help provided by the framework.
However, in practice when you come across with some application-specific functionality that only your application can
perform, such as startup and shutdown tasks etc. The abstract base class can declare virtual shutdown and startup methods.
The base class knows that it needs those methods, but an abstract class lets your class admit that it doesn't know how to
perform those actions; it only knows that it must initiate the actions. When it is time to start up, the abstract class can call the
startup method. When the base class calls this method, it can execute the method defined by the child class.

4.15. What is Implicit and Explicit Interface Implementations?

As mentioned before .Net support multiple implementations, the concept of implicit and explicit implementation provide safe
way to implement methods of multiple interfaces by hiding, exposing or preserving identities of each of interface methods,
even when the method signatures are the same.

Let's consider the interfaces defined below.

Collapse | Copy Code

interface IDisposable
{
void Dispose();
}

Here you can see that the class Student has implicitly and explicitly implemented the method named Dispose() via Dispose
and IDisposable.Dispose.

Collapse | Copy Code

class Student : IDisposable


{
public void Dispose()
{
Console.WriteLine("Student.Dispose");
}

void IDisposable.Dispose()
{
Console.WriteLine("IDisposable.Dispose");
}
}

4.16. What is Inheritance?

Ability of a new class to be created, from an existing class by extending it, is called inheritance.
Collapse | Copy Code

public class Exception


{
}

public class IOException : Exception


{
}

According to the above example the new class (IOException), which is called the derived class or subclass, inherits the
members of an existing class (Exception), which is called the base class or super-class. The class IOException can extend the
functionality of the class Exception by adding new types and methods and by overriding existing ones.

Just like abstraction is closely related with generalization, the inheritance is closely related with specialization. It is important
to discuss those two concepts together with generalization to better understand and to reduce the complexity.

One of the most important relationships among objects in the real world is specialization, which can be described as the “is-a”
relationship. When we say that a dog is a mammal, we mean that the dog is a specialized kind of mammal. It has all the
characteristics of any mammal (it bears live young, nurses with milk, has hair), but it specializes these characteristics to the
familiar characteristics of canis domesticus. A cat is also a mammal. As such, we expect it to share certain characteristics with
the dog that are generalized in Mammal, but to differ in those characteristics that are specialized in cats.

The specialization and generalization relationships are both reciprocal and hierarchical. Specialization is just the other side of
the generalization coin: Mammal generalizes what is common between dogs and cats, and dogs and cats specialize mammals
to their own specific subtypes.

Similarly, as an example you can say that both IOException and SecurityException are of type Exception. They have all
characteristics and behaviors of an Exception, That mean the IOException is a specialized kind of Exception. A
SecurityException is also an Exception. As such, we expect it to share certain characteristic with IOException that are
generalized in Exception, but to differ in those characteristics that are specialized in SecurityExceptions. In other words,
Exception generalizes the shared characteristics of both IOException and SecurityException, while IOException and
SecurityException specialize with their characteristics and behaviors.

In OOP, the specialization relationship is implemented using the principle called inheritance. This is the most common and
most natural and widely accepted way of implement this relationship.

4.17. What is Polymorphisms?


Polymorphisms is a generic term that means 'many shapes'. More precisely Polymorphisms means the ability to request that
the same operations be performed by a wide range of different types of things.

At times, I used to think that understanding Object Oriented Programming concepts have made it difficult since they have
grouped under four main concepts, while each concept is closely related with one another. Hence one has to be extremely
careful to correctly understand each concept separately, while understanding the way each related with other concepts.

In OOP the polymorphisms is achieved by using many different techniques named method overloading, operator overloading
and method overriding,

4.18. What is Method Overloading?

The method overloading is the ability to define several methods all with the same name.
Collapse | Copy Code

public class MyLogger


{
public void LogError(Exception e)
{
// Implementation goes here
}

public bool LogError(Exception e, string message)


{
// Implementation goes here
}
}

4.19. What is Operator Overloading?

The operator overloading (less commonly known as ad-hoc polymorphisms) is a specific case of polymorphisms in which some
or all of operators like +, - or == are treated as polymorphic functions and as such have different behaviors depending on the
types of its arguments.
Collapse | Copy Code

public class Complex


{
private int real;
public int Real
{ get { return real; } }

private int imaginary;


public int Imaginary
{ get { return imaginary; } }

public Complex(int real, int imaginary)


{
this.real = real;
this.imaginary = imaginary;
}
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex(c1.Real + c2.Real, c1.Imaginary + c2.Imaginary);
}
}

I above example I have overloaded the plus operator for adding two complex numbers. There the two properties named Real
and Imaginary has been declared exposing only the required “get” method, while the object’s constructor is demanding for
mandatory real and imaginary values with the user defined constructor of the class.

4.20. What is Method Overriding?

Method overriding is a language feature that allows a subclass to override a specific implementation of a method that is
already provided by one of its super-classes.

A subclass can give its own definition of methods but need to have the same signature as the method in its super-class. This
means that when overriding a method the subclass's method has to have the same name and parameter list as the super-
class's overridden method.

Collapse | Copy Code

using System;
public class Complex
{
private int real;
public int Real
{ get { return real; } }

private int imaginary;


public int Imaginary
{ get { return imaginary; } }

public Complex(int real, int imaginary)


{
this.real = real;
this.imaginary = imaginary;
}

public static Complex operator +(Complex c1, Complex c2)


{
return new Complex(c1.Real + c2.Real, c1.Imaginary + c2.Imaginary);
}

public override string ToString()


{
return (String.Format("{0} + {1}i", real, imaginary));
}
}
In above example I have extended the implementation of the sample Complex class given under operator overloading section.
This class has one overridden method named “ToString”, which override the default implementation of the standard
“ToString” method to support the correct string conversion of a complex number.
Collapse | Copy Code

Complex num1 = new Complex(5, 7);


Complex num2 = new Complex(3, 8);

// Add two Complex numbers using the


// overloaded plus operator
Complex sum = num1 + num2;

// Print the numbers and the sum


// using the overriden ToString method
Console.WriteLine("({0}) + ({1}) = {2}", num1, num2, sum);
Console.ReadLine();

4.21. What is a Use case?

A use case is a thing an actor perceives from the system. A use case maps actors with functions. Importantly, the actors need
not be people. As an example a system can perform the role of an actor, when it communicate with another system.

In another angle a use case encodes a typical user interaction with the system. In particular, it:

• Captures some user-visible function.

• Achieves some concrete goal for the user.

A complete set of use cases largely defines the requirements for your system: everything the user can see, and would like to
do. The below diagram contains a set of use cases that describes a simple login module of a gaming website.
4.22. What is a Class Diagram?

A class diagrams are widely used to describe the types of objects in a system and their relationships. Class diagrams model
class structure and contents using design elements such as classes, packages and objects. Class diagrams describe three
different perspectives when designing a system, conceptual, specification, and implementation. These perspectives become
evident as the diagram is created and help solidify the design.

The Class diagrams, physical data models, along with the system overview diagram are in my opinion the most important
diagrams that suite the current day rapid application development requirements.

UML Notations:

4.23. What is a Package Diagram?

Package diagrams are used to reflect the organization of packages and their elements. When used to represent class
elements, package diagrams provide a visualization of the name-spaces. In my designs, I use the package diagrams to
organize classes in to different modules of the system.

4.24. What is a Sequence Diagram?

A sequence diagrams model the flow of logic within a system in a visual manner, it enable both to document and validate your
logic, and are used for both analysis and design purposes. Sequence diagrams are the most popular UML artifact for dynamic
modeling, which focuses on identifying the behavior within your system.

4.25. What is two-tier architecture?

The two-tier architecture is refers to client/ server architectures as well, the term client/ server was first used in the 1980s in
reference to personal computers (PCs) on a network. The actual client/ server model started gaining acceptance in the late
1980s, and later it was adapted to World Wide Web programming.

According to the modern days use of two-tier architecture the user interfaces (or with ASP.NET, all web pages) runs on the
client and the database is stored on the server. The actual application logic can run on either the client or the server. So in
this case the user interfaces are directly access the database. Those can also be non-interface processing engines, which
provide solutions to other remote/ local systems. In either case, today the two-tier model is not as reputed as the three-tier
model. The advantage of the two-tier design is its simplicity, but the simplicity comes with the cost of scalability. The newer
three-tier architecture, which is more famous, introduces a middle tier for the application logic.
4.26. What is three-tier architecture?

The three tier software architecture (also known as three layer architectures) emerged in the 1990s to overcome the
limitations of the two tier architecture. This architecture has aggressively customized and adopted by modern day system
designer to web systems.

Three-tier is a client-server architecture in which the user interface, functional process logic, data storage and data access are
developed and maintained as independent modules, some time on separate platforms. The term "three-tier" or "three-layer",
as well as the concept of multi-tier architectures (often refers to as three-tier architecture), seems to have originated within
Rational Software.

The 3-Tier architecture has the following three tiers.

1. Presentation Tier or Web Server: User Interface, displaying/ accepting data/ input to/ from the user
2. Application Logic/ Business Logic/ Transaction Tier or Application Server: Data validation,
acceptability check before being added to the database and all other business/ application specific operations
3. Data Tier or Database server: Simple reading and writing method to database or any other storage,
connection, command, stored procedures etc

4.27. What is MVC architecture?

The Model-View-Controller (MVC) architecture separates the modeling of the domain, the presentation, and the actions based
on user input into three separate classes.

Unfortunately, the popularity of this pattern has resulted in a number of faulty usages; each technology (Java, ASP.NET etc)
has defined it in their own way making it difficult to understand. In particular, the term "controller" has been used to mean
different things in different contexts. The definitions given bellow are the closes possible ones I found for ASP.NET version of
MVC.
1. Model: DataSet and typed DataSet (some times business object, object collection, XML etc) are the most
common use of the model.
2. View: The ASPX and ASCX files generally handle the responsibilities of the view.
3. Controllers: The handling of events or the controlling is usually done in the code-behind class.

In a complex n-tier distributed system the MVC architecture place the vital role of organizing the presentation tier of the
system.

4.28. What is SOA?

A service-oriented architecture is essentially a collection of services. These services communicate with each other. The
communication can involve either simple data passing or it could involve two or more services coordinating some activity.
Some means of connecting services to each other is needed.

The .Net technology introduces the SOA by mean of web services.


The SOA can be used as the concept to connect multiple systems to provide services. It has it's great share in the future of
the IT world.

According to the imaginary diagram above, we can see how the Service Oriented Architecture is being used to provide a set of
centralized services to the citizens of a country. The citizens are given a unique identifying card, where that card carries all
personal information of each citizen. Each service centers such as shopping complex, hospital, station, and factory are
equipped with a computer system where that system is connected to a central server, which is responsible of providing service
to a city. As an example when a customer enter the shopping complex the regional computer system report it to the central
server and obtain information about the customer before providing access to the premises. The system welcomes the
customer. The customer finished the shopping and then by the time he leaves the shopping complex, he will be asked to go
through a billing process, where the regional computer system will manage the process. The payment will be automatically
handled with the input details obtain from the customer identifying card.

The regional system will report to the city (computer system of the city) while the city will report to the country (computer
system of the country).

4.29. What is the Data Access Layer?

The data access layer (DAL), which is a key part of every n-tier system, is mainly consist of a simple set of code that does
basic interactions with the database or any other storage device. These functionalities are often referred to as CRUD (Create,
Retrieve, Update, and Delete).

The data access layer need to be generic, simple, quick and efficient as much as possible. It should not include complex
application/ business logics.

I have seen systems with lengthy, complex store procedures (SP), which run through several cases before doing a simple
retrieval. They contain not only most part of the business logic, but application logic and user interface logic as well. If SP is
getting longer and complicated, then it is a good indication that you are burring your business logic inside the data access
layer.

4.30. What is the Business Logic Layer?

I know for a fact that this is a question for most, but from the other hand by reading many articles I have become aware that
not everyone agrees to what business logic actually is, and in many cases it's just the bridge in between the presentation
layer and the data access layer with having nothing much, except taking from one and passing to the other. In some other
cases, it is not even been well thought out, they just take the leftovers from the presentation layer and the data access layer
then put them in another layer which automatically is called the business logic layer. However there are no god said things
that cannot be changed in software world. You can change as and when you feel comfortable that the method you apply is
flexible enough to support the growth of your system. There are many great ways, but be careful when selecting them, they
can over complicating the simple system. It is a balance one needs to find with their experience.

As a general advice when you define business entities, you must decide how to map the data in your tables to correctly
defined business entities. The business entities should meaningfully define considering various types of requirements and
functioning of your system. It is recommended to identify the business entities to encapsulate the functional/ UI (User
Interface) requirements of your application, rather than define a separate business entity for each table of your database. For
example, if you want to combine data from couple of table to build a UI (User Interface) control (Web Control), implement
that function in the Business Logic Layer with a business object that uses couple of data object to support with your complex
business requirement.
4.31. What is Gang of Four (GoF) Design Patterns?

The Gang of Four (GoF) patterns are generally considered the foundation for all other patterns. They are categorized in three
groups: Creational, Structural, and Behavioral. Here you will find information on these important patterns.

Creational Patterns

o Abstract Factory Creates an instance of several families of classes


o Builder Separates object construction from its representation
o Factory Method Creates an instance of several derived classes
o Prototype A fully initialized instance to be copied or cloned
o Singleton A class of which only a single instance can exist

Structural Patterns

o Adapter Match interfaces of different classes


o Bridge Separates an object’s interface from its implementation
o Composite A tree structure of simple and composite objects
o Decorator Add responsibilities to objects dynamically
o Facade A single class that represents an entire subsystem
o Flyweight A fine-grained instance used for efficient sharing
o Proxy An object representing another object

Behavioral Patterns

o Chain of Resp. A way of passing a request between a chain of objects


o Command Encapsulate a command request as an object
o Interpreter A way to include language elements in a program
o Iterator Sequentially access the elements of a collection
o Mediator Defines simplified communication between classes
o Memento Capture and restore an object's internal state
o Observer A way of notifying change to a number of classes
o State Alter an object's behavior when its state changes
o Strategy Encapsulates an algorithm inside a class
o Template Method Defer the exact steps of an algorithm to a subclass
o Visitor Defines a new operation to a class without change

4.32. What is the difference between Abstract Factory and Builder design patterns?

The two design patterns are fundamentally different. However, when you learn them for the first time, you will see a
confusing similarity. So that it will make harder for you to understand them. But if you continue to study eventually, you will
get afraid of design patterns too. It is like infant phobia, once you get afraid at your early age, it stays with you forever. So
the result would be that you never look back at design patterns again. Let me see whether I can solve this brain teaser for
you.

In the image below, you have both design pattern listed in. I am trying to compare the two one on one to identify the
similarities. If you observe the figure carefully, you will see an easily understandable color pattern (same color is used to mark
the classes that are of similar kind).
Please follow up with the numbers in the image when reading the listing below.

Mark #1: Both patterns have used a generic class as the entry-class. The only difference is the name of the class. One pattern
has named it as “Client”, while the other named it as “Director”.
Mark #2: Here again the difference is the class name. It is “AbstractFactory” for one and “Builder” for the other. Additionally
both classes are of type abstract.
Mark #3: Once again both patterns have defined two generic (WindowsFactory & ConcreteBuilder) classes. They both have
created by inheriting their respective abstract class.
Mark #4: Finally, both seem to produce some kind of a generic output.

Now, where are we? Aren’t they looking almost identical? So then why are we having two different patterns here?

Let’s compare the two again side by side for one last time, but this time, focusing on the differences.

• Abstract Factory: Emphasizes a family of product objects (either simple or complex)


• Builder: Focuses on constructing a complex object step by step

• Abstract Factory: Focus on *what* is made


• Builder: Focus on *how* it is made

• Abstract Factory: Focus on defining many different types of *factories* to build many *products*, and it is
not a one builder for just one product
• Builder: Focus on building a one complex but one single *product*

• Abstract Factory: Defers the choice of what concrete type of object to make until run time
• Builder: Hide the logic/ operation of how to compile that complex object

• Abstract Factory: *Every* method call creates and returns different objects
• Builder: Only the *last* method call returns the object, while other calls partially build the object

Sometimes creational patterns are complementary: So you can join one or many patterns when you design your system. As
an example builder can use one of the other patterns to implement which components get built or in another case Abstract
Factory, Builder, and Prototype can use Singleton in their implementations. So the conclusion would be that the two design
patterns exist to resolve two type of business problems, so even though they look similar, they are not.

I hope that this shed some light to resolve the puzzle. If you still don’t understand it, then this time it is not you, it has to be
me and it is since that I don’t know how to explain it.

5. What is the Conclusion?

I don't think, that it is realistic trying to make a programming language be everything to everybody. The language becomes
bloated, hard to learn, and hard to read if everything plus the kitchen sink is thrown in. In another word every language has
their limitations. As system architect and designer we should be able to fully and more importantly correctly (this also mean
that you shouldn’t use a ballistic missile to kill a fly or hire FBI to catch the fly) utilize the available tools and features to build
usable, sustainable, maintainable and also very importantly expandable software systems, that fully utilize the feature of the
language to bring a competitively advance system to their customers. In order to do it, the foundation of a system places a
vital role. The design or the architecture of a software system is the foundation. It hold the system together, hence designing
a system properly (this never mean an *over* desinging) is the key to the success. When you talk about designing a software
system, the correct handling of OOP concept is very important. I have made the above article richer with idea but still kept it
short so that one can learn/ remind all of important concept at a glance. Hope you all will enjoy reading it.

A Practical Approach to Computer Systems Design and Architecture

1. Introduction

Our Business Analyst went abroad last week to meet a new customer who selected us to develop his Content Management
System. The Analyst had met and extensively discussed details about the business needs with the customer. Our hard working
Business Analyst returned after two weeks with a detailed Business Model document on hand, where he together with a
coworker prepared the formal requirement specification in a hurry. During this process they conferred with the customer to
clarify some requirements. The formal requirement document was sent to the customer for initial approval, where it was
returned with minor adjustments. The requested minor adjustments were made by the business analyst himself to get the
final approval from the customer's end. It was a good effort; we got the fixed set of requirements three weeks after we first
met the customer. Business Analyst sent the business model to the system architect. Soon, the Non-Functional Requirement
Document was finished and was approved by the customer with no changes. As the next immediate process, the user cases
were defined. System Architect finalized the design of the system together with the System Analyst. The Database Admin was
followed by identifying/ defining the entities and their relations together with DDL (Data Definition Language) of the system.
The UI (User Interface) designer designed the system user interface to finalize the initial design effort. At last, the deployment
model was defined and started implementing the system steadily, after getting all required approval from the customer end.

What I just mentioned, was an imaginary system development process, which has limited real world applicability. In real world
practice, there are many variables that make one to feel that system design/ development methodologies need to be adjusted
from customer to customer, as well as from project to project. This article is a challenging attempt to introduce a concept
(model) that hold onto all extreme cases of modern day system designing requirements.
The first step in designing a system requires thorough study of the problem domain. This implicitly means time, followed by
money, which threaten the customer, who doesn't have an adequate visibility over the advantages of a properly designed
system. It just makes things worse, when the current day diversity of requirements argues the value of one's experience. The
experience give you confident but if one soon says that "Oh, This is just the same solution we delivered last year" he'll soon
be ended up loosing the customer by delivering the wrong product.

There are good design methodologies out there, but often due to time limitations (where client push for quick releases, while
developer struggle with extremely tight deadlines) solution providers aren't confident to apply them. Today, Solution Providers
tend to implement systems without designing them properly. More often, the development starts after loosely evaluating the
depth of the project. The System Requirement Specification is often changed in the middle of the development. This is due to
insufficient clarity of business requirements had at the start of the project, as well as to insufficient domain expertise. The
customer often waits until the solution provider releases the system to understand it. The customer uses the first few releases
of the system to understand the direction of the project and to apply corrections. Unfortunately, some of these changes shake
the whole foundation of the system, forcing designers to rethink the initial design. But these impacts are hardly seen by the
customer's non-technical eye. A fight ensues between customer's money versus developer's 24 hours a day.

The customer estimates the correct time to enter the market at the initial stage of the project. The massive competition at the
software market place makes it important to take decisions to pin-point accuracy. The most important is to hit the market on
time.

2. Overview

2.1 What Solution Providers Do Today?

You don't need civil engineering expertise to understand the instability of building a foundation without knowing the number of
stories of the finished building. The same philosophy applies to software architecting as well. Expanding a system, which is
developed for a limited set of features, is just adding more problems than features. A high percentage of solution providers
push for add-hoc development approaches. They use extreme programming to achieve tight deadlines. The customers are
also encouraging them, having a daydream of re-factoring the system, once it is running at a profit earning stage. Another
reason for customers to treat System Design as a low priority is the time the designers/ analysts take to investigate/ design a
system. The Customer, according to some terminology is GOD, regularly expecting tangible outputs from the solution
provider. But a proper system design process may make him wait several months. In order to support this customer's need,
solution providers often plan bi-weekly or monthly system releases from the starting day of the project. This extreme need
burns out resources in the middle stage of development.

Developers are used to starting the system development process with a scaled down version of the system, and gradually
patch the rest of the system around it. This results in an unstable product with lots of repetitive, badly grouped codes.
Additionally, it creates programmer-dependant code modules, since each module is coded by individuals with different skill
sets. The inconsistent code makes debugging the system a nightmare. This costs time as well as money in many direct/
indirect ways, while making it impossible to expand.

2.2. Why We Should Design Systems Properly? Do I have to answer this?

Properly architected systems always gain that strategic advantage over common issues of the software development life cycle.
A well architected system is cheaper than a patched together system when it comes to dealing with changes and upgrades.
The architectural discipline regularizes code, while supporting and managing the implementation with short predictable
development times. The consistency of the design allows managers to pull/ push resources from/ to different sections of the
project with minimal training. These are some of the few advantages you gain with a properly designed system.
In order to drive the system development effort smoothly, the designer should introduce a steady design/ coding pattern at
the early stage of the process, allowing every developer to gain mastery over it. This also opens the opportunity to remove
the dependency on the Architect at later stage of the project.

3. The Approach to Designing a System

Let me highlight first, that I do not draw the famous user case diagram and sequence diagram, when designing systems. In-
fact I have another approach that lets you understand the system better and allows you to directly draw the class diagram.
But before drawing the class diagram, I encourage you to draw an activity diagram and/ or a system overview diagram and/
or a module interaction diagram and/ or any other type of diagram, which helps you to fully understand (feel) the system.

As I reiterated many times, designing a system mainly depends on the designer's understanding of the problem domain. So
the better you understand, the easier the system design will be. However in modern days, it is less probable to assume that
designers get a sufficient time frame to fully investigate the system, before starting to design.

As the first step, the designer has to be a master of the problem domain. A well written System Requirement Specification
(SRS) document can be used as the introduction to the system. The system designer should read it repeatedly and should
carefully understand each and every important feature, hidden in odd corners of the document. But in most cases, the
designer does not get a proper SRS prior to the system design. (At least, this is the case with service base companies).
Instead he is forced to grab the requirements through the initial business meetings and telephone conferences. This
unfortunate circumstance is the ideal case for a designer to think of a throw away prototype or even two. The prototype is the
best and the cheapest way to define the product specification, before committing yourself to unknown territory. In case of a
disagreement with a prototyped system, the designer should strategically drive the customer to write the specification for him.
The traditional advice is to wait till you get to the depth of the system before starting the design. But in practice, you can
speed up by referring to online resources, such as articles, open source projects and other similar products without heavily
depending on the SRS document (Note: New comers always need help from seniors to correctly identify the resource pools,
since the complex business requirements are hardly seen by new technical eyes.). The domain expertise you gain will not only
guarantee a good design, but also will help to better predict the future of the system and to keep adequate spaces for later
expansions. In addition to this, new comers have to be attentive not to underestimate important business requirements by
evaluating them only from technical angles. This is another crucial area, where a client could be extremely rigid and even
decide to reject the system, complaining that the solution provider delivered a wrong product.

Discover the system by asking questions. I have a technique that I've used since the very first system, I designed. I am
presenting it here for you as the second step of approach to designing a new system. Open a Notepad or get a piece of
paper, and then start asking question about the system. In this effort you are free to ask any question, but in order to get a
better start, start the process with the three main questions (about input, process, and output of the system) listed below.

1. What are the Input(s) of the system?


2. What are the Processes of the system?
3. What are the Output(s) of the system?

In order to optimize the throughput, start to rethink the system with a fresh mind by forgetting all the information you
gathered through various resources. This approach will help you to understand the definitions of the product, even when the
product specification is not very clear. As you practice this technique you will get surprised to see the way it opens up new
areas of the system. As you may already know, according to this method, interestingly, the questioner has to be the answerer
and it has to be you. Sometimes you may not be able to answer a specific question. But at least you will end up having the list
of questions to find answers to. I have seen designers struggling when they are thrown a project with a widely (loosely)
defined requirements. They do not know where to start and what to ask or not ask. If you are facing the same issue, then try
this technique and see.
A good question would be one that creates several derivative questions by the answer given to it. So an answer to a question
may produce another question (one or more) or a leaf level operation or function of the system (use case of the system). This
technique does not have rules or definitions. The questioning and answering process can drift freely in multiple directions by
the questions created from answers. The questions that are not answerable may need to be directed to the client. And those
that are not answered by the client have to be creatively handled by the system designer in a way that doesn't affect the
solidity of the system. You can creatively group them into separate module(s) for later implementations.

As an example, let's try to apply this methodology to discover the feature list of a simple Document Management System
(DMS). The questioning will start at a very abstract level with the three main questions.

1. What are the inputs for this?


Files such as word, txt, media etc (I would say any type of files)
2. What are the processes of the system?
It is a document management system and it will help my client to manage his documents properly.
3. What are the outputs?
Allow user to view file(s) online as well as allow them to checkout/ remove file(s).

If you get fairly good answers to all three questions above, I would say that you have understood the system. The above
three questions, virtually can be used to discover any system. The answers you write to these three questions will create
many more derivative questions. This process will help us uncover all use-cases or rather, in simple terms, leaf level functions
of the system. (A leaf level function is an independent, granular level operation that describes a specific function of the
system.) It also helps us discover all external/ internal (system) actors of the system. The process of asking questions and
writing answers will continue until we get to leaf level functions where we cannot ask any more questions about the answers.
Figure-1: A graphical representation of a generic system is being analyzed by asking questions

Let's go and analyze the first question (i.e about inputs) a little more to see what it will discover for us. Just allow who, what,
when, why, and how etc to create questions for you. In the sample below, I have used '*' to indicate the words that create
questions. You may also follow the numbering sequence to better recognize the way it drifts.

1. What are the inputs for this?


Files such as word, txt, media etc (I would say any type of files).

2. How do users upload a document?


The *User* gets a *web interface* to browse, select and upload a document

2.1 How do users reach to this web interface?


The user has to be *registered* with the system to access this via the provided credentials

2.1.1. How do users get registered with the system?


All *employees* will be registered by the DMS system administrator. This will happen as they deploy the system.

2.1.1.1. How does the admin knows the employee's profile, and how employees obtain their credentials?
Both of these will be manual processes, where the Admin will obtain employee profile data from the HR department and each
employee will get the access code by calling the System Administrator manually.
Note: Here we found that System admin *only* can creates users and obviously he can delete/ update them.

2.1.1.1.1. What about employees' privacy?


The system should allow employee to change their passwords.

2.1.2. Is the User Registration page a restricted one for general users?
Yes, System Admin will only see this page.

2.2. Who is a user anyway?


A user of this system *can be from four different divisions*, namely Administrative, Accounting, Marketing and Development.
Each user will belong to one and only one of these four divisions. So this means that each user of this system will have
different privileges and access permissions.

2.2.1. Do users of different divisions need to have different privileges?


Yes. The Users of each division will have different privileges. A user from Marketing or Development division will have *default
privileges* where they can upload and mange their documents but users from accounting division can *over look* marketing
division, and the administrative division can over look any other divisions, apart from doing default functions of the system.
(The power/ previllages of each devision is as Administrative > Account > Marketing = Development).

2.2.1.1. What is a default privilege of a user?


This includes upload documents, view documents online, check out documents for editing and delete a document. Again any
document uploaded will be shared among users of the same division automatically. A document belong to a one division can
be shared with another division only by explicitly giving permission. A private document will not be supported by this system
(confirmed by the client software requirement specification).
Note: I will not create question(s) out of this.

2.2.1.2. What is over looking a user?


This is the privilege of accessing documents uploaded by other users without needing any permission from the document
owner.
Note: I will not create question(s) out of this.
Note: Above answers introduce us to two modules called User Management, Security and Privileges. In order to analyze them
further, you have to treat them separately by asking questions starting form input, process, and output of each module. Let's
not dig in to that section right now.

3. How a documents flow through this system?


*Select* and *upload* the document by the user > System will validate the input file > *Files added* to "to be approved"
section > Administrator *Approves and publishes* the file > File is available for users.

3.1. Do we need a work flow management system here?


I don't think so, let's hardcode the work flow, since we don't expect them to be dynamically adjusted. This is not a very
complex system. So it is not necessary to have a separate module to manage workflows, I am happy without it.

Now, we have found few granular level operations belonging to the document uploading section. Let's list them as bellow:

Client side:
Select a document from the local directory base
Read the byte stream to system memory
Send it via the web to the server
Server Side:
Read the byte stream from the memory
Write it to a local temporary location for validations
Input Validation Module validates the input file
Move the validated file to the correct user's shared location
Add this new file to the repository system as a "File to be Approved"
Load the files that are to be approved for the system administrator to view them
System administrator validates the content of the file and approves them to be viewed online
Change the file metadata status from "tobeApproved" to "Approved"
Note: Ideal place for a diagram..

3.2. Are we going to have versioning here?


Yes, we need to have versioning. So any updating to an existing file will run through a version handler that assigns the correct
version number.
Note: This can be analyzed further deep..

3.3. Do we need to notify users, when a new document is successfully published?


The user, who own (up-loader) the document will get an email noting the reject/ accept state. In addition to that we have to
send another notification to users who have subscribed to be notified as this operation happens.
Note: This introduces a new module to the system named Notification Module. I will not dig in to this section either.

3.3. Can a user undo an update?


I need to talk to the client about this.

3.4. Can multiple users checkout one document at the same time?
Let's stop this now�

Look at the way it expands, it just keeps on expanding as you ask questions. I omit lots of the questions, since the article is
getting longer, but I believe that this sample question and answer set will provide enough guidance to understand the
concept. This process needs to be repeated (go through the questioning and answering process again and again) several times
to fully discover the system. Firstly, you have to recognize the main modules of the system. I have already identified a couple
of modules named input validating module, user management module, security module, notification module and not the last
nor the least, the main document management module. The module reorganization is one of the important parts of this
technique. If you can identify the modules of the system quicker, that will lead to easier designing. The ones who do not have
experience will always find it harder to recognize the modules of the system initially. But as you practice the technique several
times, you will gain that ability. (This comes with experience, and to get it quicker, you can apply the technique over and over
on the same system, until you feel comfortable with the module break down).

In my early days, I always started by recognizing the full list of leaf level functions of the system (granular level use cases of
the system). Then I followed that by grouping the functions to form classes (classes will group same types of functions/
operations). These classes are the ones that form the modules of the system. As I reached this point, the deep understanding
automatically guided me to identify the modules of the system. I recommend new-comers take this path until you gain
mastery over the concept. The recognized modules have to be further analyzed by asking questions (as explained above)
starting from the three main questions about the input, process and output. The modules have to be truly object-oriented and
independent. They have to have clear definition and should fully cover the specific sections of the system. They also have to
have well-defined functionally rich communication channel(s) for external party communications.
Once you design a couple of systems, the module breakdown will become easier and the concept will become friendlier. This
experience will also reveal to you that some of those modules come repeatedly in every other system you design, so you can
easily recognize/ reuse them.

You may follow this process to identify all the leaf level functions and main/ sub modules of the DMS system.

3.1. Breaking the System with Easy Concepts

Think of a governing body of a country or a private organization, and how they are being managed. Both of these complex
organizations have hierarchical structures with many smaller departments (divisions) linked to the top. The more important
finding is that they are proved to be rock solid. In this application designing technique, we treat the software system as a real
world organization. Careful study finds that all software systems can be easily mapped to a real world organization. This
mapping helps to easily identify/ define modules and also to control the system designing effort throughout the project life
cycle. When you have that luxury of visualizing a software system via a pure manual real world organization (more friendly)
you can quickly and accurately respond to requirement changes without hurting the stability of the system. When a change to
the software system is proposed, virtually apply it to the manual system first, and it will help to identify the best way/ place to
apply it in the software system. This approach will be better suited for complex systems, but will obviously work for simple
systems too. In order to successfully map a software system to a real world organization, you need to correctly analyze the
software system in a way that explains how it would process in a purely manual environment. The next step is to automate
that manual process with a software model. It is highly recommended to keep similar modules, communication pattern, rules
and naming conventions in between manual systems and software systems for better visualization.

Let's have a look at a typical organization as below and try to see, how it would respond to a typical request.

Figure-2 Showing a typical organization hierarchy

CEO � Chief Operation Officer of this system is acting as the front end (User Interface of the software system) of the
organization. The main responsibility of the CEO is to interact with the outside world, and identify/ guide managers in the
correct sequence to complete a task. The CEO will directly map to the front interface of our sample Document Management
System (DMS).
Super senior, senior and junior Managers � The manager's duty is to utilize resources (workers or sub managers) in the
correct sequence to complete a particular task. A complex organization may have several levels of managers (super senior
managers, senior managers and junior managers). Higher level managers will use one or many lower (immediately) level
managers to complete a task. According to our diagram, we have three senior level managers named Accountant, Manager
Operation, and Manager Delivery, where each manager is given a set of junior managers to perform their duties. As you can
see, all junior managers are equipped with a group of workers.

Workers � Workers do all granular level operations and more often, workers are given purely independent tasks, which they
can perform without making any dependency over any other task or worker.

Rules of the Organization �

• Higher level managers have the knowledge of the capacity of junior level worker groups. Hence, they know
what worker to pick, in order to complete a task.
• Same level entities are not allowed to communicate with each other, but if a task is needed by two or more
same level managers to complete, then that task will be handled by the manager who is immediately senior to the two or
more same level managers that are needed to complete that task.
• An entity is only responsive to the immediately higher entity, and only utilizes the immediately lower
entities.

In order to understand the organization well, let's see how this organization will respond to a typical request, made by the
CEO.

Figure-3 A request is been processed utilizing different types of workers of the organization

In this sample, the CEO of the organization has issued a request named "request 1" to "Manager Operation" (This operation
assumes to be an independent one from Accountant and Manager Delivery). The CEO knows which manager he needs to issue
the command to process this particular request successfully. In this case "Manager Operation" has received the request from
the CEO. He proceeds by making the request named "request 1.1" to "Manager 1". The "Manager Operation" and CEO are in
waiting mode now while "Manager 1" is processing the first part of the request. "Manager 1" has triggered a request named
"request 1.1.1" to "Worker 3" to complete the "Task 3". As "Manager 1" receives the result of "Task 3," he issues the next
request to complete "Task 1" to the same worker. After getting the result, "Manager 1" uses another worker named "Worker
1" to complete "Task 3". This completes "request 1.1.2" followed by "request 1.1". "Manager 1" now responds to "Manager
Operation" with the results of "request 1.1". The "Manager Operation" picks the correct junior manager to handle the second
part of the main request i.e. "request 1.2". As a result, "Manager 3" receives the "request 1.2" from the "Manager Operation",
where he responds to it by making the "request 1.2.1" to "Worker 4" to complete the "Task 3". Finally, "Manager 3" respondes
to "Manager Operation" with the result of "request 1.2" which completes the whole processing of "request 1".

In our system design approach, we will also use the same concept to break and design the software systems. You will first
identify the granular/ leaf level functions of the system (Tasks of the system) and will group them into classes, where each
class is responsible for similar types of operations. These classes are pretty much similar to workers of the above diagram. As
the number of workers of the organization increases, you add managers to manage the worker group. The same will be done
in the software system too. Again as the number of managers grows, that group will be pushed down and a few senior
managers will be introduced to the top to control them. However during this process, you need to carefully group classes of
the system to form modules as well. (The modules can be formed by grouping similar types of classes). The number of
managers and the depth of the manager pool inside a module can be decided by the complexity of the module (or the number
of worker classes loaded or grouped into the module). These modules will be treated as separate divisions of an organization,
where each module will be controlled by one or more managers, positioned considering the complexity of the system. These
module controlling managers will help modules interact with each other.

4. Start Designing our Document Management System

Initial analysis of the Document Management System has discovered a set of modules with their leaf level functions. As
explained before, it is important to break the system into smaller modules before designing them; the better you modularize
the system, the easier the system maintenance will be. Following that concept, let's modularize our DMS system horizontally
as well as vertically. This will allow us to design each module separately by treating each as a separate division of the main
organization. Even though we didn't fully analyze the DMS system, what we have discovered is detailed enough to explain the
concept with an example. As the third step of designing a system, we will draw a system architecture diagram as below. This
diagram will help us visually abstract the system and understand the key modules with their interaction in our DMS system.
Figure-4: System Architecture Diagram of the Document Management System

Manager Operation � Manager Operation is acting as the head for all divisions, where divisions are the Document
Management Division, Email/ Notification Division, and User Manager/ Security Division. The Manager Operation will
coordinate all functions of the system while helping each division interact with one another as and when it is appropriate.

E.g.:- Once a document is published, several emails needed to be sent, so then manager operation will first request the
manger of the DMS division to publish the document and depending on the state of the publication the manager operation will
request the email/ Notification division to send the correct email to the document owner and other subscribers. In this attempt
the system has used two divisions to complete the task and these two divisions have being controlled by the Manager
Operation.

DMS, Notification, User Manager/ Security � These are similar to three divisions of a generic organization. I have
separated the leaf level workers in to three groups named Data Access Layer, Template Handlers and Other Operations. The
DAL (Data Access Layer) is dealing with all database related operations such as get, add, update, and delete data, where as
the section named "Other Operations" is responsible to any other leaf level operations as required.

Common Operation � This module does the common operations. A correctly designed common operation module can be
easily reused in any system. This division is shared among all components or modules of the system. In real world
organizations also you find common divisions, such as company library, company canteen, reception etc. In most cases, you
may use this module to group classes that log exception/ transactions, store shared objects, handle errors etc.

Let's further analyze the User Management module of our Document Management System. Let's see how it supports the
functioning of three basic features of the user management module named add, edit and remove user(s). (Please refer to the
class diagram below). According to the diagram, firstly, you have the system user interacting with the DMS interface. There,
we only have one senior manager named "Manager Operation" to control the full system and one junior level manager (to
head the user management module). The manager named "User Manager" directly communicates with the junior manager of
the sub module named DAL (Data Access Layer for the User Manager module). The data access layer is responding to the
corresponding immediate manager only via the abstract class named "HandlerData". Inside the DAL you can see there are
three classes to handle three basic types of data related operations named Edit, Add and Remove data (In this sample all
handlers are same as workers of the above described organization). The drawing of the class diagrams completes the fourth
and final step, of our approach to design the system.

Figure-5: Class Diagram of Scale down Version of a UserManager Module

E.g.:- Adding a User: The user is requested to fill the registration form via the user interface. As the user clicks on the submit
button, the UI side is expected to do all required client side validation to verify the input. Then the user profile is stored inside
the model class named "User" (where it can store user profile with correct entity relations) pass it to the main manager of the
DMS system named "ManagerOperation" by invoking the method named "AddUser". The main operation manager correctly
identifies the module to talk to, to complete the request. So it invokes the method named "AddUser" of the manager named
"UserManager" (of the module named "UserManager") where that talk to the DAL (Data Access Layer) via junior manager
class named "HandlerData" to store data in the database. Once this process is completed the "ManagerOperation" evaluates
the status of the operation. Then, depending on the status, it will invoke the main manager of the notification module to send
a welcome email to the newly registered user.

The analysis of this system shows that a generic DMS system can be easily mapped to a real world organization. You can
continue the process to build the whole DMS to form an organization that manages documents. This approach will produce a
consistent system that has distributed its functionality across several modules, allowing easy maintenance. This method can
be used to design any system, including a web site, web service, other types of services (windows service etc), form based
application (windows form etc) or library. However, if you follow any other architecture/ design/ coding pattern, you may end
up using one method for web site and another to create a form based application and it may be some thing totally new when
it comes to any other type.

5. General Advice

5.1. Object-Oriented Programming (OOP) Concepts

Object-oriented programming (well known as OOP) is the concept of defining and combining independent objects to form a
software system. It has four base techniques namely inheritance, encapsulation, polymorphism and abstraction. Today,
almost all popular programming languages (such as C++, C#, Java, PHP, Ruby, Python etc) support OOP.

In my mind, I recognize OOP as another unnoticed theory of the nature, which waited until the right time of the information
age to be noticed. It was noticed in the 1960s and is now successfully used in the virtual form of nature (the so called
software field). Just to understand the relation between the two, let's think of the functionality of a part of the human body
(let's say a hand) and a well architected software module of a system. If you carefully study them, you will realize that both of
these are provided with similar kind of communication interface where a set of standard instructions drive the objects in the
required manner. There is nothing new in OOP. It strongly emphasize modularity in software (just like the nature does). It is
something already known and experienced.

Having these things in mind, designers are welcome to use any object oriented concepts as and when they are appropriate in
software systems. It will achieve the flexibility and maintainability of a complex software system. Please refer to online
resources for more details on this topic.

5.2. Design Patterns

As the OOP concept becomes widely popular in the software world, the designers start to encounter similar types of challenges
in every other object-oriented design they do. Right on time, there comes a set of widely accepted solutions to these
challenging problems with the name "Design Patterns". The Design Patterns describe a set of recurring solutions to common
problems in software design. This was originally described by a book written by four authors known as the "Gang of Four" or
simply "GoF". Hence their pattern set was named as GoF patterns. And the design patterns are still evolving.

The design patterns will brighten the design, so you should use them. Please refer to online resources to find more details
about design patterns.

5.3. Modular Based Development and Reuse of Modules

The modules of a software system have to be treated as divisions of an organization. This means that each division has to
have one or many managers, considering the complexity of the modules. The "module managers" help inter module
communications and also help to bind them together to form the entire system. A bigger module can be broken into several
sub modules, where each module has to be treated just like sub divisions of a division. It is recommended to have separate
sub modules inside each module to handle leaf level operations such as accessing a database, accessing a file server etc. The
modules can be designed using the expertise you have on various design patterns and object oriented programming concepts.

Properly designed modules can be reused in other systems too. Some of the famous modules that can be reused are, Logging,
Notifications, Exception, File Directory IO etc. When you start with this approach you will find it hard to reuse the modules at
first. You will find that you have to enhance the modules to reuse them in every new system. This will happen until you
correctly define the specification of the module or until you learn to design truly object oriented modules, but it is
recommended to expand the functions of the module until they are rich enough. This should be a continuous process that will
gradually create powerful, more complete, and functionally rich modules that you can reuse in future projects.
Here, in addition to delivering a smart product to your customer, you can open up a new market, if you can develop an
extensible framework for all commonly used modules.

5.4. Quickly Develop the Data Access Layer (DAL)

It is important to separate the data access layer and quickly nail it down. The Data Access Layer (DAL) consists of classes that
directly operate with the database, so it is like the engine of the system. This separation will better modularize the system and
also helps developers edit the data access layer (this causes lots of changes at the early stage of a project) without hurting
other part of the system. For more information about this section, you may refer to following two articles.

• Reference 1: http://www.codeproject.com/cs/database/ModelCreator.asp
• Reference 2: http://www.codeproject.com/cs/database/CSharp_Wrapper.asp

5.5. Group Operations into Classes

When you identify similar types of functions or operations, group them together. In the above example I created three
separate classes for Add, Edit, Delete operations (refers to Figure 5). This way you can keep consistent coding across the
methods of the class, since all the methods of the class are doing similar types of operations. This way you can handle
exception/ logging etc the same way for all the functions of the class.

5.6. Keep Front Layer Free

User Interface or the Front Interface of your application has to be kept free from application logic related coding. The whole
idea behind this approach is to be able to replace the front layer (User Interface) without hurting other parts of the system.

Figure-6: Explain how the front end can be easily replaced by different types of interfaces

E.g.:- As an example think of a web site you developed using .NET/ ASPX pages. In that case the front interface of the
application is the set of ASPX pages and their code behind files. If you have followed the concept above as you were
implementing the system probably you should have set of ASPX pages that are free from application logic and also another set
of modules which contains the core application logic. This simple breaking allows you to introduce a web service interface
(ASMX file) to distribute the system across two machines to expand the system. This can be done just by replacing the ASPX
files with a web service interface. This will separate the heart of the application to a separate application server and ASPX files
to a web server as the above diagram explains.

5.7. Visualize the System

This allows designers to visually model the system to capture the structure and behavior of architectures and components.
Visual abstractions help you understand the bigger view, while opening hidden areas of the system. This includes identifying
components of the system correctly; understanding how each component of the system fits together; understanding how each
component communicates with each other; and finally make each component design consistently. In my practice I draw an
activity diagram and a System Architecture Diagram (as drawn in Figure -4) if the system is very complex but only the
second, when it is not so. I encourage you to visually display the system before starting the design.

5.8. Naming Convention

1. Use lengthy meaningful/ readable names when naming variables, methods, classes, modules and any other.
This will also excuse you from not commenting your code.
2. Follow the naming convention of the technology owner, if your application is developed using Microsoft .NET
then follow the Microsoft standard and if it is any thing else then follow their naming convention. By doing so you will have the
luxury of directly using their sample code in your application without going through a naming convention adjustment process.

6. Think Fresh and Approach like a Newcomer

Today the technology changes at a rapid rate, allowing new things to evolve every day. Designers are expected to keep their
knowledge up to date with the most recent technologies, so that they can utilize them early in their designs. But the
superiority of the new technology may also lead the overwhelmed designers to overuse the technology. I have heard some
designers say that "we designed our system according to the X model, it is the latest, and that does not recommend doing it",
my simple advice is not to make bottlenecks in your system, just because you have to follow the latest technology or because
everyone else was doing it that way. There is no magical formulas that is suitable for everything, so if the technique (or the
model) does not suit, be brave to change. Think what is needed? Identify, what suits you most? Then take your decisions,
while letting everything else stand aside. Concepts are there to help you and better guide you, but not to control you. I invite
you to be creative, but also remind you, not to reinvent the wheel.

7. Additional Hints for System Designers

• Keep Interfaces simple. An interface should capture the minimum essentials of an abstraction. Don't
generalize; generalizations are generally wrong. Again, the interface must not promise more than the implementer knows how
to deliver.
• Make it fast, rather than general or powerful. It is much better to have basic operations executed
quickly than more powerful ones that are slower (of course, a fast, powerful operation is best, if you know how to get it).
• Don't hide power. When a low level of abstraction allows something to be done quickly, higher levels
should not bury this power inside something more general.
• Do a prototype. If there is anything new about the function of a system, the first implementation will have
to be redone completely to achieve a satisfactory (that is, acceptably small, fast, and maintainable) result. It costs a lot less if
you plan to have a prototype. Unfortunately, sometimes two prototypes are needed, especially if there is a lot of innovation,
but go for it.
• Divide and conquer. This is a well known method for solving a hard problem: reduce it to several easier
ones.
• Handle separately. Handle normal and worst cases separately as a rule, because the requirements for the
two are quite different. The normal case must be fast. The worst case must consider all cases.
• Memory is cheap. Therefore cache the answers to expensive computations, rather than doing them over.
• Compute in background when possible. In an interactive or real-time system, it is good to do as little
work as possible before responding to a request. The reason is twofold: firstly, a rapid response is better for the users, and
secondly, the load usually varies a great deal, so there is likely to be idle processor time later in which to do background work.
• Make actions atomic or restart-able. An atomic action (often called a transaction) is one that either
completes or has no effect.
• Allow Customer to Lead. If the requirements are not finalized, keep the design as open as possible. You
may strategically drive the customer to lead the requirement gathering process.

8. Final Note

There probably isn't a 'best' way to build a computer system; much more important is to avoid choosing a terrible way. The
software designing methodologies are still evolving and can be considered as fairly new. The software system is an
automation of a known manual process, indeed software cannot be defined for things that are not seen/ heard in the physical
world. Every process gets refined as it is being reused. The processes of the physical world (manual processes) have evolved/
reused for many generations and have tuned to perfection. The system designers can take advantage from observing
available manual systems when designing a software system to automate such process. They can first study the manual
system and automate the manual system with a software system.

So the safest path the system designer can take is to design/ implement the software system as closely as its parallel manual
system of the physical world, of course with the improvement when possible.

9. Coincident

HIPO - Hierarchy plus Input-Process-Output, is a technique for use in the top-down design of systems, and was originally
found by IBM in 1970s. The second step of the above proposed design technique is some what equal to HIPO technique. But
HIPO had serious flaws that caused it to fall out of favor. But now there is another emerging technique named HIPO-II, which
competes with the most advanced design methods while maintaining its original simplicity.

The technique I have presented here is one of my own and is not some thing I've learned or heard before. I have found it is
extremely practical and helpful to deal with current day system designing requirements. In summary it is a consistent, logical
and also a teachable technique. Amazingly some part of this technique is mapped with the IBM HIPO technique. I think it is
yet another example that proves that every thing is going on a cyclical path.

10. Summary

The approach presented here for system designing, can be broken in to four main steps as listed below.

• Identify, study and be a master of the problem domain


• Analyze the system by asking questions
o Identify the list of granular level use cases or the functions of the system and internal/ external
actors.
o Form classes by grouping similar functions together.
o Form modules by grouping similar classes together.
o Recognizes module's communication paths
• Visualize the system with a diagram, showing the module interactions
• Identify the relations of the classes and draw the class diagrams of the system separately for each module
o Place "module managers" correctly in-between modules to bind them together to form the
complete class diagram of the system.

I have ideas and contents to fill a book on this same concept. But I'd rather make it the minimum, having concerns about this
article's download time. So I am concluding this article, hoping that it was written well enough for you to understand the
concepts.

Architecture Guide: ASP.NET MVC Framework + N-tier + Entity Framework and Many More

Introduction

The Model View Controller (MVC) is an architectural pattern used in software engineering. The pattern isolates "domain logic"
(the application logic for the user) from input and presentation (GUI), permitting independent developments, testing and
maintenance of each.

Today, the Microsoft variant of MVC called ASP.NET MVC, which is now part of .NET framework 4.1, is gaining momentum
among software designers. In addition to that the enthusiasm is also high among developers to support the community with
materials that speed up application development with ASP.NET MVC framework. There are many source libraries on the
internet, where such contributions can be found. These free off-the-shell libraries/ components have positively influence the
modern software industry in many different ways. However, as it was with any other case, this has a few negatives too.
Today, unfortunately, junior designers, who are trying to do their first system in MVC, are struggling to select the right set of
off-the-shell components correctly. They do worthlessly complex designs by needlessly committing them-selves to use these
off-the-shell components. One needs to understand that you don't have to use everything in every (or the first) system you
design. You need to use only the suited ones. But finding the suited options, when many different options are made available,
is easier said than done.

The stated problem is a little more complicated than previously stated as the technology providers too have competitive
products. Therefore to start off, let me gives couple of such examples, where you see different means made available to
achieve the same goal.

1. Entity Framework, Linq to SQL, Subsonic, Hibernated or any other can be used as an ORM (Object Relational
Mapping) tool.
2. 'AutoMapper', 'StructureMap', or any other can be used to map one DTO (Data Transfer Object) to another.
3. The 'Validation Application Block' of Microsoft Enterprise Library, 'System.ComponentModel' namespace of
.NET Framework, Microsoft Workflow Engine (WF) of .NET Framework or any other can be used to validate business objects.
4. Views of MVC, Web-From or generic ASP.NET controls or even plain HTML can be used to develop the User
Interface (UI) layer.
5. JavaScript, Ajax, J-Query can be used as your front end scripting language with or without JSON (Java Script
Object Notation).
6. MVC Architecture or any other, or even a combination of architectures can be used to design a system.

Among the items listed above, you can see there are similar or more applicable options. Additionally there are other options,
which have to be selected base on your requirement. These options have to be selected considering the functional and non
functional requirement of your system. Once well designed, the system truly adds value to your development process. A
designer with experience, selects his options the right way first time, and ends up keeping significant advantages. If you are a
junior system designer, then at least be careful not to pick an awe fully wrong set of options. Such selection can make your
'software design' carrier end even before you start it.

They say "Perfection (in design) is achieved not when there is nothing more to add, but rather when there is nothing more to
take away."

One who reads through this article will realize that an architecture is built with Microsoft ASP.NET MVC Framework, Microsoft
Entity Framework, Ajax, J-Query, 'AutoMapper', Enterprise Library (Unity Application Block), 'MsTest', Log4Net etc. This design
may not be the most flawless of all. But I can assure you that this is not a terribly wrong one either. It will fall within the
acceptable range, and once completed, you will be able to re-use this as a framework to develop your very own (small to
medium sized) web applications.
Pre-requisites

In order to follow this article, you are expected to have at least 4 years or more of development experience with a sound
understanding of OOP concepts and design patterns. Additionally, since our system is going to be designed with ASP.NET MVC
framework, you need to have experience developing a few test applications with ASP.NET MVC framework, most preferably
with Microsoft Entity Framework. If you think you have sufficient expertise, then you are best to further read through this
article.

If you still have not setup ASP.NET MVC, please have the items listed below installed before proceeding any further. You can
also install ASP.NET MVC using Microsoft Web Platform Installer too.

• Microsoft Visual Studio 2010 (RC, in my case) (or any other later version)
• ASP.NET MVC
• Unity Application Block (The completed version of Enterprise Library will auto install this)
• Ajax
• J-Query
• Auto-Mapper
• Entity Frame Work – This comes with the VS 2010

What is ASP.NET MVC?

As stated before, ASP.NET MVC is the Microsoft variant of MVC and it is a free, Microsoft framework for developing great web
applications using the Model-View-Controller pattern. It provides total control over your HTML and URLs, enables rich Ajax
integration, and facilitates test driven development. Read more >>

I hope that the above description also answers the famous question that some developers have, 'Is MVC a pattern or
framework?'. Let me reiterate here again, just to ensure that you understand it correctly. The MVC is a pattern, as well as a
framework. The MVC Pattern is being used to develop Microsoft ASP.NET MVC framework. So that first to be introduced is the
pattern and then the framework.

Why ASP.NET MVC?

ASP.NET is not something completely new, but it is something that Microsoft has built on top of the standard ASP.NET library.
It can be taken as an extension to the .NET Framework. In other words, it is something greater than standard ASP.NET or
Web Forms. When you are working with Web-Form the framework itself controls plenty of variables, where as with ASP.NET
MVC it does not do that. Instead the framework allows you to control them. So with ASP.NET MVC, it is left to you to decide
how you want to build your system.
Though I said that we need to take care of everything with ASP.NET MVC, it is not really difficult. There are many resources
available on the internet to make life easier for MVC developers. Unlike before, where they complained about having to write
more codes to get something done in MVC, now you can do them quicker with the support of contributions of other
developers. The ‘MVC Contrib’ is one and was designed to add functionality and ease-of-use to Microsoft's ASP.NET MVC
Framework. The 'MVC Contrib' is useful for developers looking to develop and test web applications on top of the ASP.NET
MVC framework.

In addition to that there are many new features made available with the latest version of ASP.NET MVC framework. You can
learn more about this by reading “What’s New in ASP.NET MVC 2” document on the www.asp.net/mvc web-site.

Does ASP.NET MVC is the Only Option?

There are debates. Some designers say Web-Form is better than MVC. They say that there are many 3rd party controls
already built for Web-Form. The MVC is extend-able, yet for all they say that the architecture needs you to write more codes.
Additionally they also say that a well architected Web-Form application too can be just as extensible as MVC.

In my view point, the decision has to be taken based on your requirements. When it is 50:50, the latest technology is the
better choice. However we should not choose Web-Form simply because of that natural resistance we have for changing what
we used to be. This habit of resisting the change is not something that you can practice in IT. The IT change rapidly forcing
one to give up old things and move ahead with new ones. I think, the ASP.NET MVC going to have a great future. Microsoft
has done it right this time with ASP.NET MVC. It is already proving to be the framework for building next generation of web
applications. So why wait? If you adopt early, you will grow easier with it. If not then, you will experience the pain of
becoming an out-dated developer with the next wave of technology updates.

In the next part of the article, I will gradually start designing our Document Management System (DMS). That will
demonstrate the application of Microsoft ASP.NET MVC framework to build a real world web application. However, before we
move on to that, I need to stress-out few other important things about MVC here..

• ASP.NET MVC is "*not" WebForms 4.0


• There is a small learning curve with MVC, but there are *many* resources to assist you
• MVC gives you more control, which is generally better
• If you like Unit Testing, ASP.NET MVC will make you happy.

Building the DMS using ASP.NET MVC

I have carefully picked a couple of options to build our DMS. This design is taking advantage of Microsoft ASP.NET MVC
Framework, Microsoft Entity Framework, Ajax, J-Query, 'AutoMapper', Enterprise Library (Unity Application Block), 'MsTest',
Log4Net etc. I am planning to discuss some of the important selections that I have made in later part of this article, but
mostly I expect you to learn those by looking at the source code itself. I will mainly focus on our goal, which is to teach you
how to establish the right architecture to build a small to mid-size web application with ASP.NET MVC framework. In that
effort, I am planning touch base with all important points. I will give just enough details for an experienced developer to
understand them but not anymore as I need to control the length of this Article.

As the first step of architecturing our DMS (or any) system, you need to thoroughly analyze the system. This includes of fully
and deeply understands its requirements, time period, cost constrains and quality requirements etc. Let me give few points
that helps you understand it below...

• The business problem that the proposed system is supposed to solve?


• The functional and non functional requirements
• Project quality requirements
• How much money, the customer is willing to spend for this system?
• The project time period, start and end of the project
• What is the scale (How big the system is?)?
• How flexible the system needs to be?
• How extendable the system has to be?
• How customizable the system needs to be?

Once the system requirements are fully understood, mainly covering the questions given above, you can start the first few
steps of designing a system. This is where you define the structure of the software and find the right way in which that
structure provides conceptual integrity for the system. This is the development work product that gives the highest return on
investment in terms of quality, schedule and cost.

Design considerations

There are many aspects to consider in the design of a piece of software. The importance of each should reflect the goals the
software is trying to achieve. Some of these aspects that I referred form Wiki-Software Design are given below...

• Compatibility - The software is able to operate with other products that are designed for interoperability
with another product. For example, a piece of software may be backward-compatible with an older version of itself.
• Extensibility - New capabilities can be added to the software without major changes to the underlying
architecture.
• Fault-tolerance - The software is resistant to and able to recover from component failure.
• Maintainability - The software can be restored to a specified condition within a specified period of time. For
example, antivirus software may include the ability to periodically receive virus definition updates in order to maintain the
software's effectiveness.
• Modularity - the resulting software comprises well defined, independent components. That leads to better
maintainability. The components could be then implemented and tested in isolation before being integrated to form a desired
software system. This allows division of work in a software development project.
• Packaging - Printed material such as the box and manuals should match the style designated for the target
market and should enhance usability. All compatibility information should be visible on the outside of the package. All
components required for use should be included in the package or specified as a requirement on the outside of the package.
• Reliability - The software is able to perform a required function under stated conditions for a specified
period of time.
• Re-usability - the modular components designed should capture the essence of the functionality expected
out of them and no more or less. This single-minded purpose renders the components reusable wherever there are similar
needs in other designs.
• Robustness - The software is able to operate under stress or tolerate unpredictable or invalid input. For
example, it can be designed with a resilience to low memory conditions.
• Security - The software is able to withstand hostile acts and influences.
• Usability - The software user interface must be usable for its target user/audience. Default values for the
parameters must be chosen so that they are a good choice for the majority of the users.

Imagine that our DMS is a complicated business problem, and then try to direct your design effort to reduce its complexity.
This has to happen through abstraction and separation of concerns. This means, breaking the system in to its structural
elements, architectural components, subsystems, sub-assemblies, parts or 'chunks'. This is not hard. Any experience
designers can identify the components belonging to a system just by looking at its requirement document. However there are
standard techniques that use to do this too. I also have written an Article on this topic, which you can find in the code project
with the title "A Practical Approach to Computer Systems Design and Architecture".
How you Architecture a System?

An experienced Architect does not need to go through every single step in the book to get a reasonable design done for a
small web application. Such Architects can use their experience to speed up the process. Since I have done similar web
applications before and have understood my deliverable, I am going to take the faster approach to get the initial part of our
DMS design done. That will hopefully assist me to shorten the length of this article.

For those who do not have experience, let me briefly mention the general steps that involved in architecturing a software
below...

1. Understand the initial customer requirement - Ask questions and do research to further elaborate the
requirement
2. Define the process flow of the system preferably in visual (diagram) form. I usually draw a process-flow
diagram here. In my effort, I would try to define the manual version of the system first and then would try to convert that into
the automated version while identifying the processes and their relations. This process-flow diagram that we draw here can be
used as the medium to validate the captured requirements with the customer too.
3. Identify the software development model that suite your requirements
o When the requirements are fully captured and defined before the design start, you can use the
'Water-Fall' model. But when the requirements are undefined, a variant of 'Spiral' can be used to deal with that.
o When requirements are not defined, the system gets defined while it is being designed. In such
cases, you need to keep adequate spaces in respective modules, which later expansions are expected.
4. Decide what architecture to be used. In my case, to design our Document Management System (DMS), I will
be using a combination of ASP.NET MVC and Multitier Architecture (Three Tier Variant).
5. Analyze the system and identify its modules or sub systems.
6. Pick one sub system at a time and further analyze it and identify all granular level requirements belonging to
that part of the systems.
7. Recognize the data entities and define the relationships among entities (Entity Relationship Diagram or ER
Diagram). That can followed by identifying the business entities (Some business entities directly map with the classes of your
system) and define the business process flow.
8. Organized your entities. This is where you normalize your database, and decide what OOP concepts and
design pattern to be used etc.
9. Make your design consistent. Follow the same standards across all modules and layers. This includes
streamlining the concepts (as an example, if you have used two different design patterns in two different modules to achieve
the same goal, then pick the better approach and use that in both the places), and conventions used in the project.
10. Tuning the design is the last part of the process. In order to do this, you need to have a meeting with the
project team. In that meeting you need to present your design to your team and make them ask questions about it. Take this
as an opportunity to honestly evaluate/ adjust your design.

Building the Code Framework for our DMS

As I said, our Document Management System (DMS) architecture is done combining the three layer architecture and Model
View Controller architecture.

In order to speed up the process, let me directly define the system framework of our DMS. Please follow the instructions given
below to create your system framework directly in Visual Studio 2010.

1. Open your 'Visual Studio 2010' and create a new Project of type ASP.NET MVC (in my case it was MVC
version 2.0)
2. In the same solution, create a 'Console Library' type Project for your Data Access Layer (DAL). This will
create a separate assembly for your Data Access Layer. In addition to logically group your data access logic in to a separate
assembly this separation has the following advantages
o Allows modifying the data access logic without affecting other layers.
o Support scaling the system easily.
o Support changing the database type without affecting the corresponding business functions.
o .. etc.
3. Create a 'Console Library' type Project for core Business Operations. Just like it was with DAL, this will create
a separate layer for Business Logics.
4. Create another 'Console Library' type Project for common operations. There are some business functions
that are common to all the layers. These functions can be implemented in a separate assembly. That way you can reuse that
with other system too. I will talk about this later in the article too.

Once everything is completed, your solution will be looking like this.

In the above diagram, the 'MvcDemo' project is the MVC Web Project. That project is created using Visual Studio's default
MVC project template. In it, I decided to keep 'Views' and 'Controllers' in the same web project, while 'Models' were shifted
out to another layer (you will read more about this change later). So in summary now you have a solution with one ASP.NET
MVC Web Application project, and three empty console libraries together with a test project, which is automatically created for
us by Visual Studio.

Note: I have used the main project name ('MvcDemo') as a prefix to name the console libraries, but that is something that
you can opted to follow or not.
In our solution each sub system represents a project. Each project represents a meaningful portion of the main business
problem. If you want to reuse one project in multiple other projects (Just like we will be doing it with 'MvcDemo.Common'
project), you can do that by adding the project reference.

Let’s Look at Our Data Access Layer Design

The data access layer provides a centralized location for all calls into the database, and thus makes it easier to port the
application to other database systems. There are many different options to get the Data Access Layer built quickly.

In my effort to build the DAL, I would have chosen from many different model providers, for example:

1. NHibernate
2. LINQ to SQL

Or else I would have chosen any other model provider, possibly:

1. SubSonic
2. LLBLGen Pro
3. LightSpeed
4. ..or who knows

This means that we will be using an ORM (Object Relational Mapping) tool to generate our Data Access Layer. As you can see,
there are many tools, but all having their advantages and disadvantages. In order to select the right tool, you need consider
your project requirements, the skills of the development team, and if an organization has standardized on a specific tool etc.

However, I am not going to use the tools listed above, instead decided to use Microsoft Entity Framework (EF), which is
something Microsoft has newly introduced. The ADO.NET Entity Framework (EF) is an object-relational mapping (ORM)
framework for the .NET Framework. ADO.NET Entity Framework (EF) abstracts the relational (logical) schema of the data that
is stored in a database and presents its conceptual schema to the application. However the conceptual model that EF
created fail to meet my requirements. Therefore I had to find a work around to create the right conceptual model for this
design. You will see few adjustments that I have made to achieve my requirement in later part of this Article.

The selection of EF (Entity Framework) for my ASP.NET MVC front end is not a blindfolded decision. I do have few
affirmations...

1. ASP.NET MVC Framework is Microsoft, so as ADO.NET Entity Framework. They tend to work well together
than any other tool.
2. Latest version of EF (Entity Framework) has many promising features, and has addressed many issue had in
its initial version.
3. In general Microsoft seems serious about EF. That made me thinks that EF would have a significant share in
the future of ORM tools.

The community has raised concerns over what has been promised and is being delivered with EF. You can read this ADO .NET
Entity Framework Vote of No Confidence for more details about it. Microsoft and the Entity Framework team have received a
tremendous amount of feedback from experts in entity-based applications and software architectures on the .NET platform.
While Microsoft’s announcement of its intention to provide framework support for entity architectures was received with
enthusiasm, the Entity Framework itself has consistently proved to be cause for significant concern. However the second
version of Entity Framework (known, somewhat confusingly, as 'Entity Framework v4' because it forms part of .NET 4.0) is
available in Beta form as part of Visual Studio 2010, and has addressed many of the criticisms made of version 1.
The Entity data model (which is also called the conceptual model of the database), which ADO.NET Entity Framework auto
created for our DMS is given below. This has a 1:1 (one to one) mapping between the database tables and the so called
conceptual models. These models or objects can be used to communicate with the respective physical data source or the
tables of the database. I hope you can understand my conceptual model quite easily.

The Data Access Layer project, which is given below, has three folders namely Models, Infrastructure and Interfaces (You will
later notice that this project template is being reused in other projects of this system too). Outside of those folders, you find
few classes such as one base class and two concrete classes. These are the main operational classes of the data access layer
(DAL) project. This project template made it possible to directly access all commonly used main operational classes without
worrying about navigating in to directories.

"The inherent complexity of a software system is related to the problem it is trying to solve. The actual complexity is related
to the size and structure of the software system as actually built. The difference is a measure of the inability to match the
solution to the problem."

-- Kevlin Henney, "For the sake of simplicity" (1999)

Simplicity is the soul of efficiency. This does not mean that the design has to be unrealistically simple. It has to be just enough
to achieve the requirements and not more or less. Additionally the consistency is also important. It can reduce the differences
in between modules, thus would help to easily understand the design. Therefore the design has to be simple and consistent.
While keeping these in mind, let's have a close look at our Data Access Layer (DAL) design.
In the Data Access Layer (DAL) design, I thought of using a variant of repository pattern. The Repository pattern is commonly
used by many enterprise designers. It is a straight forward design that gives you testable & reusable code modules.
Furthermore it gives flexibility and separation of concerns between the conceptual model and business logics too. In my
design there are two Repositories namely ‘DocumentRepository’ and ‘FileRepository’, which will mediates between the domain
(also called Business Logic Layer) and data mapping layers (also called Data Access Layer) using domain objects (also called
Business Objects or Models).

In general it is recommended having one repository class for every business object of the system.

Among the few folders that you see in that project, the folder named 'Interfaces' is important. So let's check inside the
'Interfaces' folder and see what interfaces that we have in it...

1. IRepository<T> - The generic interface that abstractly defines the behavior of all the repositories of our
system. This is the super repository. This is what extends to create the abstract repository with the name
'RepositoryBase<T>'.
2. IDocumentRepository – This is a specialized repository, which defines the behavior specific to 'Document'.
3. IFileRepository – Just like it was with 'IDocumentRepository', this defines the behavior of the 'File'
repository.
4. IRepositoryContext - This defines the behavior of the context of our repositories.
5. IPagination - This defined the definition for pagination related operations.
6. 'IUnitOfWork' and 'IUnitOfWorkFactory' were there but removed from the design later. Initially, I was
planning to write some codes for dependency injection (DI) too. But later I found that Microsoft enterprise library has
everything done for us. They have an application block called 'UnityApplicaitonBlock', which does what I was initiated with
those two interfaces. Therefore I removed unity and inversion of control related implementations from the project. Now the
source code you download now will not have those implementations.
I have used interfaces in the DAL design, and that might made you ask questions like 'why we need these interfaces?' and
'why not just have the concrete implementation alone?'. There are many reasons for having interfaces in a design. They allow
implementation to be interchangeable (One common scenario is, when unit testing, you can replace the actual repository
implementation with a fake one). Additionally, when carefully used, they help to better organize your design.

The interface is the bare minimum needed to explain what a function or class will do. It's the lease amount of code you can
write for a full declaration of functionality and usability. For this reason, it's (more) clearer for a user of your function or class
to understand how the object works. The user shouldn't have to look through all of your implementations to understand what
the object does. So, again defining interfaces is the more organized approach.

In some instances, I have seen designers add interfaces for every class, which I thought is a too extreme design practice. In
my design I have used interfaces not only to organize the design but also to interchange implementation too. Later in the
article you will see how these interfaces are being used to assist 'unity application block' to inject dependencies too.

You can see in the screen above that I have set of interfaces define for pagination too. The pagination (of business objects/
entities) is something that developers code in many different layers. Some code it in the UI (User Interface) layer, while
others do it in BLL (Business Logic Layer) or DAL (Data Access Layer). I thought of implementing it inside DAL to avoid
unwanted network round trips that would occurred otherwise in a distributed multi-tier deployment setup. Additionally when
keep it inside DAL, I will have the option of using some of the built-in EF (Entity Framework) functions for pagination works.

The figure below summarizes the overall DAL design with its main components and their relations. I think it is clear how the
three interfaces and their concrete implementations are being defined.
I think it is important for you to know how this design evolves. So let me talk about that here. Initially, I had the
'IRepository<T>' interface. That was used to implement the two specialized 'Document' and 'File' repositories. That time I
noticed that the two was having many common operations. So I thought of abstractly define them with a abstract class. Thus,
decided to add a new generic abstract class called 'RepositoryBase<T>'. Once all these were done, the final system had the
generic 'IRepository<T>' interface right at the top, then the abstract 'RepositoryBase<T>' class, and then two concrete
implementations of 'File' and 'Document' repositories. I thought it is done, and had a final look before closing-up the design,
but that made me realized that the design is still having issues. So let me talk about that in the next paragraph.

The design I had made it impossible to interchange implementation of either of the specialized repository. As an example, if I
have a test/ fake version of the 'DocumentRepository' implemented with the name 'TestDocumentRepository' and wanted to
interchange that with the 'DocumentRepository', then it is not possible with my design. So I decided to do few more
adjustment to the design by introducing two specialized interfaces called 'IDocumentRepository' and 'IFileRepository'. This
made it possible to fully hide the special implementations, hence gain the required interchangeability. That final change
concludes my DAL design.
As I said before, I used unity application block to inject dependencies to this system. The code below shows how one can use
the unity application block to interchange implementations of IDocumentRepository. The Unity Application Block supports
writing this code in 'global.asax' file or to use the 'web.config' to set detail to resolve dependencies. Please expect more details
on this later..

Collapse | Copy Code

//when using the actual DocumentRepository implementation


.RegisterType<IDocumentRepository, DocumentRepository>()

//when using the test version of the DocumenRepository implementation


.RegisterType<IDocumentRepository, TestDocumentRepository>()

I also realized that with few adjustments, this very same design pattern can be used in business logic layer too. So you will
see the same design approach is being re-used in 'MvcDemo.Core' project too.

Before we move on to the next section, let's have a look at the implementation of 'RepositoryBase<T>' class too. In the base
repository implementation, I was careful not to make it necessarily complex. As you can see, it only has the most needed
methods. You may also see how the dependency that this class has with the ‘IRepositoryContext’ is handled by passing the
dependent class through the constructor. You will later see how this technique is used to inject dependencies across all layers.
You can find more about Unity DI (Dependency Injection) here..

Collapse | Copy Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Linq.Expressions;
using MvcDemo.Dal.Interfaces;
using MvcDemo.Dal.Infrastructure;
using MvcDemo.Dal.EntityModels;

namespace MvcDemo.Dal
{
public abstract class RepositoryBase<T> : IRepository<T>
where T: class
{
public RepositoryBase()
: this(new DmsRepositoryContext())
{
}

public RepositoryBase(IRepositoryContext repositoryContext)


{
repositoryContext = repositoryContext ?? new DmsRepositoryContext();
_objectSet = repositoryContext.GetObjectSet<T>();
}
private IObjectSet<T> _objectSet;
public IObjectSet<T> ObjectSet
{
get
{
return _objectSet;
}
}

#region IRepository Members

public void Add(T entity)


{
this.ObjectSet.AddObject(entity);
}

public void Delete(T entity)


{
this.ObjectSet.DeleteObject(entity);
}

public IList<T> GetAll()


{
return this.ObjectSet.ToList<T>();
}

public IList<T> GetAll(Expression<Func<T, bool>> whereCondition)


{
return this.ObjectSet.Where(whereCondition).ToList<T>();
}

public T GetSingle(Expression<Func<T, bool>> whereCondition)


{
return this.ObjectSet.Where(whereCondition).FirstOrDefault<T>();
}

public void Attach(T entity)


{
this.ObjectSet.Attach(entity);
}

public IQueryable<T> GetQueryable()


{
return this.ObjectSet.AsQueryable<T>();
}

public long Count()


{
return this.ObjectSet.LongCount<T>();
}

public long Count(Expression<Func<T, bool>> whereCondition)


{
return this.ObjectSet.Where(whereCondition).LongCount<T>();
}

#endregion

}
}

In the above code, the 'ObjectSet' is a public property that has being exposed via 'get'. That will allow outside parties to know
the currently active object set of the respective repository. However when you implement the repository with a specific type,
the returned 'ObjectSet' becomes predictable. This is a weakness of my design. As an example, when implementing
‘IFileRepository’ the 'ObjectSet' will guarantee to return 'IObjectSet<File>' but not anything else. So then one can argue
saying that the property is not necessary to have publicly exposed. That is a very valid argument. As you can realize now, I
cannot defend my design. One should be able to defend his/ her design. Therefore, I think it is acceptable to reduce the
property's access level from 'public' to 'protected'. That way only the extended classes will be able to access the active object
set. As I said before, you have to question your design, the questioning validate the design.

If you check the code line below, you might notice something unfamiliar there. The '??' operator is not commonly used in
general coding, but happened to be very useful for me here.

Collapse | Copy Code

repositoryContext = repositoryContext ?? new DmsRepositoryContext();

The '??' operator is called the null-coalescing operator and is used to define a default value for a null able value types as well
as reference types. It returns the left-hand operand if it is not null; otherwise it returns the right operand.

This code pattern is important when using an external module (Unity Application Block) to inject dependencies.

Let's Look at Our Business Logic Layer Design

The business logic layer is usually one of the layers in our multi-layer architecture. This part of the code contains the business
logic for our application. This separation of business functions into a separate project would have the same advantages that
we recognized in the Data Access Layer design.

The screen below expands the 'Business Logic Layer' part of the system. In that, the folder named 'Models' has a set of 'View'
and 'Edit' model classes. These classes represent the 'Models' of the MVC pattern. They are the domain/ conceptual models of
our DMS's BLL (Business Logic Layer). As an example, to display a document in the front end, you can have a view-model
with the name 'DocumentViewModel', with properties to display on the UI in it. These model classes have their corresponding
'Views' and 'Controllers' too. In addition to that, when a ‘View’ (Web Page) is use to edit/ update an entity, you can use a
'DocumentEditModel' to capture user inputs. That same model can use to store the definitions of its property validation
requirement too (read 'Validating Business Objects' below for more details).
You can further break this system to make it more flexible. But that comes with a cost. Further you break, difficult it will be to
maintain your code. I thought this is just right for our requirement. Therefore based on your requirements you can decide how
further you need to break the system.

You can ignore the ‘Mapping’ related interfaces for now, but I will come back to that little later.

As you can see in the screen above, the BLL design is somewhat similar to our Data Access Layer (DAL) design. Just like it
was with DAL, I have a separate set of interfaces that define the framework for this layer.

• IService<T> - Is the super interface that uses to implement the services of this application. I also had
another interface called ‘IServiceBase’, but that make BLL inconsistent with the DAL design. Therefore I decided to remove
that from the design later.
• IDocumentService - This defines the 'Document' specific services.
• IFileService - This defines the 'File' specific services.
• IMapper, IMapperRegister - I was trying to make the mapping library a plug-gable one, so that I will have
the option to plug any other mapping library later. However, you need to give me little more time to complete that part of the
code.

As you see above, I have 'DocumentService', which implements 'IDocumentService', and 'FileService', which implements
'IFileService'. The 'ServiceBase<T>', which is the counter part of the 'RepositoryBase<T>' of DAL, is empty yet. However with
my experience I know that we are going to get functions that are common to both Document and File Service later, that could
abstractly implement/ define in the 'ServiceBase<T>'. I thought it is a good practice to have an abstract type base class
defines whenever you do multiple implementations out of a generic interface.
Let's Look at Our Presentation Layer (User Interface) Design

This is the topmost layer of our application. The presentation layer displays information for the user. It communicates with
other layers to produce results to the web browser.

In general the architecture we used has several differences that I wanted to point at. We removed the 'Models' of the MVC
from our web project and include that in the Business Logic Layer. We also removed the regular presentation layer of the
three tier architecture and merge that with the MVC front end. This means that 'Views' and 'Controllers' of the MVC represent
the Presentation Layer part of the three tiered system. As this is bit complex to explain, I have drawn the diagram below to
further elaborate it.
In the screen below you will see how our ASP.NET MVC web project structure looks like. The default directory structure of an
ASP.NET MVC Application has 3 top-level directories:

• /Controllers
• /Models
• /Views

As you can probably guess, it recommend putting your Controller classes underneath the 'Controllers' directory, your view
templates underneath your 'Views' directory and as you already knows we have decided to move the 'Models' out of this
project. So in our project we will not use the 'Model' folder.

In general ASP.NET MVC framework doesn't force you to always use this structure. Unless you have a good reason to use an
alternative file layout, I'd recommend using this default layout.
Dependency Injection

Dependency injection is a way of objects getting configured with their dependencies by an external entity. This may sound a
bit abstract, so let me give you an example here.

E.g.:- In our code you have a class called 'DmsController', which has a dependency with 'IDocumentService'. This means that
when you create an object of type DmsController, you need to pass an implementation of 'IDocumentService' as a parameter.
In this case think that you have two implementation of 'IDocumentService', where one is called 'DocumentService' (actual)
and the other is called 'TestDocumentService' (Unit Test). Then the Unity Application Block (using a pattern called Unity
Pattern) allows you to dynamically configure the right implementation to resolve the dependency that ‘DmsController’ has with
'IDocumentService'.

If that is still not clear, let me show the way that I am using this application block to inject dependencies in my code. In order
to use Unity Application Block, you need to have a custom controller factory defined. In the screen above, you can see a class
called 'UnityControllerFactory'. I used that class as my custom controller factory. If you look at the source code of that class,
you will see that it inherits from the MVC 'DefaultControllerFactory'. This means that I can use that class to replace the default
MVC Controller Factory. As per the requirement of Unity Application Block, this custom class is used to set the container that
carries the detail to resolve interfaces. Let me show you how the ‘Application_Start’ method of ‘Global.asax’ looks like..
Collapse | Copy Code

protected void Application_Start()


{
AreaRegistration.RegisterAllAreas();

RegisterRoutes(RouteTable.Routes);

/*//Configure container with web.config


UnityConfigurationSection section =
(UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(_container, "containerOne");*/

_container = new UnityContainer()


.RegisterType<IDocumentService, DocumentService>(new ContainerControlledLifetimeManager())
.RegisterType<IFileService, FileService>()
.RegisterType<IDocumentRepository, DocumentRepository>()
.RegisterType<IFileRepository, FileRepository>()
.RegisterType<IRepositoryContext, DmsRepositoryContext>()
.RegisterType<IFormsAuthenticationService, FormsAuthenticationService>()
.RegisterType<IMembershipService, AccountMembershipService>();

//Set for Controller Factory


IControllerFactory controllerFactory = new UnityControllerFactory(_container);

ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}

As I said above, the 'UnityContainer' is used to register the interfaces with its respective concrete implementations. This is
just one time registration hence it is advised to do it inside the 'Application_Start' method of the 'Global.asax'. The container
is passed on to my custom made UnityControllerFactory. Finally, you have to use the built-in method of ‘ControllerBuilder’ to
set my controller factory as the current controller factory of this application. The rest is automatic. For more details on this
topic, please visit the Unity Dependency Injection IoC Screencast ..>>

You can also see how my ‘UnityControllerFactory’ looks like …

Collapse | Copy Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
using System.Web.Routing;
using System.ComponentModel;

namespace MvcDemo.Infrastracture.Mvc
{
public class UnityControllerFactory : DefaultControllerFactory
{
private readonly IUnityContainer _container;

public UnityControllerFactory(IUnityContainer container)


{
_container = container;
}

protected override IController GetControllerInstance(RequestContext requestContext, Type


controllerType)
{
if (controllerType != null)
{
return _container.Resolve(controllerType) as IController;
}
return base.GetControllerInstance(requestContext, controllerType);
}
}
}

The 'DefaultControllerFactory' represents the controller factory that is registered by default. This class provides a convenient
base class for developers who want to make only minor changes to controller creation. As you can see, we have created our
custom controller factory with the name ‘UnityControllerFactory‘ by extending the default controller factory.

Reference..

• ASP.NET MVC Tip: Dependency Injection with Unity Application Block


• DI using Unity Application Blocks

Validating Business Objects

A business object used to store data. A smooth functioning of a business function depends on the validity of its associated
business objects. Therefore it is essential validating business objects before them being used in business functions. As an
example, let's take a business object named 'User', which has a property called 'Password'. Let's also assume that its length
has to be at least 8 characters long. Then, before you storing the password, you need to do a length validation to make sure
that the property meets its business requirement. In .NET there are several options available for object validations.

• Validation Application Block of Enterprise Library


• WorkFlow Foundation, Rules Engine
• .NET framework's built-in 'Data Annotation Validator'
• ..etc.

The validation can be done at different layers of a system. Some validations can efficiently be done inside the UI (User
Interface) layer. The UI layer is the faster and most efficient layer for user input validations. However there are other
validations that you cannot do in UI layer due to various limitations. As an example the business logic layer is the most
suitable place to validate a credit card detail.
The 'Data Annotation Validator' is what we will be using in our code. That allows validation in the UI layer as well as in the
BLL. Additionally, as I noted above, it is part of .NET framework too. Please refer some online materials find more about 'Data
Annotation Validator'. A quick Googling brought 'this' up for me.

Scalability Options of the Design

Since we have separate projects for our 'BLL' and 'DAL', we have the option of breaking those layers in to physically tiers too.
As an example you can wrap the 'MvcDemo.Core' (BLL) project with a ‘WebService’ to deploy it in a separate Application
Server. You can use a ‘WebService’ proxy to communicate with the 'BLL', while keeping the 'MvcDemo' web site in the original
server. The same technique can be used to further scale the system with 'DAL' project too.

The 'MvcDemo.Common' project is a special one that groups all common operations that are common to any project. As
examples we do exception loggings, data type conversions, null handling, encryptions etc in our common project. You can use
this project in all of your company projects. All common functions that you want to re-use can be added to this project. Over
time, this common project will grow in its size and have more and more classes representing more and more sharable
business functions.

In addition to creating that common project, you can also extend the same concept to develop domain centric platforms too. A
domain centric platform will have commonly used business functions that are specific to a particular domain. In order to build
platform like that, you need to select a domain that your company is providing solutions for. As an example if your company is
focusing on providing financial solutions, then you can create a platform for financial applications. This can be done by
selecting and adding business functions to your platform at the completion of each financial project. This approach will
gradually build a platform that you can use as the base framework to develop any financial application.

Summary of the DMS Design

As you can see in the diagram above, the system has three main sections.

• MVC - This has the views and controllers. In my design, I have a controller called 'DmsController'. That
controller supposes to control all DMS related operations. However it would be better if I had separate controllers for each
business entity of my system. In that case since I have two business entities, I should have two controllers namely
'DocumentController' and 'FileController'. A controller can associate with one or more models. As an example
'DocumentController' can associate with 'DocumentViewModel'. 'DocumentEditModel', 'DocumentDetailViewModel',
'DocumentSummaryViewModel' etc.

There are view models as well as Edit models. A view models use to display details in a view. The properties of a view models
need to directly map to the properties that you display in the associated view. An edit models is different and use to capture
user inputs. As an example when you upload a new document or edit properties of an existing document, you need to use a
'DocumentEditModel'. That has to be associated with 'DocumentEditView'. Additionally, an Edit models need to have its
respective validations defined against each property too.

• BLL - The Business Logic Layer mainly has models, and services. The Services associate with Mapping (in
my case I used 'AutoMapper' but there are many other feature rich libraries for this) Library to map Data Objects to Business
Models and wise versa.

• DAL - The DAL mainly has repositories and repository context together with the Entity Framework entity
models.

Unit Testing

Unit testing is very important part of programming. It can be taken as the first mode of testing done on the code. That helps
developers to find bugs early. The earlier the defects were detected, the easier they can be fixed.

In this project, we will be using 'Unity Application Block' together with 'MsTest' to perform unit testing. The 'Unity Application
Block' allow us to develop highly loosely coupled ASP.NET MVC applications. I didn't yet complete the Unit Testing part in the
source code, but I will explain you how that can be done.
Look at the diagram below. This is the same diagram that I used above. You will see that I have completely removed the DAL
part and have changed the 'DocumentService' to 'TestDocService'. What I have done here is that I am trying to test the
'DmsController' functions while keeping the 'DocumentService' under my control. In order to do that, I developed a new
'TestDocService' class by implementing the 'IDocumentService' interface. Instead of using dependency that the
'DocumentService' has with DAL, now I can hardcode everything inside 'TestDocService'. In other word, I can create a self
sufficient service implementation with 'TestDocSercvice'. You can have few such test implementations to test various other
scenarios too. As an example you can implement a 'Test' version of 'DocumentService' to test 'Pagination' related behaviors.
That can have a 'GetDocumentList' method implementation that returns a 'DocumentListViewModel ' with few hundred of
'DocumentViewModel' in it. This test implementation can be used to test the pagination part of the User Interface.

I found this great blog post that you can use to further read along this topic.

• Walkthrough: Creating a Basic MVC Project with Unit Tests in Visual Studio
• Dave Arlin - Bloggin'

Other Things to be Noted

The Exception handling is one of the most import aspects of software development. It improves the quality of the software.
However there are many techniques that developers use to handle exceptions. I thought it is important to consolidating
exception-handling knowledge into a set of polished best practices and patterns. In my code I decided to catch/ log exceptions
in 'Service' classes. You can log the exception and wrap it in a custom exception and throw it back to the UI layer. That way
UI layer has to catch the exception again and redirect user to the respective error view. However I decided to cut that part off,
instead I decided to return null when there is an exception. This frankly limits your options, when it comes to showing the
right error message to the user. You can see the implementation of 'DocumentService' class to see how I have handled
exceptions in my code.
For further readings...

• Exception Handling Best Practices in .NET


• Best Practices for Handling Exceptions

Conclusion

An effective design needs one to address each specific problem separately and uniquely than treating everything as if they
have the same needs. When it comes to putting this into practice, it requires you to use your experience. I have this design,
to take that as the basis for you to hopefully develop your own concepts in this area. At a later time you may need to revisit
this write-up, perhaps to review and challenge your own concept.

S-ar putea să vă placă și