Design patterns in Microsoft.NET. Part 2

Introduction

As a solutions architect, we have to deal with several design patterns in order to design our solution. Design patterns are a way to conceptualize a reusable solution to commonly occurring problem in a given context in software design. Design pattern is today a way to communicate architectural ideas and decisions through a common language. In this series of articles, I will explain the essential design patterns (by the Gang of Four) with real-world code examples. In this second article, I want to talk about behavioral design patterns.

Talking about the design patterns

Behavioral design patterns

Chain of Responsibility design pattern: It consists of a source of command objects and a series of processing objects and it’s a way of communicating between objects. Each processing object contains a set of logic that describes the types of command objects that it can handle, and how to pass off those that it cannot to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.

You can use this design pattern when you have more than one object that may handle a request, you have a scenario that you need to pass a request to one of several objects without specifying the receiver and you have handlers of a request that should be specified dynamically.

The UML diagram for this design pattern is shown in the Figure 1.

01

Figure 1

And an example of this design pattern is found in the Listing 1.

public abstract class Handler

{

public int RequestLimit { get; private set; }

public Handler NextHandler { get; private set; }

 

public abstract void HandleRequest(int request);

 

public Handler(Handler handler, int requestLimit)

{

NextHandler = handler;

RequestLimit = requestLimit;

}

}

 

public class Worker : Handler

{

public Worker(Handler handler)

: base(handler, 10000)

{}

 

public override void HandleRequest(int request)

{

if (request < RequestLimit)

{

Console.WriteLine(“{0} handled a {1} request”, GetType().Name, request);

}

else

{

if (NextHandler != null)

{

NextHandler.HandleRequest(request);

}

}

}

}

 

public class Manager : Handler

{

public Manager(Handler handler)

: base(handler, 20000)

{}

 

public override void HandleRequest(int request)

{

if (request < RequestLimit)

{

Console.WriteLine(“{0} handled a {1} request”,GetType().Name, request);

}

else

{

if (NextHandler != null)

{

NextHandler.HandleRequest(request);

}

}

}

}

 

public class SeniorManager : Handler

{

public SeniorManager(Handler handler)

: base(handler, 50000)

{}

 

public override void HandleRequest(int request)

{

if (request < RequestLimit)

{

Console.WriteLine(“{0} handled a {1} request”,GetType().Name, request);

}

else

{

if (NextHandler != null)

{

NextHandler.HandleRequest(request);

}

}

}

}

 

class Program

{

static void Main(string[] args)

{

SeniorManager seniorManager = new SeniorManager(null);

Manager manager = new Manager(seniorManager);

Worker worker = new Worker(manager);

 

// Run requests along the chain

worker.HandleRequest(5000);

worker.HandleRequest(15000);

worker.HandleRequest(35000);

Console.WriteLine();

manager.HandleRequest(5000);

manager.HandleRequest(15000);

manager.HandleRequest(35000);

Console.WriteLine();

seniorManager.HandleRequest(5000);

seniorManager.HandleRequest(15000);

seniorManager.HandleRequest(35000);

// Wait for user

 

Console.Read();

}

}

Listing 1

Command design pattern: It encapsulates a request as an object, and it’s mainly used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.

Three terms always associated with the command pattern are client, invoker and receiver. The client instantiates the command object and provides the information required to call the method at a later time. The invoker decides when the method should be called. The receiver is an instance of the class that contains the method’s code.

The UML diagram for this design pattern is shown in the Figure 2.

02

Figure 2

And the example for this design pattern is shown in the Listing 2.

public interface Command

{

void Execute();

}

 

public class Light

{

public Light() { }

 

public void TurnOn()

{

System.Console.WriteLine(“The light is on”);

}

 

public void TurnOff()

{

System.Console.WriteLine(“The light is off”);

}

}

 

public class FlipUpCommand : Command

{

private Light _objLight;

 

public FlipUpCommand(Light light)

{

this._objLight = light;

}

 

public void Execute()

{

this._objLight.TurnOn();

}

}

 

public class FlipDownCommand : Command

{

private Light _objLight;

 

public FlipDownCommand(Light light)

{

this._objLight = light;

}

 

public void Execute()

{

this._objLight.TurnOff();

}

}

 

public class Switch : Command

{

private Command _objFlipUpCommand;

private Command _objFlipDownCommand;

 

private bool _bIsUp;

public bool IsUp

{

get

{

return this._bIsUp;

}

set

{

this._bIsUp = value;

}

}

 

public Switch()

{

Light objLamp = new Light();

 

this._objFlipUpCommand = new FlipUpCommand(objLamp);

this._objFlipDownCommand = new FlipDownCommand(objLamp);

}

 

public void Execute()

{

if (this._bIsUp)

{

this._objFlipUpCommand.Execute();

}

else

{

this._objFlipDownCommand.Execute();

}

}

}

 

public class PressSwitch {

 

public static void Main(String[] args)

{

Switch objSwitch = new Switch();

objSwitch.Execute();

}

}

Listing 2

Iterator design pattern: It provides a way to sequentially access aggregate objects without exposing the structure of the aggregate.

For example, a tree, linked list, hash table, and an array all need to be iterated with the methods search, sort, and next. Rather than having 12 different methods to manage (one implementation for each of the previous three methods in each structure), using the iterator pattern yields just seven: one for each class using the iterator to obtain the iterator and one for each of the three methods. Therefore, to run the search method on the array, you would call array.search(), which hides the call to array.iterator.search().

The pattern is widely used in C# and in the .NET framework we have the IEnumerator and IEnumerable interfaces to help us to implement iterators for aggregates. When you implement your own aggregate object you should implement these interfaces to expose a way to traverse your aggregate.

You use this when you need a uniform interface to traverse different aggregate structures, you have various ways to traverse an aggregate structure and you don’t want to expose the aggregate object’s internal representation.

The UML diagram for this design pattern is shown in the Listing 2.

03

Figure 3

And an example code in C# of this design pattern is shown in the Listing 3.

public class AggregateItem

{

public string Data { get; set; }

public AggregateItem(string data)

{

this.Data = data;

}

}

 

interface Aggregate

{

Iterator GetIterator();

}

 

class AggregateImpl : Aggregate

{

private readonly List<AggregateItem> _aggregate;

public int Count

{

get

{

return _aggregate.Count;

}

}

 

public AggregateItem this[int index]

{

get

{

return _aggregate[index];

}

set

{

_aggregate[index] = value;

}

}

 

public AggregateImpl()

{

_aggregate = new List<AggregateItem>();

}

 

public Iterator GetIterator()

{

return new IteratorImpl(this);

}

}

 

interface Iterator

{

object First();

object Next();

bool IsDone();

object Current();

}

 

class IteratorImpl : Iterator

{

private readonly AggregateImpl _aggregate;

private int _nCurrentIndex;

 

public object First()

{

return _aggregate[0];

}

 

public object Next()

{

object result = null;

if (_nCurrentIndex < _aggregate.Count – 1)

{

result = _aggregate[_nCurrentIndex];

_nCurrentIndex++;

}

return result;

}

 

public bool IsDone()

{

return _nCurrentIndex >= _aggregate.Count;

}

 

public object Current()

{

return _aggregate[_nCurrentIndex];

}

 

public IteratorImpl(AggregateImpl aggregate)

{

_nCurrentIndex = 0;

_aggregate = aggregate;

}

}

Listing 3

Mediator design pattern: – It encapsulates the interaction between a set of objects. The pattern helps to lose couple the object by keeping them from referring each other. You use this design pattern when the behavior is distributed between some objects can be grouped or customized, object reuse is difficult because it communicates with other objects, and objects in the system communicate in well-defined but complex ways.

The UML diagram for this design pattern is shown in the Figure 4.

04

Figure 4

And an example of this design pattern is shown in the Listing 4.

public interface Mediator

{

void Send(string message, Colleague colleague);

}

 

public class ConcreteMediator : Mediator

{

public List<ConcreteColleague> Colleagues { get; private set; }

public ConcreteMediator()

{

Colleagues = new List<ConcreteColleague>();

}

 

public void Send(string message, Colleague colleague)

{

foreach (Colleague currentColleague in Colleagues)

{

if (!currentColleague.Equals(colleague))

{

currentColleague.Recieve(message);

}

}

}

}

 

public abstract class Colleague

{

protected Mediator _mediator;

 

public Colleague(Mediator mediator)

{

_mediator = mediator;

}

public abstract void Send(string message);

public abstract void Recieve(string message);

}

 

public class ConcreteColleague : Colleague

{

public int ID { get; set; }

 

public ConcreteColleague(Mediator mediator, int id)

: base(mediator)

{

ID = id;

}

public override void Send(string message)

{

_mediator.Send(message, this);

}

public override void Recieve(string message)

{

Console.WriteLine(“{0} recieved the message: {1}”,ID, message);

}

}

 

class Program

{

static void Main(string[] args)

{

ConcreteMediator mediator = new ConcreteMediator();

ConcreteColleague colleague1 = new ConcreteColleague(mediator, 1);

ConcreteColleague colleague2 = new ConcreteColleague(mediator, 2);

mediator.Colleagues.Add(colleague1);

mediator.Colleagues.Add(colleague2);

colleague1.Send(“Hello from colleague 1”);

colleague2.Send(“Hello from colleague 2”);

Console.Read();

}

}

Listing 4

Memento design pattern: It helps to save the object internal state in an external place enabling us to restore the state later when needed. The memento pattern doesn’t violate encapsulation of the internal state. The pattern is rarely used but it’s very helpful in scientific computing or in computer games.

It’s mainly used when you need to save object’s state and use the saved state later in order to restore the saved state and you don’t want to expose the internal state of your object (see Figure 5).

05

Figure 5

An example code for this pattern is shown in the Listing 5.

public class Originator<T>

{

public T State { get; set; }

public Memento<T> SaveMemento()

{

return (new Memento<T>(State));

}

public void RestoreMemento(Memento<T> memento)

{

State = memento.State;

}

}

 

public class Memento<T>

{

public T State { get; private set; }

public Memento(T state)

{

State = state;

}

}

 

public class Caretaker<T>

{

public Memento<T> Memento { get; set; }

}

 

class Program

{

static void Main(string[] args)

{

Originator<string> org = new Originator<string>();

org.State = “Old State”;

Caretaker<string> caretaker = new Caretaker<string>();

caretaker.Memento = org.SaveMemento();

Console.WriteLine(“This is the old state: {0}”, org.State);

org.State = “New state”;

Console.WriteLine(“This is the new state: {0}”, org.State);

org.RestoreMemento(caretaker.Memento);

Console.WriteLine(“Old state was restored: {0}”, org.State);

Console.Read();

}

}

Listing 5

Observer design pattern: It is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.

You mainly use this pattern when you have a publisher/subscriber model, objects need to be notified of a change in another objects, and you need that the object that notify its state change would not know about its subscribers.

The UML diagram for this design pattern is shown in the Figure 6.

06

Figure 6

An example code for this design pattern is shown in the Listing 6.

public abstract class Subject

{

private List<IObserver> _observers;

 

public Subject()

{

_observers = new List<IObserver>();

}

 

public void Attach(IObserver observer)

{

_observers.Add(observer);

}

 

public void Detach(IObserver observer)

{

_observers.Remove(observer);

}

 

public void Notify()

{

foreach (IObserver observer in _observers)

{

observer.Update();

}

}

}

 

public class ConcreteSubject<T> : Subject

{

public T SubjectState { get; set; }

}

 

public interface IObserver

{

void Update();

}

 

public class ConcreteObserver<T> : IObserver

{

private T _observerState;

public ConcreteObserver(ConcreteSubject<T> subject)

{

Subject = subject;

}

 

public void Update()

{

_observerState = Subject.SubjectState;

Console.WriteLine(“The new state of the observer:{0}”, _observerState.ToString());

}

}

 

class Program

{

static void Main(string[] args)

{

ConcreteSubject<string> subject = new ConcreteSubject<string>();

subject.Attach(new ConcreteObserver<string>(subject));

subject.Attach(new ConcreteObserver<string>(subject));

subject.SubjectState = “Hello World”;

subject.Notify();

System.Console.Read();

}

}

Listing 6

Strategy design pattern: It allows you to use multiple algorithms interchangeably.  One reason you might use a Strategy design pattern is to simplify an overly complex algorithm. Sometimes, as an algorithm evolves to handle more and more situations, it can become very complex and difficult to maintain. Breaking these complex algorithms down into smaller more manageable algorithms might make your code more readable and more easily maintained.

The UML diagram for this pattern is shown in the Figure 7.

07

