Transcript
Page 1: Groovy Architectural Flexibility

Architectural Flexibility

using Groovy

Page 2: Groovy Architectural Flexibility

David Dawson

CEO, Principal Consultant

[email protected]

@davidthecoder

Page 3: Groovy Architectural Flexibility

What kind

of

Code is Best?

Page 4: Groovy Architectural Flexibility

Object Oriented

or

Functional?

Page 5: Groovy Architectural Flexibility

Strongly Typed

or

Weakly Typed?

Page 6: Groovy Architectural Flexibility

To Meta

or

Not to Meta?

Page 7: Groovy Architectural Flexibility

Data

or

Type

Page 8: Groovy Architectural Flexibility

Why?

Page 9: Groovy Architectural Flexibility

●Non functional requirements

[tx/ sec, latency, deployment etc]

Page 10: Groovy Architectural Flexibility

●Non functional requirements

[tx/ sec, latency, deployment etc]

●Developer Comprehension

Page 11: Groovy Architectural Flexibility

●Non functional requirements

[tx/ sec, latency, deployment etc]

●Developer Comprehension

●Coding Style

Page 12: Groovy Architectural Flexibility

●Non functional requirements

[tx/ sec, latency, deployment etc]

●Developer Comprehension

●Coding Style

●Data Model(s)

Page 13: Groovy Architectural Flexibility

●Non functional requirements

[tx/ sec, latency, deployment etc]

●Developer Comprehension

●Coding Style

●Data Model(s)

●Others … [bias...?]

Page 14: Groovy Architectural Flexibility

Forces on Code

Page 15: Groovy Architectural Flexibility

What kind

of

Code is Best?

Page 16: Groovy Architectural Flexibility

WrongQuestion

Page 17: Groovy Architectural Flexibility
Page 18: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Page 19: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Page 20: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

REST

Page 21: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

REST

Events

Page 22: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

RESTProvided API

Events

Page 23: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

RESTProvided API

UserDSL

Events

Page 24: Groovy Architectural Flexibility

Context

Page 25: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

RESTProvided API

UserDSL

Events

Page 26: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Page 27: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Page 28: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Core Domain

Page 29: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Core Domain

Forces

Page 30: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Core Domain

Forces● Express Type

Page 31: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Core Domain

Forces● Express Type

● Understand Identity

Page 32: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Core Domain

Forces● Express Type

● Understand Identity

● Use Ubiquitous Language

Page 33: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Core Domain

Forces● Express Type

● Understand Identity

● Use Ubiquitous Language

● Relatively high code churn

Page 34: Groovy Architectural Flexibility

OrderMenu

Recipe

Page 35: Groovy Architectural Flexibility

OrderMenu

Recipe

orderId

recipeId

menuId

Page 36: Groovy Architectural Flexibility

class OrderService {

}

