Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com...

Preview:

Citation preview

Applying Design Patterns with .Netan introduction via CLR

Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007© 2006-2007 Capgemini – Belgian Microsoft Community of Practice – https://troom-x.capgemini.com/MSCoPBelgium/

O B J E C T I V E S

InsightProvide an insight in design patterns.

Identify design patternsName, problem, solution and consequences

.Net Framework patternsUnderstand some design decisions of the .Net Framework.

Practical useHow can you adopt design patterns in your own code.

A S S U M P T I O N S

Familiar with OOPYou are familiar with the OO programming paradigm.

Familiar with .Net (preferably)You master the basics of .Net – not a must

Master UML basicsEssentially, you understand class diagrams

No Pattern ExpertI don’t want to bore no one ;-)

T H E P L A N

18:15 Quick introductionWhat are they? Where do they come from? Why use them?

18:25 ClassificationWhat types exist?

18:35 The patternsSingleton, observer, composite, decorator, MVC, etc., etc.

20:15 .Net coding patternsCoding patterns in .Net: APM, the using keyword, etc.

Quick introduction

What are design patt erns?

NameIncreases design vocabulary: one or two words describe it all.

ProblemWhen to apply the pattern: the problem description and its context.

SolutionProvides an abstract description of a general arrangement of elements that solve the problem. There is no such thing as a concrete, out-of-the-box solution.

ConsequencesTrade-offs of applying the pattern. It is important to evaluate different design alternatives and understand the cost and benefits.

”Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.

Christopher Alexander - 1977

Why use design patt erns?

They are proven solutionsPatterns reflect the experience, knowledge and insights of developers who have successfully used these patterns in their own work many times.

VocabularyEase communication between team-members. One or two words say it all.

Recognize problemsAnd immediately determine the solution without having to (stop and) analyze the problem first.

(Productivity)Speed up (in the long run) the development process by providing tested, proven development paradigms.

Classification

Classifi cati on

FundamentalUsed by most classic patterns. So ubiquitous that they’re rarely even mentioned.Examples: Delegation, Interface, Proxy, Immutable object, …

ArchitecturalAn architectural pattern expresses a fundamental structural organization schema for a software system.Examples: MVC, Client Server, SOA, …

CreationalDeal with object creation mechanisms, trying to create objects in a manner suitable to the situation. Examples: Abstract Factory, Builder, Lazy Initialization, Singleton, …

StructuralEase the design by identifying a simple way to realize relationships between entities.Examples: Adapter, Bridge, Façade, Composite, …

Classifi cati on ( co nt ’d )

BehavioralIdentify common communication patterns between objects and realize them. Increase flexibility in carrying out this communication.Examples: Command, Event Listener, Observer, …

ConcurrencyHandle threading issues by providing suitable locking mechanisms.Examples: Monitor object, Thread Pool, Thread-specific storage, …

Enterprise patternsMentioned for the sake of completeness. Not discussed here.Examples: Unit of work, data transfer object, gateway, …

Fundamental patterns

Fundamental Patt erns

Immutable ObjectMainly used for performance or organizational reasons.const and readonly keyword although attributes could change, still considered immutable.String , DateTime, … Once it is created, it can never be altered again.

Interface PatternDefine the contract of a class used all over the place (polymorphism).

Marker InterfaceAllows you to provide an underlying semantic property to a class.Generally not used in .Net attributes provide meta information. For performance reasons, however, some exist: INamingContainer, IRequiresSessionState, IReadOnlySessionState (ASP.Net)

Architectural patterns

3-ti er architecture

ProblemModularize software by separating application tiers by responsibility.

SolutionSeparate the application in the following tiers:• Presentation: represents the user interface of the client application. (could be using MVC)• Logic: the business/application logic of the application encapsulated by a domain model.

(could be running on several physical tiers like client, Application server, …)•Data: The data access code. The only code that knows the DB.Higher level layers depend on lower level layers only.

AdvantagesModules can be upgraded independently. Distributed deployment. Better encapsulation of responsibility (which is the whole point of OO).3/n-tier allows independent scalability of each tier.

Model View Controller

ProblemSeparate data (Model) and user interface (View/Presentation) so that changes to the user interface do not impact the data handling and that the data can be reorganized without changing the user interface.