Figure 7

An example code for this design pattern is shown in the Listing 7.

using System;

 

namespace Wikipedia.Patterns.Strategy

{

class MainApp

{

static void Main()

{

Context anObject;

 

// Three contexts following different strategies

anObject = new Context(new ConcreteStrategyA());

anObject.Execute();

 

anObject.UpdateContext(new ConcreteStrategyB());

anObject.Execute();

 

anObject.UpdateContext(new ConcreteStrategyC());

anObject.Execute();

}

}

 

interface IStrategy

{

void Execute();

}

 

class ConcreteStrategyA : IStrategy

{

public void Execute()

{

Console.WriteLine(“Called ConcreteStrategyA.Execute()”);

}

}

 

class ConcreteStrategyB : IStrategy

{

public void Execute()

{

Console.WriteLine(“Called ConcreteStrategyB.Execute()”);

}

}

 

class ConcreteStrategyC : IStrategy

{

public void Execute()

{

Console.WriteLine(“Called ConcreteStrategyC.Execute()”);

}

}

 

class Context

{

IStrategy strategy;

 

public Context(IStrategy strategy)

{

this.strategy = strategy;

}

 

public void UpdateContext(IStrategy strategy)

{

this.strategy = strategy;

}

 

public void Execute()

{

strategy.Execute();

}

}

}

Listing 7

Conclusion

In this article, I’ve explained the essential design patterns (by the Gang of Four) with UML diagrams and real-world code examples.

 

Advertisements

Customer Discovery, first phase of Customer Development

Image

