93
Applying Design Patterns with .Net an introduction via CLR Gino Heyman – [email protected] – February 27 th , 2007 © 2006-2007 Capgemini – Belgian Microsoft Community of Practice – https://troom-x.capgemini.com/MSCoPBelgium/

Applying Design Patterns with.Net an introduction via CLR Gino Heyman – [email protected] – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

  • View
    219

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Applying Design Patterns with .Netan introduction via CLR

Gino Heyman – [email protected] – February 27 th, 2007© 2006-2007 Capgemini – Belgian Microsoft Community of Practice – https://troom-x.capgemini.com/MSCoPBelgium/

Page 2: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 3: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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 ;-)

Page 4: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 5: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Quick introduction

Page 6: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 7: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 8: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Classification

Page 9: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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, …

Page 10: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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, …

Page 11: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Fundamental patterns

Page 12: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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)

Page 13: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Architectural patterns

Page 14: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 15: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 16: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 17: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Model View Controller ( c o n t ’d )

Model

View Controller

Simple Model

Page 18: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Model View Controller ( c o n t ’d )

Model

View Controller

Observer

Model with Observer

Page 19: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 20: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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!

Page 21: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 22: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 23: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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>

Page 24: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 25: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 26: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Creational patterns

Page 27: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 28: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

The Singleton (cont ’d)Class diagram

- «ctor» ResourceManager()

...

- instance : ResourceManager

ResourceManager

+ «property» Instance

Page 29: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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)

Page 30: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 31: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 32: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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, …

Page 33: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 34: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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>>

Page 35: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 36: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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; }}

Page 37: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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)

Page 38: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Builder ( c o n t ’d )

Classic class diagram

+ Construct()

Director

+ Build() : Product

Builder

ConcreteBuilderProduct

Page 39: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 40: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Prototype ( c o n t ’d )

Classic class diagram

Client

+ Clone() : Prototype

Prototype

Proto2Proto1

Page 41: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Prototype ( c o n t ’d )

Simple .Net code example

public class Prototype : ICloneable{

// ...

public object Clone(){

return this.MemberwiseClone();}

// ...}

Page 42: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Structural patterns

Page 43: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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!

Page 44: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Adapter ( c o n t ’d )

Class Diagrams

+ Request()

Target

+ Request()

Adapter

Adaptee

-adaptee

Adaptee.SpecificRequest()

+ Request()

«interface»

ITarget

Adaptee

+ Request()

Adapter

base.SpecificRequest()

Page 45: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 46: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Façade ( c o n t ’d )

Class Diagram

Facade

Page 47: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 48: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Bridge ( c o n t ’d )

Class Diagram

+ Operation()

Abstraction

+ OperationImpl()

Implementation

RefinedAbstraction Implementation1 Implementation2

- implementor

implementor.OperationImpl()

Page 49: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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)

Page 50: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Composite ( c o n t ’d )

Class Diagram

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

Component

Leaf Composite

*

children

Page 51: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 52: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Decorator ( c o n t ’d )

+ Operation()

Component

+ Operation()

Decorator

- component

+ state

Decorator1

+ Operation()+ AddedOperation()

Decorator2

Component.Operation();

base.Operation();AddedOperation();

ConcreteComponent

Class Diagram

Page 53: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Decorator ( c o n t ’d )

.Net Streams

Stream

BufferedStream CryptoStream DeflateStream

Page 54: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 55: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 56: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 57: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Proxy ( c o n t ’d )

Class Diagram

+ Request()

Subject

+ Request()

RealSubject

+ Request()

ProxyrealSubject

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

Page 58: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Behavioral patterns

Page 59: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 60: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 61: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 62: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Chain of responsibilityClass Diagram

+ HandleRequest# OnHandleRequest()

# successor : Handler

Handler

Handler1 Handler2

# successor

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

Page 63: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 64: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 65: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 66: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Interpreter ( c o n t ’d )

Class Diagram

Context

Client+ Interpret(Context)

Expression

TerminalExpression NonTerminalExpression

Page 67: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 68: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 69: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Mediator ( c o n t ’d )

Class Diagram

Mediator Colleague

Colleague1 Colleague2

mediator

ConcreteMediator

Page 70: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 71: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Memento ( c o n t ’d )

Class Diagram

+ SetMemento(Memento m)+ CreateMemento()

# state

Originator

+ SetState()+ GetState()

# state

Memento

state = m.GetState();

Page 72: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 73: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

State ( c o n t ’d )

Class Diagram

state.Handle();

Request()

Context

~ Handle()

Statestate

State1 State2

Page 74: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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.

Page 75: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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) {}

Page 76: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 77: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Visitor ( c o n t ’d )

Class Diagram

+ VisitA(ElementA)+ VisitB(ElementB)

Visitor

Visitor1 Visitor2

+ Accept(Visitor)

Element

Visitor1 Visitor2

Page 78: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Concurrency patterns

Page 79: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 80: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 81: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

} } }}

Page 82: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 83: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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)

Page 84: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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)

Page 85: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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");

Page 86: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

.Net Coding Patterns

Page 87: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

. 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()) { // ... }}

Page 88: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

. 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);

Page 89: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

. 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();}

Page 90: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

. 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); // ...}

Page 91: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

Resources and references

Page 92: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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

Page 93: Applying Design Patterns with.Net an introduction via CLR Gino Heyman – gino.heyman@capgemini.com – February 27 th, 2007 © 2006-2007 Capgemini – Belgian

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/