SlideShare a Scribd company logo
1 of 22
Ed Blackburn
Freelance Developer
@ejblackburn
http://ejb.name
Oyster Card
July 2003
© “Oyster Card" by Frank Murmann is licensed under CC BY3.0
Contactless
2014
“Prove it”
Components
• Identity Management
• Customer Services
• Customer Portal
• Payment and Risk Services
• Canonical, versioned reference data
• Path finding fare generation for routes
• Journey Construction, apportionment, capping and fares
“Behaviour”
© “Relativity" by M. C. Escheris, 1953
Evolving the MVP
• Revenue Protection
• Disruptions
• Travel Products (Weekly, Monthly, Annual…)
Philosophy
• Object-Orientation; an object has both state (data)
and behaviour (logic)
• Domain model focused
• Tell don’t ask
• SOLID
“Tell Don’t Ask”
https://pragprog.com/articles/tell-dont-ask
Tell Don’t Ask
public class Journey
{
…
public void AssociateRevenueInspectionTap(Tap tap) {..};
public void CounterZeroRateDueToRevenueProtection() {..};
…
}
Tell Don’t Ask?
public class Journey : Entity<Journey, JourneyKey>, IComparable<Journey>, IComparable<Tap>,
ITapSequence, ICanProtectRevenue, IJourneyAffectedByRevenueInspection, IMayNotExist,
IHaveTravelDayKey, IRateable, IDisruptable
{
…
public void AssociateRevenueInspectionTap(Tap tap) {..};
public void CounterZeroRateDueToRevenueProtection() {..};
public bool IsCounteredBy(Tap candidate) {..};
public bool Exists { get; }
public bool ContainsRevenueInspectionTap { get; }
…
}
internal IRule<Tap> CreateRule(TravelDay travelDay)
{
// Create rules
return Rule.Create(..);
}
private IRule<Tap> CreateRule(TravelDay travelDay)
{
// Create rules
return Rule.Create(specification: new IsRITWithinPreviousJourney(travelDay),
ifSatisfied: ScenarioT01,
ifNotSatisfied: Rule.Create(..));
}
private IRule<Tap> CreateRule(TravelDay travelDay)
{
// Create rules
return Rule.Create(specification: new IsRITWithinPreviousJourney(travelDay),
ifSatisfied: ScenarioT01,
ifNotSatisfied: Rule.Create(
specification: new
IsPreviousJourneyDisrupted(travelDay),
ifSatisfied: ScenarioTDIS01,
ifNotSatisfied: ScenarioT02
));
}
public sealed class IsTapTypeRailInspection : Specification<Tap>
{
private static readonly ISpecification<Tap> _compositeSpecification =
new IsTapModeRail().And(new IsTapTypeRevenueInspection());
protected override bool IsSatisfiedBy(Tap candidate)
{
return _compositeSpecification.IsSatisfiedBy(candidate);
}
}
“Small Is Beautiful”
• E. F. Schumacher
• To counter Bigger is Better
• Empowers developers to build complex features
through small lego pieces
• Easy to read
Aggregate
“Nothing outside the Aggregate boundary can
hold a reference to anything inside, except to
the root entity…”
- Eric Evans, Domain Driven Design, 2004
Aggregates & Continuations?
public class Card : Entity<Card, TravelTokenId> {
…
public void PerformCommand(IRuleCommand<Journey> command)
{
PerformCommand(command, () => _journeys.Select(item => … )
}
private void PerformCommand<TEntity>(IRuleCommand<TEntity> command,
Func<IEnumerable<TEntity>> getEntities)
{
Rule.Create(command).Process(getEntities());
}
…
}
Pipelines and decorators
public interface ICardOperation
{
Card Process(Card card);
}
public interface IDecoratedCardOperation
{
ICardOperation InnerCardOperation { get; private set; }
}
public class RevenueProtection : ICardOperation, IDecoratedCardOperation
{
public RevenueProtection (...)
{
...
}
public Card Process (Card card)
{
card = InnerCardOperation.Process (card);
...
return card;
}
public ICardOperation InnerCardOperation { get;set;}
}
Summary
• Abstractions rot code
• Small interfaces
• If you have a DTO reconsider your approach
• Even anaemic models can be encapsulated
• Immutability is your friend
Future?
• Token based software system
• Anything can create a token
• Vehicle registration plate
• Phone / wearable
• APIs (dog fooding with mobile)
• Data, data, data…

More Related Content

Similar to Ed Blackburn NDC

Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your CodeDrupalDay
 
Game jump: frontend introduction #1
Game jump: frontend introduction #1Game jump: frontend introduction #1
Game jump: frontend introduction #1Sebastian Pożoga
 
iPhone - web development lotus notes domino
iPhone - web development lotus notes dominoiPhone - web development lotus notes domino
iPhone - web development lotus notes dominodominion
 
Medium TechTalk — iOS
Medium TechTalk — iOSMedium TechTalk — iOS
Medium TechTalk — iOSjimmyatmedium
 
Oracle MAF real life OOW.pptx
Oracle MAF real life OOW.pptxOracle MAF real life OOW.pptx
Oracle MAF real life OOW.pptxLuc Bors
 
A Rich Web experience with jQuery, Ajax and .NET
A Rich Web experience with jQuery, Ajax and .NETA Rich Web experience with jQuery, Ajax and .NET
A Rich Web experience with jQuery, Ajax and .NETJames Johnson
 
Client side development with knockout.js
Client side development with knockout.jsClient side development with knockout.js
Client side development with knockout.jsValdis Iljuconoks
 
A Rich Web Experience with jQuery, Ajax and .NET
A Rich Web Experience with jQuery, Ajax and .NETA Rich Web Experience with jQuery, Ajax and .NET
A Rich Web Experience with jQuery, Ajax and .NETJames Johnson
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j queryMd. Ziaul Haq
 
Knockoutjs UG meeting presentation
Knockoutjs UG meeting presentationKnockoutjs UG meeting presentation
Knockoutjs UG meeting presentationValdis Iljuconoks
 
Omnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the ThingsOmnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the ThingsJustin Edelson
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup PerformanceJustin Cataldo
 
How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)David Giard
 
