Slide 1

Slide 1 text

Starring Directed By Special Appearance Introducing With

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Hi, I’m Henning

Slide 4

Slide 4 text

!"#

Slide 5

Slide 5 text

Carola Lilienthal & Henning Schwentner Foreword by Michael Feathers Modernize Legacy Systems and Mitigate Risk Domain-Driven Transformation

Slide 6

Slide 6 text

Software != End in itself

Slide 7

Slide 7 text

@hschwentner ! ! " Software is build Tech people business people # " for for by

Slide 8

Slide 8 text

@hschwentner (Application) Programming 1. Learn about a domain 2. Build a model for it 3. Add technology to build the system: • programming language • UI • database • …

Slide 9

Slide 9 text

Photo: Henning Schwentner Let’s look at an example!

Slide 10

Slide 10 text

@hschwentner Example: A Banking Domain bank account customer teller computer transaction

Slide 11

Slide 11 text

@hschwentner Example: A Banking Domain computer Banking 3000

Slide 12

Slide 12 text

@hschwentner Programming 1. Learn about a domain 2. Build a model for it 3. Add technology to build the system: • programming language • UI • database • …

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

https://hschwentner.io Read on in:

Slide 15

Slide 15 text

@hschwentner Programming 1. Learn about a domain 2. Build a model for it 3. Add technology to build the system: • programming language • UI • database • …

Slide 16

Slide 16 text

@hschwentner Rules of thumb: # $

Slide 17

Slide 17 text

Objects from real world turn into objects in software

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

«Entity» BankAccount

Slide 20

Slide 20 text

Actions from real world turn into operations in software

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

«Entity» BankAccount withdraw() deposit()

Slide 23

Slide 23 text

=> Object-orientation

Slide 24

Slide 24 text

@hschwentner Programming 1. Learn about a domain 2. Build a model for it 3. Add technology to build the system: • programming language • UI • database • …

Slide 25

Slide 25 text

@hschwentner Coupling • thus, we build coupling. we couple the system to technology Model DB UI Programming Language

Slide 26

Slide 26 text

@hschwentner Coupling— What to Do About It? => it’s a good idea to localize that coupling! => that’s one of the reasons for modularity

Slide 27

Slide 27 text

@hschwentner Insertion: History

Slide 28

Slide 28 text

@hschwentner No Modularity goto goto Program: goto goto goto == chaos

Slide 29

Slide 29 text

@hschwentner Structured Programming Edsger Dijkstra Edgar Dijkstra: Go To Statement Considered Harmful callable unit callable unit callable unit 1968

Slide 30

Slide 30 text

@hschwentner Information Hiding David Parnas Programming R. Morris Techniques Editor On the Criteria To Be Used in Decomposing Systems into Modules D.L. Parnas Carnegie-Mellon University This paper discusses modularization as a mechanism for improving the flexibility and comprehensibility of a system while allowing the shortening of its development time. The effectiveness of a "modularization" is dependent upon the criteria used in dividing the system into modules. A system design problem is presented and both a conventional and unconventional decomposition are described. It is shown that the unconventional decompositions have distinct advantages for the goals outlined. The criteria used in arriving at the decom- positions are discussed. The unconventional decomposi- tion, if implemented with the conventional assumption that a module consists of one or more subroutines, will be less efficient in most cases. An alternative approach to implementation which does not have this effect is sketched. Key Words and Phrases: software, modules, modularity, software engineering, KWIC index, software design CR Categories: 4.0 Introduction A lucid statement of the philosophy of modular programming can be found in a 1970 textbook on the design of system programs by Gouthier and Pont [1, ¶I0.23], which we quote below: 1 A well-defined segmentation of the project effort ensures system modularity. Each task forms a separate, distinct program module. At implementation time each module and its inputs and outputs are well-defined, there is no confusion in the intended interface with other system modules. At checkout time the in- tegrity of the module is tested independently; there are few sche- duling problems in synchronizing the completion of several tasks before checkout can begin. Finally, the system is maintained in modular fashion; system errors and deficiencies can be traced to specific system modules, thus limiting the scope of detailed error searching. Usually nothing is said about the criteria to be used in dividing the system into modules. This paper will discuss that issue and, by means of examples, suggest some criteria which can be used in decomposing a system into modules. Copyright @ 1972, Association for Computing Machinery, Inc. General permission to republish, but not for profit, all or part of this material is granted, provided that reference is made to this publication, to its date of issue, and to the fact that reprinting privileges were granted by permission of the Association for Com- puting Machinery. Author's address: Department of Computer Science, Carnegie- Mellon University, Pittsburgh, PA 15213. A Brief Status Report The major advancement in the area of modular programming has been the development of coding techniques and assemblers which (l) allow one module to be written with little knowledge of the code in another module, and (2) allow modules to be reas- sembled and replaced without reassembly of the whole system. This facility is extremely valuable for the production of large pieces of code, but the systems most often used as examples of problem systems are highly- modularized programs and make use of the techniques mentioned above. 1 Reprinted by permission of Prentice-Hall, Englewood interface imple- mentation " # 1972