SolutionAdd additional layering to the presentation layer (of the three-tier model):•Model: domain-specific representation of the information on which the application operates.•View: Renders the model into a form suitable for interaction, the user interface.•Controller: Responds to events, typically user actions, and invokes changes on the model.

ConsequencesBetter encapsulation of responsibilities. Increases flexibility and reuse.Many different flavors and opinions. Overhead.

Model View Controller ( c o n t ’d )

WinFormsController is usually implemented in the form class, but a dedicated separate controller is possible. The View is represented by controls.

ASP.NetController is usually implemented in the page’s code-behind file, but a dedicated separate controller is possible. The view is represented by the aspx/ascx (XHTML) of the page and/or controls.

Model View Controller ( c o n t ’d )

Model

View Controller

Simple Model

Model View Controller ( c o n t ’d )

Model

View Controller

Observer

Model with Observer

Humble Dialog

ProblemMake GUIs unit testable.

SolutionCreate a presentation interface. Pass the presentation instance to a smart class (controller, if you like) and let it interact only with this interface.

ConsequencesEasy to (unit) test GUIs via mock views.

Dependency Injecti on

Problem/goal•Achieve loose coupling/avoid tight coupling (which is inherent to OO programming)•Create testable objects (test-driven development using mock objects or stubs)

When do we have tight coupling?•Whenever a class is associated with another class and calls it.•If class X inherits class Y•Transitive dependency: X Y Z X

SolutionPlug-in mechanism: establish a level of abstraction via a public interface (or base class)Let the architecture/framework unite the objects, not the objects themselves

ConsequencesThree forms: setter-, constructor- and interface-based injection. Difficult to make a choice (if it weren’t for .Net).Manageable. Easy to write Mock objects for Unit testing. Configuration is peace of cake.Runtime vs. compile time issues!

Dependency Injecti on ( c o n t ’d )

Class diagram (Example from Elia)

+ Initialize(name, config)# «.ctor» ProviderBase()

+ «property» Name+ «property» Description

ProviderBase

+ TransferData(jobId, fromDate, untilDate)~ OnTransferProgressed(ea)~ OnTransferCompleted()~ OnTransferFailed()

TransferHandlerProvider

+ GetProvider(name)

+ «indexer» this(name)

TransferHandlerService

*

+ «property» Providers

Read the attributes from the configuration section (passed along by the framework)

A B C

Dependency Injecti on ( c o n t ’d )

private static void LoadProviders(){ if (handlers == null) { lock (syncRoot) { if (handlers == null) // Double check { // Get a reference to the section TransferHandlerServiceSection section = ConfigurationManager.GetSection("mrdb/transferHandlerService") as TransferHandlerServiceSection;

handlers = new TransferHandlerCollection(); ProvidersHelper.InstantiateProviders(section.Providers, handlers, typeof(TransferHandlerProvider));

} } }}

Provider Initialization code

Dependency Injecti on ( c o n t ’d )

<log4net debug="false"> <appender name="trace” type="log4net.Appender.TraceAppender, log4net"> <layout type="log4net.Layout.PatternLayout,log4net"> <param name="ConversionPattern“ value="%d [%t] %-5p %c - %m%n" /> </layout> </appender></log4net>

.config file examples

<mrdb> <transferHandlerService> <providers> <add name="subscriptions" type="Elia.Mrdb.Core.Subscriptions.SubscriptionsTransferHandler, Elia.Mrdb.Core.Subscriptions" connectionStringName="subscriptions" serviceName="sub"/> </providers> </transferHandlerService></mrdb>

Dependency Injecti on ( c o n t ’d )

Some built-in .Net Provider classes• MembershipProvider (has static Membership class for ease of use)• RoleProvider (has static Roles class for ease of use)• SessionStateStoreProviderBase• SettingsProvider• ProtectedConfigurationProvider• SiteMapProvider• ProfileProvider (has static Profile class for ease of use)• PersonalizationProvider• WebEventProvider

Other .Net DI classes• TraceListener• ConnectionStrings section

SOA (SaaS)

ProblemPublish resources on a network as independent services that can be accessed without knowledge of their underlying platform implementation.

