Sunteți pe pagina 1din 35

Design Patterns in Practice

By Doug, Jeremy, & Mike

What is a design pattern?


A design pattern is a reusable solution to
a common problem in software design.
A design pattern is not code.
A design pattern can vary in scope from
very simplistic to an entire system.

The different kinds of patterns


Creational
Patterns that focus on object creation.

Structural
Patterns that focus on the relationships
between entities.

Behavioral
Patterns that focus on the communication
patterns between objects.

Concurrency
Patterns that deal with multi-threaded
programming techniques.

What are the benefits?


Can significantly speed up the
development process.
Wide adoption of common patterns result
in code that is easier to understand and
maintain over time.
Proper usage of design patterns will
result in a better overall design.

What are the drawbacks?


Can introduce more levels of indirection.
Improper usage will negate the benefits.
Adding complex design patterns to
simple problems can result in over
engineering.

The Interface
What is it?
An interface contains only the signatures of
methods, properties, events or indexers.
It is a contract between you and the rest of
the world.

Why should you use it?


It insulates the rest of the world from the
underlying implementation.

When should you use it?


Whenever you are needing to isolate
yourself.

The Interface vs. Abstract Classes


The problem setup:
A group of physicians want to have a
document management system to keep track
of their publications.

1 week later
Can we have third party authored
documents about us in our system?

After 2 months of sheer bliss


Can we have procedure and diagnosis
information on the documents that are
related to procedures they have
performed?

Our code is starting to cave


There are dozens of places in our code
that have logic similar to the following:
public void ProcessD ocum ent(D ocum ent doc)
{
if (doc is AuthoredD ocum ent)
{
// D o author specifi
c stuff
...
}
if (doc is M edicalD ocum ent)
{
// D o m edicalstuff
...
}
if (doc is PhysicianD ocum ent)
{
// D o physician stuff
...
}
}

This is
dangerous!

1 day later
Can we have patient related documents
for the procedures we have done or have
found on-line?

What we could have done

if (doc is IMedicalDocument)
{
// Do medical stuff...
}
if (doc is IPhysicianDocument)
{
// Do physician stuff...
}

The Singleton

The singleton pattern is used to restrict


the number of instances of a class to
one.
How is this useful?
Why is this controversial?

The Singleton - Implementation


Singleton C# code
public sealed class Singleton
{
private static readonly Singleton m_instance = new Singleton();
/// <summary>
/// Explicit static constructor to tell C# compiler
/// not to mark this type as beforefieldinit
/// </summary>
static Singleton()
{
}
/// <summary>
/// Private constructor to enforce singleton pattern.
/// </summary>
private Singleton()
{
}
/// <summary>
/// Static property to return the singleton instance.
/// </summary>
public static Singleton Instance
{
get { return m_instance; }
}
}

The Factory

What
The factory
pattern
is ahelp
creational
are
common
uses
for apattern
doessome
the
factory
with?
Returning
that
uses a Interface
singleton
object to provide
factory?
implementations
Logging
implementations
of object
a requested
Simplifies complex
creation interface
a
to
caller.
Configuration
Caching
Data access
Testing

The Factory in Data Access


DAOFactory
+<static> GetInstance() : DAOFactory
+GetDAO<T>() : T where T : IDAO

uses

DAOFactoryConfiguration
+GetTypeName(in key : string) : string
+SetTypeName(in key : string, in typeName : string)

// Retrieve our DAO from the factory.


IPersonDAO dao = DAOFactory.GetInstance.GetDAO<IPersonDAO>();
// Invoke the appropriate retrieval method.
IPerson person = dao.GetPerson(modelId);

Other Factory Uses

Create fake
implementations
instead of
waiting

Test really
hard
scenarios

The Delegate

What
are
common
uses
for a
The delegate
doessome
thepattern
delegate
is ahelp
technique
with?
Separation
delegate?
where
an object
expresses certain
of concerns
Data
behavior,
in reality
Reuseaccess
ofbut
common
logicdelegates the
Business layer
responsibility
fordelegates
implementing/executing
Asynchronous
that
behavior toprogramming
an associated object.

The Delegate Inside the DAO

public IPerson GetPerson(Guid modelId)


{
// Construct our delegate that can fill out our request
// and empty out the response from the data source.
GetPersonDataDelegate del = new GetPersonDataDelegate(modelId);
// Obtain a reference to the call point by passing the delegate
IDataCall<IPerson> call = DataCallFactory.Instance.GetDataCall(del);
// Execute the call and return the result.
return call.Execute();
}

A Common Problem
How should I instrument my code?
The real problems are
What should I capture?
Where should I store the captured data?
Who should I notify when things go bad?
What does bad mean?
How do I change the system behavior to
optimize the system resources that are
available to me?
How do I keep my code clean???

A Common Solution
public void Execute()
{
DateTime startedOn = DateTime.UtcNow;
Logger logger = new Logger();
try
{
logger.Write(string.Format(
"Starting GetPerson([{0}]) at {1}", m_modelId, DateTime.UtcNow));

What if my logger doesnt support


my needs right now?

// Execute call

What if this was slow?

logger.Write(string.Format(
"Finished GetPerson([{0}]) at {1} and it worked!",
m_modelId, DateTime.UtcNow));

Should we let someone know


about this?

}
catch (Exception e)
{
logger.Write(string.Format("GetPerson([{0}]) failed {1}.", m_modelId, e));
throw;
}
finally
{
DateTime endedOn = DateTime.UtcNow;

Who was the user?

TimingSystem.GetInstance().LogExecutionTime("GetPerson", endedOn.Subtract(startedOn));
}
}

A Better Solution - The Interceptor


First, design the core system without any
instrumentation.
Next, identify the key points in the call
stack; these are the interception points.
Finally, identify important information to
communicate at the interception points.

The Interceptor UML

Interceptor Implementations

More can be added dynamically at run


time.

Using Our Interceptor


public void Execute()
{
IContext ctx = Dispatcher.GetInstance().CreateContext(m_modelId);
try
{
Dispatcher.Started(ctx);
// Execute call
Dispatcher.Ended(ctx);
}
catch (Exception e)
{
Dispatcher.Errored(ctx, e);
throw;
}
}

Much cleaner and more extensible

Service Oriented Architecture


What is it?

Service Oriented Architecture

SOA - Simplified
A simplistic view of one service

Why do you
have all of
these layers?

What is a
model?

Proper Coupling

Is this
allowed?

Loose coupling is one of the tenants;


however, appropriate sacrifices can be
made to achieve performance goals.

Bad SOA!

You must adhere to the design pattern or


your implementation will collapse under
its own weight.

Database Coupling

Database Loose Coupling

What if an
account is
removed?

Some data integrity checks must be


moved to higher levels in the
architecture.

Loose Coupling Wrap-up


True loose coupling is not easy.
An event model must be part of your
solution to achieve truly isolated services.
Performance and extensibility are often
at odds with each other.
These design patterns are really
powerful!

Questions

Future Topics
Unit Testing
SOA Deep Dive
Pub / Sub
Business Intelligence / Analytics
Free Text Search

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