fen 2014ucn teknologi/act2learn1 higher order functions observer pattern delegates events visitor...

29
FEN 2014 UCN Teknologi/act2learn 1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Upload: diane-gibson

Post on 18-Jan-2016

229 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

FEN 2014 UCN Teknologi/act2learn 1

Higher order functions

Observer PatternDelegates

EventsVisitor Pattern

Lambdas and closuresLambdas in libraries

Page 2: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

• Problem:– An unknown number of clients (observers)

want to be notified, when some object change state.

– Example: Ib’s cognac bottle:

FEN 2014 UCN Teknologi/act2learn 2

Observer Pattern

Page 3: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

FEN 2014 UCN Teknologi/act2learn 3

Observer Pattern

Drinker_1

Drinker_2

Drinker_N

Drinker_I

Drinks (change state)

Notify

Notify

Notify

Page 4: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

• Design Requirements:– Drinkers should be able to come and

go (add and remove observers).– Drinkers should know as little as

possible about how state is represented in the bottle.

– The bottle should know as little as possible about the observers.

– Drinkers may react differently on the notification about state change.

FEN 2014 UCN Teknologi/act2learn 4

Observer Pattern

Page 5: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Solution: Observer Pattern

FEN 2014 UCN Teknologi/act2learn 5

BottleState

ChangeAmount()

IObserver

NotifyMe()

IObservable

NotifyAll()Add()Remove()

0..*0..1 0..*0..1

Optimist Pessimist

Page 6: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

FEN 2014 UCN Teknologi/act2learn6

Observer Pattern(Call-back)

• A number of different objects (observers) wants to be notified when some given object (observable or subject) changes state.

• Subject must allow observers to enrol dynamically, and subject shall have no knowledge about the observers.

• This pattern is in sometimes known as call-back.

BottleState

ChangeAmount()

IObserver

NotifyMe()

IObservable

NotifyAll()Add()Remove()

0..*0..1 0..*0..1

Optimist Pessimist

Page 7: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

FEN 2014 UCN Teknologi/act2learn 7

Observer Pattern• Example: a number of

objects are interested in being told when some other object is changing state.

• These objects (the observers) must implement the interface IObserver.

• This means implementing the method NotifyMe.

• This method will be called when the observed object (subject) changes state.

• Subject must maintain a collection of observers and be able to notify all objects in the collection (IObservable).

• Subject calls NotifyAll, when a change in state happens

BottleState

ChangeAmount()

IObserver

NotifyMe()

IObservable

NotifyAll()Add()Remove()

0..*0..1 0..*0..1

Optimist Pessimist

See it work

Page 8: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Exercise• Add a Realist to the example. A realist will act as a pessimist, if

the bottle amount is less than 50 cl. and like an optimist otherwise.

• Make a method on BottleState that fills the bottle (amount = 70);

• (Extra): Refactor the observer example, so all the code to handle observers are placed in an abstract class. The method NotityAll() is to be abstract. The subject (BottleState) is to inherit the abstract class and implement NotifyAll().

FEN 2014 UCN Teknologi/act2learn 8

Page 9: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

FEN 2014 UCN Teknologi/act2learn 9

Observer Pattern and delegates

• Observer Pattern is an object-oriented design that simulates void-pointers in for instance C/C++ and higher order functions in for instance Pascal and functional languages.

• In C# the language construct delegate provides some of the same possibilities.

Page 10: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Delegates

• A delegate is a language construct that facilitates passing methods as parameters to other methods.

• This can be done both for instance and class methods.

• This can be done across objects and classes.• Delegates are object oriented and type safe.• Actual, a delegate is an object which contains a

collection of methods that may be invoked.

FEN 2014 UCN Teknologi/act2learn 10

Page 11: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Observer Delegate

• These features can be used to implement call-back:

• View: code sample

FEN 2014 UCN Teknologi/act2learn 11

Page 12: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Delegates:• The delegate must be

defined.

• The observers must implement a method with the signature (return type and parameter list) as the delegate.

FEN 2014 UCN Teknologi/act2learn 12

