+ All Categories
Home > Technology > Design Patterns

Design Patterns

Date post: 10-May-2015
Category:
Upload: betclic-everest-group-tech-team
View: 13,882 times
Download: 0 times
Share this document with a friend
Description:
In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design Patterns are formalized best practices that the programmer must implement in the application.
Popular Tags:
61
Design Patterns Training 02/2014
Transcript
Page 1: Design Patterns

Design Patterns Training

02/2014

Page 2: Design Patterns

Agenda

What’s a design pattern…

Pros / Cons

Families

Patterns x10

2All photos and pictures included in those slides are courtesy and copyright of their respective owners.

Page 3: Design Patterns

Homework

Object-Oriented Design : Coupling

Cohesion

Inheritance

Interface

Polymorphism

S.O.L.I.D. principles Refer A. Sauvinet mini-training

3

Page 4: Design Patterns

Definition

In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design

Patterns are formalized best practices that the programmer must implement in the application

4

Page 5: Design Patterns

Pros / Cons

Pros : speed up development by providing tested, proven paradigms

Robust solution

Smart design

Flexibility

Re-usable

Cons : Usage reveals missing feature in programming language

Inappropriate use of patterns may unnecessarily increase complexity

Some patterns have impacts on performance

5

Page 6: Design Patterns

Families

3 main families : Creational patterns : control object creation mechanisms

Structural patterns : ease relationships between entities

Behavioral pattern : increase flexibility and communication between objects

2 extra families : Concurrency patterns

Lock

MDP : Messaging Design Pattern

Architectural patterns MVC : Model-View-Controller

MVVM : Model-View-ViewModel

MVP : Model-View-Presenter

Event-driven architecture

6

Page 7: Design Patterns

Families : Creational Patterns

Control object creation mechanisms Singleton*

Builder*

Abstract Factory

Prototype

Factory method*

Lazy initialization

Object pool

7

Page 8: Design Patterns

Families : Structural Patterns

Ease relationships between entities Adapter*

Decorator*

Composite*

Aggregate

Façade*

Proxy

8

Page 9: Design Patterns

Families : Behavioral Patterns

Increase flexibility and communication between objects Chain of responsibility*

Command

Iterator

Observer

Visitor*

Strategy*

9

Page 10: Design Patterns

And what about the famous IoC ?

Inversion of Control is not a pattern, it’s a programming technique.

Coupling is not known at compile time, only at runtime

Hands-on : Using a factory pattern

Using a service locator pattern

Using a dependency injection, for example:

• A constructor injection

• Parameter injection

• A setter injection

• An interface injection

Using a contextualized lookup

Using Template method design pattern

Using strategy design pattern

10

Page 11: Design Patterns

11

Page 12: Design Patterns

12

Page 13: Design Patterns

Singleton

Restricts instanciation of a class to one object.

Provides a global point of access to it

13Note : be careful with multithread, use (double) lock pattern

Page 14: Design Patterns

Singleton - Code

14

public static class Utils{

private static IUtilsInstance _instance;

public static IUtilsInstance Instance{

get{

if (_instance != null)_instance = new UtilsInstance();

}return _instance;

}}

}

Naive implementation

Page 15: Design Patterns

Singleton - Code

15

public static class Utils{

private static volatile object _lock = new object();

private static IUtilsInstance _instance;

public static IUtilsInstance Instance{

get{

if (_instance != null)return _instance;

lock (_lock){

if (_instance != null){

return _instance;}_instance = new UtilsInstance();return _instance;

}}set { _instance = value; }

}}

Page 16: Design Patterns
Page 17: Design Patterns

Builder

Separate construction of a complex object from its representation

Solution to the telescoping constructor anti-pattern Many parameters, mandatory or optional

17

Page 18: Design Patterns

Without Builder

public class BadCar

{

public bool HasGPS { get; private set; }

public bool IsCityCar { get; private set; }

public bool IsSportCar { get; private set; }

public bool IsCabrioletCar { get; private set; }

public int Seats { get; private set; }

public BadCar(bool hasGps);

public BadCar(bool hasGps, bool isCityCar);

public BadCar(bool isCabrioletCar, int seats);

public BadCar(bool hasGps, bool isCityCar, bool isSportCar, bool isCabrioletCar, int seats);

}

18

Program :

public void main()

{

var car = new BadCar(false, false, true, false, 2);

}

Page 19: Design Patterns

Without Builder

19

public class BadCabriolet : BadCar{

public BadCabriolet(bool hasGps) : base(hasGps) { }

public BadCabriolet(bool hasGps, bool isCityCar) : base(hasGps, isCityCar) { }

public BadCabriolet(bool isCabrioletCar, int seats) : base(isCabrioletCar, seats) { }

public BadCabriolet(bool hasGps, bool isCityCar, bool isSportCar, bool isCabrioletCar, int seats): base(hasGps, isCityCar, isSportCar, isCabrioletCar, seats)

{}

}

