39
Crafted Design Sandro Mancuso @sandromancuso http://leanpub.com/socra

Crafted Design - GeeCON 2014

Embed Size (px)

DESCRIPTION

How can we quickly tell what an application is about? How can we quickly tell what it does? How can we distinguish business concepts from architecture clutter? How can we quickly find the code we want to change? How can we instinctively know where to add code for new features? Purely looking at unit tests is either not possible or too painful. Looking at higher-level tests can take a long time and still not give us the answers we need. For years, we have all struggled to design and structure projects that reflect the business domain. In this talk Sandro will be sharing how he designed the last application he worked on, twisting a few concepts from Domain-Driven Design, properly applying MVC, borrowing concepts from CQRS, and structuring packages in non-conventional ways. Sandro will also be touching on SOLID principles, Agile incremental design, modularisation, and testing. By iteratively modifying the project structure to better model the product requirements, he has come up with a design style that helps developers create maintainable and domain-oriented software.

Citation preview

Page 1: Crafted Design - GeeCON 2014

Crafted Design

Sandro Mancuso@sandromancusohttp://leanpub.com/socra

Page 2: Crafted Design - GeeCON 2014
Page 3: Crafted Design - GeeCON 2014

What is this application about? What are the main concepts?

What does this application do? What are the main features?

Where do I need to change? Where do I put a new feature?

Page 4: Crafted Design - GeeCON 2014

Looking from above, I can’t see what the application does or is about

Architectural and design concepts mixed with domain

Badly structured packages/namespaces

I don’t know where to start Classes and methods are too low level

Page 5: Crafted Design - GeeCON 2014

Example: Layered structure

What does this application do? What is it about?

Page 6: Crafted Design - GeeCON 2014

Example: Layered-domain structure

Books and Users. Cool, but what does this application do?

Page 7: Crafted Design - GeeCON 2014

Example: MVC structure

Awesome. It’s a web application. So?

Page 8: Crafted Design - GeeCON 2014
Page 9: Crafted Design - GeeCON 2014

MVC & MVC Variations

• MVC (Smalltalk 76/80)• MVC (general concept – 1988)• Three-Tier Architecture (Presentation, Logic, Data)• MVC (Model 1/Model 2)• Model View Adapter (MVA)• Model View Presenter (MVP)• Model View ViewModel (MVVM)• Presentation-Abstraction-Control (PAC)• ….

Page 10: Crafted Design - GeeCON 2014

MVC used badly

Anaemic Domain

Fat Controllers

Coupling with MVC framework

Page 11: Crafted Design - GeeCON 2014

MVC & MVC Variations

They are all wrong. But they are also right. It all depends on the ‘V’iew.

Page 12: Crafted Design - GeeCON 2014

Views impact MVC structureDepending on the view technology, Views and Controllers

responsibility becomes more/less coupled or blurred.

Web applications Single-page AJAX applications with stateless backend Console-based applications Desktop applications Games Mobile / tablets External systems (talking via Queues / Webservices)

However, the model should remain unchanged.

Page 13: Crafted Design - GeeCON 2014

MVC – A Macro Organisational Pattern

Model

V C M

?

DeliveryMechanism

Page 14: Crafted Design - GeeCON 2014

“Model” is overloaded and confusing

Model (M in MVC) Domain Model (DDD) View Model Data Model Entities & Active Record

and other artificial definitions from MVC frameworks

Associated with the persistence mechanism?

Page 15: Crafted Design - GeeCON 2014

M => Domain Model (DDD)

Domain Model combines state and behaviour, with more focus on the latter.

DDD define a few building blocks to your domain:

Entities Value Objects Factories Repositories

Services Application Domain Infrastructure

Aggregates

Page 16: Crafted Design - GeeCON 2014

<< Web app >>

Embedded Domain Model

ModelV C DM

DeliveryMechanism

Infrastructure Infrastructure

DBQueue

Page 17: Crafted Design - GeeCON 2014

Deployable Domain Model

DeliveryMechanisms

<< external system >>

<< mobile app >>

DB

<< deployable app >>

Model

Infrastructure

DM<<W/S>>

<<W/S>>

Page 18: Crafted Design - GeeCON 2014

Event-Driven Domain Model

DeliveryMechanisms DB

Queue

<< external app 2 >>

<< external app 1 >> << deployable app >>

Model

Infrastructure

DMQueue

<<event 1>>

<<event 2>>

Page 19: Crafted Design - GeeCON 2014

Domain Model – Responsibilities

UC = Use Case, DS = Domain Service, S = Infra. Service, R = Repository

Model

UC 1

R 3

DS 1

DS 3

R 1

S

Infrastructure Impl

DM

DS 2

Impl

UC 2

<< web app >>

Page 20: Crafted Design - GeeCON 2014

Repositories (not DAOs)

Model

<<repository>>

Library

<<repository>>

Users

Infrastructure<<Mongo>>

Books

Domain Model

<<Oracle>>

Users