As part of my research about the Steve Blank´s  (@sgblank) Customer Development methodology, now I´m reading the book The Startup Owner’s Manual: The Step-By-Step Guide for Building a Great Company (http://www.amazon.com/The-Startup-Owners-Manual-Step-By-Step/dp/0984999302) which is very good resource for every entrepreneur.

In this post, I would like to share my notes and insights about the first phase in the Customer Development method: the Customer Discovery. The goal of Customer Discovery is to be sure that a specific product solves known problem for an identifiable customer segment. This phase is executed by the founders.

A startup begins with the vision of its founders: a vision of a new product or service that solves a customers´ problem. The goal of customer discovery is to turn the founders´ initial hypothesis (guesses) about customers, market and solution (product/service) into facts in order to search for the problem/solution fit. Facts exist only outside the building, where customer live, so we need to get out of the building in front of the customers (days, months and even years). It´s done by the founders, so they can know if it´s a vision or just hallucination, so the value proposition matches the customer segment it plans to target. Remember that most business model fails because we waste money, effort and time in building the wrong product.

It´s remarkable to say that there may be multiple value propositions and multiple customer segments, but the problem/solution fit is only achieved when the revenue and pricing model, value proposition, and customer acquisition efforts all match up with customers´ needs.

In a startup, at the first day, we don´t have plenty of customer knowledge, so the first product (minimum viable product – MVP) is not designed to satisfy a mainstream customers but small group of early customers who have bought the startup´s vision. They will give feedback to startups necessary to add features to the product over time and tell others about the product to the world. The idea is to put the MVP in front of customers to find out whether we have understood the customer problem to define the key features of the solution. Then, we iteratively refine the solution.

The business model canvas from Alex Osterwalder (@AlexOsterwalder) is the scorecard used in the customer discovery step to organizing our thinking by specifing the hypotheses (guesses) and experiments as well as a medium to record the result (pass/fail) of the experiments for the validation of hypotheses in searching for the business model.

The business model canvas (http://en.wikipedia.org/wiki/Business_Model_Canvas) enables specifying how the company expects to make money in nine blocks: value proposition, customer segment, channels, customer relationship and demand creation, revenue and pricing model, partners, activities and costs structure.

The business model canvas can´t be static snapshot but dynamic. We need to update the canvas to reflect any pivot and iterations in time period (let´s say a week). After the time period, we need to agree on the changes to the business model and integrate them in a new view of the canvas to work on for the next time period. In any precise moment of the time, we have the current canvas and a stack of previous canvases.

We need to do a market research using Total Available Market (TAM) and Served Available Market (SAM). TAM covers every way a customer can currently meet a need, and SAM is the portion of the TAM that our product covers. TAM answers the question: How big is the market (the total of all unit sales of all the competing products)? In short, TAM is the total potential market. TAM is expressed using dollar value. Identifying the TAM and SAM can help to understand the target customers. We can use several tools such as Google Insights, Google Trends and Facebook ads, industry-analyst reports, market-research reports and competitor´s  press.

We also have to launch a landing page (with call-to-action) as product concept, traffic analysis and medium for validating hypothesis as well as to contact the target customers using a contact list in order to conduct survey, get insights and receive feedback. After that, we need to launch a low fidelity MVP.

Customer Discovery phase has four sub-phases.

  • Phase 1 deconstructs the founders´ vision into the nine parts of the business model canvas
    • Goal: To sketch out the possible problems we´re solving and what product we´re building and how we believe this will create value for the customers, in other words we´re stating our hypothesis
    • Description: We need to describe the jobs the customers are trying to get done and outline their pains and gains as well as to list the products/services we´re trying to offer to alleviate pains and create gains. The team specifies the hypothesis for each part of the business model (value proposition, customer segment, channels, market type, customer relationship and demand creation, revenue and pricing model, partners, activities and costs structure) including the list of experiments to conduct to prove or disprove each one
    • Tools:
  • Phase 2 enables conducting experiments to test the problem-related hypotheses in the business model canvas
    • Goal: To understand the problem/solution fit by turning hypotheses into facts or discarding them if they´re wrong and replacing them with new hypotheses
    • Description: We do so by hearing our customers and testing the most important elements in the business model including the customer problems, value proposition, pricing, channel strategy and sales process in order to understand how important the problem is and how big it can become (start getting out of the building to talk as many potential customers as possible). Building a landing page is hard because we need customer insights and iterating without talking directly to customers is slow. So, talking directly to customers has more learning validation than any other method. In other to structure the problem presentation, we can use the following checklist:
    • State the top 3 problems
    • Ask the customer to prioritize the problems
    • Ask the customer how he works today and his pains and gains today
    • Ask the customer how he solves the problems today
    • Very briefly, describe how we might solve the problem
    • Would the customer use the solution if it were free?
    • Would the customer pay $X per year?
    • Ask for referrals to others

Phase 3 enables testing the solution by presenting the value proposition and low fidelity MVP

Phase 4 enables stopping and assessing the results of the experiments we´ve conducted and verified

  • Goal: To verify, if we need whether to pivot or to start selling the product because we´ve achieved the problem/solution fit
  • Description: We can have a full understanding of customers´ problems and needs, confirmed the value proposition solves real problems, determined a sizable volume of customers, learn the customers will pay for the product and finally made certain the revenue will deliver a profitable business
  • Tools:

According to the Ash Maurya (@ashmaurya), there are 3 rules to actionable metrics derived from Lean Startup principles.

Rule 1: Measure the right macro

Eric Ries recommends focusing on the macro effect of an experiment such as sign-ups versus button clicks.

There are only a handful of macro metrics (only 5 – AARRR) that really matter. These are the metrics for pirates from Dave McClure (@davemcclure) organized depending on the customer lifecycle as shown below:

  • Acquisition: Users come to the site from several channels
    • Key question:
      • How do users find you?
    • Examples:
      • X number of clicks
      • Y number of page views
      • Z time on the site
  • Activation: Users have a happy first experience with the product
    • Key question:
      • Do users have a great first experience?
    • Examples:
      • Conversion rate
      • Number of users that sign-up
      • Number of users that watch product demonstration
  • Retention: Users come several times to the site to use the product
    • Key question:
      • Do users come back?
    • Examples:
      • Number of users using the product per month
      • Number of email click throughts
      • Number of feedback
      • Retention rate
  • Referral: Users like the product enough to refer it to others
    • Key question:
      • Do users tell others?
    • Examples:
      • Number of referrals
      • Number of activations
      • Viral factor > 1 (it means that every customer gets more than one another customer, therefore your product will grow virally)
      • Conversion rate
  • Revenue: Users engage on monetization activities (purchase, subscription, etc), so to find out how much profit they make for every customer and scale the number of customers
    • Key question:
      • How do you make money?
    • Examples:
      • How much money do you make for every customer you acquire
      • Minimum revenue
      • Cancellation rate. Number of customer who cancel in any given month compared to total (paying) customers

Of the 5 metrics, only 2 metrics matter before the product/market fit (activation and retention). Before the product/market fit, we´re building some product that people want by providing a great first experience (activation) and most important customer engagement (retention).

Rule 2: Create simple reports

Reports that are hard to understand, simply won´t get used. Funnel reports are a great way to summarize key metrics. Funnel reports are simple and map well to Dave McClure´s AARRR startup metrics.

Image

Figure 1

Image

Figure 2

Image

Figure 3

David Cancel´s Funnel is shown below:

Image

Figure 4

Funnel reports have a key drawback: because we´re constantly changing the product, it´s impossible to tie back observed results to specific actions taken a month ago; so, it´s used a reporting period where events generated in that period are aggregated across all users

Funnel reports work well for micro-optimization experiments (such as landing page conversion) but fall short for macro-pivot experiments, so we need to combine them with cohorts.

A cohort analysis is a form of study design. For example, when the development team makes design choices, then they go back to review traffic data to evaluate the success of their choices. A cohort is a group of people who share a common characteristic or experience and we wish to track this property, for example, bucket users into the month they join. The most common cohort attribute is “join date”.

Let´s illustrate the concept of cohort analysis with two figures:

Image

Figure 5

The previous report is used for Retention. It´s generated using monthly cohort by join date and tracking key activities over time.

Image

Figure 6

A good report combining funnel and cohort is “Weekly Cohort Report by Join Date” as shown below:

Image

Figure 7

In the previous report, we group users by the week in the year they signed-up and then we track all their events over time. We can see visible changes in the metrics which can be tied back to specific activities done in a particular week.

Apart from reactive monitoring the funnel, cohorts can also be used to proactively measure A/B test experiments. For example, a report shows the experiment about a cohort measuring the “plan type” attribute for the Freemium versus Free Trials.

Image

Figure 8

Rule 3: Metrics are people

Metrics can only tell you what users did. To make them actionable, we need to tie them to actual people. This is important before the product/market fit when we don´t have a huge number of users and we rely on qualitative versus quantitative validation.

For example, a list of people which failed in the download step in the funnel.

Image

Figure 9

Finally, there are some techniques to getting to actionable metrics:

  • Split tests metrics. Produce the most actionable of all metrics, because it can confirm or refute a specific hypothesis. The real value is when we integrate them into the decision loop: putting the ideas into practice, seeing what happens, and learning. A good rule of thumb is to ask: if this test turns out differently from how I expect, will that cast serious doubts on what I think I know about my customers? If not, try something bigger. For example, let´s say we add a new feature, we´re using A/B tests in which 50% of customers (group A) see the new feature and the other 50% (group B) not. After some days, we measure the revenue and noticed that group B has 20% of revenue higher. After that, we roll out the feature to 100% (group A + group B) customers and keep on doing experiments/tests with more features in the same way
  • Per-customer metrics. It means that metrics are people too. For example, instead of looking at the total number of page views in a given month, consider looking at the number of page views per new and returning customer (most conversion). Those metrics should be relatively constant
  • Funnel metrics and cohort analysis. It´s a kind of per-customer metrics. For example, consider an ecommerce product that has a couple of key customer lifecycle events: registering for the product, signing for a free trial, using the product, and becoming a paying customer. We can create a simple report that shows these metrics for subsequent cohort (groups) over time. If the report says what percentage of customers who registered subsequently went on to take each lifecycle action. If these numbers are holding steady from cohort to cohort, then we have feedback telling that nothing is changing. If one cohort suddenly shifts up and down, we get into investigation

After, the customer discovery phase is successfully finished; we can proceed to customer validation in order to try to validate the sales roadmap, so we can be sure that a market is saleable and large enough that a viable business might be built.

What do you think about customer discovery phase? Please, feel free to tell your experience and comments.

Introduction

As a solutions architect, we have to deal with several design patterns in order to design our solution. Design patterns are a way to conceptualize a reusable solution to commonly occurring problem in a given context in software design. Design pattern is today a way to communicate architectural ideas and decisions through a common language. In this series of articles, I will explain the essential design patterns (by the Gang of Four) with real-world code examples. In this first article, I want to talk about creational and structural design patterns.

Talking about the design patterns

In order to explain the essential design patterns, I want to organize the design patterns the same way as the Gang of Four did as creational, structural and behavioral.

Creational design patterns

Factory design pattern: The factory design pattern is used to create instances of classes without specifying the exact class. The essence is: “Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses”. It’s mainly used for the creation of objects regarding to the configuration files or user input.

The UML representation is shown in the Figure 1.

Figure 1

An example in C# is shown in the Listing 1.

public interface ISession

{

void Initiate();

}

public class DatabaseSession : ISession

{

void Initiate()

{ }

}

public class MessageQueueSession : ISession

{

void Initiate()

{ }

}

public class SessionFactory

{

public static ISession GetSession(string session)

{

ISession objResult = null;

switch(session)

{

case “database”:

objResult = new DatabaseSession();

case “mqueue”:

objResult = new MessageQueueSession();

}

return objResult;

}

}

Listing 1

Abstract Factory: It provides a way to encapsulate a group of individual factories that have a common theme. In normal usage, the client software creates a concrete implementation of the abstract factory and then uses the generic interfaces to create the concrete objects that are part of the theme. It’s a factory of factory, so we need to create another layer to the example in the Listing 1.

Flyweight pattern: It’s used to maximize the sharing of objects resulting in reduced memory consumption, for example, you have large amount of small objects that share common information reducing the storage of the objects. It’s an extension of the factory design pattern.

The UML diagram is shown in the Figure 2.

Figure 2

Let’s see an implementation in C# (see Listing 2).

public enum eNumbers

{

One,

Two,

Three,

// .. and so on with every number

}

public class NumbersFactory

{

private Dictionary<eNumbers, Number> _numbers = new Dictionary<eNumbers, Number>();

public Number GetNumber(eNumbers number)

{

if (!_numbers.ContainsKey(number))

{

switch (number)

{

case (eNumbers.One):

{

_numbers.Add(number, new One());

break;

}

case (eNumbers.Two):

{

_numbers.Add(number, new Two());

break;

}

case (eNumbers.Three):

{

_numbers.Add(number, new Three());

break;

}

default:

{

break;

}

}

}

return _numbers[number];

}

}

public abstract class Number

{

protected int _number;

protected string _numberName;

protected int _numberSize;

public abstract void WriteNumber(int numberSize);

}

public class One : Number

{

public One()

{

this._number = 1;

this._numberName = “One”;

}

public override void WriteNumber(int numberSize)

{

this._numberSize = numberSize;

Console.WriteLine(string.Format(“{0} is size {1}”,_numberName, _numberSize));

}

}

public class Two : Number

{

public Two()

{

this._number = 2;

this._numberName = “Two”;

}

public override void WriteNumber(int numberSize)

{

this._numberSize = numberSize;

Console.WriteLine(string.Format(“{0} is size {1}”,_numberName, _numberSize));

}

}

public class Three : Number

{

public Three()

{

this._number = 3;

this._numberName = “Three”;

}

public override void WriteNumber(int numberSize)

{

this._numberSize = numberSize;

Console.WriteLine(string.Format(“{0} is size {1}”, _numberName, _numberSize));

}

}

Listing 2

Singleton design pattern: It’s used to insure that only a single instance of a given object can exist. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.

The UML diagram is shown in Figure 3.

Figure 3

And the example in C# is shown in the Listing 3.

public sealed class Singleton

{

private static readonly Singleton _instance = new Singleton();

private Singleton() { }

public static Singleton Instance

{

get

{

return _instance;

}

}

}

Listing 3

Builder design pattern: It separates the construction of a complex object from its representation so that the same construction process can create different representations. This pattern is not commonly used. It’s like the abstract factory with the difference that the builder is concerned about how the objects are created and the abstract factory is concerned about what objects are created.

Let’s see the UML diagram for this pattern (see Figure 4).

Figure 4

Let’s see an implementation using C# (see Listing 4).

class Pizza

{

public string Dough { get; set; }

public string Sauce { get; set; }

public string Topping { get; set; }

}

abstract class PizzaBuilder

{

public Pizza pizza { get; protected set; }

public void CreatePizza()

{

pizza = new Pizza();

}

public abstract void BuildDough();

public abstract void BuildSauce();

public abstract void BuildTopping();

}

class HawaiianPizzaBuilder : PizzaBuilder

{

public override void  BuildDough()

{

pizza.Dough = “Cross”;

}

public override void BuildSauce()

{

pizza.Sauce = “Mild”;

}

public override void BuildTopping()

{

pizza.Topping = “Ham+Pineapple”;

}

}

class SpicyPizzaBuilder : PizzaBuilder

{

public override void BuildDough()

{

pizza.Dough = “Pan Baked”;

}

public override void BuildSauce()

{

pizza.Sauce = “Hot”;

}

public override void BuildTopping()

{

pizza.Topping = “Pepperoni+Salami”;

}

}

class Cook

{

public PizzaBuilder PizzaBuilder { get; set; }

public Pizza Pizza { get { return PizzaBuilder.pizza; } }

public void MakePizza()

{

PizzaBuilder.CreatePizza();

PizzaBuilder.BuildDough();

PizzaBuilder.BuildSauce();

PizzaBuilder.BuildTopping();

}

}

static void Main(string[] args)

{

Cook cook = new Cook();

cook.PizzaBuilder = new SpicyPizzaBuilder();

cook.MakePizza();

cook.PizzaBuilder = new HawaiianPizzaBuilder();

cook.MakePizza();

}

Listing 4

Lazy initialization: The idea is to delay the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed (see Listing 5).

using System;

using System.Collections;

using System.Collections.Generic;

public class Fruit

{

private string _typeName;

private static Dictionary<string, Fruit> _typesDictionary = new Dictionary<string, Fruit>();

private Fruit(String typeName)

{

this._typeName = typeName;

}

public static Fruit GetFruitByTypeName(string type)

{

Fruit fruit;

if (!_typesDictionary.ContainsKey(type))

{

// Lazy initialization

fruit = new Fruit(type);

_typesDictionary.Add(type, fruit);

}

else

fruit = _typesDictionary[type];

return fruit;

}

public static void ShowAll()

{

if (_typesDictionary.Count > 0)

{

Console.WriteLine(“Number of instances made = {0}”, _typesDictionary.Count);

foreach (KeyValuePair<string, Fruit> kvp in _typesDictionary)

{

Console.WriteLine(kvp.Key);

}

Console.WriteLine();

}

}

}

class Program

{

static void Main(string[] args)

{

Fruit.GetFruitByTypeName(“Banana”);

Fruit.ShowAll();

Fruit.GetFruitByTypeName(“Apple”);

Fruit.ShowAll();

// returns pre-existing instance from first

// time Fruit with “Banana” was created

Fruit.GetFruitByTypeName(“Banana”);

Fruit.ShowAll();

Console.ReadLine();

}

}

Listing 5

Object pool design pattern: It’s a set of initialized objects that are kept ready to use, rather than allocated and destroyed on demand. A client of the pool will request an object from the pool and perform operations on the returned object. When the client has finished with an object, it returns it to the pool, rather than destroying it. It is a specific type of factory object. It’s mainly used in situations where the cost of initializing a class instance is high, the rate of instantiation of a class is high, and the number of instances in use at any one time is low, such as database connections, socket connections, threads and large graphic objects like fonts or bitmaps.

When writing an object pool, the programmer has to be careful to make sure the state of the objects returned to the pool is reset back to a sensible state for the next use of the object. If this is not observed, the object will often be in some state that was unexpected by the client program and may cause the client program to fail. The pool is responsible for resetting the objects, not the clients.

Structural design patterns

Adapter design pattern: It converts the interface of a class into another interface clients expect. Adapter lets the classes work together that couldn’t otherwise because of incompatible interfaces, by providing its interface to clients while using the original interface.

Let’s see the UML diagram for this pattern (see Listing 5).

Figure 5

The implementation of the design pattern is shown in the Listing 6.

public interface IClient

{

void DoWork();

}

public interface IAdaptor

{

void MethodA();

}

public interface IAdaptee

{

void MethodB();

}

public class Adaptee : IIAdaptee

{

public void MethodB()

{ }

}

public class Adaptor : IAdaptor

{

private Adaptee _objAdaptee;

public Adaptor(Adaptee objAdaptee)

{

this._objAdaptee = objAdaptee;

}

public void MethodA()

{

this._objAdaptee.MethodB();

}

}

public class Client : IClient

{

private IAdaptor _objAdaptor;

public Client(IAdaptor objAdaptor)

{

this._objAdaptor = objAdaptor;

}

public void DoWork()

{

this._objAdaptor.MethodA();

}

}

Listing 6

Bridge design pattern: It decouples an abstraction from its implementation so that the two can vary independently. In other words we make a bridge between the abstraction and its implementation and therefore we won’t have a binding between the two.

Let’s see UML diagram for this design pattern (see Figure 6).

Figure 6

Let’s see an implementation of this design pattern (see Listing 7).

public class Abstraction

{

private Bridge _bridge;

public Abstraction(Bridge bridge)

{

_bridge = bridge;

}

public void Operation()

{

Console.Write(“Using”);

_bridge.OperationImplementation();

}

}

public interface Bridge

{

void OperationImplementation();

}

public class BridgeImplementationA : Bridge

{

public void OperationImplementation()

{

Console.Write(“BridgeImplementationA”);

}

}

public class BridgeImplementationB : Bridge

{

public void OperationImplementation()

{

Console.Write(“BridgeImplementationB”);

}

}

Listing 7

Composite design pattern:  The main idea is to compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

The UML diagram for this design pattern is shown in the Figure 7.

Figure 7

Now let’s see the code example in C# (see Listing 8).

using System;

using System.Collections.Generic;

namespace Composite

{

class Program

{

interface IGraphic

{

void Print();

}

class CompositeGraphic : IGraphic

{

private List<IGraphic> child = new List<IGraphic>();

public CompositeGraphic(IEnumerable<IGraphic> collection)

{

child.AddRange(collection);

}

public void Print()

{

foreach(IGraphic g in child)

{

g.Print();

}

}

}

class Ellipse : IGraphic

{

public void Print()

{

Console.WriteLine(“Ellipse”);

}

}

static void Main(string[] args)

{

new CompositeGraphic(new IGraphic[]

{

new CompositeGraphic(new IGraphic[]

{

new Ellipse(),

new Ellipse(),

new Ellipse()

}),

new CompositeGraphic(new IGraphic[]

{

new Ellipse()

})

}).Print();

}

}

}

Listing 8

Decorator design pattern: It allows an objects behavior to be altered at runtime.This change in behavior is accomplished by wrapping an object with a new object.  This new wrapper object is the Decorator. The Decorator object will implement the same interface as the object being wrapped.  Because the decorated object uses the same interface as an undecorated object, other parts of your system do not need to be aware of whether or not one or more decorations are in use. The decorator (wrapper) can now alter the behavior of the object being wrapped by either completely replacing various methods or by altering the behavior of the methods of the object being decorated.

This is very important to implement cross-functional features (aspect-oriented programming) in your applications such as logging, security, transactions, etc. It can be also used to express context-specify aspects to plain objects without changing their implementation (see Listing 9).

public interface IReport

{

void Print();

}

public class Report : IReport

{

public void IReport.Print()

{

HttpContext.Current.Response.Write(“This is the report body.”);

}

}

public class ReportHeaderDecorator : IReport

{

private IReport _innerReport;

public ReportHeaderDecorator(IReport innerReport)

{

_innerReport = innerReport;

}

public void IReport.Print()

{

HttpContext.Current.Response.Write(“<h3>This is the report header</h3>”);

HttpContext.Current.Response.Write(“<hr />”);

_innerReport.Print();

}

}

public class ReportFooterDecorator : IReport

{

private IReport _innerReport;

public ReportFooterDecorator(IReport innerReport)

{

_innerReport = innerReport;

}

public void IReport.Print()

{

_innerReport.Print();

HttpContext.Current.Response.Write(“<hr />”);

HttpContext.Current.Response.Write(“<h6>This is the report footer.</h6>”);

}

}

IReport myReport;

myReport = new Report();

myReport = new ReportHeaderDecorator(myReport);

myReport = new ReportFooterDecorator(myReport);

myReport.Print();

Listing 9

Facade design pattern: It’s mainly used to provide a simpler interface into a more complicated series of complicated interfaces and or sub systems (see Figure 8).

Figure 8

Another UML diagram is shown in the Figure 9.

Figure 9

And an implementation is shown in the Listing 10.

using System;

namespace Facade

{

class Computer

{

class CPU

{

public void Freeze() { }

public void Jump(long addr) { }

public void Execute() { }

}

class Memory

{

public void Load(long position, byte[] data) { }

}

class HardDrive

{

public byte[] Read(long lba, int size) { return null; }

}

CPU cpu = new CPU();

Memory memory = new Memory();

HardDrive hardDrive = new HardDrive();

void StartComputer()

{

cpu.Freeze();

memory.Load(0x22, hardDrive.Read(0x66, 0x99));

cpu.Jump(0x44);

cpu.Execute();

}

static void Main(string[] args)

{

Computer facade = new Computer();

facade.StartComputer();

}

}

}

Listing 10

Proxy design pattern: It provides a Placeholder for another object to control access to it. A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.

The UML diagram for this design pattern is shown in the Listing 10.

Figure 10

An implementation of this design pattern is shown in the Listing 11.

using System;

namespace Proxy

{

class Program

{

interface IImage

{

void Display();

}

class RealImage : IImage

{

public RealImage(string fileName)

{

FileName = fileName;

LoadFromFile();

}

private void LoadFromFile()

{

Console.WriteLine(“Loading ” + FileName);

}

public String FileName { get; private set; }

public void Display()

{

Console.WriteLine(“Displaying ” + FileName);

}

}

class ProxyImage : IImage

{

public ProxyImage(string fileName)

{

FileName = fileName;

}

public String FileName { get; private set; }

private IImage image;

public void Display()

{

if (image == null)

image = new RealImage(FileName);

image.Display();

}

}

static void Main(string[] args)

{

IImage image = new ProxyImage(“HiRes_Image”);

}

}

}

Listing 11

Conclusion

In this article, I’ve explained the essential design patterns (by the Gang of Four) with UML diagrams and real-world code examples.

Writing persistent layers using DLinq and Hibernate

By: John Charles (Juan Carlos) Olamendy Turruellas

Introduction

In this article, I will illustrate the principles, techniques and tools to develop applications using Linq to SQL and Hibernate technologies. As we know, ADO.NET is the standard data access library in Microsoft.NET and Linq to SQL is an extension to .NET languages to add native support for accessing and updating data by using traditional object operations following the object-oriented paradigm. Hibernate is a technology that enables the developer to manage (access and update) relational data in Java platform by defining persistent entities and mapping them to relational database tables by executing object operations.

ORM State of the art

Developing software is a complicated task and most significant development projects involve a relational database where CRUD operations are the corner stone of the solution. There are a lot of monolithic applications where the data access code and the data presentation are in one place. This is very difficult to develop and maintain, because the developer must understand how to write SQL code.

Then a new approach and several technologies supporting it come up. Object-relational mapping (ORM) is an approach to automatically connect the domain model of your application to a relational database system by using metadata as the descriptor of the object and data.

ORM solves the object-relational impendence mismatch problem (tabular data versus domain model) by replacing direct persistence related to the database access with high level object operations.

It’s very important to remark that there are many benefits to using ORM other than data access techniques, as shown:

  • ORM automatically mapping the object model to the back-end relational data using metadata. This simplifies the development and maintenance effort.
  • It requires a few lines of code to implement the data management logic by creating dynamic queries.
  • ORM technologies provide transparent caching objects, thus improving the overall performance of the system.

Getting started with Hibernate the examples

In order to illustrate the ORM concepts using Hibernate technology, we’re going to connect to a PostgreSQL database and create a table to persist the state of the Department business entity (see Listing 1).

CREATE TABLE department(

deptno integer NOT NULL,

deptname character varying(255),

“location” character varying(255),

CONSTRAINT department_pkey PRIMARY KEY (deptno)

)

WITH (OIDS=FALSE);

ALTER TABLE department OWNER TO john;

Listing 1

For the Hibernate code examples, we’re going to create a standalone console application in Java using NetBeans 6.5.

First step is to add a project using NetBeans 6.5 (see Figure 1).

Figure 1

Then set a name and the location for the project (see Figure 2).

Figure 2

In order to support Hibernate in the project, we need to add the Hibernate library to the project. Open the Projects windows and right-click on the Libraries node of the project and select “Add Library” option from the context menu. Then browse to the Hibernate library in the “Add Library” dialog box (see Figure 3).

Figure 3

The implementation strategy for this example is by following the top-down approach. That is, we’re going to configure the underlying Hibernate files for the connection to the back-end database system in this case the PostgreSQL database where the department table resides, then we’re going to generate the business entities’ classes and their underlying mapping using the NetBeans tools, as well as an utility class for doing common operations in Hibernate such as configuration loading and session creation.

Now let’s create the Hibernate configuration file using the wizards in NetBeans. The Hibernate configuration file (hibernate.cfg.xml) contains information about the database connection, resource mappings and other connections properties. This file is used by the Configuration class’ instances when to invoke the configure method to load this information for Hibernate to use.

Select the File | New File menu option. In the “New File” wizard, go to the Hibernate categories and select the “Hibernate Configuration File” in the “File Types” pane, and click on Next button (see Figure 4).

Figure 4

In the next page, leave it as shown in Figure 5 and click on the Next button.

Figure 5

In the “Select a Data Source” page, select a register data source to the department table in the PostgreSQL database and click on the Finish button.

The IDE creates the configuration file at the root of the context classpath of the application (in the Files window, WEB-INF/classes). In the Projects window the file is located in the <default package> source package. The configuration file contains information about a single database. If you plan to connect to multiple databases, you can create multiple configuration files in the project, one for each database servers, but by default the helper utility class will use the hibernate.cfg.xml file located in the root location.

If you expand the Libraries node in the Projects window you can see that the IDE added the required Hibernate JAR files and the PostgreSQL connector JAR (see Figure 6).

Figure 6

To use this Hibernate configuration we can create a helper class that handles startup and that accesses Hibernate’s SessionFactory class to obtain a Session object. The instances of this class call configure method, which loads the hibernate.cfg.xml configuration file from the classpath and then builds the SessionFactory to obtain the Session object.

Select the File | New File menu option. In the “New File” wizard, go to the Hibernate categories and select the “HibernateUtil.java” in the “File Types” pane, and click on Next button (see Figure 7).

Figure 7

In the “Name and Location” page, let’s enter the values as shown in the Figure 8.

Figure 8

For the examples, I’m going to use the POJO Department.java class definition. The “Hibernate Mapping Files and POJOs from a Database” wizard generates files based on the department table in the back-end database. When you use the wizard you select all the tables for which you want POJOs and mapping files and the IDE then generates the files for you based on the database tables and adds the mapping entries to hibernate.cfg.xml configuration file.

Select the File | New File menu option. In the “New File” wizard, go to the Hibernate categories and select the “Hibernate Mapping Files and POJOs from a Database” in the “File Types” pane, and click on Next button (see Figure 9).

Figure 9

In the “Name and Location” page, leave the data as shown in the Figure 10.

Figure 10

Add from the Available Table panel to Selected Table panel, the tables to be mapped to business entities  and click on the Next button(see Figure 11).

Figure 11

In the “Generation of Code” page, leave the data as shown in the Figure 12 and click on the Finish button.

Figure 12

Mapping classes to database tables can be accomplished through XML configuration file or using Java annotation. The most common used configuration file in Hibernate is the XML configuration file, and from this file Hibernate can generate skeletal source code for the persistence classes. The one-to-many and many-to-many relationships are also generated.

Let’s see the generated mapping (see Listing 2) and business entities (see Listing 3) for our example.

<?xml version=”1.0″?><!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN”

http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”&gt;

<!– Generated Jul 3, 2009 2:49:24 PM by Hibernate Tools 3.2.1.GA –>

<hibernate-mapping>

<class name=”hibernatetestjavaapp.Department” table=”department” schema=”human_resources”>

<id name=”deptno” type=”int”>

<column name=”deptno” />

<generator />

</id>

<property name=”deptname” type=”string”>

<column name=”deptname” length=”50″ not-null=”true” />

</property>

<property name=”location” type=”string”>

<column name=”location” length=”50″ />

</property>

</class>

</hibernate-mapping>

Listing 2

package hibernatetestjavaapp;// Generated Jul 3, 2009 2:49:18 PM by Hibernate Tools 3.2.1.GA

/**

* Department generated by hbm2java

*/

public class Department  implements java.io.Serializable {

private int deptno;

private String deptname;

private String location;

public Department() {

}

public Department(int deptno, String deptname) {

this.deptno = deptno;

this.deptname = deptname;

}

public Department(int deptno, String deptname, String location) {

this.deptno = deptno;

this.deptname = deptname;

this.location = location;

}

public int getDeptno() {

return this.deptno;

}

public void setDeptno(int deptno) {

this.deptno = deptno;

}

public String getDeptname() {

return this.deptname;

}

public void setDeptname(String deptname) {

this.deptname = deptname;

}

public String getLocation() {

return this.location;

}

public void setLocation(String location) {

this.location = location;

}

}

Listing 3

Now we’re ready to manage the department data using Hibernate from the main application. We’re going to follow a template for the creation of the queries (see Listing 4).

/** To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package hibernatetestjavaapp;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

/**

*

* @author root

*/

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package hibernatetestjavaapp;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

/**

*

* @author root

*/

public class Main {

/**

* @param args the command line arguments

*/

public static void main(String[] args)

{

SessionFactory factory = HibernateUtil.getSessionFactory();

Session session = factory.openSession();

try

{

session.getTransaction().begin();

//Here comes the Hibernate code to manage the data

session.getTransaction().commit();

}

catch (Throwable e)

{

if (session.getTransaction().isActive())

{

session.getTransaction().rollback();

}

System.out.println(e.getMessage());

}

session.close();

}

}

Listing 4

As you can see the HibernateUtil class invokes the getSessionFactory to create a new session factory and from this point, a new session is created. The SessionFactory is a heavyweight object, and there would be normally a single instance in the application. The Session has amount in common with JDBC Connection object, because in order to manipulate an object in a database system, we need to open a session first and then execute the underlying operations. The Session instances also manage caching functionality, lazy loading of objects, and watching for changes of the associated objects. The Transaction instances in Hibernate have the same responsibilities than their counterpart JDBC transactions. It’s required Hibernate operations to be enclosed in transactions.

Now let’s start to manipulate the department data using Session object in order to illustrate how to create, update, read and delete (CRUD) operations.

The create operation is implemented very simple. Just create an instance of the Department class and invoke the save method of the Session instance (see Listing 5). Creating an instance of a class does not automatically persist the object in the database. You need to explicitly save the object with a valid Hibernate session by using the active session’s save method.

If you are not able to determine the state of the object, then the active session’s saveOrUpdate method is used. In this case, Hibernate uses the identifier of the object to determine whether insert a new row or update an existing one.

/** To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package hibernatetestjavaapp;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

/**

*

* @author root

*/

public class Main {

/**

* @param args the command line arguments

*/

public static void main(String[] args)

{

SessionFactory factory = HibernateUtil.getSessionFactory();

Session session = factory.openSession();

try

{

session.getTransaction().begin();

//Here comes the Hibernate code to manage the data

Department objDepartment = new Department();

objDepartment.setDeptno(120);

objDepartment.setDeptname(“Human Resources”);

objDepartment.setLocation(“Philadelphia”);

session.save(objDepartment);

session.getTransaction().commit();

}

catch (Throwable e)

{

if (session.getTransaction().isActive())

{

session.getTransaction().rollback();

}

System.out.println(e.getMessage());

}

session.close();

}

}

Listing 5

In order to retrieve a department object from the database, we need to use HQL. HQL is conceptually similar to SQL with the exception that the names in the query refers to the names used in the mapping files. Let’s supposed we want to get the last created entity, so we need to create a HQL query where the identifier of this entity (in this case, the department number) is equal to a value.

In our example, we need to create a Query object (similar in functionality to PreparedStatement in JDBC), populate the parameter of the query with the appropriate value and display the result. We use the uniqueResult method because it is guaranteed to throw an exception if somehow the query identifies more than one department (see Listing 6).

There is another method to get data from the underlying database system using the active session’s load and get methods. These methods are straightforward taking as arguments the class type of the object to load and its identifier. The load method also takes a lock mode as argument to specify whether Hibernate should look into the cache for the object, and which database lock model to follow.

/** To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package hibernatetestjavaapp;

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

/**

*

* @author root

*/

public class Main {

/**

* @param args the command line arguments

*/

public static void main(String[] args)

{

SessionFactory factory = HibernateUtil.getSessionFactory();

Session session = factory.openSession();

try

{

session.getTransaction().begin();

//Here comes the Hibernate code to manage the data

Query objQuery = session.createQuery(“from Department where deptno=:deptno”);

objQuery.setInteger(“deptno”,120);

Department objDepartment = (Department)objQuery.uniqueResult();

System.out.println(“Department data. Name=”+objDepartment.getDeptname()+”, Location=”+objDepartment.getLocation());

session.getTransaction().commit();

}

catch (Throwable e)

{

if (session.getTransaction().isActive())

{

session.getTransaction().rollback();

}

System.out.println(e.getMessage());

}

session.close();

}

}

Listing 6

In the same way, we can create a query to get a list of departments which are located in New York by using the follow query “Query objQuery = session.createQuery(“from Department where location=:location”)” and the complete code is shown in the Listing 7.

/** To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package hibernatetestjavaapp;

import java.util.List;

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

/**

*

* @author root

*/

public class Main {

/**

* @param args the command line arguments

*/

public static void main(String[] args)

{

SessionFactory factory = HibernateUtil.getSessionFactory();

Session session = factory.openSession();

try

{

session.getTransaction().begin();

//Here comes the Hibernate code to manage the data

Query objQuery = session.createQuery(“from Department where location=:location”);

objQuery.setString(“location”,”New York”);

List<Department> arrDepartment = (List<Department>)objQuery.list();

for(Department objDepartment:arrDepartment)

{

System.out.println(“Department data. Name=”+objDepartment.getDeptname()+”, Location=”+objDepartment.getLocation());

}

session.getTransaction().commit();

}

catch (Throwable e)

{

if (session.getTransaction().isActive())

{

session.getTransaction().rollback();

}

System.out.println(e.getMessage());

}

session.close();

}

}

Listing 7

Now let’s suppose we want to update the data of a department entity (see Listing 8).

/** To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package hibernatetestjavaapp;

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

/**

*

* @author root

*/

public class Main {

/**

* @param args the command line arguments

*/

public static void main(String[] args)

{

SessionFactory factory = HibernateUtil.getSessionFactory();

Session session = factory.openSession();

try

{

session.getTransaction().begin();

//Here comes the Hibernate code to manage the data

Query objQuery = session.createQuery(“from Department where deptno=:deptno”);

objQuery.setInteger(“deptno”, 120);

Department objDepartment = (Department)objQuery.uniqueResult();

objDepartment.setLocation(“Detroit”);

session.getTransaction().commit();

}

catch (Throwable e)

{

if (session.getTransaction().isActive())

{

session.getTransaction().rollback();

}

System.out.println(e.getMessage());

}

session.close();

}

}

Listing 8

And finally to complete the CRUD operations, let’s explain how to delete this department entity (see Listing 9).

/** To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package hibernatetestjavaapp;

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

/**

*

* @author root

*/

public class Main {

/**

* @param args the command line arguments

*/

public static void main(String[] args)

{

SessionFactory factory = HibernateUtil.getSessionFactory();

Session session = factory.openSession();

try

{

session.getTransaction().begin();

//Here comes the Hibernate code to manage the data

Query objQuery = session.createQuery(“from Department where deptno=:deptno”);

objQuery.setInteger(“deptno”, 120);

Department objDepartment = (Department)objQuery.uniqueResult();

session.delete(objDepartment);

session.getTransaction().commit();

}

catch (Throwable e)

{

if (session.getTransaction().isActive())

{

session.getTransaction().rollback();

}

System.out.println(e.getMessage());

}

session.close();

}

}

Listing 9

It’s remarkable to say that the examples in the previous listings are based on persistent objects associated to an active connection. But in Hibernate, there the concept Detach objects which are objects with a representation (using mapping) in the databases, but changes to their states are not reflected in the database because they are not connected to the database. A detached object can be created by closing a session that it was associated with, or by evicting it from the session with a call to the active session’s evict method. In order to persist the changes of their states, the application must re-attach it to a valid Hibernate session by calling the load, refresh, merge, update and save methods on the new session with a reference to the detached object.

Paging in Hibernate is also straightforward. There are two methods on the Query interface for implementing paging, setFirstResult and setMaxResult methods. The setFirstResult method takes an integer that represents the first row in the result set starting with 0. The setMaxResults method specifies how many rows must be retrieved by the operation (see Listing 10).

Query qryDepartments = session.createQuery(“from Department”);qryDepartments.setFirstResult(1);

qryDepartments.setMaxResults(10);

Listing 10

In order to sort your query results, you will need to use the sort by clause. You can order the result by either ascending (asc) or descending (desc) (see Listing 11).

Query objQuery = session.createQuery(“from Department d where d.location=:location order by d.deptno desc”);

Listing 11

Hibernate also supports join operations. The operations supported by Hibernate are inner join, cross join, left outer join, right outer join, and full outer join.

Batch updates on Hibernate are very straightforward by using the executeUpdate method for executing SQL statements. This method returns an integer value that contains the number of rows affected by the operation. Let’s supposed that we want to raise 10% the salary to employees using a batch update, then we execute the following code (see Listing 12).

Query qryRaiseSalary = session.createQuery(“update Employee set salary=salary*1.1”);int nRowCount = qryRaiseSalary.executeUpdate();

Listing 12

Getting started with Linq to SQL the examples

In order to illustrate the ORM concepts using Linq to SQL technology, we’re going to create a console project in Microsoft Visual Studio.NET 2008. As the back-end database, we’re going to use the AdventureWorks database shipped with Microsoft SQL Server 2005/2008 as well as the Production.Product. We’re going to explain the operations on the data source using Linq to SQL similar as we do in the Hibernate cases.

Next step is to add a “Linq to SQL” artifact to the project by selecting the Project | Add New Item menu option (see Figure 13).

Figure 13

Modeling the business entities

After that, the Object Relational (O/R) designer is launched which enables to model the classes that represent the underlying data model and the methods for each stored procedure in the back-end database system. It will also create a strongly typed DataContext class (the ProductionDataContext class).

Unlike the DataSet/TableAdapter approach, when we’re defining the entity classes in the designer, we don’t have to specify the SQL queries; instead we have to focus on defining the entity classes and the mapping of these classes to the underlying data model. SQL to Linq framework will generate the appropriate SQL statements at runtime when you interact and use the business entities.

In order to create the business entities, the easy way is to open a database connection in the Server Explorer windows, select the tables and views you want to model and map from it, and drag and drop them onto the designer surface.

In this case, drag and drop the Production.Product table on the designer surface (see Figure 14). After that you can see the Product business entity.

Figure 14

Let’s see a part of the generated Product class mapping back to the Production.Product table on the data source by exposing properties that represent the fields and the relationships (see Listing 13).

      [Table(Name=”Production.Product”)]public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged

{

private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

private int _ProductID;

private string _Name;

private string _ProductNumber;

private bool _MakeFlag;

private bool _FinishedGoodsFlag;

private string _Color;

private short _SafetyStockLevel;

private short _ReorderPoint;

private decimal _StandardCost;

private decimal _ListPrice;

private string _Size;

private string _SizeUnitMeasureCode;

private string _WeightUnitMeasureCode;

private System.Nullable<decimal> _Weight;

private int _DaysToManufacture;

private string _ProductLine;

private string _Class;

private string _Style;

private System.Nullable<int> _ProductSubcategoryID;

private System.Nullable<int> _ProductModelID;

private System.DateTime _SellStartDate;

private System.Nullable<System.DateTime> _SellEndDate;

private System.Nullable<System.DateTime> _DiscontinuedDate;

private System.Guid _rowguid;

private System.DateTime _ModifiedDate;

#region Extensibility Method Definitions

partial void OnLoaded();

partial void OnValidate(System.Data.Linq.ChangeAction action);

partial void OnCreated();

partial void OnProductIDChanging(int value);

partial void OnProductIDChanged();

partial void OnNameChanging(string value);

partial void OnNameChanged();

partial void OnProductNumberChanging(string value);

partial void OnProductNumberChanged();

partial void OnMakeFlagChanging(bool value);

partial void OnMakeFlagChanged();

partial void OnFinishedGoodsFlagChanging(bool value);

partial void OnFinishedGoodsFlagChanged();

partial void OnColorChanging(string value);

partial void OnColorChanged();

partial void OnSafetyStockLevelChanging(short value);

partial void OnSafetyStockLevelChanged();

partial void OnReorderPointChanging(short value);

partial void OnReorderPointChanged();

partial void OnStandardCostChanging(decimal value);

partial void OnStandardCostChanged();

partial void OnListPriceChanging(decimal value);

partial void OnListPriceChanged();

partial void OnSizeChanging(string value);

partial void OnSizeChanged();

partial void OnSizeUnitMeasureCodeChanging(string value);

partial void OnSizeUnitMeasureCodeChanged();

partial void OnWeightUnitMeasureCodeChanging(string value);

partial void OnWeightUnitMeasureCodeChanged();

partial void OnWeightChanging(System.Nullable<decimal> value);

partial void OnWeightChanged();

partial void OnDaysToManufactureChanging(int value);

partial void OnDaysToManufactureChanged();

partial void OnProductLineChanging(string value);

partial void OnProductLineChanged();

partial void OnClassChanging(string value);

partial void OnClassChanged();

partial void OnStyleChanging(string value);

partial void OnStyleChanged();

partial void OnProductSubcategoryIDChanging(System.Nullable<int> value);

partial void OnProductSubcategoryIDChanged();

partial void OnProductModelIDChanging(System.Nullable<int> value);

partial void OnProductModelIDChanged();

partial void OnSellStartDateChanging(System.DateTime value);

partial void OnSellStartDateChanged();

partial void OnSellEndDateChanging(System.Nullable<System.DateTime> value);

partial void OnSellEndDateChanged();

partial void OnDiscontinuedDateChanging(System.Nullable<System.DateTime> value);

partial void OnDiscontinuedDateChanged();

partial void OnrowguidChanging(System.Guid value);

partial void OnrowguidChanged();

partial void OnModifiedDateChanging(System.DateTime value);

partial void OnModifiedDateChanged();

#endregion

public Product()

{

OnCreated();

}

[Column(Storage=”_ProductID”, AutoSync=AutoSync.OnInsert, DbType=”Int NOT NULL IDENTITY”, IsPrimaryKey=true, IsDbGenerated=true)]

public int ProductID

{

get

{

return this._ProductID;

}

set

{

if ((this._ProductID != value))

{

this.OnProductIDChanging(value);

this.SendPropertyChanging();

this._ProductID = value;

this.SendPropertyChanged(“ProductID”);

this.OnProductIDChanged();

}

}

}

[Column(Storage=”_Name”, DbType=”NVarChar(50) NOT NULL”, CanBeNull=false)]

public string Name

{

get

{

return this._Name;

}

set

{

if ((this._Name != value))

{

this.OnNameChanging(value);

this.SendPropertyChanging();

this._Name = value;

this.SendPropertyChanged(“Name”);

this.OnNameChanged();

}

}

}

……

Listing 13

You see that the Product class is decorated with the Table attribute pointing to the underlying database table. As well as this class inherits from INotifyPropertyChanging and INotifyPropertyChanged interfaces which are used by the DataContext based class to track when data is dirty or need to be refreshed. Then every attribute of the Product class is decorated by the Column attribute. The Column attribute establishes the primary key, if it’s a surrogate key (auto-generated), as well as the data type and underlying information such as nullability and other constraint checks.

The other important class is the DataContext based class which is the core channel used to communicate with the data source. It contains the properties and methods for interacting with the database tables added on the designer (see Listing 14). This class is decorated with the System.Data.Linq.DatabaseAttributte attribute to establish which database to connect on the SQL server.

      [System.Data.Linq.Mapping.DatabaseAttribute(Name=”AdventureWorks”)]public partial class ProductionDataContext : System.Data.Linq.DataContext

{

private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();

#region Extensibility Method Definitions

partial void OnCreated();

partial void InsertProduct(Product instance);

partial void UpdateProduct(Product instance);

partial void DeleteProduct(Product instance);

#endregion

public ProductionDataContext() :

base(global::LinqToSqlTestConsApp.Properties.Settings.Default.AdventureWorksConnectionString, mappingSource)

{

OnCreated();

}

public ProductionDataContext(string connection) :

base(connection, mappingSource)

{

OnCreated();

}

public ProductionDataContext(System.Data.IDbConnection connection) :

base(connection, mappingSource)

{

OnCreated();

}

public ProductionDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :

base(connection, mappingSource)

{

OnCreated();

}

public ProductionDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :

base(connection, mappingSource)

{

OnCreated();

}

public System.Data.Linq.Table<Product> Products

{

get

{

return this.GetTable<Product>();

}

}

}

Listing 14

The final aspect is the DBML file which contains the connection string, the provider information and the metadata mappings to the Production.Product table (see Listing 15).

<?xml version=”1.0″ encoding=”utf-8″?><Database Name=”AdventureWorks” xmlns=”http://schemas.microsoft.com/linqtosql/dbml/2007″&gt;

<Connection Mode=”AppSettings” ConnectionString=”Data Source=remote_server;Initial Catalog=AdventureWorks;Integrated Security=True” SettingsObjectName=”LinqToSqlTestConsApp.Properties.Settings” SettingsPropertyName=”AdventureWorksConnectionString” Provider=”System.Data.SqlClient” />

<Table Name=”Production.Product” Member=”Products”>

<Type Name=”Product”>

<Column Name=”ProductID” Type=”System.Int32″ DbType=”Int NOT NULL IDENTITY” IsPrimaryKey=”true” IsDbGenerated=”true” CanBeNull=”false” />

<Column Name=”Name” Type=”System.String” DbType=”NVarChar(50) NOT NULL” CanBeNull=”false” />

<Column Name=”ProductNumber” Type=”System.String” DbType=”NVarChar(25) NOT NULL” CanBeNull=”false” />

<Column Name=”MakeFlag” Type=”System.Boolean” DbType=”Bit NOT NULL” CanBeNull=”false” />

<Column Name=”FinishedGoodsFlag” Type=”System.Boolean” DbType=”Bit NOT NULL” CanBeNull=”false” />

<Column Name=”Color” Type=”System.String” DbType=”NVarChar(15)” CanBeNull=”true” />

<Column Name=”SafetyStockLevel” Type=”System.Int16″ DbType=”SmallInt NOT NULL” CanBeNull=”false” />

<Column Name=”ReorderPoint” Type=”System.Int16″ DbType=”SmallInt NOT NULL” CanBeNull=”false” />

<Column Name=”StandardCost” Type=”System.Decimal” DbType=”Money NOT NULL” CanBeNull=”false” />

<Column Name=”ListPrice” Type=”System.Decimal” DbType=”Money NOT NULL” CanBeNull=”false” />

<Column Name=”Size” Type=”System.String” DbType=”NVarChar(5)” CanBeNull=”true” />

<Column Name=”SizeUnitMeasureCode” Type=”System.String” DbType=”NChar(3)” CanBeNull=”true” />

<Column Name=”WeightUnitMeasureCode” Type=”System.String” DbType=”NChar(3)” CanBeNull=”true” />

<Column Name=”Weight” Type=”System.Decimal” DbType=”Decimal(8,2)” CanBeNull=”true” />

<Column Name=”DaysToManufacture” Type=”System.Int32″ DbType=”Int NOT NULL” CanBeNull=”false” />

<Column Name=”ProductLine” Type=”System.String” DbType=”NChar(2)” CanBeNull=”true” />

<Column Name=”Class” Type=”System.String” DbType=”NChar(2)” CanBeNull=”true” />

<Column Name=”Style” Type=”System.String” DbType=”NChar(2)” CanBeNull=”true” />

<Column Name=”ProductSubcategoryID” Type=”System.Int32″ DbType=”Int” CanBeNull=”true” />

<Column Name=”ProductModelID” Type=”System.Int32″ DbType=”Int” CanBeNull=”true” />

<Column Name=”SellStartDate” Type=”System.DateTime” DbType=”DateTime NOT NULL” CanBeNull=”false” />

<Column Name=”SellEndDate” Type=”System.DateTime” DbType=”DateTime” CanBeNull=”true” />

<Column Name=”DiscontinuedDate” Type=”System.DateTime” DbType=”DateTime” CanBeNull=”true” />

<Column Name=”rowguid” Type=”System.Guid” DbType=”UniqueIdentifier NOT NULL” CanBeNull=”false” />

<Column Name=”ModifiedDate” Type=”System.DateTime” DbType=”DateTime NOT NULL” CanBeNull=”false” />

</Type>

</Table>

</Database>

Listing 15

Linq to SQL enables modeling stored procedures as methods of the DataContext class. Let’s suppose we need to return a list of a product based on a given product subcategory id (see Listing 15).

create procedure spSelectProductBySubcategory@pSubcategoryId int

as

begin

select *

from Production.Product

where ProductSubcategoryID=@pSubcategoryId;

end;

go

Listing 16

Now we can use the Server Explorer windows to drag and drop this stored procedure on the in the right pane of the designer surface (see Figure 3).

Figure 15

Executing CRUD operations using Linq to SQL

Now that we have defined our object model representing the data model, we are ready to execute CRUD (create, read, update, delete) operations over the relational data schema through the object model in C#.

The first example is to display a list of the products in the database (see Listing 17). The first step is to create a ProductionDataContext instance and then develop a Linq query similar to SQL to return the list of products based on the product makeflag equals to true. In this case the where clause enables filtering features on the query. Notice that the filter expression follows the C# syntax rather the SQL syntax, in this case, the comparison uses the “==” logical operator rather than the “=” logical operator. The result is stored in the objResultset object which is defined by using the var keyword to define a strongly type compile time variable reference by inferring the type at compile time. You can also see that a relational projection operation is achieved by using the new features of C# language such as anonymous type and object initialization in order to return a subset of the fields. Anonymous types enable defining an inline class without having to explicitly declare it.

using System;using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace LinqToSqlTestConsApp

{

public class Program

{

static void Main(string[] args)

{

ProductionDataContext objDataContext = new ProductionDataContext();

var objResultset = from objProduct in objDataContext.Products

where objProduct.MakeFlag == true

select new { ProductId= objProduct.ProductID, Number = objProduct.ProductNumber, Name= objProduct.Name, Color = objProduct.Color };

foreach (var objProduct in objResultset)

{

System.Console.WriteLine(“ProductId={0}, Product Number={1}, Name={2}, Color={3}”, objProduct.ProductId, objProduct.Number, objProduct.Name, objProduct.Color);

}

System.Console.WriteLine(“Press any key to finish …”);

System.Console.ReadKey();

}

}

}

Listing 17

Now let’s create a new product item (see Listing 19).

using System;using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace LinqToSqlTestConsApp

{

public class Program

{

static void Main(string[] args)

{

ProductionDataContext objDataContext = new ProductionDataContext();

Product objProduct = new Product();

objProduct.Name = “Ad Race 11”;

objProduct.ProductNumber = “AR-53323”;

objProduct.MakeFlag = true;

objProduct.FinishedGoodsFlag = true;

objProduct.SafetyStockLevel = 100;

objProduct.ReorderPoint = 750;

objProduct.StandardCost = 0;

objProduct.DaysToManufacture = 0;

objProduct.ProductSubcategoryID = 22;

objProduct.ProductModelID = 31;

objProduct.SellStartDate = DateTime.Now;

objProduct.ModifiedDate = DateTime.Now;

objDataContext.Products.InsertOnSubmit(objProduct);

objDataContext.SubmitChanges();

System.Console.WriteLine(“Press any key to finish …”);

System.Console.ReadKey();

}

}

}

Listing 19

When you execute the SubmitChanges method of the DataContext, then all the updates to the data are wrapped in a transaction, so the underlying relational database will never be in an inconsistent state after updating the changes.

If no transaction is already in the scope, then the SubmitChanges method will automatically start a database transaction. You can also define your transaction scope using the TransactionScope object. This makes very easy to integrate your transactional code with existing one.

In the following step, we’re going to retrieve the newly created product item and update its Name field value (see Listing 20).

using System;using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace LinqToSqlTestConsApp

{

public class Program

{

static void Main(string[] args)

{

ProductionDataContext objDataContext = new ProductionDataContext();

var objProduct = (from objProd in objDataContext.Products

where objProd.Name == “Ad Race 11”

select objProd).First();

objProduct.Name = “Ad Race 111”;

objDataContext.SubmitChanges();

System.Console.WriteLine(“Press any key to finish …”);

System.Console.ReadKey();

}

}

}

Listing 20

The last CRUD operation to test is the delete operation. Now we’re going to delete the created product item (see Listing 21).

using System;using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace LinqToSqlTestConsApp

{

public class Program

{

static void Main(string[] args)

{

ProductionDataContext objDataContext = new ProductionDataContext();

var objProduct = (from objProd in objDataContext.Products

where objProd.Name == “Ad Race 111”

select objProd).First();

objDataContext.Products.DeleteOnSubmit(objProduct);

objDataContext.SubmitChanges();

System.Console.WriteLine(“Press any key to finish …”);

System.Console.ReadKey();

}

}

}

Listing 21

Now let’s call for the stored procedure defined in the Listing 1 (see Listing 6).

ProductionDataContext objDataContext = new ProductionDataContext();var arrProduct = objDataContext.spSelectProductBySubcategory(1);

Listing 22

In order to implement database paging in Linq to SQL, we need to use the Skip and Take methods (see Listing 7).

ProductionDataContext objDataContext = new ProductionDataContext();var objProductSubcategory = (from objProdSubc in objDataContext.ProductSubcategories

where objProdSubc.ProductSubcategoryID == 2

select objProdSubc).Skip(200).Take(10);

Listing 23

Conclusion

In this article, I’ve covered the principles, techniques and tools to write persistent layers using DLinq and Hibernate technologies.

Scalability

Scalability is the system’s ability to accept higher load (to grow) without degradation is called scalability. It´s one quality attribute to take in consideration in the architectural definition of enterprise applications. From my perspective, it´s one of the most important because bad architectural decisions that impact negatively in product scalability; it also impacts negatively in the growth of the product as well as in the growth of the enterprise which supports its business process in the underlying enterprise application. So it´s important to follow good architectural decisions on the product design to impact positively on the scalability.

Scalable hardware or software can expand to support increasing workloads. This capability allows computer equipment and software programs to grow over time, rather than needing to be replaced. Scalable software typically refers to business applications that can adapt to support an increasing amount of data or a growing number of users.

In order to impact positively the scalability of an enterprise application, we need to follow best practices. I will explain a bunch of techniques that I´ve applied during my career as a software architect to support correctly software scalability as well as I´ve confirmed by researching about this topic on these days.

The rationale behind the techniques is to split your application logic into several modules and sub-systems according to the principle of separation of responsability and the premise that if you can´t split it, you can´t scale it. Related pieces of functionality must belong together, while unrelated pieces of functionality must belong apart. Splitting your solution artifacts assures that the workload can be broken down into manageable units. These components must be decoupled and communicate each other asynchronously as much as possible.

At the application tier is implemented by the following techniques:

  • applications in different application pool. This allows scaling each pool of processes and servers, according to the demand and resource consumption. Applications are further divided by sub-systems and components on separated processes or set of nodes (distributed processing)
  • decoupling the components in different modules and sub-systems according to its responsability in the solution
  • avoid synchronous communication (coupling) between the components as much as possible. Once the components are decoupled, then these components must communicate each other using asynchronous mechanisms using queues, multicast messages, ESB, batch process, so they can be scaled independently. The rationale is that if component A calls to component B synchronously (they´re tighly coupled), if you need to scale component A, you must also scale component B. Equally, this coupling impacts negatively on the availability of the system (if component B is not available, then component A may fail in its behavior)
  • farm of applications using clustering and load-balancer techniques (if we need more processing power, we just add another node)
  • business logic optimization (refactoring)
  • application hosting environment tuning
  • caching techniques (memcache)
  • avoid distributed transactions

At the database tier is implemented by the following techniques:

  • sharding (partitioning) the data horizontally and vertically
  • running each partition on separated RDBMS or set of nodes
  • farm of RDBMS using clustering and load-balancer techniques (if we need more processing power, we just add another node)
  • optimization techniques (DBMS tuning, indexes)

At the infrastructure tier is implemented by the following techniques:

  • OS tuning
  • Storage system tuning
  • Hardware optimization

In this article, I´ve covered the key concepts and principles of scalability in enterprise applications as well as a bunch of techniques that I´ve applied to impact positively in this important quality attribute.

Uploading files using ExtJS and ASP.NET MVC

Introduction

Recently I’ve been researching a lot about the use of ExtJS JavaScript framework along with ASP.NET MVC to build very rich Web applications. I’m very comfortable and the more I read, the more I like ExtJS along with ASP.NET MVC, so I’m digging more and more about finding new applications of ExtJS. In this article, I want to talk about uploading files using ExtJS and ASP.NET MVC.

Getting started with the solution

The first step is to create a MVC application in Visual Studio.NET 2008 (see Figure 1).

Figure 1

Next step is to add the ExtJS library files to the ASP.NET MVC project. Let’s add the following files and directories into the Scripts directory: ext-all.js, ext-base.js and resources directory (see Figure 2).

Figure 2

In order to implement the logic to upload files into our site, we’re going to use an extension to the TextField component. This new component is not included in the ExtJS distribution. Let’s create a file named fileuploadfield.js inside the ext directory and a file named fileuploadfield.css inside the ext/resources/css directory (see Figure 3).

Figure 3

Now let’s include the ExtJS library files in our solution by going to the Site.Master page and adding the references to the ExtJS files inside the head element (highlighted in yellow in the Listing 1). As well, we need to add a <asp:ContentPlaceHolder> tag element as container of the customized JavaScript and CSS code for each page (highlighted in green in the Listing 1).

<head runat=”server”>

<title><asp:ContentPlaceHolder ID=”TitleContent” runat=”server” /></title>

<link href=”../../Content/Site.css” rel=”stylesheet” type=”text/css” />

<!– Include the ExtJS framework –>

<link href=”../../Scripts/ext/resources/css/ext-all.css” rel=”stylesheet” type=”text/css” />

<script type=”text/javascript” src=”../../Scripts/ext/ext-base.js”></script>

<script type=”text/javascript” src=”../../Scripts/ext/ext-all.js”></script>

<!– Placeholder to include CSS and JS files customized for each page –>

<asp:ContentPlaceHolder ID=”Scripts” runat=”server” />

</head>

Listing 1

Now we need to add code for the fileuploadfield element. The JavaScript code is shown in the Listing 2.

/*!

* Ext JS Library 3.0+

* Copyright(c) 2006-2009 Ext JS, LLC

* licensing@extjs.com

* http://www.extjs.com/license

*/

Ext.ns(‘Ext.ux.form’);

 

/**

* @class Ext.ux.form.FileUploadField

* @extends Ext.form.TextField

* Creates a file upload field.

* @xtype fileuploadfield

*/

Ext.ux.form.FileUploadField = Ext.extend(Ext.form.TextField,  {

/**

* @cfg {String} buttonText The button text to display on the upload button (defaults to

* ‘Browse…’).  Note that if you supply a value for {@link #buttonCfg}, the buttonCfg.text

* value will be used instead if available.

*/

buttonText: ‘Browse…’,

/**

* @cfg {Boolean} buttonOnly True to display the file upload field as a button with no visible

* text field (defaults to false).  If true, all inherited TextField members will still be available.

*/

buttonOnly: false,

/**

* @cfg {Number} buttonOffset The number of pixels of space reserved between the button and the text field

* (defaults to 3).  Note that this only applies if {@link #buttonOnly} = false.

*/

buttonOffset: 3,

/**

* @cfg {Object} buttonCfg A standard {@link Ext.Button} config object.

*/

 

// private

readOnly: true,

 

/**

* @hide

* @method autoSize

*/

autoSize: Ext.emptyFn,

 

// private

initComponent: function(){

Ext.ux.form.FileUploadField.superclass.initComponent.call(this);

 

this.addEvents(

/**

* @event fileselected

* Fires when the underlying file input field’s value has changed from the user

* selecting a new file from the system file selection dialog.

* @param {Ext.ux.form.FileUploadField} this

* @param {String} value The file value returned by the underlying file input field

*/

‘fileselected’

);

},

 

// private

onRender : function(ct, position){

Ext.ux.form.FileUploadField.superclass.onRender.call(this, ct, position);

 

this.wrap = this.el.wrap({cls:’x-form-field-wrap x-form-file-wrap’});

this.el.addClass(‘x-form-file-text’);

this.el.dom.removeAttribute(‘name’);

 

this.fileInput = this.wrap.createChild({

id: this.getFileInputId(),

name: this.name||this.getId(),

cls: ‘x-form-file’,

tag: ‘input’,

type: ‘file’,

size: 1

});

 

var btnCfg = Ext.applyIf(this.buttonCfg || {}, {

text: this.buttonText

});

this.button = new Ext.Button(Ext.apply(btnCfg, {

renderTo: this.wrap,

cls: ‘x-form-file-btn’ + (btnCfg.iconCls ? ‘ x-btn-icon’ : ”)

}));

 

if(this.buttonOnly){

this.el.hide();

this.wrap.setWidth(this.button.getEl().getWidth());

}

 

this.fileInput.on(‘change’, function(){

var v = this.fileInput.dom.value;

this.setValue(v);

this.fireEvent(‘fileselected’, this, v);

}, this);

},

 

// private

getFileInputId: function(){

return this.id + ‘-file’;

},

 

// private

onResize : function(w, h){

Ext.ux.form.FileUploadField.superclass.onResize.call(this, w, h);

 

this.wrap.setWidth(w);

 

if(!this.buttonOnly){

var w = this.wrap.getWidth() – this.button.getEl().getWidth() – this.buttonOffset;

this.el.setWidth(w);

}

},

 

// private

onDestroy: function(){

Ext.ux.form.FileUploadField.superclass.onDestroy.call(this);

Ext.destroy(this.fileInput, this.button, this.wrap);

},

 

 

// private

preFocus : Ext.emptyFn,

 

// private

getResizeEl : function(){

return this.wrap;

},

 

// private

getPositionEl : function(){

return this.wrap;

},

 

// private

alignErrorIcon : function(){

this.errorIcon.alignTo(this.wrap, ‘tl-tr’, [2, 0]);

}

 

});

 

Ext.reg(‘fileuploadfield’, Ext.ux.form.FileUploadField);

 

// backwards compat

Ext.form.FileUploadField = Ext.ux.form.FileUploadField;

Listing 2. Content of the fileuploadfield.js file

The content of the styles for the uploadfilefield is shown in the Listing 3.

/*!

* Ext JS Library 3.0+

* Copyright(c) 2006-2009 Ext JS, LLC

* licensing@extjs.com

* http://www.extjs.com/license

*/

/*

* FileUploadField component styles

*/

.x-form-file-wrap {

position: relative;

height: 22px;

}

.x-form-file-wrap .x-form-file {

position: absolute;

right: 0;

-moz-opacity: 0;

filter:alpha(opacity: 0);

opacity: 0;

z-index: 2;

height: 22px;

}

.x-form-file-wrap .x-form-file-btn {

position: absolute;

right: 0;

z-index: 1;

}

.x-form-file-wrap .x-form-file-text {

position: absolute;

left: 0;

z-index: 3;

color: #777;

}

Listing 3. Content of the fileuploadfield.cs file

Next step is to add a controller and a default view to the ASP.NET MVC solution (see Figure 4).

Figure 4

 

Right-click on the Index action method of the UploadFileController class and select Add View option from the context menu (see Figure 5).

Figure 5

Now let’s create another JS file in the Scripts directory with necessary JS code to create a form and an uploadfilefield element. The code for the UploadFileFieldFom.js is shown in the Listing 4. In this file, you can see that we are creating a FormPanel object which will be rendered into div element named fileupload. In this case, the fileUpload property is set to true. The items array contains just the fileuploadfile element. The name property in the fileuploadfile element is the parameter with the information of the file to be uploaded to the server. The buttons property contains the buttons of the forms and its underlying action handler. In this code, the most important thing is the url property which points in this case to uploadfile/upload. The waitMsg is the message to be shown to the user. The success property references to a function to be called when then everything is OK while the failure property references a function to be called when an error occurs.

Ext.onReady(function()

{

var form = new Ext.FormPanel({

renderTo: ‘fileupload’,

fileUpload: true,

width: 400,

frame: true,

title: ‘File Upload’,

bodyStyle: ‘padding: 10px 10px 0 10px;’,

labelWidth: 50,

items: [{

xtype: ‘fileuploadfield’,

emptyText: ‘Select a file’,

fieldLabel: ‘File’,

name: ‘file’,

buttonText: ‘Choose a file’

}],

buttons: [{

text: ‘Save’,

handler: function()

{

if (form.getForm().isValid())

{

form.getForm().submit({

url: ‘uploadfile/upload’,

waitMsg: ‘Please, wait while uploading a file…’,

success: function(form, o)

{

Ext.Msg.show({

title: ‘Result’,

msg: o.result.result,

buttons: Ext.Msg.OK,

icon: Ext.Msg.INFO

});

},

failure: function(form, o)

{

Ext.Msg.show({

title: ‘Result’,

msg: o.result.error,

buttons: Ext.Msg.OK,

icon: Ext.Msg.ERROR

});

}

});

}

}

}]

});

});

Listing 4. Content in the UploadFileFieldFom.js file

Let’s include the fileuploadfield.css, fileuploadfield.js and uploadfilefieldfom.js (highlighted in yellow) files as well as the div (highlighted in green) element (where the form will be rendered) into the Index.aspx page (see Listing 5).

<%@ Page Title=”” Language=”C#” MasterPageFile=”~/Views/Shared/Site.Master” Inherits=”System.Web.Mvc.ViewPage” %>

 

<asp:Content ID=”Content1″ ContentPlaceHolderID=”TitleContent” runat=”server”>

Index

</asp:Content>

 

<asp:Content ID=”Content2″ ContentPlaceHolderID=”MainContent” runat=”server”>

 

<h2>Index</h2>

<div id=”fileupload”>

</div>

</asp:Content>

 

<asp:Content ID=”Content3″ ContentPlaceHolderID=”Scripts” runat=”server”>

<link href=”../../Scripts/ext/resources/css/fileuploadfield.css” rel=”stylesheet” type=”text/css” />

<script type=”text/javascript” src=”../../Scripts/ext/fileuploadfield.js”></script>

<script type=”text/javascript” src=”../../Scripts/uploadfilefieldfom.js”></script>

</asp:Content>

Listing 5

As you know from the configuration of the fileuploadfield JS element, we’re going to execute a POST HTTP request to the url uploadfile/upload, so we need to implement the Upload action method on the UploadFileController.css class. This action method must be annotated with AcceptVerbsAttribute attribute HttpVerbs.Post value. Then we need to check if the file was uploaded successfully by checking the Request.Files[“file”] where the file key was setup in the ExtJS fileuploadfield component. Finally, we return a message using JSON format with error or success information (see Listing 6).

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Mvc.Ajax;

 

namespace UploadFiles_ExtJS_MvcApp.Controllers

{

public class UploadFileController : Controller

{

//

// GET: /UploadFile/

 

public ActionResult Index()

{

return View();

}

 

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Upload()

{

HttpPostedFileBase postedFile = Request.Files[“file”];

JsonResult objResult = null;

if (postedFile != null)

{

objResult = new JsonResult()

{

ContentType = “text/html”,

Data = new { success = true, result = “File uploaded successfully” }

};

}

else

{

objResult = new JsonResult()

{

ContentType = “text/html”,

Data = new { success = false, error = “File uploaded error” }

};

}

 

return objResult;

}

 

}

}

Listing 6

Let’s run the solution and see the results (see Figure 6).

Figure 6

Conclusion

In this article, I’ve illustrated how to upload files using ExtJS and ASP.NET MVC. Now you can apply this solution to your own business problems.

Load data on forms with ExtJS and ASPNET MVC

Introduction

Now I’ve followed researching a lot about ExtJS support for rich Internet applications and nice user experience and the more I read about this library, the more I like it. S, I’ve decided to write this article to illustrate how to create an edit form in ExtJS and integrated with ASP.NET MVC framework. After researching a lot in order to know how to get request parameter from the URL string using Ext libraries, I’ve developed my own solution.

Getting started with the solution

We’re going to implement the Edit Employee use case for a Human Resources Management system. The Edit Employee use case description is as follows: A screen prompts the user to update valid information (whether optional or mandatory) for an existing employee such as employee identifier, full name, address, age, salary and department. The screen shows employee information by the employee identifier passed by the screen parameters.

This use case fits well to illustrate the main artifacts and steps for a solution using ExtJS and ASP.NET. The implementation strategy for this use case is to create an ExtJS form on the client-side to load data and send the updated data to the server to be processed. The server-side application is developed using ASP.NET MVC framework. The persistence layer will be Linq to represent business entities and to persist data to the database system. As the development environment we’re going to use Microsoft Visual Studio.NET 2008 and as the database system Microsoft SQL Server 2005/2008.

Open Visual Studio.NET 2008 and create an ASP.NET MVC application (see Figure 1).

Figure 1

Next step is to create the database schema for the solution. Our schema will contain two entities: employee and department. Let’s create the HumanResources database and the underlying tables and its constraints in order to maintain the data integrity. For this example, we also need some data on the tables (see Listing 1).

 

create table department

(

deptno varchar(20) primary key,

deptname varchar(50) not null,

location varchar(50)

);

create unique index undx_department_deptname on department(deptname);

 

insert into department

values(‘HQ-200′,’Headquarter-NY’,’New York’);

insert into department

values(‘HR-200′,’Human Resources-NY’,’New York’);

insert into department

values(‘OP-200′,’Operations-NY’,’New York’);

insert into department

values(‘SL-200′,’Sales-NY’,’New York’);

insert into department

values(‘HR-300′,’Human Resources-MD’,’Maryland’);

insert into department

values(‘OP-300′,’Operations-MD’,’Maryland’);

insert into department

values(‘SL-300′,’Sales-MD’,’Maryland’);

 

create table employee

(

empno varchar(20) primary key,

fullname varchar(50) not null,

address varchar(120),

age int,

salary numeric(8,2) not null,

deptno varchar(20) not null,

constraint fk_employee_department_belong_rltn foreign key(deptno)

references department(deptno)

);

create unique index undx_employee_fullname on employee(fullname);

 

insert into employee

values(‘EMP-0001′,’John Doe’,’20 Madison St.’, 32, 3000.99, ‘HQ-200’);

Listing 1

Then let’s create a Linq to SQL Classes item inside the Model folder to define the structure of the entities and the persistence mechanism. The object definition in Linq to SQL is shown in the Figure 2.

Figure 2

Next step is to develop the EmployeeRepository class to manage the data access logic to the employee table (CRUD operations). Regarding to our use case, we only need to implement the read by employee identifier and update operations (see Listing 2).

using System;

using System.Data;

using System.Configuration;

using System.Linq;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Xml.Linq;

 

namespace LoadDataOnForm_ExtJS_ASPNETMVC.Models

{

public class EmployeeRepository

{

private HumanResourcesDataContext _ctxHumanResources = new HumanResourcesDataContext();

 

public employee FindByKey(string empno)

{

return (from emp in this._ctxHumanResources.employees

where emp.empno == empno

select emp).SingleOrDefault();

}

 

public void Update(employee employee)

{

var origEmployee = this.FindByKey(employee.empno);

origEmployee.fullname = employee.fullname;

origEmployee.address = employee.address;

origEmployee.age = employee.age;

origEmployee.salary = employee.salary;

origEmployee.deptno = employee.deptno;

 

this._ctxHumanResources.SubmitChanges();

}

}

}

Listing 2

Now that we have defined the business logic’s artifacts, that is the business entities and the services that process the entities, we need to move onto the presentation layer. The implementation strategy for the presentation layer is ASP.NET MVC. MVC stands for model-view-controller. We have worked on the model piece of the architecture before. Now let’s define another important piece of the architecture: the controller.

Right-click on the Controllers folder in the Solution Explorer window and select Add|Controller option from the context menu. Set EmployeeController as the name (see Figure 3).

Figure 3

Now let’s go to the presentation piece to define the graphical interface using ExtJS JavaScript library. The first step is to download and copy the distribution of ExtJS inside the Scripts directory. For our solution, we only need ext-all.js file, ext-base.js file and the resources directory (see Figure 4).

Figure 4

Now let’s include this library in our project. For this purpose, let’s go to the Site.Master page and adding the references to the ExtJS files inside the head HTML element (highlighted in yellow in the Figure 14). As well, we need to add a <asp:ContentPlaceHolder> tag element as container of the customized JavaScript and CSS code for each page (highlighted in green in the Listing 5).

<head runat=”server”>

<title><asp:ContentPlaceHolder ID=”TitleContent” runat=”server” /></title>

<link href=”../../Content/Site.css” rel=”stylesheet” type=”text/css” />

 

<!– Include the ExtJS framework –>

<link href=”../../Scripts/ext/resources/css/ext-all.css” rel=”stylesheet” type=”text/css” />

<script type=”text/javascript” src=”../../Scripts/ext/ext-base.js”></script>

<script type=”text/javascript” src=”../../Scripts/ext/ext-all.js”></script>

<!– Placeholder to include CSS and JS files customized for each page –>

<asp:ContentPlaceHolder ID=”Scripts” runat=”server” />

</head>

Figure 5

Now let’s add the view to present the form to edit the data related to one employee. Go to the EmployeeController controller and right-click on the Index action method and select Add View option from the context menu. Click on the Add button on Add View dialog box (see Figure 6).

Figure 6

In order to implement the ExtJS form, we need to add a JavaScript file to the Scripts directory (see Figure 7).

Figure 7

Then include the JavaScript file and add a div element (with id=employeeeditform) into the Index.aspx view (see Listing 4).

<%@ Page Title=”” Language=”C#” MasterPageFile=”~/Views/Shared/Site.Master” Inherits=”System.Web.Mvc.ViewPage” %>

 

<asp:Content ID=”Content1″ ContentPlaceHolderID=”TitleContent” runat=”server”>

Index

</asp:Content>

 

<asp:Content ID=”Content2″ ContentPlaceHolderID=”MainContent” runat=”server”>

 

<h2>Edit Employee form</h2>

<div id=”employeeeditform”></div>

 

</asp:Content>

 

<asp:Content ID=”Content3″ ContentPlaceHolderID=”Scripts” runat=”server”>

<script type=”text/javascript” src=”../../Scripts/employee_editform.js”></script>

</asp:Content>

 

Listing 3

Now it’s time to go to the employee_editform.js file and write some code in JavaScript to configure the ExtJS form and its underlying widgets.

The first step is to define the form. The properties are self-descriptive. In this case, the url property points to the UpdateEmployee action method on the EmployeeController controller. This method is also accessed using POST HTTP verb (see Listing 6).

var form= new Ext.FormPanel({

title:’Edit Employee Form’,

renderTo: ’employeeeditform’,

width: 400,

url:’employee/updateemployee’,

defaults:{xtype:’textfield’},

bodyStyle:’padding: 10px’,

Listing 4

The items property is the list of widgets for the fields of the form. Here the default widget is textfield (this is specified in the defaults property). The first field is employee number which is required (specified by the allowBlank property) textfield. The second field is the fullname which is also a required textfield. The address field is an option textarea. The age field is an optional numberfield. The salary field is a required numberfield. And finally, the department number field (see Listing 7).

          items:[

{fieldLabel:’Employee ID’,name:’empno’, allowBlank:false},

{fieldLabel: ‘Fullname’,name: ‘fullname’, allowBlank:false},

{xtype: ‘textarea’,fieldLabel: ‘Address’,name: ‘address’,multiline: true},

{xtype:’numberfield’,fieldLabel:’Age’,name:’age’},

{xtype:’numberfield’,fieldLabel:’Salary’,name:’salary’, allowBlank:false},

{fieldLabel: ‘Department ID’,name: ‘deptno’, allowBlank:false}

],

Listing 5

Then the buttons property is defined (see Listing 8). As you can see in order to save button will submit the data (each field and its value will be posted in the request parameter). This can be analyzed in details in my previous articles about forms in ExtJS and the way to submit its data. In this article, we don’t implement the UpdateEmployee action in the Employee controller in order to focus on the loading data logic.

        buttons: [{

text: ‘Save’,

handler: function()

{

form.getForm().submit({

success: function(a, b)

{

Ext.Msg.alert(‘Success’, ‘ok’);

},

failure: function(a, b)

{

Ext.Msg.alert(‘Failure’, ”);

}

});

}

},

{

text: ‘Reset’,

handler: function()

{

form.getForm().reset();

}

}]

Listing 6

And the final ExtJS code is to load the initial data for the employee by passing the employee identifier by the id parameter.  After researching about getting request parameter from the URL string using Ext JS libraries, I have not found any code exceprt with the solution. The only thing that I’ve found is a little function written in pure JavaScript. After thinking myself about the problem nature, I’ve found out that the solution can’t be in any JavaScript code because the responsibility to process HTML request along with the request parameters resides in the server-side of the solution. So, I’ve figured out my own solution using global variables in JavaScript along with HTML request process model in ASP.NET MVC . The first step is to define a global JavaScript variable and assigned the value of the employee identifier taking from the request parameters. We do this by defining the global variable (before including the employee_editform.js library) in the script section of the Listing 3 in the Index.aspx view of the Index action in Employee controller (see highlighted in yellow in the Listing 7).

<asp:Content ID=”Content3″ ContentPlaceHolderID=”Scripts” runat=”server”>

<script type=”text/javascript”>

var emp_id = ‘<%=Request[“emp_id”] %>’;

</script>

<script type=”text/javascript” src=”../../Scripts/employee_editform.js”></script>

</asp:Content>

Listing 7

The next step is to define the data load ExtJS load logic to load data from the GetEmployee action in the Employee controller and specify to send the employee identifier by the request parameter empno and the value of empno request parameter is taken from the previous defined global variable emp_id as shown highlighted in yellow in the Listing 8.

    form.getForm().load({

url: ‘/employee/getemployee’,

method: ‘GET’,

params: {’empno’: emp_id},

failure: function(form, action) {

Ext.Msg.alert(“Load employee data failed”, action.result.errorMessage);

}

});

Listing 8

Then, you have the complete employee_editform.js file (see Listing 8).

Ext.ns(’employeeditform’);

 

Ext.BLANK_IMAGE_URL = ‘../ext/resources/images/default/s.gif’;

 

employeeditform.FormTutorial = {

init: function(){

//Begin of code   here

Ext.QuickTips.init();

var form= new Ext.FormPanel({

title:’Edit Employee Form’,

renderTo: ’employeeeditform’,

width: 400,

url:’/employee/updateemployee’,

defaults:{xtype:’textfield’},

bodyStyle:’padding: 10px’,

items:[

{fieldLabel:’Employee ID’,name:’empno’, allowBlank:false},

{fieldLabel: ‘Fullname’,name: ‘fullname’, allowBlank:false},

{xtype: ‘textarea’,fieldLabel: ‘Address’,name: ‘address’,multiline: true},

{xtype:’numberfield’,fieldLabel:’Age’,name:’age’},

{xtype:’numberfield’,fieldLabel:’Salary’,name:’salary’, allowBlank:false},

{fieldLabel: ‘Department ID’,name: ‘deptno’, allowBlank:false}

],

buttons: [{

text: ‘Save’,

handler: function()

{

form.getForm().submit({

success: function(a, b)

{

Ext.Msg.alert(‘Success’, ‘ok’);

},

failure: function(a, b)

{

Ext.Msg.alert(‘Failure’, ”);

}

});

}

},

{

text: ‘Reset’,

handler: function()

{

form.getForm().reset();

}

}]

});

form.getForm().load({

url: ‘/employee/getemployee’,

method: ‘GET’,

params: {’empno’: emp_id},

failure: function(form, action) {

Ext.Msg.alert(“Load employee data failed”, action.result.errorMessage);

}

});

//End of code here

}

}

 

Ext.onReady(employeeditform.FormTutorial.init,employeeditform.FormTutorial);

 

Listing 9

Now let’s go to the EmployeeController controller and implement the corresponding action methods (see Listing 10).

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Mvc.Ajax;

using LoadDataOnForm_ExtJS_ASPNETMVC.Models;

 

namespace LoadDataOnForm_ExtJS_ASPNETMVC.Controllers

{

public class EmployeeController : Controller

{

private EmployeeRepository _repoEmployee = new EmployeeRepository();

 

//

// GET: /Employee/

 

public ActionResult Index()

{

return View();

}

 

//

// GET: /Employee/GetEmployee

[AcceptVerbs(HttpVerbs.Get)]

public ActionResult GetEmployee(string _dc, string empno)

{

try

{

var objEmployee = this._repoEmployee.FindByKey(empno);

var results = (new

{

success = “true”,

data = (new

{

empno = objEmployee.empno,

fullname = objEmployee.fullname,

address = objEmployee.address,

age = objEmployee.age,

salary = objEmployee.salary,

deptno = objEmployee.deptno

})

});

return Json(results);

}

catch (Exception)

{

var results = (new

{

success = “false”,

errorMessage = “Employee not found”

});

return Json(results);

}

}

 

//

// POST: /Employee/UpdateEmployee

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult UpdateEmployee(employee employee)

{

string strResponse = String.Empty;

try

{

this._repoEmployee.Update(employee);

strResponse = “{success: true}”;

}

catch (Exception)

{

strResponse = “{success: false, error: \”An error occurred\”}”;

}

return Content(strResponse);

}

}

}

 

 

Listing 10

Now let’s run the solution (see Figure 8). You can see that we have sent the employer identifier EMP-0001 using the emp_id request parameter in the URL string.

Figure 8

Conclusion

In this article, I’ve illustrated how to create an edit form in ExtJS and integrated with ExtJS JavaScript library and ASP.NET MVC framework.