SlideShare a Scribd company logo
1 of 44
Download to read offline
Observations on the
Implementation of Design
Patterns in C# and .NET
Dmitri Nesteruk
@dnesteruk
Why design patterns?
Design patterns are no longer as
fashionable
Still relevant, translated to most
OOP languages
We assume everyone knows
them
Made a video course on them
(book might happen)
Design pattern and architecture-
related observations
Local Inversion of Control
Normal control: x.foo(y)
Inverted control: y.foo(x)
Implemented using e.g. extension methods
Names.Add(name);
“Names should add to itself the name”
name.AddTo(Names);
“Take name and add to Names”
public static T AddTo<T>(
this T self,
ICollection<T> c)
{
c.Add(self);
return self;
}
name.AddTo(Names);
name.AddTo(Names)
.AddTo(OtherNames)
.SomeOtherStuff();
op == "AND" || op == "OR" || op == "XOR"
Operation is AND or OR or XOR
new[]{"AND","OR","XOR"}.Contains(op)
This list of operations contains our operation (ugly)
op.IsOneOf("AND","OR","XOR")
Operation is one of the following
public static bool IsOneOf<T>(
this T self,
params T[] items)
{
return items.Contains(self);
}
Composite
Exposing collections and scalar objects in a uniform
way
Different scales:
Properties
Entire objects
Property Composite
I have names {FirstName, MiddleName, LastName}
Sometimes, I want an individual name
person.FirstName
Sometimes, I want to print the full name
string.Join(" ", person.Names)
How do I get person.Names?
public class Person
{
string FirstName, … { get; }
public IEnumerable<string> Names
{
yield return FirstName;
…
}
}
Array-Backed Properties
Suppose I want to add Title before the names…
How should I expose it?
Why not store names contiguously?
Never accidentally fail to yield a name from Names
Easier serialization (never miss a property)
Many aggregate get-only properties (e.g., full name
without title)
public class Person
{
private string names[4];
public string Title
{
get { return names[0]; }
set { names[0] = value; }
}
public string FullNameNoTitle
=> names.Skip(1).Join(' ');
}
Composite at Class Scale
Neural network model
A single neuron can be
connected to another
neuron
A bunch of neurons form a
layer
We want all forms of
entities to be connectable
class Neuron
{
public List<Neuron> In, Out;
}
class Neuron
{
public List<Neuron> In, Out;
public void ConnectTo(Neuron other)
{
Out.Add(other);
other.In.Add(this);
}
}
public class NeuronLayer :
Collection<Neuron> {}
var neuron1 = new Neuron();
var neuron2 = new Neuron();
var layer1 = new NeuronLayer();
var layer2 = new NeuronLayer();
neuron1.ConnectTo(neuron2);
neuron1.ConnectTo(layer1);
layer2.ConnectTo(neuron1);
layer1.ConnectTo(layer2);
Hot to make a single ConnectTo()?
Cannot make a base class: NeuronLayer already has
one
Use a common interface
NeuronLayer is an IEnumerable<Neuron>
So why not make Neuron IEnumerable<Neuron>
too?
class Neuron : IEnumerable<Neuron>
{
public List<Neuron> In, Out;
public void ConnectTo(Neuron other)
{
Out.Add(other);
other.In.Add(this);
}
}
public class Neuron : IEnumerable<Neuron>
{
public List<Neuron> In, Out;
public IEnumerator<Neuron> GetEnumerator()
{
yield return this;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public static void ConnectTo(
this IEnumerable<Neuron> self,
IEnumerable<Neuron> other)
{
if (ReferenceEquals(self, other)) return;
foreach (var from in self)
foreach (var to in other)
{
from.Out.Add(to);
to.In.Add(from);
}
}
var neuron1 = new Neuron();
var neuron2 = new Neuron();
var layer1 = new NeuronLayer();
var layer2 = new NeuronLayer();
neuron1.ConnectTo(neuron2);
neuron1.ConnectTo(layer1);
layer2.ConnectTo(neuron1);
layer1.ConnectTo(layer2);
Dynamic in Design Patterns
Runtime-constructed Null Object
Dynamic Proxy
Dynamic Visitor
Null Object
A no-op object that can be injected when required
Typically conforms to an interface
We might not want to explicitly construct such an
object (e.g., for testing)
Dynamic to the rescue!
public interface ILog
{
void Info(string msg);
void Warn(string msg);
}
class ConsoleLog : ILog
{
public void Info(string msg)
{
WriteLine(msg);
}
⋮
}
public class BankAccount
{
private ILog log;
private int balance;
public BankAccount(ILog log) { this.log = log; }
public void Deposit(int amount)
{
balance += amount;
log.Info(
$"Deposited ${amount}, balance is now {balance}");
}
}
Problem
We have a hard dependency on ILog
We cannot supply null – too many NREs
We cannot rewrite existing code to use ?.
everywhere
Log may be passed on to other components
How to make a log that does nothing?
sealed class NullLog : ILog
{
public void Info(string msg) {}
public void Warn(string msg) {}
}
public class Null<T> :
DynamicObject where T:class
{
⋮
}
override bool TryInvokeMember(
InvokeMemberBinder binder,
object[] args, out object result)
{
result = Activator.CreateInstance(
binder.ReturnType);
return true;
}
public static T Instance
{
get
{
// ImpromptuInterface
return new Null<T>().ActLike<T>();
}
}
var log = Null<ILog>.Instance;
var ba = new BankAccount(log);
Dynamic Visitor
Dispatch = how many pieces of info do I need to
know what to call?
Static dispatch = all information must be known at
compile time 
Then what’s the point of polymorphism?
interface IStuff { }
class Foo : IStuff { }
class Bar : IStuff { }
static void f(Foo foo) { }
static void f(Bar bar) { }
IStuff i = new Foo();
f(i); // cannot resolve
// call needs to be on i
public abstract class Expression
{
public abstract void Accept(IExpressionVisitor visitor);
}
public interface IExpressionVisitor
{
void Visit(DoubleExpression de);
void Visit(AdditionExpression ae);
}
public class DoubleExpression : Expression
{
override void Accept(IExpressionVisitor visitor)
{
visitor.Visit(this);
}
} // f⋆⋆⋆ this, too much work!
interface IStuff { }
class Foo : IStuff { }
class Bar : IStuff { }
static void f(Foo foo) { }
static void f(Bar bar) { }
IStuff i = new Foo();
f((dynamic)i); // woo-hoo!
// dynamic dispatch!
Dynamic Proxy
Null Object: remove logging from entity
Dynamic Proxy: add logging to entity (at runtime!)
Implementations of Null<T> and Log<T> are
almost identical…
public class Log<T> : DynamicObject
where T : class, new()
{
private readonly T subject;
private Dictionary<string, int> methodCallCount =
new Dictionary<string, int>();
protected Log(T subject)
{
this.subject = subject;
}
⋮
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
try
{
// logging
WriteLine($"Invoking {subject.GetType().Name}.{binder.Name} ([{string.Join(",", args)}])");
// more logging
if (methodCallCount.ContainsKey(binder.Name)) methodCallCount[binder.Name]++;
else methodCallCount.Add(binder.Name, 1);
result = subject.GetType().GetMethod(binder.Name).Invoke(subject, args);
return true;
}
catch
{
result = null;
return false;
}
}
public static I As<I>() where I : class
{
// ensure I is an interface
return new Log<T>(new T())
.ActLike<I>();
}
public string Info
{
get
{
var sb = new StringBuilder();
foreach (var kv in methodCallCount)
sb.AppendLine($"{kv.Key} called {kv.Value} time(s)");
return sb.ToString();
}
}
// will not be proxied automatically
public override string ToString()
{
return $"{Info}{subject}";
}
var ba = Log<BankAccount>.As<IBankAccount>();
ba.Deposit(100);
ba.Withdraw(50);
WriteLine(ba); // ToString()
// DynamicObject overrides :(
That’s it!
Questions? Answers? Hate mail? @dnesteruk
Design Patterns in .NET online course at http://bit.ly/2p3aZww
ImpromptuInterface: https://github.com/ekonbenefits/impromptu-interface

More Related Content

What's hot

Declarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeDeclarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeKevlin Henney
 
Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)Rick Copeland
 
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBTDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBtdc-globalcode
 
Expression trees in c#, Алексей Голубь (Svitla Systems)
Expression trees in c#, Алексей Голубь (Svitla Systems)Expression trees in c#, Алексей Голубь (Svitla Systems)
Expression trees in c#, Алексей Голубь (Svitla Systems)Alina Vilk
 
Free Monads Getting Started
Free Monads Getting StartedFree Monads Getting Started
Free Monads Getting StartedKent Ohashi
 
Functions in python
Functions in pythonFunctions in python
Functions in pythonIlian Iliev
 
Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Andrey Akinshin
 
Easy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEEasy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEUehara Junji
 
Python quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung FuPython quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung Fuclimatewarrior
 
Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4Ismar Silveira
 
Compiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersCompiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersEelco Visser
 
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...Uehara Junji
 
Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with StatixEelco Visser
 
Code as data as code.
Code as data as code.Code as data as code.
Code as data as code.Mike Fogus
 
Naïveté vs. Experience
Naïveté vs. ExperienceNaïveté vs. Experience
Naïveté vs. ExperienceMike Fogus
 
The Macronomicon
The MacronomiconThe Macronomicon
The MacronomiconMike Fogus
 
Introduction to Python and TensorFlow
Introduction to Python and TensorFlowIntroduction to Python and TensorFlow
Introduction to Python and TensorFlowBayu Aldi Yansyah
 

What's hot (20)

Declarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeDeclarative Thinking, Declarative Practice
Declarative Thinking, Declarative Practice
 
Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)
 
