View
219
Download
2
Tags:
Embed Size (px)
Citation preview
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/
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/