Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Model Pollution

Model Pollution

Avatar for Henning Schwentner

Henning Schwentner

September 23, 2025
Tweet

More Decks by Henning Schwentner

Other Decks in Programming

Transcript

  1. !"#

  2. Carola Lilienthal & Henning Schwentner Foreword by Michael Feathers Modernize

    Legacy Systems and Mitigate Risk Domain-Driven Transformation
  3. @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 • …
  4. @hschwentner Programming 1. Learn about a domain 2. Build a

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

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

    model for it 3. Add technology to build the system: • programming language • UI • database • …
  7. @hschwentner Coupling • thus, we build coupling. we couple the

    system to technology Model DB UI Programming Language
  8. @hschwentner Coupling— What to Do About It? => it’s a

    good idea to localize that coupling! => that’s one of the reasons for modularity
  9. @hschwentner Structured Programming Edsger Dijkstra Edgar Dijkstra: Go To Statement

    Considered Harmful callable unit callable unit callable unit 1968
  10. @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
  11. @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
  12. @hschwentner Separation of Concerns Ø Single responsibility principle Ø do

    one thing well Ø Change because of one reason Ø Separation of business logic and technical code Corollaries
  13. @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”
  14. @hschwentner Domain Logic Patterns Martin Fowler ! • Transaction Script

    • Table Module • Domain Model • Anti-Pattern: Anemic Domain Model
  15. @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
  16. @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
  17. @hschwentner The Domain Model Lives in the Domain Layer User

    Interface Application Domain Infrastructure
  18. @hschwentner port port Hexagonal Architecture Foto: Dennis Hamilton/flickr/CC BY 2.0

    http://alistair.cockburn.us/Hexagonal%2Barchitecture adapter adapter Alistair Cockburn
  19. @hschwentner Kinds of Ports - For UI etc. - Methods

    to be called - “from above” - For DB and infrastructure - Interfaces to be implemented - “from below”
  20. @hschwentner Domain The Solution Domain Infrastructure bank transaction Oracle DB

    Infrastructure bank transaction Oracle DB port adapter Step 1
  21. @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 ! "
  22. @hschwentner Designed for Testability “All application code can be compiled,

    run, and tested separate from infrastructure” Easy unit tests Plays well with TDD !
  23. @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
  24. @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
  25. @hschwentner class BankAccount { void deposit(Amount amount) void withdraw(Amount amount)

    /*...*/ } class Amount { /*...*/ }} «Entity» BankAccount withdraw() deposit() «Value Object» Amount
  26. @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
  27. @hschwentner import javax.persistence.*; @Entity class BankAccount { @Id final IBAN

    iban; @Embedded Amount balance; BankAccount(IBAN iban) {this.iban = iban} /*...*/ }} @Embeddable class Amount { /*...*/ }}
  28. @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
  29. @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
  30. @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
  31. @hschwentner class BankAccount { void Deposit(Amount amount) void Withdraw(Amount amount)

    /*...*/ } readonly record struct Amount { /*...*/ }} «Entity» BankAccount withdraw() deposit() «Value Object» Amount
  32. @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
  33. @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 { /*...*/ }}
  34. @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 "
  35. @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) !
  36. @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) !
  37. @hschwentner import org.jmolecules.ddd.annotation.*; @Entity class BankAccount { @Identity final IBAN

    iban; Amount balance; /*...*/ }} @ValueObject class Amount { /*...*/ }} NOT JPA entity! xMolecules
  38. @hschwentner using NMolecules.DDD; [Entity] class BankAccount { [Identity] readonly IBAN

    iban; Amount balance; /*...*/ }} [ValueObject] readonly record struct Amount { /*...*/ }} xMolecules
  39. @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)
  40. 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
  41. @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.”
  42. 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