Oop objects_classes
Oop objects_classesOop objects_classes
Oop objects_classes
 
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBTDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
 
Expression trees in c#, Алексей Голубь (Svitla Systems)
Expression trees in c#, Алексей Голубь (Svitla Systems)Expression trees in c#, Алексей Голубь (Svitla Systems)
Expression trees in c#, Алексей Голубь (Svitla Systems)
 
Free Monads Getting Started
Free Monads Getting StartedFree Monads Getting Started
Free Monads Getting Started
 
Functions in python
Functions in pythonFunctions in python
Functions in python
 
Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?
 
Easy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEEasy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVE
 
Functions
FunctionsFunctions
Functions
 
Python quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung FuPython quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung Fu
 
Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4
 
Compiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersCompiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | Interpreters
 
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
 
Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with Statix
 
Code as data as code.
Code as data as code.Code as data as code.
Code as data as code.
 
Naïveté vs. Experience
Naïveté vs. ExperienceNaïveté vs. Experience
Naïveté vs. Experience
 
The Macronomicon
The MacronomiconThe Macronomicon
The Macronomicon
 
Introduction to Python and TensorFlow
Introduction to Python and TensorFlowIntroduction to Python and TensorFlow
Introduction to Python and TensorFlow
 
Go Java, Go!
Go Java, Go!Go Java, Go!
Go Java, Go!
 