Slide 31

Slide 31 text

@hschwentner Separation of Concerns Edsger Dijkstra “…study in depth an aspect in isolation […], all the time knowing that one is occupying oneself only with one of the aspects.” one aspect in isolation 1974

Slide 32

Slide 32 text

@hschwentner Separation of Concerns Ø Single responsibility principle Ø do one thing well Ø Change because of one reason Ø Separation of business logic and technical code Corollaries

Slide 33

Slide 33 text

@hschwentner Loose Coupling/ High Cohesion Ed Yourdon Larry Constantine ! in which direction? 1979

Slide 34

Slide 34 text

@hschwentner Layered Architecture

Slide 35

Slide 35 text

@hschwentner 2 Layer Architecture Program “uses” Legend: DB

Slide 36

Slide 36 text

@hschwentner below The One Rule above Acyclic Dependency Principle allowed forbidden

Slide 37

Slide 37 text

@hschwentner Fundamental Theorem of Software Engineering David Wheeler $ “We can solve any problem by introducing an extra level of indirection” “…except for the problem of too many levels of indirection”

Slide 38

Slide 38 text

@hschwentner 3 Layer Architecture Presentation Logic Data

Slide 39

Slide 39 text

@hschwentner 4 Layer Architecture User Interface Application Domain Infrastructure

Slide 40

Slide 40 text

@hschwentner Domain Layer and Domain Model

Slide 41

Slide 41 text

@hschwentner Domain Logic Patterns Martin Fowler !

Slide 42

Slide 42 text

@hschwentner Domain Logic Patterns Martin Fowler ! • Transaction Script • Table Module • Domain Model • Anti-Pattern: Anemic Domain Model

Slide 43

Slide 43 text

@hschwentner Rules of thumb: # $

Slide 44

Slide 44 text

Objects from real world turn into objects in software

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

«Entity» BankAccount

Slide 47

Slide 47 text

Actions from real world turn into operations in software

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

«Entity» BankAccount withdraw() deposit()

Slide 50

Slide 50 text

=> Object-orientation

Slide 51

Slide 51 text

@hschwentner Is everything in the world an object?

Slide 52

Slide 52 text

@hschwentner Another rule of thumb: # $

Slide 53

Slide 53 text

Values from real world turn into values in software

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

«Entity» BankAccount withdraw() deposit() «Value Object» Amount

Slide 56

Slide 56 text

@hschwentner Domain-Driven Design Eric Evans "

Slide 57

Slide 57 text

@hschwentner Entity Tactical Design Value Object Is it a thing? Is it a property of a thing? Can you touch it? Is it identityless? Does it have an identity? Rules of Thumb

Slide 58

Slide 58 text

@hschwentner Entity vs. Value - Identity - Life cycle - Can be mutable - No identity - Always immutable Contract Map Name Length 12.5 m “John Miller” Entity Value Object

Slide 59

Slide 59 text

@hschwentner Entity Value Object Aggregate Service Factory Repository Tactical Design

Slide 60

Slide 60 text

«Entity» BankAccount withdraw() deposit() «Value Object» Amount

Slide 61

Slide 61 text

@hschwentner The Domain Model Lives in the Domain Layer User Interface Application Domain Infrastructure

Slide 62

Slide 62 text

@hschwentner The Problem with Layers

Slide 63

Slide 63 text

@hschwentner The Problem Infrastructure User Interface Application Domain allowed BAD!

Slide 64

Slide 64 text

@hschwentner The Problem Domain Infrastructure bank transaction Oracle DB Concrete BAD!

Slide 65

Slide 65 text

@hschwentner Beyond Layered Architecture

Slide 66

Slide 66 text

@hschwentner below above From above/below to inside/outside out- side inside

Slide 67

Slide 67 text

@hschwentner port port Hexagonal Architecture Foto: Dennis Hamilton/flickr/CC BY 2.0 http://alistair.cockburn.us/Hexagonal%2Barchitecture adapter adapter Alistair Cockburn

Slide 68

Slide 68 text

@hschwentner Kinds of Ports - For UI etc. - Methods to be called - “from above” - For DB and infrastructure - Interfaces to be implemented - “from below”

Slide 69

Slide 69 text

@hschwentner secondary port primary port adapter adapter Kinds of Ports Legend: Flow of control Dependency

Slide 70

Slide 70 text

@hschwentner Domain The Solution Domain Infrastructure bank transaction Oracle DB Infrastructure bank transaction Oracle DB port adapter Step 1

Slide 71

Slide 71 text