Solution (principles)• Encapsulation/abstraction: higher level of abstraction then OO or Components. Could be considered

a step further then Components.• Loose coupling: dependency between different services is reduced to a minimum, while they could be

aware of each other.• Contract (!): Services adhere to agreements in terms of service interface, protocol, security and

address.•Reusability: Logic is divided in several services to promote possible reuse.•Autonomy: a service has full control over the logic it implements/serves.•Statelessness: Services retain no information on current activities.•Discoverability: Discovery mechanisms like UDDI help finding services. (not a real success)•Interoperability: this is why SOAP is the most used protocol in SOA environments.

ConsequencesStill in an early phase of adoption, hard to determine required granularity (level of abstraction), versioning, performance.ESB product are flooding the market: they claim to ease the implementation of SOAs by providing infrastructure that is responsible for many aspects of a SOA system.

Creational patterns

The Singleton

ProblemFor whatever reason (performance, structure, …), assure that a certain type/class can be instantiated only once (or a controllable number of times).

Sometimes considered an Anti-patternSome argue that a singleton is just an euphemism for a global variable.

Solution•Narrow down visibility of the constructor (private or protected)•Provide a public, read-only property to the instance (could be using lazy initialization)

ConsequencesHandle with care in multithreaded environments when using lazy initializationMuch more flexible than static classes (utility classes) by allowing inheritance.

.Net ExamplesSystem.Console, HttpContext.Current

The Singleton (cont ’d)Class diagram

- «ctor» ResourceManager()

...

- instance : ResourceManager

ResourceManager

+ «property» Instance

The Singleton (cont ’d)