“A Repository represents all objects of a certain type as a conceptual set. It acts like a collection, except with more elaborate querying capability.”

~ Eric Evans

Page 21: Crafted Design - GeeCON 2014

Command & Query Use Cases

<< web app >>

Model

RDS

<<Write Model>>

UC

Model

<<Read Model>>

UC

DB

DB

Queue <<domain events>>

Page 22: Crafted Design - GeeCON 2014

So, how does the app structure look like?

Page 23: Crafted Design - GeeCON 2014

Web project responsibility

Control flow (invoke use cases)

JSON / XML parsers or converters

Page Objects, validators, etc

Static files

Page 24: Crafted Design - GeeCON 2014

Core responsibility (simple project)

Tells what the system is about

Tells what the system does

Page 25: Crafted Design - GeeCON 2014

Core responsibility (bigger project)

Epic / Theme

Epic / Theme

Epic / Theme

Related domain concepts

Page 26: Crafted Design - GeeCON 2014

What is inside model packages?

Aggregate root (entity)

Repository

Entity (part of Book aggregate)

Domain Service

Value Object (part of Book aggregate)Part of aggregate behaviour

Repository

Value Object (part of User aggregate)

Aggregate root (entity)

Domain Service

Page 27: Crafted Design - GeeCON 2014

What is inside infrastructure?

Interfaces defined by the domain.Dependency Inversion Principle (DIP)

CreditCardProcessor implementations

Repository implementations

Page 28: Crafted Design - GeeCON 2014

Domain Model collaborations guideline

C

UC 1

UC 2

DS 1

DS 3

DS 2

R 3

R 1

cl

cl

cl

cl

C = Controller, UC = Use Case, DS = Domain Service, R = Repository, cl = class

Page 29: Crafted Design - GeeCON 2014

Class responsibility

C UC DS R

cl

DB

Input Output

End of code branch

Produces the outputEnd of flow

First to handle inputStart of the flow

Execution Flow

Closer to the input: Control flow, higher level abstraction, detailed work is delegated (e.g. ProcessTrade (UC), MakePayment (UC)) — More suitable for Outside-In TDD (mockist).

Closer to the output / end of branch: Specific and detailed behaviour, no delegation, lower level abstraction (e.g. Parse XML (Parser), Create User (Repository))

Domain Model entry point Domain Concept

entry point

Page 30: Crafted Design - GeeCON 2014

Defining testing strategies and boundaries

• Unit• Integration• Acceptance• Journey• Black box• Component• System• Functional• Alpha• Beta• Conformance• …

Types of tests

?

Page 31: Crafted Design - GeeCON 2014

Testing strategies: User Journey

Model

UC 1

DM

UC 2

<< web app >>UC 1

UC 2

Tests the journey a user will have to do something useful in the system

Application is tested as a black box normally using a BDD framework

Use cases are facked. We just want to know if the application presents the user with the correct journey

Designed according to User Stories and Features

<<fake>>

<<fake>>

Page 32: Crafted Design - GeeCON 2014

Infrastructure Impl

Testing strategies: Acceptance (Action / Behavioural)

UC DS 1

<<mock>>

RDS 2 R

Tests a behaviour (action) provided by the system

Use Case is the entry point and all external dependencies are stubbed

Domain Model

Normally tested using a BDD framework

Page 33: Crafted Design - GeeCON 2014

Testing strategies: IntegrationTests the classes at the system boundaries

Infrastructure Impl

UC DS 1

<<mock>>

RDS 2 R

Domain Model

Normally done using an in-memory Database using a unit testing framework

Page 34: Crafted Design - GeeCON 2014

Testing strategies: Unit (Class level)Unit test at class/method level

Infrastructure Impl

UC DS 1

RRDS 2

Domain Model

DS 1

DS 2All collaborators are mocked / stubbed (spies)

Page 35: Crafted Design - GeeCON 2014

Testing strategies: End-to-End

Model

UC 1

R 3

DS 1

DS 3

R 1

S

Infrastructure Impl

DM

DS 2

Impl

UC 2

<< web app >>

Full application deployed

Uses BDD framework, accessing a testing database and fake external dependencies

Very few tests at this level, just to make sure application is wired properly

Page 36: Crafted Design - GeeCON 2014

Outside-In vs. Classic TDD

The closer to the input a class is, the more flow control and delegation it does. The closer to the output a class is, the more specific and less delegation it does.

Using Outside-in TDD starting from Controllers and/or Use Cases.

Model

UC 1

R 3

DS 1

DS 3

R 1

S

Infrastructure Impl

DM

DS 2

Impl

UC 2

<< web app >>

Page 37: Crafted Design - GeeCON 2014

Answering the two original questions What is the application about? (main concepts)

What does the application do? (main features)

Expressed by nouns

Expressed by verbs(Actions)

Page 38: Crafted Design - GeeCON 2014
Page 39: Crafted Design - GeeCON 2014

Thank You

http://leanpub.com/socra

@sandromancuso