Similar to Design Pattern Observations

Javascript fundamentals for php developers
Javascript fundamentals for php developersJavascript fundamentals for php developers
Javascript fundamentals for php developersChris Ramakers
 
Introduction to Functional Programming
Introduction to Functional ProgrammingIntroduction to Functional Programming
Introduction to Functional ProgrammingHoàng Lâm Huỳnh
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)James Titcumb
 
Java Serialization
Java SerializationJava Serialization
Java Serializationjeslie
 
エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理maruyama097
 
Functional Programming You Already Know
Functional Programming You Already KnowFunctional Programming You Already Know
Functional Programming You Already KnowKevlin Henney
 
Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5Stephan Schmidt
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest UpdatesIftekhar Eather
 
Kotlin for android developers whats new
Kotlin for android developers whats newKotlin for android developers whats new
Kotlin for android developers whats newSerghii Chaban
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)Pavlo Baron
 
Design patterns illustrated 010PHP
Design patterns illustrated 010PHPDesign patterns illustrated 010PHP
Design patterns illustrated 010PHPHerman Peeren
 
Implementation of interface9 cm604.30
Implementation of interface9 cm604.30Implementation of interface9 cm604.30
Implementation of interface9 cm604.30myrajendra
 
شرح مقرر البرمجة 2 لغة جافا - الوحدة السابعة
شرح مقرر البرمجة 2   لغة جافا - الوحدة السابعةشرح مقرر البرمجة 2   لغة جافا - الوحدة السابعة
شرح مقرر البرمجة 2 لغة جافا - الوحدة السابعةجامعة القدس المفتوحة
 