def process( def order ) { if (valid(order)) { dispatch(order) persist(order) return OrderResult.SENT } OrderResult.INVALID //or similar}

Page 37: Groovy Architectural Flexibility

class OrderService {

}

process( Order order ) { if (valid(order)) { dispatch(order) persist(order) return OrderResult.SENT } OrderResult.INVALID //or similar}

OrderResult

Page 38: Groovy Architectural Flexibility

class OrderService {

}

process( Order order ) { if (valid(order)) { dispatch(order) persist(order) return OrderResult.SENT } OrderResult.INVALID //or similar}

OrderResultvalidateAndDispatch

Page 39: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

REST

Events

Provided API

UserDSL

Page 40: Groovy Architectural Flexibility

Events

Page 41: Groovy Architectural Flexibility

Events

Page 42: Groovy Architectural Flexibility

EventsEvent Processor

Page 43: Groovy Architectural Flexibility

EventsEvent Processor

Subscription

Subscription

Subscription

Page 44: Groovy Architectural Flexibility

EventsEvent Processor

Subscription

Subscription

Subscription

Event

Page 45: Groovy Architectural Flexibility

EventsEvent Processor

Subscription

Subscription

Subscription

Page 46: Groovy Architectural Flexibility

Events

Forces

Event Processor

Page 47: Groovy Architectural Flexibility

EventsEvent Processor

Forces● Performance

Page 48: Groovy Architectural Flexibility

EventsEvent Processor

Forces● Performance

● Technically focused, technical language

Page 49: Groovy Architectural Flexibility

EventsEvent Processor

Forces● Performance

● Technically focused, technical language

● No interest in type or identity

Page 50: Groovy Architectural Flexibility

EventsEvent Processor

Forces● Performance

● Technically focused, technical language

● No interest in type or identity

● Interest in functionality

Page 51: Groovy Architectural Flexibility

EventsEvent Processor

Forces● Performance

● Technically focused, technical language

● No interest in type or identity

● Interest in functionality

● Data/ algorithm oriented

Page 52: Groovy Architectural Flexibility

class EventProcessor {

List<Subscription> subscriptions

}

void process(Message message) { subscriptions.findAll { it.canHandle(message) }.each { it.dispatch(message) }}

Page 53: Groovy Architectural Flexibility

class EventProcessor {

List<Subscription> subscriptions

}

void process(Message message) { subscriptions.findAll { it.canHandle(message) }.each { it.dispatch(message) }}

Page 54: Groovy Architectural Flexibility

class EventProcessor {

List<Subscription> subscriptions

}

void process(Message message) { subscriptions.findAll { it.canHandle(message) }.each { it.dispatch(message) }}

200k messages : 450ms

Page 55: Groovy Architectural Flexibility

class EventProcessor {

List<Subscription> subscriptions

}

void process(Message message) { for(Subscription sub in subscriptions) { if(it.canHandle(message)) {

it.dispatch(message) } }}

80ms200k messages : 450ms

Page 56: Groovy Architectural Flexibility

class EventProcessor {

List<Subscription> subscriptions

}

@CompileStaticvoid process(Message message) { for(Subscription sub in subscriptions) { if(it.canHandle(message)) {

it.dispatch(message) } }}

30ms200k messages : 450ms 80ms

Page 57: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

REST

Events

Provided API

UserDSL

Page 58: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

REST

Events

Provided API

UserDSL

Page 59: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

REST

Page 60: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

REST

Page 61: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

RESTDomain Transformer

Page 62: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

RESTDomain Transformer

Forces

Page 63: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

RESTDomain Transformer

Forces● Interested only in integration

Page 64: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

RESTDomain Transformer

Forces● Interested only in integration

● Designed to remove type

Page 65: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

RESTDomain Transformer

Forces● Interested only in integration

● Designed to remove type

● Affinity with Data & Values

Page 66: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

RESTDomain Transformer

Forces● Interested only in integration

● Designed to remove type

● Affinity with Data & Values

● Data Transformation

Page 67: Groovy Architectural Flexibility

class OrderTransformer {

}

def send(Message message) { RestMessage msg = New RestMessage()

msg.txt = message.text target.doProcessing(msg)}

Page 68: Groovy Architectural Flexibility

class OrderTransformer {

}

def send(Message message) { RestMessage msg = New RestMessage()

msg.txt = message.text target.doProcessing(msg)}

Page 69: Groovy Architectural Flexibility

class OrderTransformer {

}

def send(Message message) { RestMessage msg = New RestMessage()

msg.txt = message.text target.doProcessing(msg)}

Page 70: Groovy Architectural Flexibility

msg.txt = message.text target.doProcessing(msg)

Page 71: Groovy Architectural Flexibility

def msg=[txt:message.text] target.doProcessing(msg)

Page 72: Groovy Architectural Flexibility

def transformer = { target, message ->

def msg=[text:message.text] target.doProcessing(msg) }

Page 73: Groovy Architectural Flexibility

def transformer = { message, target ->

def msg=[txt:message.text] target.doProcessing(msg) }

transformer = transformer.curry(aTarget)transformer(text:”Hello GGX!”)

Page 74: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

REST

Events

Provided API

UserDSL

Page 75: Groovy Architectural Flexibility

UserDSL

Page 76: Groovy Architectural Flexibility

UserDSL

Domain SpecificLanguage

Page 77: Groovy Architectural Flexibility

UserDSL

Domain SpecificLanguage

Forces

Page 78: Groovy Architectural Flexibility

UserDSL

Domain SpecificLanguage

Forces● User Comprehension

Page 79: Groovy Architectural Flexibility

UserDSL

Domain SpecificLanguage

Forces● User Comprehension

● Expressiveness

Page 80: Groovy Architectural Flexibility

UserDSL

Domain SpecificLanguage

Forces● User Comprehension

● Expressiveness

● Ease of Use versus Intuitive

Page 81: Groovy Architectural Flexibility

def orders = Order.findAllByUserName(“someone”)

Page 82: Groovy Architectural Flexibility

def orders = Order.findAllByUserNameAndOrderTax\BetweenOrOrderValueLessThanAndAddress1Like( “someone”, 5, 6, 15.20, “%Some Street%”)

Page 83: Groovy Architectural Flexibility

def orders = Order.findAllByUserNameAndOrderTax\BetweenOrOrderValueLessThanAndAddress1Like( “someone”, 5, 6, 15.20, “%Some Street%”)

def orders = Order.findAll { username == “someone” orderValue in [5 .. 6] address1 =~ “%Some Street%”}

Page 84: Groovy Architectural Flexibility

def orders = Order.findAllByUserNameAndOrderTax\BetweenOrOrderValueLessThanAndAddress1Like( “someone”, 5, 6, 15.20, “%Some Street%”)

def orders = Order.findAll { username == “someone” orderValue in [5 .. 6] address1 =~ “%Some Street%”}

Page 85: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Core Domain

Forces● Express Type

● Understand Identity

● Use Ubiquitous Language

● Relatively high code churn

Page 86: Groovy Architectural Flexibility

Core Domain

Application PoliciesBusiness Rules

Core Domain

Forces● Express Type

● Understand Identity

● Use Ubiquitous Language

● Relatively high code churn

Page 87: Groovy Architectural Flexibility

List<Order> findAuthorisedRecords(User user) {

List<Order> orders = Orders.list()

List<Order> selectedOrders = new ArrayList<>();

for(Order order: orders) { if(order.user == user) { SelectedOrders << order }}

return Collections.sort(selectedOrders)

}

Page 88: Groovy Architectural Flexibility

List<Order> findAuthorisedRecords(User user) {

List<Order> orders = Orders.list()

List<Order> selectedOrders = new ArrayList<>();

for(Order order: orders) { if(order.user == user) { SelectedOrders << order }}

return Collections.sort(selectedOrders)

}

Page 89: Groovy Architectural Flexibility

List<Order> findAuthorisedRecords(User user) {

List<Order> orders = Orders.list()

List<Order> selectedOrders = new ArrayList<>();

for(Order order: orders) { if(order.user == user) { selectedOrders << order }}

return Collections.sort(selectedOrders)

}

Page 90: Groovy Architectural Flexibility

List<Order> findAuthorisedRecords(User user) {

def orders = Orders.list()

def selectedOrders = []

for(def order: orders) { if(order.user == user) { selectedOrders << order }}

return Collections.sort(selectedOrders)

}

Page 91: Groovy Architectural Flexibility

List<Order> findAuthorisedRecords(User user) {

def orders = Orders.list()

def selectedOrders = orders.findAll { order.user == user}

return Collections.sort(selectedOrders)

}

Page 92: Groovy Architectural Flexibility

List<Order> findAuthorisedRecords(User user) {

def orders = Orders.list()

return orders.findAll { order.user == user}.sort { order.id}

}

Page 93: Groovy Architectural Flexibility

List<OrderDetails> findAuthorisedRecords(User user) {

def orders = Orders.list()

return orders.findAll { it.user == user}.sort { it.id}.collect { it as OrderDetails}

}

Page 94: Groovy Architectural Flexibility

Understand Context

Page 95: Groovy Architectural Flexibility

Understand Context

Identify Forces

Page 96: Groovy Architectural Flexibility

Understand Context

Identify Forces

Drive Code

Page 97: Groovy Architectural Flexibility

Understand Context

Identify Forces

Drive Code

Page 98: Groovy Architectural Flexibility

Reject Dogma

Page 99: Groovy Architectural Flexibility

Questions

@davidthecoder

Page 100: Groovy Architectural Flexibility

Thank you!

@davidthecoder


Top Related