yow west 2017 - yow! conference...yow west 2017 our sponsors cost of a dependency trainer dev at...

Post on 30-Dec-2020

8 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

YOW West 2017OUR SPONSORS

Cost of a dependency

Dev at CashiesTrainer – Practical Rx

Lee CampbellAuthor of eBook and website IntroToRx.com Conference Circuit

Project success

LongevityHow long will your project need to be used for?

How long will it need to be maintained for?

How long will each of it’s dependent parts be relevant for?

FreedomsSingle man dependencies vs Fungible assets

Technology lock-in vs Technology agnostic

A case studyA COLLECTION OF EXPERIENCES

A case study

How did it get like this?COMPOUNDING EFFECTS

1. Single repo

Single repo\GUI

\Server

\Datastore

Single repo\GUI

◦ FeatureA

◦ FeatureB

\Server◦ FeatureA

◦ FeatureB

◦ Shared

\Datastore

Single repo\GUI

◦ FeatureA

◦ FeatureB

◦ FeatureC

\Server◦ FeatureA

◦ FeatureB

◦ FeatureC

◦ Shared◦ Logic

◦ Scripts (Builds, Deployments)

\Datastore

Single repo\GUI

◦ FeatureA

◦ FeatureB

◦ FeatureC

\Server◦ FeatureA

◦ FeatureB

◦ FeatureC

◦ Shared◦ Logic

◦ Scripts (Builds, Deployments)

\Datastore◦ FeatureA

◦ FeatureB

◦ FeatureC

Single repo\GUI

◦ FeatureA

◦ FeatureB

◦ FeatureC

◦ Shared

\Server◦ FeatureA

◦ FeatureB

◦ FeatureC

◦ Shared◦ Logic

◦ Contracts

\Framework◦ Comms Layer

◦ Data Persistence abstraction

◦ Scripts (Builds, Deployments)

\Datastore◦ FeatureA

◦ FeatureB

◦ FeatureC

Single repoWho defines requirements and budget for each part of the system?

Can this progression be maintained for the expected lifetime of the system?

Do these things change together?

Single repo - ConsequencesBuild times increase

Testing burden

Friction to innovate

Blurry boundaries

Lack of responsibility

2. Depend on abstractions

Interface all the thingsView Models

Translators

Validators

ConsequencesTesting now becomes an exercise in mocking

Debugging is always a case of hitting finding "implementations of"

ConsequencesFocus is diluted

Cognitive load is increased through indirection

Depend on (external) abstractionsWe can also take dependencies on interface define by someone else

So maybe you just mock out your ◦ IoC Continer

◦ SqlConnection

◦ ORM UnitOfWork

But these are normally defined in their package, with the implementation.

3. Deep layering

Deep layeringDeep system dependencies

Deep layering

Deep layeringMy application

◦ My libraries◦ My Framework

◦ My Framework subsystem

◦ Generic public packages

◦ Low level generic public packages

Deep layeringMy application

◦ My libraries (Domain, Data Access, Comms, Controls, Styles)◦ My Framework (DataAccess, Comms, Contracts, Generic Utilities, Controls, Styles)

◦ My Framework subsystem (Implementation specific DataAccess, Comms etc)

◦ Generic public packages (ORM, Serializers, Web Platform, Messaging, Document manipulation)

◦ Low level generic public packages (Network interfaces, Collections Libraries)

Deep layeringNon linear growth

3 deep with each dependency having 3 children

1 + 3 + 9 = 13 total

Deep layeringNon linear growth

Add 2 more layers (5 layers)

1 + 3 + (9 * 13) = 121 total

1

1 1 1

13 13 13 13 13 13 13 13 13

Deep layeringNon linear growth

Add 2 more layers (7 layers)

1 + 3 + (9 * 121) = 1093 total

1

1 1 1

121 121 121 121 121 121 121 121 121

+ baggagePackages that include

◦ minified and original resource

◦ Documentation (JavaDoc/Intellisense)

◦ Tooling

Deep call stacksI depend on abstractions

But they also depend on abstractions

So I have deep call stacks

Deep call stackshttps://twitter.com/gregyoung/status/734713437146734592

ConsequencesCognitive load increases exponentially with each layer

Technical freedom is slowly eroded as each layer add more dependencies

Compounding Consequences

Compounding consequencesBuild times

Test times

Lack of Ownership

Compensating behaviourMagic Build scripts

Using the real IoC Container in tests

AOP

Complicated becomes complexCant be rationalised about

Emergent behaviour (bugs, not features)

AlternativesIS THERE A BETTER WAY?

Single repoFEATURE DEPENDENCY

If it changes together, it lives togetherWays to identify

◦ The person that has final say on requirements is different

◦ Release cadences are different

◦ Code change cadence is different

◦ Failures are ignored

"Decompose your applications based on volatility" - Juval Lowy

Single repo\GUI

◦ FeatureA

◦ FeatureB

◦ FeatureC

◦ Shared

\Server◦ FeatureA

◦ FeatureB

◦ FeatureC

◦ Shared◦ Logic

◦ Contracts

\Framework◦ Comms Layer

◦ Data Persistence abstraction

◦ Scripts (Builds, Deployments)

\Datastore◦ FeatureA

◦ FeatureB

◦ FeatureC

Multi repoFeatureA

◦ GUI

◦ Server

◦ DataStore

◦ Contracts

FeatureB◦ GUI

◦ Server

◦ DataStore

◦ Contracts

FeatureC

◦ GUI

◦ Server

◦ DataStore

◦ Contracts

GUI Lib

Comms Lib

Persistence Lib

Multi repoInherently parallel to build and test

Forces the discussion about design by contract

Can reduce the knee jerk reaction to share code

Encapsulation

Justify the interfaceWhat is the benefit of this being injected?

Can it be encapsulated into this unit?

Private by defaultInstead of Reuse being a goal, aim for encapsulation.

Rule of 3

Reuse is an evolution

The snip ruleAvoid dependencies that require finesse to remove

Single line to cut

Code in actionA DOMAIN MODEL WITH NO DEPENDENCIES

Only depends on .NET

So how does it do anythingThe Domain Model defines the interfaces for the things it needs

◦ IRepository<T>

Can you tell what technology we are using here?

Consumers are responsible to implement it

We are isolating the business logic from our technology choices.

Inversion of Control

Hosts compose shallow dependenciesHexagonal Architecture (Alistair Cockburn)

Ports and Adapters

Onion Architecture

We define our PortsIRepository is one of our ports

We may have a SQLServer adapter, or perhaps a MongoDB one

Composition

App Service

Domain Model

Data Service

ORM Data store

Comms Service

SerializationMessaging platform

Composition

Domain Model

Commsadapter

Data adapter

App Service

Data store

Comms

AdaptersCODE BREAK OUT

Composition instead of AOPI can just use normal old Decorator pattern

ResultsMulti repo

◦ Division of labour

◦ Cohesive code base

◦ Reduced cognitive load

◦ Technical freedom

ResultsEncapsulation

◦ Reduced cognitive load

◦ Less busy work

◦ Snip rule

ResultsInversion of Dependencies / Ports and Adapter

◦ Focused code

◦ Fast tests

◦ Shallow stacks

◦ Technical Freedom

Know your costsCognitive load

Onboarding friction

Technical Freedom

Time to prod

More informationLeeCampbell.com

Implementing Domain Driven Design – Vaugh Vernon

Greg Young – Good enough software

Hex Arch – Alistair Cockburn

Having the computer to do what you want isn’t the hard part,having a person understand the intent of your code is.

top related