Issue with polymorphism :

Page 20: Design Patterns

With Builder

20

public class Car

{

public bool HasGPS { get; set; }

public bool IsCityCar { get; set; }

public bool IsSportCar { get; set; }

public bool IsCabrioletCar { get; set; }

public int Seats { get; set; }

}

public class CarBuilder{

private Car Car = new Car());

public Car GetCar(){

return Car;}

public CarBuilder SetSeats(int nbSeats){

Car.Seats = nbSeats;return this;

}

public CarBuilder SetSportsCar(){

Car.IsSportCar = true;return this;

}

public CarBuilder SetCabriolet();public CarBuilder SetGps();

}

• Wrap properties set into methods

• Really easy to make it « fluent »

public class Car

{

public bool HasGPS { get; private set; }

public bool IsCityCar { get; private set; }

public bool IsSportCar { get; private set; }

public bool IsCabrioletCar { get; private set; }

public int Seats { get; private set; }

public CarBuilder Builder { get; private set; }

private Car(CarBuilder Builder);

}

Page 21: Design Patterns

With Builder

21

public class Prog{

public void Main(){

var builder = new CarBuilder();

builder.SetSeats(2);builder.SetSportsCar();

var car = builder.GetCar();

...

var fluentCar = builder.SetSeats(2).SetSportsCar().SetGps().GetCar();}

}

• Initialization is wordy

• Extension is easy

• Polymorphism

Page 22: Design Patterns
Page 23: Design Patterns

Factory Method

Define an interface for creating a single object, but let subclasses decide which class to instantiate

Can be used to ease TDD mocking

3 different implementations Subclassing

Interface

Static

23

Note : Subclassing implementation depends on private constructor = class cannot be extended

if protected constructor = subclass have to redefine all factory methods !

Page 24: Design Patterns

Example

24

public interface ICar{

string GetType();}

public interface ICarFactory{

ICar MakeCar(int nbDoors);}

class Sedan : ICar{

public string GetType() { return "Sedan"; }}

class Coupe : ICar{

public string GetType() { return "Coupe"; }}

class CarFactory : ICarFactory{

public ICar MakeCar(int nbDoors){

return (nbDoors > 2) ? (ICar)new Sedan() : new Coupe();}

}

public class Proog

{public void Main(){

var f = new CarFactory();ICar coupe = f.MakeCar(2);ICar sedan = f.MakeCar(5);

}}

Page 25: Design Patterns
Page 26: Design Patterns

Adapter

Convert the interface of a class into another interface clients expect

Helps two incompatible interfaces to work together

26

Page 27: Design Patterns

Without adapter

27

public class DataParser{

private string Data;

public void SetData(string data){

this.Data = data;}

public void ParseData(){

Console.WriteLine(this.Data.Replace(" - ", " / "));}

}

public class DataProvider{

public string[] Datas;

public string GetStringData(){

return this.Datas.Aggregate(string.Empty, (current, data) => current + (data + " - "));}

}

public class Prog{

public void Main(){

var a = new DataParser();var b = new DataProvider();

a.SetData(b.GetStringData());a.ParseData();

}}

Page 28: Design Patterns

With adapter

28

public class DataParserFormat1Adapter{

public DataProvider B { get; set; }

public DataParserFormat1Adapter(DataProvider b){

this.B = b;}

public string GetStringData(){

return this.B.Datas.Aggregate(string.Empty, (current, data) => current + (data + " - "));}

}

public class Prog{

public void Main(){

var a = new DataParser();var b = new DataProvider();

var adapter = new DataParserFormat1Adapter(b);var data = adapter.GetStringData();

a.SetData(data);a.ComputeData();

}}

Page 29: Design Patterns
Page 30: Design Patterns

Decorator

Attach additional responsibilities to an object dynamically keeping the same interface

30

Page 31: Design Patterns

Without Decorator

31

public interface IArmor{

void Fight();

string GetDescription();}