@hschwentner uses implements Legend:

Slide 72

Slide 72 text

@hschwentner Dependency Inversion Depend on abstractions, not on concretions! Robert C. Martin “Uncle Bob” "

Slide 73

Slide 73 text

@hschwentner Onion Architecture U I “application core” domain services domain model infra app ture struc serv lication ices !

Slide 74

Slide 74 text

@hschwentner The 4 Tenets •The application is built around an independent object model •Inner layers define interfaces. Outer layers implement interfaces •Direction of coupling is toward the center •All application core code can be compiled and run separate from infrastructure Jeffrey Palermo ! "

Slide 75

Slide 75 text

@hschwentner Designed for Testability “All application code can be compiled, run, and tested separate from infrastructure” Easy unit tests Plays well with TDD !

Slide 76

Slide 76 text

@hschwentner Clean Architecture Robert C. Martin “Uncle Bob” interactor = use case object U I entities DB devices w eb control use cases gate presenters lers ways

Slide 77

Slide 77 text

The price of cleanness is eternal mapping

Slide 78

Slide 78 text

Explicit Architecture Herberto Graca #

Slide 79

Slide 79 text

@hschwentner Putting it all together

Slide 80

Slide 80 text

@hschwentner Architecture Hamburger Application Domain Infrastructure UI coarse grained Henning Schwentner $

Slide 81

Slide 81 text

@hschwentner Architecture Hamburger fine grained model repository interface controller use case service entity value object view data model repository implementation widget library REST frame- work transaction handling domain library programming language ORM file system access domain event

Slide 82

Slide 82 text

@hschwentner Pollution by Frameworks

Slide 83

Slide 83 text

@hschwentner What about Spring, JPA, Hibernate & co.?

Slide 84

Slide 84 text

@hschwentner class BankAccount { void deposit(Amount amount) void withdraw(Amount amount) /*...*/ } class Amount { /*...*/ }} «Entity» BankAccount withdraw() deposit() «Value Object» Amount

Slide 85

Slide 85 text

@hschwentner class BankAccount { /*...*/ } class Amount { /*...*/ }}

Slide 86

Slide 86 text

@hschwentner class BankAccount { final IBAN iban; Amount balance; /*...*/ }} class Amount { /*...*/ }}

Slide 87

Slide 87 text

@hschwentner class BankAccount { final IBAN iban; Amount balance; BankAccount(IBAN iban) {this.iban = iban} /*...*/ }} class Amount { /*...*/ }} the identity should never change …and it should be initialized at creation, i.e. in the constructor

Slide 88

Slide 88 text

@hschwentner import javax.persistence.*; @Entity class BankAccount { @Id final IBAN iban; @Embedded Amount balance; BankAccount(IBAN iban) {this.iban = iban} /*...*/ }} @Embeddable class Amount { /*...*/ }}

Slide 89

Slide 89 text

@hschwentner import javax.persistence.*; @Entity class BankAccount { @Id final IBAN iban; @Embedded Amount balance; BankAccount(IBAN iban) {this.iban = iban} /*...*/ }} @Embeddable class Amount { /*...*/ }} When you use this You have to have this

Slide 90

Slide 90 text

@hschwentner import javax.persistence.*; @Entity class BankAccount { @Id IBAN iban; @Embedded Amount balance; BankAccount() {} /*...*/ }} @Embeddable class Amount { /*...*/ }} When you use this You have to have this …and a default constructor …and fields cannot be final

Slide 91

Slide 91 text

@hschwentner import jakarta.persistence.*; @Entity class BankAccount { @Id IBAN iban; @Embedded Amount balance; BankAccount() {} /*...*/ }} @Embeddable class Amount { /*...*/ }} when someone changes the technology, we have to change the business logic, too

Slide 92

Slide 92 text

@hschwentner Pollution by Frameworks

Slide 93

Slide 93 text

@hschwentner What about Entity Framework & co.?

Slide 94

Slide 94 text

@hschwentner class BankAccount { void Deposit(Amount amount) void Withdraw(Amount amount) /*...*/ } readonly record struct Amount { /*...*/ }} «Entity» BankAccount withdraw() deposit() «Value Object» Amount

Slide 95

Slide 95 text

@hschwentner class BankAccount { /*...*/ } readonly record struct Amount { /*...*/ }}

Slide 96

Slide 96 text

@hschwentner class BankAccount { readonly IBAN iban; Amount balance; /*...*/ }} readonly record struct Amount { /*...*/ }}

Slide 97

Slide 97 text

@hschwentner class BankAccount { readonly IBAN iban; Amount balance; BankAccount(IBAN iban) {this.iban = iban} /*...*/ }} readonly record struct Amount { /*...*/ }} the identity should never change …and it should be initialized at creation, i.e. in the constructor

Slide 98

Slide 98 text