Hipster oriented programming (Mobilization Lodz 2015)
Hipster oriented programming (Mobilization Lodz 2015)Hipster oriented programming (Mobilization Lodz 2015)
Hipster oriented programming (Mobilization Lodz 2015)Jens Ravens
 
Java Generics
Java GenericsJava Generics
Java Genericsjeslie
 
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Codemotion
 
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#Mark Needham
 

Similar to Design Pattern Observations (20)

Javascript fundamentals for php developers
Javascript fundamentals for php developersJavascript fundamentals for php developers
Javascript fundamentals for php developers
 
Introduction to Functional Programming
Introduction to Functional ProgrammingIntroduction to Functional Programming
Introduction to Functional Programming
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Java Serialization
Java SerializationJava Serialization
Java Serialization
 
エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理
 
Functional Programming You Already Know
Functional Programming You Already KnowFunctional Programming You Already Know
Functional Programming You Already Know
 
L04 Software Design 2
L04 Software Design 2L04 Software Design 2
L04 Software Design 2
 
Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
C# for Java Developers
C# for Java DevelopersC# for Java Developers
C# for Java Developers
 
Kotlin for android developers whats new
Kotlin for android developers whats newKotlin for android developers whats new
Kotlin for android developers whats new
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
Object-oriented Basics
Object-oriented BasicsObject-oriented Basics
Object-oriented Basics
 
Design patterns illustrated 010PHP
Design patterns illustrated 010PHPDesign patterns illustrated 010PHP
Design patterns illustrated 010PHP
 
Implementation of interface9 cm604.30
Implementation of interface9 cm604.30Implementation of interface9 cm604.30
Implementation of interface9 cm604.30
 
شرح مقرر البرمجة 2 لغة جافا - الوحدة السابعة
شرح مقرر البرمجة 2   لغة جافا - الوحدة السابعةشرح مقرر البرمجة 2   لغة جافا - الوحدة السابعة
شرح مقرر البرمجة 2 لغة جافا - الوحدة السابعة
 
Hipster oriented programming (Mobilization Lodz 2015)
Hipster oriented programming (Mobilization Lodz 2015)Hipster oriented programming (Mobilization Lodz 2015)
Hipster oriented programming (Mobilization Lodz 2015)
 
Java Generics
Java GenericsJava Generics
Java Generics
 
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
 
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
 

More from Dmitri Nesteruk

Good Ideas in Programming Languages
Good Ideas in Programming LanguagesGood Ideas in Programming Languages
Good Ideas in Programming LanguagesDmitri Nesteruk
 
CallSharp: Automatic Input/Output Matching in .NET
CallSharp: Automatic Input/Output Matching in .NETCallSharp: Automatic Input/Output Matching in .NET
CallSharp: Automatic Input/Output Matching in .NETDmitri Nesteruk
 
Design Patterns in Modern C++
Design Patterns in Modern C++Design Patterns in Modern C++
Design Patterns in Modern C++Dmitri Nesteruk
 