public class ResourceManager{ private static ResourceManager instance = new ResourceManager();

public static ResourceManager Instance { get { return instance; } }

private ResourceManager() { }

// more instance members here...}

Simplest form (implicitly threadsafe and lazy)

The Singleton (cont ’d)

public class ReferenceFile{

private static ReferenceFile instance;

private ReferenceFile() { }

public static ReferenceFile Instance{

get{

if (instance == null)instance = new ReferenceFile();

return instance; }

}

// more class instance members here}

With explicit lazy initialization

The Singleton (cont ’d)

public class ReferenceFile{

private const string sessionId = “Something Unique like a GUID”;private ReferenceFile() { }

public static ReferenceFile Instance{

get{

if (HttpContext.Current.Session[sessionId] == null)HttpContext.Current.Session[sessionId] = new

ReferenceFile();return

(ReferenceFile)HttpContext.Current.Session[sessionId]; }

}

// more class instance members here}

ASP.Net version

Factory Method

ProblemEncapsulate the creation of objects without knowing the type or initialization in advance.(Generally, the term factory method is used to refer to any method whose purpose is the creation of objects)

SolutionDefine a separate (usually static) method for the creation of the object. Use a descriptive name.

ConsequencesAllows the class developer to define the interface for creating objects while retaining control of which class to instantiate.Factory methods are a very common practice. Usually used in the context of an abstract factory or builder implementation.

.NetImage.FromFile/FromStream, WebRequest.Create, DataTable.NewRow, DbConnection.CreateCommand, DbCommand.CreateParameter, …

Abstract Factory

ProblemEncapsulate object creation. Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Solution•Create a factory class that provides a (factory) method that creates objects•Use only the abstract interface in your client code.

ConsequencesSometimes it’s hard to find a common interface that justifies the application of this pattern.The logic that determines the exact type of class that is created can be put in configuration files comes close to dependency injection

Abstract Factory ( c o n t ’d )

Classic Class Diagram

+ CreateProductA() : AbstractProductA+ CreateProductB() : AbstractProductB

AbstractFactory

ConcreteFactory1 ConcreteFactory2

<<instantiate>>

AbstractProductA

ProductA1 ProductA2

<<instantiate>>

<<instantiate>>

AbstractProductB

ProductB1 ProductB2<<instantiate>>

Abstract Factory ( c o n t ’d )

Example from .Net (2.0)

+ CreateConnection() : DbConnection+ CreateCommand() : DbCommand...

DbProviderFactory

OdbcFactory OleDbFactory OracleClientFactory SqlClientFactory

+ GetFactory(string name) : DbProviderFactory

DbProviderFactories

Client

Abstract Factory ( c o n t ’d )

Example usage from .Net (2.0)

private static DbConnection CreateConnection(ConnectionStringSettings s){ if (settings != null) { DbProviderFactory factory = DbProviderFactories.GetFactory(s.ProviderName); DbConnection c = factory.CreateConnection(); c.ConnectionString = s.ConnectionString; return c; } else { return null; }}

Builder

ProblemSeparate the construction of a complex (concrete) object from its representation so that the same construction process can create different representations.

SolutionDiffers with abstract factory in that it merely ‘configures’ a concrete object in stead of returning a specific type of object.

ConsequencesSeparates the construction of a complex object from its representation, which makes the complex class simpler.Builder allows a step-by-step construction (e.g. parsing of text)

Builder ( c o n t ’d )

Classic class diagram

+ Construct()

Director

+ Build() : Product

Builder

ConcreteBuilderProduct

Prototype

ProblemOptimize the creation of objects that are determined by prototypical instances.(is used for example when the inherent cost of creating a new object in the standard way is considered expensive)

Solution•Create an abstract class with an abstract Clone() method that acts as a ‘polymorphic constructor’.•Derive classes from this class and implement the Clone method.

ConsequencesSometimes it complements, sometimes it overlaps with other factory patterns.Reduces subclassing,

.NetSystem.Object.MemberwiseClone() creates new object and copies non-static fields. (shallow copy)System.ICloneable intended to support deep copies

Prototype ( c o n t ’d )

Classic class diagram

Client

+ Clone() : Prototype

Prototype

Proto2Proto1

Prototype ( c o n t ’d )

Simple .Net code example

public class Prototype : ICloneable{

// ...

public object Clone(){

return this.MemberwiseClone();}

// ...}

Structural patterns

Adapter

ProblemAdapt or wrap one interface to comply to another – the one that the client expects.

SolutionCreate a wrapper class that consumes one interface and exposes another

ConsequencesTwo types: object and class adapter. (Class adapter might require multiple inheritance.Only applicable if a class provides the required logic, but not the required interface.)

.Net Examples•COM Callable wrappers•Runtime Callable wrappers•DataAdapters no adapter pattern!

Adapter ( c o n t ’d )

Class Diagrams

+ Request()

Target

+ Request()

Adapter

Adaptee

-adaptee

Adaptee.SpecificRequest()

+ Request()

«interface»

ITarget

Adaptee

+ Request()

Adapter

base.SpecificRequest()

Façade

ProblemProvide a unified interface to a set of interfaces in a subsystem without damaging the generic form of the sub system.

SolutionEncapsulate subsystem logic in one or more façade classes. Don’t allow direct interaction with the subsystem from outside the façade.

ConsequencesClients don’t know/care about subsystem and needs to deal only with a minimal set of classes.The Façade promotes loose coupling by adding a level of abstraction/encapsulation. Façade does not mean that the client can’t use the subsystem directly if it want/needs to.

Façade ( c o n t ’d )

Class Diagram

Facade

Bridge

Problem“Decouple an abstraction from its implementation so that the two can vary independently”Can be useful when not only the class itself (the interface) undergoes frequent changes, but also what the class does (its implementation).

SolutionCreate an abstract implementation class (or interface).Create an abstract class (or interface) for the class interface, and use the implementation.Refine the base class interface.

ConsequencesHigh flexibility of the OO design (decoupling of interface and implementation).A lot of delegation complexity.

Bridge ( c o n t ’d )

Class Diagram

+ Operation()

Abstraction

+ OperationImpl()

Implementation

RefinedAbstraction Implementation1 Implementation2

- implementor

implementor.OperationImpl()

Composite

ProblemOrganize objects into hierarchical (tree) structures.

SolutionCreate an (abstract) base class that holds a collection to instances of derived types.

ConsequencesUniformity: treat all components the same way (makes the client simple)Extensibility: new component sub classes work wherever old ones doCan lead to recursive iterations through the hierarchy danger of writing code that produces an infinite loop.

.NetAll controls (parent and children) in WinForms and ASP.NetTreeNode(Collection)

Composite ( c o n t ’d )

Class Diagram

+ Operation()+ Add(Component)+ Remove(Component)+GetChild(int)

Component

Leaf Composite

*

children

Decorator (wrapper)

ProblemAdd new functionality to an existing class dynamically/at runtime.Avoid excessive sub-classing and gain run time flexibility

SolutionWrap the existing (decorated) class in a decorator class. Add members to the decorator. Pass the existing class in the .ctor of the decorator.

ConsequencesDecorators provide a flexible alternative (it ads behavior to instances and not the whole class) to sub classing for extending functionality.Could result in a maintenance headache when over-used. Testing of object types (the ‘is’ keyword) does not work (identity crisis).

.NetStreams! See later.

Decorator ( c o n t ’d )

+ Operation()

Component

+ Operation()

Decorator

- component

+ state

Decorator1

+ Operation()+ AddedOperation()

Decorator2

Component.Operation();

base.Operation();AddedOperation();

ConcreteComponent

Class Diagram

Decorator ( c o n t ’d )

.Net Streams

Stream

BufferedStream CryptoStream DeflateStream

Flyweight

ProblemManage/manipulate many objects that cannot afford to have extraneous data.Avoid the overhead of managing a large number of very similar class instances.

SolutionMaintain a list/pool of flyweight objects by key. Map the key to shared data.

ConsequencesRun-time cost associated with transferring, finding and/or computing extrinsic state.Reduces the total amount of instances through sharing.Reduces the amount of intrinsic state per object.

ExamplesShare font information for many character in a text document.Keep one instance per image in a browser, even though it is displayed may times

Flyweight ( c o n t ’d )

BTree

Times 24 Times 12 Times-Bold 12 Courier 12

500

1 300 199

100 6 194 12 187

Proxy

ProblemProvide a surrogate or placeholder for another object to control access to it.

SolutionEncapsulate the original object, wrap the methods to control access.Remote Proxy physical boundaries.Virtual Proxy for Lazy initialization.Protection Proxy add security checks.Cache Proxy holds temporary copies of results from the real object for better performance

ConsequencesDecorator-likeBehaves much like an adapter/wrapper but without a change to the interface

.NetWeb Service proxy, Remoting proxies

Proxy ( c o n t ’d )

Class Diagram

+ Request()

Subject

+ Request()

RealSubject

+ Request()

ProxyrealSubject

// …realSubject.Request();// ...

Behavioral patterns

Strategy

ProblemDefine a family of interchangeable encapsulated algorithms that receives the same input type and provides the same output type in different manners that can be determined in run-time.

SolutionDefine a strategy operation and encapsulate it in a strategy base class.Implement different strategy versions.

ConsequencesGreater flexibility and reuseSimpler codeAlgorithms can be changed dynamically- Inflexible strategy interface

.NetArrayList.SortASP.Net control adapters

Command

ProblemEncapsulate an action and its parameters.

SolutionEncapsulate action parameters in a class and provide an ‘execute’ method.

ConsequencesCan improve API design: clearer than a method with many parametersAllows storage of procedure parameters (for multiple executions or undo-scenarios)Multiple commands or actions can be queued (thread pool) or stacked (undo)

.NetDbCommand, Thread

Chain of responsibility

ProblemAvoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

SolutionCreate a linked list of command objects

ConsequencesReduced coupling: client object doesn’t need to know handling objectIncreased flexibility by distributing responsibilities among objectsNo guaranteed handling

.NetMore convenient via event, example: KeyEventArgs

Chain of responsibilityClass Diagram

+ HandleRequest# OnHandleRequest()

# successor : Handler

Handler

Handler1 Handler2

# successor

OnHandleRequest();If (successor != null) successor.HandleRequest();

Observer

ProblemObserve the state of an object. If the state changes, inform all dependent objects of this change.

SolutionCreate a subject that allows observers to subscribe themselves, provide a method that notifies all subscribers (the observers).

ConsequencesModularity: subject and observes may vary independentlyExtensibility: you can define and add any number of observersCustomizability: different observers can provide different views of the subject

.NetNot really applied in .Net multicast delegates (and event) provide this kind of behavior.

Observer ( c o n t ’d )

Class Diagram

+ Attach(Observer)+ Detach(Observer)+ Notify()

Subject

+ Update()

Observer+ observers

*

foreach (Observer o in observers) o.Update();

ConcreteSubject ConcreteObserver

Interpreter

ProblemGiven a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

SolutionCreate a hierarchy of classes that interpret data given a context.

ConsequencesEasy to change and extend grammar (via inheritance)Easy implementationComplex grammars are hard to maintain

.NetDataColumn.Expression uses an internal ExpressionParser class.

Interpreter ( c o n t ’d )

Class Diagram

Context

Client+ Interpret(Context)

Expression

TerminalExpression NonTerminalExpression

Iterator

ProblemProvide a way to access elements of an aggregate object sequentially, without exposing its underlying representation.

SolutionLoop constructions and language constructs

ConsequencesStraightforwardWatch out in multi-threaded environments (collection may not change during iteration)

.NetGetEnumerator(), foreach, IEnumerable, Example: XPathNodeIterator

Mediator

ProblemDefine an object that encapsulates how a set of objects interact.

SolutionCreate a mediator as the only class that has detailed knowledge of the methods of other classes.

ConsequencesLimits sub-classingCentralizes controlPromotes loose coupling by keeping objects from referring to each other explicitlyLets you vary their interaction independentlyMostly applied in GUIs

.Net

.Net promotes mediator use in GUIs (e.g. the form), but doe not require you to move the mediator code to a dedicated class.

Mediator ( c o n t ’d )

Class Diagram

Mediator Colleague

Colleague1 Colleague2

mediator

ConcreteMediator

Memento

ProblemWithout violating encapsulation, capture and externalize an object's internal state so that the object can be restored back to this state

SolutionCreate a memento class that can hold the state of another object.

ConsequencesPreserves encapsulation boundaries (even though data is extracted)Simplifies the originatorMight be expensive

Memento ( c o n t ’d )

Class Diagram

+ SetMemento(Memento m)+ CreateMemento()

# state

Originator

+ SetState()+ GetState()

# state

Memento

state = m.GetState();

State

ProblemAllow an object to alter its behavior when its internal state changes

SolutionAdd state-dependant behavior in external state classes.

ConsequencesMakes state-transitions explicit.Easily extendible, just make a new state subclass

State ( c o n t ’d )

Class Diagram

state.Handle();

Request()

Context

~ Handle()

Statestate

State1 State2

Template method

ProblemDefine the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure

SolutionExpose a method that calls abstract methods.

ConsequencesPromotes code-reuseAvoids forgetting to call the base implementation.

Template Method ( c o n t ’d )

Simple .Net code examplepublic void HandleRequest(DateTime timeStamp){ try { //... Trace.WriteLine("Before OnHandleRequest", "info"); OnHandleRequest(timeStamp); Trace.WriteLine("After OnHandleRequest", "info"); // ... } catch (Exception ex) { // log } finally { // Clean up }}

protected abstract void OnHandleRequest(DateTime timeStamp) {}

Visitor

ProblemDefine operations to be performed on elements of an object structure.Separate an algorithm from an object structure.

SolutionCreate a visitor class with a method(s) that accepts the element to visit, create elements with a method that accept the visitor(s).

ConsequencesMakes adding new operations easyAdding new concrete element classes is hardVisitors can easily accumulate state of class hierarchiesBreaks encapsulation

Visitor ( c o n t ’d )

Class Diagram

+ VisitA(ElementA)+ VisitB(ElementB)

Visitor

Visitor1 Visitor2

+ Accept(Visitor)

Element

Visitor1 Visitor2

Concurrency patterns

Monitor object

ProblemSynchronize concurrent method execution to ensure that only one method at a time runs within an object.

SolutionUse the System.Threading.Monitor class

ConsequencesAllows you to synchronize method executionNo centralized synchronization

Acti ve Object

ProblemDecouple method execution from method invocation to simplify synchronized access to a shared resource.

SolutionCan be easily achieved with callback delegates (in .Net, that is)Queue requests and execute them on a dedicated thread

ConsequencesRelieves client objects from dealing with concurrency problemsAllows scheduling requests as desired (e.g. prioritization)Although becoming more common, ALL interaction happens asynchronouslyHarder to debug

.NetInvoke & BeginInvoke methods

Double Checking Lock

ProblemReduce locking overhead when implementing "lazy initialization" in a multi-threaded environment

private static void LoadProviders(){ if (handlers == null) { lock (syncRoot) { if (handlers == null) // Double check { // Get a reference to the section

} } }}

Consumer/Producer

ProblemCoordinate the concurrent production and consumption of information among producer and consumer objects that are working on different threads.

SolutionCreate a container that synchronizes access to the underlying data.

ConsequencesSynchronization of access to data is fully encapsulated, any object can add or remove data without bothering about thread-safety

Read/Write Lock

ProblemAllow concurrent read access to an object but require exclusive access for write operations

SolutionUse the System.Threading.ReaderWriterLock class

ConsequencesDistinguishing readers from writers (unlike monitors) to promote concurrency (if there are more readers than writers)

Thread Pool

ProblemAvoid the overhead of creating a new thread for short running operations.

SolutionUse the Thread.ThreadPool

ConsequencesRe-use threads from the poolBeware of over-use (ASP.Net introduced asynchronous pages in version 2.0 to avoid 503)

Thread-specifi c storage

ProblemStore data that is exclusive to a thread.

SolutionUse Thread Local Storage (TLS)

ConsequencesDon’t worry about concurrent access to objects

LocalDataStoreSlot slot = Thread.AllocateDataSlot();Thread.SetData(slot, "whatever");

.Net Coding Patterns

. N e t c o d i n g p a tt e r n s ( c o n t ’ d )

The using statement

using (DbConnection c = CreateConnection()){ using (DbCommand cmd = c.CreateCommand()) { // ... }}

. N e t c o d i n g p a tt e r n s ( c o n t ’ d )

Scope Encapsulation

protected List<T> GetList(DbCommand cmd, ReadDelegate readDelegate){ try { OpenConnection(); List<T> ret = new List<T>(); using (IDataReader r = cmd.ExecuteReader()) { while (r.Read()) { ret.Add(readDelegate(r));} } return ret; } catch { throw; } finally { CloseConnection(); }}

public delegate T ReadDelegate(IDataRecord record);

. N e t c o d i n g p a tt e r n s ( c o n t ’ d )

Transaction Scope

using (TransactionScope ts = new TransactionScope()){ DbCommand cmd = CreateCommand("DELETE FROM User2Role WHERE UserId = @id"); AddCommandParameter(cmd, "@id", user.Id); ExecutNonQuery(cmd);

cmd.CommandText = "DELETE FROM [User] WHERE (Id = @id)"; ExecutNonQuery(cmd);

ts.Complete();}

. N e t c o d i n g p a tt e r n s ( c o n t ’ d )

The Asynchronous Programming Model

public void RunAsync(){ WebRequest req = WebRequest.Create("http://www.capgemini.com/"); IAsyncResult res = req.BeginGetResponse(new AsyncCallback(GotResponse), req);}

public void GotResponse(IAsyncResult result){ WebRequest req = result.AsyncState as WebRequest; WebResponse response = req.EndGetResponse(result); // ...}

Resources and references

R e f e r e n c e s - b o o k s

Design Patterns. Elements of reusable Object-Oriented Software.Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (aka the GoF) – 1995, Addison Wesley

Pattern Oriented Analysis and DesignSherif M. Yacoub, Hany H. Ammar

Patterns of Enterprise Application ArchitectureMartin Fowler – 2003, Pearson Education

Design Patterns in C#Steven John Metsker – 2004, Pearson Education

Object-Oriented Analysis & DesignMike O’Docherty

We b s i t e s & t o o l s

Lutz Roeder’s Reflectorhttp://www.aisto.com/roeder/dotnet/

Microsofthttp://msdn.microsoft.com/msdnmag/issues/05/07/DesignPatterns/http://msdn2.microsoft.com/en-us/library/aa973811.aspx

Visio UML 2.0 stencils by Pavel Hrubyhttp://www.softwarestencils.com/uml/index.html

Misc.http://en.wikipedia.org/http://www.objectmentor.com/resources/articles/TheHumbleDialogBox.pdfhttp://www.dofactory.com/