event-getriebene programmierung in der praxis - … programmierung in der praxis ... domain driven...

Post on 17-May-2018

217 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Event-getriebene Programmierung in der PraxisDipl.-Inf. (FH) Marco Emrich Oct. 2014 @ XP-Days

Wo?Wozu?Wer?

GUIhttps://www.flickr.com/photos/joris/2410290034

https://www.flickr.com/photos/11319126@N00/8270409318/in/photostream

Architektur

Evented-SOA

Microservices

http://martinfowler.com/articles/microservices.html

GenerallesProgrammier-Modell

Method vs.

Event https://www.flickr.com/photos/gen/325927418

Sender ReceiverMessage

Method Call

Sender ReceiverListen

Raise Event

Event

Sender

ReceiverListen

Event

Raise Event Receiver

Listen

Receiver

Listen

https://www.flickr.com/photos/caroslines/547184477

Wiring

Sender

Receiver

Listen

Raise Event

Receiver

Listen

Receiver

Listen

Event-BUS

Pub/Sub

Sender

Receiver

Listen

EventRaise Event

Receiver

Listen

ReceiverListen

Sender

Raise Event

Event vs. Method

Method

Sender tells Receiver

Sync

Fixed Coupling

New Receiver: change to Sender

Event

Receiver listens to Sender

(Pseudo-) Async

Loose Coupling

New Receiver: no change to Sender

Sometimes: Hard to Test/Debug

Testing?

Isolationhttps://www.flickr.com/photos/loufi/3500076/

Winner?https://www.flickr.com/photos/48424574@N07/5096035675

Domain Driven Design

Hexagonal Architecture

Vaughn Vernon

Alistair Cokburn

Hexagonal Architecture

DomainModel

Hexagonal Architecture

DomainModel

Adapter Adapter

Adapte

rAdapter

Adapte

r

Adapter

Adapter

Adapter

Hexagonal Architecture

DomainModel

Adapter Adapter

Adapte

rAdapter

Adapte

r

Adapter

Adapter

Persistance

Adapter

Hexagonal Architecture

DomainModel

Adapter Adapter

Adapte

rAdapter

Adapte

r

Adapter

Adapter

Persistance

Adapter

GUI

Hexagonal Architecture

DomainModel

Adapter Adapter

Adapte

rAdapter

Adapte

r

Adapter

Adapter

Persistance

Adapter

GUI

Events

Events

Events

Events

CQRSEven Sourcing

Domain Eventsvs.

Commandshttps://www.flickr.com/photos/stevedave/3566325269

Event Storming

We want you for Kata

Code Retreat

Practice

http://udoncrew.deviantart.com/art/UFS-Impossible-Contortion-109860059

Try Extremes

TDD

Pair-Programming

2 x 35 min

+ Retrospective

Callcenter Kata

0911/123499040/456780171/3456789….

Phone Number / Caller ID

0911/123499040/456780171/3456789….

Phone Number / Caller ID

0911 Nürnberg

040 Hamburg

0911/123499….

040/45678….

0911/123499040/456780171/3456789….

Phone Number / Caller ID

0911 Nürnberg

0911/123499….

040/45678….

Statistik

040 Hamburg

Constraints

no Method-communication, Events only

Constraints

no Method-communication, Events only

Small Classes (SRP) max. 20-30 LOC / (Java: 50) max. 5 Methods

http://nodejs.org/api/events.html#events_emitter_addlistener_event_listener

JavaScript / Node.JS

https://github.com/asyncly/EventEmitter2

JavaScript / Browser

JavaScript / Node.JS

var EventEmitter = require('events').EventEmitter

var PhoneNumberGenerator = function(numbers) { this.numbers = numbers; this.currentNumber = 0;};

PhoneNumberGenerator.prototype = new EventEmitter();

PhoneNumberGenerator.prototype.sendNextNumber = function() { this.emit('NewPhoneNumberCreated', this.numbers[this.currentNumber]);}

var sleep = require('sleep');

PhoneNumberGenerator.prototype.start = function() { while(1) { sleep.sleep(n); this.sendNextNumber(); }}

JavaScript / Node.JS

JavaScript / Node.JSdescribe('PhoneNumberGenerator', function() { it('should emit numbers', function(done) { var generator = new PhoneNumberGenerator(['012345678']); generator.on('NewPhoneNumberCreated', function(payload) { expect(payload).toEqual('012345678') done(); }); generator.sendNextNumber();

});});

JavaScript / Node.JS

describe('PhoneNumberCounter', function() { it('should increase count on Number Events', function() { var emitterDummy = new EventEmitter; var counter = new PhoneNumberCounter(emitterDummy, 'NewPhoneNumberCreated'); emitterDummy.emit('NewPhoneNumberCreated', '1234'); emitterDummy.emit('NewPhoneNumberCreated', '4567'); expect(counter.value).toEqual(2); });});

https://github.com/jcoglan/eventful

gem install eventful

Ruby

class Watcher include Eventfulend

w = Watcher.new

w.on(:filechange) { |watcher, path| puts path }

w.fire(:filechange, '/path/to/file.txt')

Ruby - Eventful

java.util.EventListener

or

https://github.com/micwin/ticino

Java

Ticino - Eventdefinition

public class IncomingXmlEvent {

private String xml;

public IncomingXmlEvent(String xml) { this.xml = xml; }

public String getXml() { return xml; }}

Ticino - Receiver

public class Receiver { public void doSomethingWithThisEvent( IncomingXmlEvent incomingXml) { System.out.println("incoming: " + incomingXml.getXml()); }}

Ticino - Wiring

import net.micwin.ticino.Ticino;

public class Main { public static void main(String[] args) { Receiver rec = new Receiver(); Ticino.register(IncomingXmlEvent.class, rec); }}

Ticino.dispatch(new IncomingXmlEvent(newXml));

JUnit Hint

@Test(timeout=1000)public void mytest() { callAsyncTask(); waitForAsyncTask(); AssertAsyncTaskResult();}

https://github.com/marcoemrich/

@marcoemrich

www.webmasters.de

https://www.flickr.com/photos/eilonwy77/6270262038/in/photostream/

top related