public class SimpleArmor : IArmor{

public virtual void Fight(){

//Launch Simple missile}

public virtual string GetDescription(){

return "Armor Mark I";}

}

public class SimpleArmorWithLaser : SimpleArmor{

public override void Fight(){

base.Fight();LaunchLaser();

}

private void LaunchLaser(){

// Enable BBQ LAser}

public virtual string GetDescription(){

return "Mark II with Laser";}

}

Page 32: Design Patterns

Without Decorator

32

public class SimpleArmorWithTazer : SimpleArmor{

public override void Fight(){

base.Fight();this.EnableTazer();

}

private void EnableTazer(){

// Enable Heart Attack Tazer}

public override string GetDescription(){

return "Mark II with Tazer";}

}

Page 33: Design Patterns

Without Decorator

33

public class SimpleArmorWithTazer : SimpleArmor{

public override void Fight(){

base.Fight();this.EnableTazer();

}

private void EnableTazer(){

// Enable Heart Attack Tazer}

public override string GetDescription(){

return "Mark II with Tazer";}

}

public class SimpleWindowWithLaserAndTazer : SimpleArmorWithLaser{

public override void Fight(){

base.Fight();this.EnableTazer();

}

private void EnableTazer(){

// Enable Heart Attack Tazer}

public override string GetDescription(){

return base.GetDescription() + " and with Tazer";}

}

Page 34: Design Patterns

With Decorator

34

public abstract class ArmorDecorator : IArmor{

public IArmor DecoratedArmor { get; private set; }

public ArmorDecorator(IArmor decoratedArmor){

this.DecoratedArmor = decoratedArmor;}

public virtual void Fight(){

DecoratedArmor.Fight();}

public virtual string GetDescription(){

return DecoratedArmor.GetDescription();}

}

Page 35: Design Patterns

With Decorator

35

public class LaserDecorator : ArmorDecorator{

public LaserDecorator(IArmor decoratedArmor) : base(decoratedArmor) { }

public override void Fight(){

base.Fight();LaunchLaser();

}

private void LaunchLaser(){

// Enable BBQ Laser}

public override string GetDescription(){

return base.GetDescription() + " with Laser";}

}

Page 36: Design Patterns

With Decorator

36

public class LaserDecorator : ArmorDecorator{

public LaserDecorator(IArmor decoratedArmor) : base(decoratedArmor) { }

public override void Fight(){

base.Fight();LaunchLaser();

}

private void LaunchLaser(){

// Enable BBQ Laser}

public override string GetDescription(){

return base.GetDescription() + " with Laser";}

}

public class TazerDecorator : ArmorDecorator{

public TazerDecorator(IArmor decoratedArmor) : base(decoratedArmor) { }

public override void Fight(){

base.Fight();EnableTazer();

}

private void EnableTazer(){

// Enable Heazrt Attack Tazer}

public override string GetDescription(){

return base.GetDescription() + " with Tazer";}

}

Page 37: Design Patterns

With Decorator

37

public class Jarvis{

public void Main(){

IArmor ironman = new TazerDecorator(new LaserDecorator(new SimpleArmor()));

Console.WriteLine(ironman.GetDescription());}

}

Page 38: Design Patterns
Page 39: Design Patterns

Composite

Compose objects into tree structures to represent part-whole hierarchies

39

Page 40: Design Patterns

Composite Example

40

public interface IDrawable{

void Render();}

public class Ellipse : IDrawable{

public void Render(){

Console.WriteLine("Ellipse");}

}

public class Square: IDrawable{

public void Render(){

Console.WriteLine("Square");}

}

Page 41: Design Patterns

41

public class CompositeGraphic : IDrawable{

//Collection of Graphics.private readonly List<IDrawable> graphics;

public CompositeGraphic(){

//initialize generic Collection(Composition)graphics = new List<IDrawable>();

}

public void Add(IDrawable graphic);public void AddRange(params IDrawable[] graphic);public void Delete(IDrawable graphic);

//Render the graphic.public void Render(){

foreach (var childGraphic in graphics){

childGraphic.Render();}

}}

Page 42: Design Patterns

42

public class FrankensteinReturn{

public void Main(){

var eyes = new CompositeGraphic(new Square(), new Square());var mouth = new Ellipse();var head = new CompositeGraphic(new Square(), new Square(), new Square());

var frankenstein = new CompositeGraphic(head, eyes, mouth);}

}

Page 43: Design Patterns

43

Page 44: Design Patterns

Façade

Provide a unified interface to a set of interfaces in a subsystem

Facade defines a higher-level interface that makes the subsystem easier to use

BC example : Register in Global

44

Page 45: Design Patterns

Façade example

45

/* Complex parts */class CPU {

public void freeze() { ... }public void jump(long position) { ... }public void execute() { ... }

}

class Memory {public void load(long position, byte[] data) { ... }

}

class HardDrive {public byte[] read(long lba, int size) { ... }

}

Page 46: Design Patterns

Façade example

46

class ComputerFacade{

private CPU processor;private Memory ram;private HardDrive hd;

public ComputerFacade() {this.processor = new CPU();this.ram = new Memory();this.hd = new HardDrive();

}

public void Start() {processor.freeze();ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));processor.jump(BOOT_ADDRESS);processor.execute();

}}

/* ServiceDesk */

class You {public static void main() {

var computer = new ComputerFacade();computer.Start();

}}

Page 47: Design Patterns
Page 48: Design Patterns

Chain of responsibility

Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.

Good practice : Loose coupling

BC example : login, register processes

48

Page 49: Design Patterns

Chain of responsibility example - pipeline

49

ProcessorTask

TaskTask

RequestLogin

ProcessorAuthentication

Task

Login = «testuser»

Password = « pwd123 »

Status = ok

User = null

Request

Login = «testuser»

Password = « pwd123 »

Status = ok

User = null

FraudTask

Request

Login

Password

Status = Forbidden by Fraud

User = null

Request

Infos

Status

Page 50: Design Patterns

50

Page 51: Design Patterns

Strategy

Define a family of algorithms, encapsulate each one, and make them interchangeable.

Strategy lets the algorithm vary independently from clients that use it.

O from SOLID : Open for extension but closed for modification.

51Note : For more information, key words : Policy-based design

Page 52: Design Patterns

Strategy example

52

interface DepositStrategy{

decimal Execute(decimal amount); };

class Eiole : DepositStrategy{

private decimal feeAmount = 10;

public decimal Execute(decimal amount) {

return amount + feeAmount;}

};

class Metacharge : DepositStrategy{

private decimal feeRate = 0,05;

public decimal Execute(decimal amount) {

return amount * (1 + feeRate);}

};

class DepositContext{

private List<DepositStrategy> strategies;...

private DepositStrategy PickStrategyFor(decimal amount) { // strategy with minimum fees; }

public decimal ExecuteStrategy(decimal amount) {

return this.strategy.Execute(amount);}

};

Page 53: Design Patterns

Strategy example

53

class DepositService{

public void Deposit(decimal amount) {

var context = new DepositContext();context.strategies.add(new Eiole());context.strategies.add(new Metacharge());

var totalAmount = context.ExecuteStrategy(amount);}

};

0 -> 200 € => Metacharge> 200 € => Eiole

Page 54: Design Patterns
Page 55: Design Patterns

Visitor

Represent an operation to be performed on the elements of an object structure.

Visitor lets you define a new operation without changing the classes of the elements on which it operates.

55Note : Implementation may have a real impact on performance !

Page 56: Design Patterns

Visitor example

56

interface IArticleVisitor{

void Visit(SportArticle sport);void Visit(PokerArticle poker);void Visit(TurfArticle turf);

}

interface IArticle{

string GetContent();...void Accept(IArticleVisitor visitor);

}

class SportArticle : IArticle{

public string GetContent()...

public void Accept(IArticleVisitor visitor) { visitor.Visit(this); }}

class SumUpArticleVisitor : IArticleVisitor{

private string Summary { get; set; }public string GetSummary() { return this.Summary; }

void Visit(SportArticle sport) { this.Summary += sport.GetContent().Substring(0, 200); }void Visit(PokerArticle poker) { this.Summary += poker.GetContent().Substring(0, 200); }void Visit(TurfArticle turf) { this.Summary += turf.GetContent().Substring(0, 200); }

public string BuildSummary(List<IArticle> articles) {

foreach(var article in articles) {article.Accept(this);

}return Summary;

}}

Page 57: Design Patterns

Visitor example

57

class SportArticle : IArticle{

public string MatchId { get; }

public void Accept(IArticleVisitor visitor) { visitor.Visit(this); }}

class UpdateStatusArticleVisitor : IArticleVisitor{

void Visit(SportArticle sport) { this.IsLive = Amelco.GetStatus(sport.MatchId) == 2; }

void Visit(PokerArticle poker) { }

void Visit(TurfArticle turf) { this.IsLive = PMC.GetStatus(turf.RaceId) == 99; }

public bool IsReferenceLive(IArticle article) {

article.Accept(this);return this.IsLive;

}}

class TurfArticle : IArticle{

public string RaceId { get; }

public void Accept(IArticleVisitor visitor) { visitor.Visit(this); }}

Page 58: Design Patterns

Conclusion

“With great power, comes great responsibilities” – Uncle Ben

• Design patterns are powerful tools, don’t hesitate to use them but beware of :

– Complexity

– Performance

58

Page 59: Design Patterns

59

Page 60: Design Patterns

Find out more

• On https://techblog.betclicgroup.com/

Page 61: Design Patterns

About Betclic• Betclic Everest Group, one of the world leaders in online gaming, has a unique portfolio

comprising various complementary international brands: Betclic, Everest Gaming, bet-at-home.com, Expekt…

• Active in 100 countries with more than 12 million customers worldwide, the Group is committed to promoting secure and responsible gaming and is a member of several international professional associations including the EGBA (European Gaming and Betting Association) and the ESSA (European Sports Security Association).

• Through our brands, Betclic Everest Group places expertise, technological know-how and security at the heart of our strategy to deliver an on-line gaming offer attuned to the passion of our players.


Recommended