Introduction to Programming Bots
Introduction to Programming BotsIntroduction to Programming Bots
Introduction to Programming BotsDmitri Nesteruk
 
Converting Managed Languages to C++
Converting Managed Languages to C++Converting Managed Languages to C++
Converting Managed Languages to C++Dmitri Nesteruk
 
YouTrack: Not Just an Issue Tracker
YouTrack: Not Just an Issue TrackerYouTrack: Not Just an Issue Tracker
YouTrack: Not Just an Issue TrackerDmitri Nesteruk
 
Victor CG Erofeev - Metro UI
Victor CG Erofeev - Metro UIVictor CG Erofeev - Metro UI
Victor CG Erofeev - Metro UIDmitri Nesteruk
 
Dynamics CRM Data Integration
Dynamics CRM Data IntegrationDynamics CRM Data Integration
Dynamics CRM Data IntegrationDmitri Nesteruk
 
ReSharper Presentation for NUGs
ReSharper Presentation for NUGsReSharper Presentation for NUGs
ReSharper Presentation for NUGsDmitri Nesteruk
 
ReSharper Architecture & Extensions
ReSharper Architecture & ExtensionsReSharper Architecture & Extensions
ReSharper Architecture & ExtensionsDmitri Nesteruk
 

More from Dmitri Nesteruk (20)

Good Ideas in Programming Languages
Good Ideas in Programming LanguagesGood Ideas in Programming Languages
Good Ideas in Programming Languages
 
CallSharp: Automatic Input/Output Matching in .NET
CallSharp: Automatic Input/Output Matching in .NETCallSharp: Automatic Input/Output Matching in .NET
CallSharp: Automatic Input/Output Matching in .NET
 
Design Patterns in Modern C++
Design Patterns in Modern C++Design Patterns in Modern C++
Design Patterns in Modern C++
 
C# Tricks
C# TricksC# Tricks
C# Tricks
 
Introduction to Programming Bots
Introduction to Programming BotsIntroduction to Programming Bots
Introduction to Programming Bots
 
Converting Managed Languages to C++
Converting Managed Languages to C++Converting Managed Languages to C++
Converting Managed Languages to C++
 
Monte Carlo C++
Monte Carlo C++Monte Carlo C++
Monte Carlo C++
 
Tpl DataFlow
Tpl DataFlowTpl DataFlow
Tpl DataFlow
 
YouTrack: Not Just an Issue Tracker
YouTrack: Not Just an Issue TrackerYouTrack: Not Just an Issue Tracker
YouTrack: Not Just an Issue Tracker
 
Проект X2C
Проект X2CПроект X2C
Проект X2C
 
Domain Transformations
Domain TransformationsDomain Transformations
Domain Transformations
 
Victor CG Erofeev - Metro UI
Victor CG Erofeev - Metro UIVictor CG Erofeev - Metro UI
Victor CG Erofeev - Metro UI
 
Developer Efficiency
Developer EfficiencyDeveloper Efficiency
Developer Efficiency
 
Distributed Development
Distributed DevelopmentDistributed Development
Distributed Development
 
Dynamics CRM Data Integration
Dynamics CRM Data IntegrationDynamics CRM Data Integration
Dynamics CRM Data Integration
 
ReSharper Presentation for NUGs
ReSharper Presentation for NUGsReSharper Presentation for NUGs
ReSharper Presentation for NUGs
 
ReSharper Architecture & Extensions
ReSharper Architecture & ExtensionsReSharper Architecture & Extensions
ReSharper Architecture & Extensions
 
Web mining
Web miningWeb mining
Web mining
 
Data mapping tutorial
Data mapping tutorialData mapping tutorial
Data mapping tutorial
 
Reactive Extensions
Reactive ExtensionsReactive Extensions
Reactive Extensions
 

Recently uploaded

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetEnjoy Anytime
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 