Don't Worry jQuery is very Easy:Learning Tips For jQuery
Don't Worry jQuery is very Easy:Learning Tips For jQueryDon't Worry jQuery is very Easy:Learning Tips For jQuery
Don't Worry jQuery is very Easy:Learning Tips For jQueryshabab shihan
 
Week 4 - jQuery + Ajax
Week 4 - jQuery + AjaxWeek 4 - jQuery + Ajax
Week 4 - jQuery + Ajaxbaygross
 

Similar to Ed Blackburn NDC (20)

Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Game jump: frontend introduction #1
Game jump: frontend introduction #1Game jump: frontend introduction #1
Game jump: frontend introduction #1
 
Jquery fundamentals
Jquery fundamentalsJquery fundamentals
Jquery fundamentals
 
iPhone - web development lotus notes domino
iPhone - web development lotus notes dominoiPhone - web development lotus notes domino
iPhone - web development lotus notes domino
 
Medium TechTalk — iOS
Medium TechTalk — iOSMedium TechTalk — iOS
Medium TechTalk — iOS
 
Oracle MAF real life OOW.pptx
Oracle MAF real life OOW.pptxOracle MAF real life OOW.pptx
Oracle MAF real life OOW.pptx
 
A Rich Web experience with jQuery, Ajax and .NET
A Rich Web experience with jQuery, Ajax and .NETA Rich Web experience with jQuery, Ajax and .NET
A Rich Web experience with jQuery, Ajax and .NET
 
Client side development with knockout.js
Client side development with knockout.jsClient side development with knockout.js
Client side development with knockout.js
 
jQuery besic
jQuery besicjQuery besic
jQuery besic
 
A Rich Web Experience with jQuery, Ajax and .NET
A Rich Web Experience with jQuery, Ajax and .NETA Rich Web Experience with jQuery, Ajax and .NET
A Rich Web Experience with jQuery, Ajax and .NET
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
 
Knockoutjs UG meeting presentation
Knockoutjs UG meeting presentationKnockoutjs UG meeting presentation
Knockoutjs UG meeting presentation
 
Omnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the ThingsOmnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the Things
 
EVOLVE'16 | Enhance | Oscar Bolaños & Justin Edelson | Search All the Things:...
EVOLVE'16 | Enhance | Oscar Bolaños & Justin Edelson | Search All the Things:...EVOLVE'16 | Enhance | Oscar Bolaños & Justin Edelson | Search All the Things:...
EVOLVE'16 | Enhance | Oscar Bolaños & Justin Edelson | Search All the Things:...
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
 
22 j query1
22 j query122 j query1
22 j query1
 
How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)
 