namespace DelegateExample{

delegate void Drinkers(int amount); //Declare the delegate's signature

class DelegateDemo {

static void Main(string[] args)//---class Optimist

{

public void NotifyMe(int amount) { Console.WriteLine("There is still left: “

+amount+" cl of cognac:-)"); } //---

Page 13: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Delegates:• A delegate is declared.

• The observers NotifyMe method are added to the delegate.

• Change state methods of the observable take the delegate as parameter.

• When the observable change state, all methods in the delegate is called.

• Note the check for not null!

FEN 2014 UCN Teknologi/act2learn 13

//---

Drinkers myDrinkers;BottleState myBottle = new BottleState();Pessimist ib = new Pessimist();Optimist kurt = new Optimist();

myDrinkers = ib.NotifyMe;myDrinkers += kurt.NotifyMe;//---

public void ChangeAmount(Drinkers myDrinkers){ Console.Write("Enter new bottleamount: "); this.amount = Convert.ToInt32(Console.ReadLine());

if(myDrinkers != null) myDrinkers(amount); //---

Not nice: The delegate

shouldn’t be public

Page 14: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Exercise

• Add a Realist to the example. A realist will act as a pessimist, if the bottle amount is less than 50 cl. and like an optimist otherwise.

FEN 2014 UCN Teknologi/act2learn 14

Page 15: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Delegates are objects them selves.They inherit from System.Delegate via System.MulticastDelegate

FEN 2014 UCN Teknologi/act2learn 15

St r i ng Ar r ay Val ueType Except i on Del egat e Cl ass1

Mul t i castDel egat e

Cl ass2

Cl ass3

Obj ect

Enum1

St r uct ur e1EnumPr i mi t i ve t ypes

Bool ean

Byt e

I nt 16

I nt 32

I nt 64

Char

Si ngl e

Doubl e

Deci mal

Dat eTi me

System-defined types

User-defined types

Del egat e1

Ti meSpan

Gui d

Page 16: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Events

• Delegates are often used for event based systems• The keyword event in C# makes this a little easier• The mechanism behind is the same. A event is a sort

of a specialised delegate.• Events are often used in object oriented GUI

programs • Events can be used with advantage in other areas

such as simulation and real-time systems.

• Example from Troelsen, chap. 10.

FEN 2014 UCN Teknologi/act2learn 16

Page 17: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Visitor Delegate

• Used for traversing a collection and changing elements without knowing anything about the internal structure of the collections.

• A sort of “mutator iterator”

• May be simulated using the Visitor Pattern (GoF 1995)

FEN 2014 UCN Teknologi/act2learn 17

Collection

y

x

z

ModifyAll( )

public int Double(int x){ return 2*x; }

View: code sample

Page 18: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Visitor Delegate

• In the container, define visiting delegates and methods visiting the container.

FEN 2014 UCN Teknologi/act2learn 18

public delegate int ModifyElement(int e);public delegate bool CheckElement(int e);

public void ModifyAll(ModifyElement f){ //implement according to data representation}

public void ModifySome(ModifyElement f, CheckElement p){ //implement according to data representation}

Page 19: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Visitor Delegate• In the client, declare

some methods to visit the container.

• Declare the delegates and add the visitor methods.

• Visit the container.

FEN 2014 UCN Teknologi/act2learn 19

public static int Double(int x){ return 2*x;}

public static bool Even(int x){ return x % 2 == 0;}

//---Container.ModifyElement toDo= Double;Container.CheckElement cond = Even;

con1.ModifySome(toDo, cond);//---

Page 20: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Exercise

• Add methods to the Visitor example, so it is possible to increase all numbers greater than 20 in the container by 7.

• Test

FEN 2014 UCN Teknologi/act2learn 20

Page 21: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Lambdas

• Since C# 3.0 lambdas have been part of C#. Lambdas make it possible to work with delegates without explicitly declaring delegates etc.

• A lambda is an anonymous function witch can be passed to a method that accepts a delegate as parameter.

• Lambdas are sometimes called lambda expressions.

• The term “lambda” comes from the theory of functional programming. (Alonzo Church: Lambda Calculus, 1936).

FEN 2014 UCN Teknologi/act2learn 21

View: code sample

Page 22: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Visitor using lambdas• It’s not necessary to

declare delegates explicitly.

• The standard library delegate Func<in, out> can be used in the visitor method.

• Call the visitor method on the container supplying two lambda expressions (anonymous methods) as argument.

FEN 2014 UCN Teknologi/act2learn 22

public void ModifySome(Func<int, int> f,

Func<int, bool> p){ //Applies f only to elements in the container //that satisfy p for (int i = 0; i < a.Length; i++) { if (p(a[i])) a[i] = f(a[i]); }}

//---

con1.ModifySome((x) => 2 * x, (x) => x % 2 == 0);

//---

Page 23: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Dissecting the lambda expression

FEN 2014 UCN Teknologi/act2learn 23

//---

con1.ModifySome((x) => 2 * x,

(x) => x % 2 == 0);//---

Lambda operator

Input parameter

Function code (body)

Page 24: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Lambda typingHow are lambda expressions typed? Some examples…

What’s New 24

() =>

{ ...}

Action

(i) =>

{ ...}

Action<int>

() =>

{ ...

return d;}

Func<double>

(i) =>

{ ...

return d;}

Func<int, double>

Page 25: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Lambda typingHow are lambda expressions typed? Some examples…

What’s New 25

(i) =>

{ ...

return d==0;}

Predicate<int>

View: code sample

Page 26: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Closures and lambdas• Sometimes you may want to

use variables in the lambda expression that are not passed as parameters to the lambda:

• The variable c is defined outside the lambdas scope.

• The compiler computes the closure of the lambda.

• The compiler generates a class with the lambda method and the needed variables, and it is actually this class that is passed around.

FEN 2014 UCN Teknologi/act2learn 26

//---

int c = 2;con1.ModifySome((x) => c * x, (x) => x % 2 == 0);//---

Page 27: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Exercise

• Add code to the lambda example, so all numbers greater than 20 in the container are increased by 7.

• Add a new higher order function: public it SumSome(int seed, Predicate<int> p)that sums the elements in the container that satisfies p. seed is the start value of the summing.

• Test by summing, for instance only elements greater than or equal to 20.

• Generalise your function, so it only sums elements in a given range (from start index to end index).

FEN 2014 UCN Teknologi/act2learn 27

Page 28: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Lambdas in the libraries

• Lambdas are heavily used in the libraries.• Many methods are to be called with a lambda

expression as argument:

FEN 2014 UCN Teknologi/act2learn 28

View: code sample

Page 29: FEN 2014UCN Teknologi/act2learn1 Higher order functions Observer Pattern Delegates Events Visitor Pattern Lambdas and closures Lambdas in libraries

Exercise

• Try some of the higher order functions defined on collections.– For instance:

• Find/FindLast: Find first/last element with Y == 3.• FindAll: Find all elements with X==Y• Exists/All: Use exists to determine if the list contains (0, 0).• Sum: Find the sum of the square of the x’s• Average: Find the average of the x’s• Count: How many pairs have x != y?

• Try to change List to some other collection. Which higher order functions do still apply?

FEN 2014 UCN Teknologi/act2learn 29

View: code sample