Design Pattern Observations

  • 1. Observations on the Implementation of Design Patterns in C# and .NET Dmitri Nesteruk @dnesteruk
  • 2. Why design patterns? Design patterns are no longer as fashionable Still relevant, translated to most OOP languages We assume everyone knows them Made a video course on them (book might happen) Design pattern and architecture- related observations
  • 3. Local Inversion of Control Normal control: x.foo(y) Inverted control: y.foo(x) Implemented using e.g. extension methods
  • 4. Names.Add(name); “Names should add to itself the name” name.AddTo(Names); “Take name and add to Names”
  • 5. public static T AddTo<T>( this T self, ICollection<T> c) { c.Add(self); return self; }
  • 7. op == "AND" || op == "OR" || op == "XOR" Operation is AND or OR or XOR new[]{"AND","OR","XOR"}.Contains(op) This list of operations contains our operation (ugly) op.IsOneOf("AND","OR","XOR") Operation is one of the following
  • 8. public static bool IsOneOf<T>( this T self, params T[] items) { return items.Contains(self); }
  • 9. Composite Exposing collections and scalar objects in a uniform way Different scales: Properties Entire objects
  • 10. Property Composite I have names {FirstName, MiddleName, LastName} Sometimes, I want an individual name person.FirstName Sometimes, I want to print the full name string.Join(" ", person.Names) How do I get person.Names?
  • 11. public class Person { string FirstName, … { get; } public IEnumerable<string> Names { yield return FirstName; … } }
  • 12. Array-Backed Properties Suppose I want to add Title before the names… How should I expose it? Why not store names contiguously? Never accidentally fail to yield a name from Names Easier serialization (never miss a property) Many aggregate get-only properties (e.g., full name without title)
  • 13. public class Person { private string names[4]; public string Title { get { return names[0]; } set { names[0] = value; } } public string FullNameNoTitle => names.Skip(1).Join(' '); }
  • 14. Composite at Class Scale Neural network model A single neuron can be connected to another neuron A bunch of neurons form a layer We want all forms of entities to be connectable
  • 16. class Neuron { public List<Neuron> In, Out; public void ConnectTo(Neuron other) { Out.Add(other); other.In.Add(this); } }
  • 17. public class NeuronLayer : Collection<Neuron> {}
  • 18. var neuron1 = new Neuron(); var neuron2 = new Neuron(); var layer1 = new NeuronLayer(); var layer2 = new NeuronLayer(); neuron1.ConnectTo(neuron2); neuron1.ConnectTo(layer1); layer2.ConnectTo(neuron1); layer1.ConnectTo(layer2);
  • 19. Hot to make a single ConnectTo()? Cannot make a base class: NeuronLayer already has one Use a common interface NeuronLayer is an IEnumerable<Neuron> So why not make Neuron IEnumerable<Neuron> too?
  • 20. class Neuron : IEnumerable<Neuron> { public List<Neuron> In, Out; public void ConnectTo(Neuron other) { Out.Add(other); other.In.Add(this); } }
  • 21. public class Neuron : IEnumerable<Neuron> { public List<Neuron> In, Out; public IEnumerator<Neuron> GetEnumerator() { yield return this; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } }
  • 22. public static void ConnectTo( this IEnumerable<Neuron> self, IEnumerable<Neuron> other) { if (ReferenceEquals(self, other)) return; foreach (var from in self) foreach (var to in other) { from.Out.Add(to); to.In.Add(from); } }
  • 23. var neuron1 = new Neuron(); var neuron2 = new Neuron(); var layer1 = new NeuronLayer(); var layer2 = new NeuronLayer(); neuron1.ConnectTo(neuron2); neuron1.ConnectTo(layer1); layer2.ConnectTo(neuron1); layer1.ConnectTo(layer2);
  • 24. Dynamic in Design Patterns Runtime-constructed Null Object Dynamic Proxy Dynamic Visitor
  • 25. Null Object A no-op object that can be injected when required Typically conforms to an interface We might not want to explicitly construct such an object (e.g., for testing) Dynamic to the rescue!
  • 26. public interface ILog { void Info(string msg); void Warn(string msg); } class ConsoleLog : ILog { public void Info(string msg) { WriteLine(msg); } ⋮ }
  • 27. public class BankAccount { private ILog log; private int balance; public BankAccount(ILog log) { this.log = log; } public void Deposit(int amount) { balance += amount; log.Info( $"Deposited ${amount}, balance is now {balance}"); } }
  • 28. Problem We have a hard dependency on ILog We cannot supply null – too many NREs We cannot rewrite existing code to use ?. everywhere Log may be passed on to other components How to make a log that does nothing?
  • 29. sealed class NullLog : ILog { public void Info(string msg) {} public void Warn(string msg) {} }
  • 30. public class Null<T> : DynamicObject where T:class { ⋮ }
  • 31. override bool TryInvokeMember( InvokeMemberBinder binder, object[] args, out object result) { result = Activator.CreateInstance( binder.ReturnType); return true; }
  • 32. public static T Instance { get { // ImpromptuInterface return new Null<T>().ActLike<T>(); } }
  • 33. var log = Null<ILog>.Instance; var ba = new BankAccount(log);
  • 34. Dynamic Visitor Dispatch = how many pieces of info do I need to know what to call? Static dispatch = all information must be known at compile time  Then what’s the point of polymorphism?
  • 35. interface IStuff { } class Foo : IStuff { } class Bar : IStuff { } static void f(Foo foo) { } static void f(Bar bar) { } IStuff i = new Foo(); f(i); // cannot resolve // call needs to be on i
  • 36. public abstract class Expression { public abstract void Accept(IExpressionVisitor visitor); } public interface IExpressionVisitor { void Visit(DoubleExpression de); void Visit(AdditionExpression ae); } public class DoubleExpression : Expression { override void Accept(IExpressionVisitor visitor) { visitor.Visit(this); } } // f⋆⋆⋆ this, too much work!
  • 37. interface IStuff { } class Foo : IStuff { } class Bar : IStuff { } static void f(Foo foo) { } static void f(Bar bar) { } IStuff i = new Foo(); f((dynamic)i); // woo-hoo! // dynamic dispatch!
  • 38. Dynamic Proxy Null Object: remove logging from entity Dynamic Proxy: add logging to entity (at runtime!) Implementations of Null<T> and Log<T> are almost identical…
  • 39. public class Log<T> : DynamicObject where T : class, new() { private readonly T subject; private Dictionary<string, int> methodCallCount = new Dictionary<string, int>(); protected Log(T subject) { this.subject = subject; } ⋮
  • 40. public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { try { // logging WriteLine($"Invoking {subject.GetType().Name}.{binder.Name} ([{string.Join(",", args)}])"); // more logging if (methodCallCount.ContainsKey(binder.Name)) methodCallCount[binder.Name]++; else methodCallCount.Add(binder.Name, 1); result = subject.GetType().GetMethod(binder.Name).Invoke(subject, args); return true; } catch { result = null; return false; } }
  • 41. public static I As<I>() where I : class { // ensure I is an interface return new Log<T>(new T()) .ActLike<I>(); }
  • 42. public string Info { get { var sb = new StringBuilder(); foreach (var kv in methodCallCount) sb.AppendLine($"{kv.Key} called {kv.Value} time(s)"); return sb.ToString(); } } // will not be proxied automatically public override string ToString() { return $"{Info}{subject}"; }
  • 43. var ba = Log<BankAccount>.As<IBankAccount>(); ba.Deposit(100); ba.Withdraw(50); WriteLine(ba); // ToString() // DynamicObject overrides :(
  • 44. That’s it! Questions? Answers? Hate mail? @dnesteruk Design Patterns in .NET online course at http://bit.ly/2p3aZww ImpromptuInterface: https://github.com/ekonbenefits/impromptu-interface