Don't Worry jQuery is very Easy:Learning Tips For jQuery
Don't Worry jQuery is very Easy:Learning Tips For jQueryDon't Worry jQuery is very Easy:Learning Tips For jQuery
Don't Worry jQuery is very Easy:Learning Tips For jQuery
 
Week 4 - jQuery + Ajax
Week 4 - jQuery + AjaxWeek 4 - jQuery + Ajax
Week 4 - jQuery + Ajax
 

Ed Blackburn NDC

  • 2. Oyster Card July 2003 © “Oyster Card" by Frank Murmann is licensed under CC BY3.0
  • 5. Components • Identity Management • Customer Services • Customer Portal • Payment and Risk Services • Canonical, versioned reference data • Path finding fare generation for routes • Journey Construction, apportionment, capping and fares
  • 7. Evolving the MVP • Revenue Protection • Disruptions • Travel Products (Weekly, Monthly, Annual…)
  • 8. Philosophy • Object-Orientation; an object has both state (data) and behaviour (logic) • Domain model focused • Tell don’t ask • SOLID
  • 10. Tell Don’t Ask public class Journey { … public void AssociateRevenueInspectionTap(Tap tap) {..}; public void CounterZeroRateDueToRevenueProtection() {..}; … }
  • 11. Tell Don’t Ask? public class Journey : Entity<Journey, JourneyKey>, IComparable<Journey>, IComparable<Tap>, ITapSequence, ICanProtectRevenue, IJourneyAffectedByRevenueInspection, IMayNotExist, IHaveTravelDayKey, IRateable, IDisruptable { … public void AssociateRevenueInspectionTap(Tap tap) {..}; public void CounterZeroRateDueToRevenueProtection() {..}; public bool IsCounteredBy(Tap candidate) {..}; public bool Exists { get; } public bool ContainsRevenueInspectionTap { get; } … }
  • 12.
  • 13. internal IRule<Tap> CreateRule(TravelDay travelDay) { // Create rules return Rule.Create(..); }
  • 14. private IRule<Tap> CreateRule(TravelDay travelDay) { // Create rules return Rule.Create(specification: new IsRITWithinPreviousJourney(travelDay), ifSatisfied: ScenarioT01, ifNotSatisfied: Rule.Create(..)); }
  • 15. private IRule<Tap> CreateRule(TravelDay travelDay) { // Create rules return Rule.Create(specification: new IsRITWithinPreviousJourney(travelDay), ifSatisfied: ScenarioT01, ifNotSatisfied: Rule.Create( specification: new IsPreviousJourneyDisrupted(travelDay), ifSatisfied: ScenarioTDIS01, ifNotSatisfied: ScenarioT02 )); }
  • 16. public sealed class IsTapTypeRailInspection : Specification<Tap> { private static readonly ISpecification<Tap> _compositeSpecification = new IsTapModeRail().And(new IsTapTypeRevenueInspection()); protected override bool IsSatisfiedBy(Tap candidate) { return _compositeSpecification.IsSatisfiedBy(candidate); } }
  • 17. “Small Is Beautiful” • E. F. Schumacher • To counter Bigger is Better • Empowers developers to build complex features through small lego pieces • Easy to read
  • 18. Aggregate “Nothing outside the Aggregate boundary can hold a reference to anything inside, except to the root entity…” - Eric Evans, Domain Driven Design, 2004
  • 19. Aggregates & Continuations? public class Card : Entity<Card, TravelTokenId> { … public void PerformCommand(IRuleCommand<Journey> command) { PerformCommand(command, () => _journeys.Select(item => … ) } private void PerformCommand<TEntity>(IRuleCommand<TEntity> command, Func<IEnumerable<TEntity>> getEntities) { Rule.Create(command).Process(getEntities()); } … }
  • 20. Pipelines and decorators public interface ICardOperation { Card Process(Card card); } public interface IDecoratedCardOperation { ICardOperation InnerCardOperation { get; private set; } } public class RevenueProtection : ICardOperation, IDecoratedCardOperation { public RevenueProtection (...) { ... } public Card Process (Card card) { card = InnerCardOperation.Process (card); ... return card; } public ICardOperation InnerCardOperation { get;set;} }
  • 21. Summary • Abstractions rot code • Small interfaces • If you have a DTO reconsider your approach • Even anaemic models can be encapsulated • Immutability is your friend
  • 22. Future? • Token based software system • Anything can create a token • Vehicle registration plate • Phone / wearable • APIs (dog fooding with mobile) • Data, data, data…