@hschwentner How to Use Entity Framework?

Slide 99

Slide 99 text

@hschwentner using System.ComponentModel.DataAnnotations; using Microsoft.EntityFrameworkCore; class BankAccount { [Key] readonly IBAN iban; Amount balance; BankAccount(IBAN iban) {this.iban = iban} /*...*/ }} [Owned] readonly record struct Amount { /*...*/ }}

Slide 100

Slide 100 text

@hschwentner using System.ComponentModel.DataAnnotations; using Microsoft.EntityFrameworkCore; class BankAccount { [Key] readonly IBAN iban; Amount balance; BankAccount(IBAN iban) {this.iban = iban} /*...*/ }} [Owned] readonly record struct Amount { /*...*/ }} Fields can still be readonly (because reflection does not respect it) ! Identity as primary key -> Technology "

Slide 101

Slide 101 text

@hschwentner using System.ComponentModel.DataAnnotations; using Microsoft.EntityFrameworkCore; class BankAccount { [Key] readonly IBAN iban; Amount balance; BankAccount() {} /*...*/ }} [Owned] readonly record struct Amount { /*...*/ }} …and you must have a default constructor " Identity as primary key -> Technology " Fields can still be readonly (because reflection does not respect it) !

Slide 102

Slide 102 text

@hschwentner And when we use FluentAPI?

Slide 103

Slide 103 text

@hschwentner using System.ComponentModel.DataAnnotations; using Microsoft.EntityFrameworkCore; class BankAccount { readonly IBAN iban; Amount balance; BankAccount() {} /*...*/ }} readonly record struct Amount { /*...*/ }} But you STILL must have a default constructor " No more compile time dependencies to EF ! Fields can still be readonly (because reflection does not respect it) !

Slide 104

Slide 104 text

@hschwentner LeasingNinja https://leasingninja.io

Slide 105

Slide 105 text

xMolecules

Slide 106

Slide 106 text

xMolecules $ Henning Schwentner Stephan Pirnbaum Oliver Drotbohm

Slide 107

Slide 107 text

@hschwentner import org.jmolecules.ddd.annotation.*; @Entity class BankAccount { @Identity final IBAN iban; Amount balance; /*...*/ }} @ValueObject class Amount { /*...*/ }} NOT JPA entity! xMolecules

Slide 108

Slide 108 text

@hschwentner Boilerplate and Model Pollution Reduction

Slide 109

Slide 109 text

@hschwentner using NMolecules.DDD; [Entity] class BankAccount { [Identity] readonly IBAN iban; Amount balance; /*...*/ }} [ValueObject] readonly record struct Amount { /*...*/ }} xMolecules

Slide 110

Slide 110 text

@hschwentner Domain-Driven Refactorings • Strategic Refactorings • Tactical Refactorings (Against Big Ball of Mud) Catalog: https://hschwentner.io/domain-driven-refactorings strategic transformation tactical transformation team-organizational transformation • Socio-Technical • Tactical refactorings (Against Model Anemia)

Slide 111

Slide 111 text

https://hschwentner.io Read on in: https://hschwentner.io/domain-driven-refactorings Carola Lilienthal & Henning Schwentner Foreword by Michael Feathers Modernize Legacy Systems and Mitigate Risk Domain-Driven Transformation

Slide 112

Slide 112 text

No content

Slide 113

Slide 113 text

Consulting

Slide 114

Slide 114 text

No content

Slide 115

Slide 115 text

@hschwentner FEEDBACK

Slide 116

Slide 116 text

No content

Slide 117

Slide 117 text

No content

Slide 118

Slide 118 text

@hschwentner Bibliography Buschmann, Frank, Regine Meunier, Hans Rohnert, Peter Sommerlad, and Michael Stal. Pattern-Oriented Software Architecture Volume 1: A System of Patterns. Hoboken, NJ: Wiley, 1996. Cockburn, Alistair. “Hexagonal Architecture.” January 4, 2005. https://alistair.cockburn.us/hexagonal-architecture/. Dijkstra, Edsger. “Go To Statement Considered Harmful.” Communications of the ACM 11, no. 3 (March 1968): 147–48. Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software. Boston: Addison-Wesley, 2004. Fowler, Martin. Patterns of Enterprise Application Architecture. Boston: Addison- Wesley, 2005. Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Reading, MA: Addison-Wesley, 1995. Graca, Herberto. “DDD, Hexagonal, Onion, Clean, CQRS, … How I Put It All Together.”

Slide 119

Slide 119 text

No content

Slide 120

Slide 120 text

Henning Schwentner https://hschwentner.io in/henningschwentner [email protected] Kolleg:in gesucht (Deutschlandweit) Carola Lilienthal & Henning Schwentner Foreword by Michael Feathers Modernize Legacy Systems and Mitigate Risk Domain-Driven Transformation