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

The return of the native principles

The return of the native principles

74a9577769c489b07066e881764f4911?s=128

Bartłomiej Słota

April 08, 2019
Tweet

Transcript

  1. THE RETURN OF THE NATIVE PRINCIPLES PAWEŁ SZYMCZYK BARTŁOMIEJ SŁOTA

  2. BARTŁOMIEJ SŁOTA Consultant @ Software engineer Speaker Blogger @bartekslota bartslota.blogspot.com

    bartlomiej.slota@gmail.com github.com/bslota linkedin.com/in/bslota
  3. Trainer & Consultant @ Software engineer Speaker PAWEŁ SZYMCZYK @p_szymczyk

    pawel@pszymczyk.com github.com/pszymczyk linkedin.com/in/pszymczyk
  4. None
  5. ROK 2003

  6. None
  7. None
  8. None
  9. None
  10. None
  11. ROK 2012

  12. None
  13. None
  14. None
  15. None
  16. None
  17. None
  18. ROK 2019

  19. MICROSERVICES DDD EVENT SOURCING CQRS EDA SERVERLESS AGILE HEXAGONAL ARCHITECTURE

    CLEAN ARCHITECTURE SOFTWARE DEVELOPMENT
  20. MONOLITH MICROSERVICES

  21. AGILE

  22. WHYYY?

  23. THE RETURN OF THE NATIVE PRINCIPLES Time Procedural Programming Framework

    Database ORM Junior Developer Regular Developer Object Oriented Programming Functional Programming TDD SOLID GRASP Patterns Architecture Microservices Distributed Systems DDD Event Driven Architecture ETAPY DOJRZAŁOŚCI
  24. THE RETURN OF THE NATIVE PRINCIPLES Time Procedural Programming Framework

    Database ORM Junior Developer Regular Developer Object Oriented Programming Functional Programming TDD SOLID GRASP Patterns Architecture Microservices Distributed Systems DDD Event Driven Architecture ETAPY DOJRZAŁOŚCI
  25. THE RETURN OF THE NATIVE PRINCIPLES Time Procedural Programming Framework

    Database ORM Junior Developer Regular Developer Object Oriented Programming Functional Programming TDD SOLID GRASP Patterns Architecture Microservices Distributed Systems DDD Event Driven Architecture ETAPY DOJRZAŁOŚCI
  26. OBJECT ORIENTED PROGRAMMING

  27. THE RETURN OF THE NATIVE PRINCIPLES TEXT ZAŁOŻENIA PARADYGMATU OBIEKTOWEGO

    ▸ Abstrakcja ▸ Enkapsulacja ▸ Polimorfizm ▸ Dziedziczenie, kompozycja, delegacja
  28. THE RETURN OF THE NATIVE PRINCIPLES TEXT ABSTRAKCJA

  29. ABSTRAKCJA pozwala opanować złożoność poprzez ukrywanie nieistotnych detali

  30. THE RETURN OF THE NATIVE PRINCIPLES ENKAPSULACJA

  31. THE RETURN OF THE NATIVE PRINCIPLES POZIOMY ABSTRAKCJI W KODZIE

    Bill customer Sum charging costs Calculate charging cost Poziom abstrakcji Read tariff from repository Read tariff document from MongoDB … 1 0 0 0 1 0 1 1 0 0 …. 1 1 0
  32. THE RETURN OF THE NATIVE PRINCIPLES HEXAGONAL ARCHITECTURE CORE DOMAIN

    CORE DOMAIN PORTY wysoki poziom abstrakcji ADAPTERY niski poziom abstrakcji
  33. POZIOMY ABSTRAKCJI VS DDD BUILDING BLOCKS.

  34. THE RETURN OF THE NATIVE PRINCIPLES AGGREGATE, ENTITIES & VALUE

    OBJECTS public class Customer { private CustomerId id; private CustomerStatus status; ... public Customer activate() { if (canBeActivated()) { return new Customer(this.id, CustomerStatus.ACTIVE); } else { throw IllegalStateException("Customer cannot be activated"); } } ... }
  35. THE RETURN OF THE NATIVE PRINCIPLES SERWIS APLIKACYJNY public class

    CustomerActivation { ... @Transactional public Customer activate(CustomerActivationCommand command) { final Customer customer = customerRepository.findById(command.customerId()); final Customer activatedCustomer = customer.activate(); return customerRepository.save(activatedCustomer); } }
  36. THE RETURN OF THE NATIVE PRINCIPLES POLITYKA CZYLI “WHAT” VS

    “HOW” class LinearIncomeTaxCalculation implements IncomeTaxCalculationPolicy { private final BigDecimal RATE = BigDecimal.valueOf(0.19d); @Override public Tax calculate(YearlyIncome income) { return new Tax(income.getValue().multiply(RATE)); } } interface IncomeTaxCalculationPolicy { Tax calculate(YearlyIncome income); } Wysoki poziom abstrakcji Niski poziom abstrakcji
  37. THE RETURN OF THE NATIVE PRINCIPLES POLITYKA CZYLI “WHAT” VS

    “HOW” class LinearIncomeTaxCalculation implements IncomeTaxCalculationPolicy { private final BigDecimal RATE = BigDecimal.valueOf(0.19d); @Override public Tax calculate(YearlyIncome income) { return new Tax(income.getValue().multiply(RATE)); } } interface IncomeTaxCalculationPolicy { Tax calculate(YearlyIncome income); } Wysoki poziom abstrakcji class GeneralIncomeTaxCalculation implements IncomeTaxCalculationPolicy { private final BigDecimal FIRST_LEVEL_RATE = BigDecimal.valueOf(0.19d); private final BigDecimal SECOND_LEVEL_RATE = BigDecimal.valueOf(0.32d); private final BigDecimal FIRST_LEVEL_LIMIT = BigDecimal.valueOf(85000); @Override public Tax calculate(YearlyIncome income) { BigDecimal firstLevelValue = income.getValueBelowOrEqual(FIRST_LEVEL_LIMIT); BigDecimal secondLevelValue = income.getValueAbove(FIRST_LEVEL_LIMIT); return new Tax(firstLevelValue.multiply(FIRST_LEVEL_RATE) + secondLevelValue.multiply(SECOND_LEVEL_RATE)); } } Niski poziom abstrakcji
  38. THE RETURN OF THE NATIVE PRINCIPLES POZIOMY ABSTRAKCJI W ARCHITEKTURZE

  39. THE RETURN OF THE NATIVE PRINCIPLES ABSTRAKCJA I ENKAPSULACJA W

    PAKIETACH
  40. THE RETURN OF THE NATIVE PRINCIPLES ABSTRAKCJA I ENKAPSULACJA W

    MIKROSERWISACH
  41. THE RETURN OF THE NATIVE PRINCIPLES WYSOKA KOHEZJA

  42. THE RETURN OF THE NATIVE PRINCIPLES MONOLITH FIRST

  43. THE RETURN OF THE NATIVE PRINCIPLES PAKIETYZACJA WARSTWOWA VS FUNKCJONALNA

  44. THE RETURN OF THE NATIVE PRINCIPLES PAKIETYZACJA FUNKCJONALNA VS KOMPONENTOWA

  45. THE RETURN OF THE NATIVE PRINCIPLES PAKIETYZACJA KOMPONENTOWA CD.

  46. WYCIEK ABSTRAKCJI

  47. THE RETURN OF THE NATIVE PRINCIPLES CORE DOMAIN WYCIEK ABSTRAKCJI

    - INFRASTRUKTURA /REST/full
  48. THE RETURN OF THE NATIVE PRINCIPLES WYCIEK ABSTRAKCJI - INFRASTRUKTURA

    Wysoki poziom abstrakcji Niski poziom abstrakcji import javax.sql.rowset.CachedRowSet; interface CustomerRepository { CachedRowSet findAll(); } import javax.sql.rowset.CachedRowSet; class SqlCustomerRepository implements CustomerRepository { @Override public CachedRowSet findAll() { // sql specific implementation } }
  49. THE RETURN OF THE NATIVE PRINCIPLES WYCIEK ABSTRAKCJI - INFRASTRUKTURA

    MICROSERVICE ENTITY MICROSERVICE MICROSERVICE ENTITY ENTITY ENTITY
  50. THE RETURN OF THE NATIVE PRINCIPLES DLACZEGO CHCECIE NAPISAĆ TEN

    SYSTEM OD NOWA? “To stoi na jakimś archaicznym Glassfish’u, cały soap, logowanie, deployment wszystko zrobione na natywnych rozwiązaniach Glassfish. Dostęp do bazy nawet nie jest przez Hibernate tylko jest jakiś kastomizowany Hades." “Ta logika biznesowa jest już nie na czasie. Obecnie biznes rządzi się już innymi prawami.” vs.
  51. TEMPO I CZĘSTOTLIWOŚĆ ZMIAN LOGIKI BIZNESOWEJ I TECHNIKALIÓW SĄ INNE

    ]
  52. THE RETURN OF THE NATIVE PRINCIPLES WYCIEK ABSTRAKCJI - DOMENA

    class LinearIncomeTaxCalculation implements IncomeTaxCalculationPolicy { private final BigDecimal RATE = BigDecimal.valueOf(0.19d); @Override public Tax calculate(YearlyIncome income) { return new Tax(income.getValue().multiply(RATE)); } } Wysoki poziom abstrakcji Niski poziom abstrakcji interface IncomeTaxCalculationPolicy { Tax calculate(YearlyIncome income); }
  53. THE RETURN OF THE NATIVE PRINCIPLES WYCIEK ABSTRAKCJI - DOMENA

    class LinearIncomeTaxCalculation implements IncomeTaxCalculationPolicy { private final BigDecimal RATE = BigDecimal.valueOf(0.19d); @Override public Tax calculate(YearlyIncome income) { return new Tax(income.getValue().multiply(RATE)); } } Wysoki poziom abstrakcji Niski poziom abstrakcji class AnnualSettlementUseCase { void account(CustomerId customerId) { Customer customer = customerRepository.findOne(customerId); IncomeTaxCalculationPolicy incomeTaxPolicy = //choose correct policy Tax tax = incomeTaxPolicy.calculate(customer.getYearlyIncome()); // do sth with calculated tax } } interface IncomeTaxCalculationPolicy { Tax calculate(YearlyIncome income); }
  54. THE RETURN OF THE NATIVE PRINCIPLES WYCIEK ABSTRAKCJI - DOMENA

    class LinearIncomeTaxCalculation implements IncomeTaxCalculationPolicy { private final BigDecimal RATE = BigDecimal.valueOf(0.19d); @Override public Tax calculate(YearlyIncome income) { return new Tax(income.getValue().multiply(RATE)); } } Wysoki poziom abstrakcji Niski poziom abstrakcji class AnnualSettlementUseCase { void account(CustomerId customerId) { Customer customer = customerRepository.findOne(customerId); IncomeTaxCalculationPolicy incomeTaxPolicy = //choose correct policy if (incomeTaxPolicy instanceof LinearIncomeTaxCalculation) { //do something only for this special case } } } interface IncomeTaxCalculationPolicy { Tax calculate(YearlyIncome income); }
  55. SOLID/GRASP

  56. THE RETURN OF THE NATIVE PRINCIPLES SINGLE RESPONSIBILITY ▸ Powinien

    istnieć jeden powód do zmiany w klasie, na przykład: ▸ Zmienia się flow obsługi przypadku użycia ▸ Zmienia się sposób obliczenia opłaty za nocne ładowanie ▸ Zmieniają się wymaganie dotyczące wydajności bazy danych
  57. THE RETURN OF THE NATIVE PRINCIPLES SINGLE RESPONSIBILITY ▸ Żadna

    klasa która miesza kod domenowy z technologią nie jest zgodna z SRP 1. Zmienia się domena 2. Zmienia się technologia CLASS /REST/full
  58. THE RETURN OF THE NATIVE PRINCIPLES SINGLE RESPONSIBILITY ▸ Hexagonal

    architecture ‣ Port - zmienia się domena ‣ Adapter - zmieniają się technikalia CORE DOMAIN
  59. THE RETURN OF THE NATIVE PRINCIPLES SINGLE RESPONSIBILITY VS DDD

    BUILDING BLOCKS
  60. SRP VS TEAMS BE FE QA PO

  61. SRP VS TEAMS BE FE QA PO

  62. THE RETURN OF THE NATIVE PRINCIPLES TEXT OPEN CLOSED PRINCIPLE

    ▸ Tworzymy klasy / komponenty które są zamknięte na modyfikacje… ale są otwarte na rozszerzenia ▸ Otwartość na rozszerzenia - możliwość dodawania nowej funkcjonalności bez zmian w klasach / komponentach zamkniętych na modyfikacje
  63. THE RETURN OF THE NATIVE PRINCIPLES OCP - POLITYKA /

    STRATEGIA POLICY SOME CONCRETE POLICY FANCY POLICY BUSINESS LOGIC Wysoki poziom abstrakcji Niski poziom abstrakcji
  64. THE RETURN OF THE NATIVE PRINCIPLES OCP - POLITYKA /

    STRATEGIA POLICY SOME CONCRETE POLICY FANCY POLICY ANOTHER POLICY BUSINESS LOGIC Wysoki poziom abstrakcji Niski poziom abstrakcji
  65. THE RETURN OF THE NATIVE PRINCIPLES OCP - POLITYKA /

    STRATEGIA POLICY SOME CONCRETE POLICY FANCY POLICY ANOTHER POLICY BUSINESS LOGIC YET ANOTHER POLICY Wysoki poziom abstrakcji Niski poziom abstrakcji
  66. THE RETURN OF THE NATIVE PRINCIPLES HEXAGONAL ARCHITECTURE - OCP

    NA POZIOMIE ARCHITEKTURY CORE DOMAIN
  67. THE RETURN OF THE NATIVE PRINCIPLES LISKOV SUBSTITUTION PRINCIPLE ▸

    Przez dziedziczenie lub implementację interfejsu tworzymy specyficzne obiekty które spełniają bazowy kontrakt
  68. THE RETURN OF THE NATIVE PRINCIPLES LISKOV SUBSTITUTION PRINCIPLE class

    Employee { void takeSalary() { //do sth } } @Test public void shouldTakeSalary() { //given Employee employee = someEmplyee(); //when employee.takeSalary(); //then salaryTaken(employee); }
  69. THE RETURN OF THE NATIVE PRINCIPLES LISKOV SUBSTITUTION PRINCIPLE class

    Employee { void takeSalary() { //do sth } } @Test public void shouldTakeSalary() { //given Employee employee = someEmplyee(); //when employee.takeSalary(); //then salaryTaken(employee); } class Volunteer extends Employee { @Override void takeSalary() { throw new UnsupportedOperationException(); } }
  70. THE RETURN OF THE NATIVE PRINCIPLES LISKOV SUBSTITUTION PRINCIPLE class

    Employee { void takeSalary() { //do sth } } @Test public void shouldTakeSalary() { //given Employee employee = new Volunteer(); //when employee.takeSalary(); //then salaryTaken(employee); } class Volunteer extends Employee { @Override void takeSalary() { throw new UnsupportedOperationException(); } }
  71. THE RETURN OF THE NATIVE PRINCIPLES INTERFACE SEGREGATION PRINCIPLE

  72. THE RETURN OF THE NATIVE PRINCIPLES INTERFACE SEGREGATION PRINCIPLE class

    Service { void methodA() { } void methodB() { } void methodC() { } } class ClientA { @Autowired Service service; void doSth() { service.methodA(); } } class ClientB { @Autowired Service service; void doSth() { service.methodB(); } }
  73. THE RETURN OF THE NATIVE PRINCIPLES INTERFACE SEGREGATION PRINCIPLE LEKIEM

    NA GOD OBJECT
  74. THE RETURN OF THE NATIVE PRINCIPLES DEPENDENCY INVERSION PRINCIPLE ▸

    Moduły wysokiego poziomu nie powinny zależeć od modułów niskiego poziomu ▸ Abstrakcje nie powinny zależeć od detali - to detale powinny zależeć od abstrakcji
  75. THE RETURN OF THE NATIVE PRINCIPLES DEPENDENCY INVERSION PRINCIPLE class

    InMemoryCustomerRepository implements CustomerRepository { private final Map<CustomerId, Customer> customers = new HashMap<>(); @Override public Customer findBy(CustomerId customerId) { return customers.get(customerId); } } Wysoki poziom abstrakcji Niski poziom abstrakcji public class CustomerActivation { private final CustomerRepository customerRepository; public CustomerActivation(CustomerRepository customerRepository) { this.customerRepository = customerRepository; } public Customer activateBy(CustomerId customerId) { Customer customer = customerRepository .findBy(customerId); return customer.activate(); } } public interface CustomerRepository { Customer findBy(CustomerId customerId); Customer save(Customer customer); }
  76. THE RETURN OF THE NATIVE PRINCIPLES TEXT DEPENDENCY INVERSION PRINCIPLE

    Wysoki poziom abstrakcji Niski poziom abstrakcji public class CustomerActivation { private final CustomerRepository customerRepository; public CustomerActivation(CustomerRepository customerRepository) { this.customerRepository = customerRepository; } public Customer activateBy(CustomerId customerId) { Customer customer = customerRepository.findBy(customerId); return customer.activate(); } } @RestController public class CustomerController { private final CustomerActivation activation; public CustomerController(CustomerActivation activation) { this.activation = activation; } @PutMapping(“/customers/{id}") Customer activate(@PathVariable("id") String id) { return activation.activateBy(CustomerId.from(id)); } }
  77. THE RETURN OF THE NATIVE PRINCIPLES TEXT ŚPICIE?

  78. None
  79. Od dziś tylko DDD, mikroserwisy i Event Sourcing!!!

  80. THANK YOU! @bartekslota bartslota.blogspot.com bartlomiej.slota@gmail.com github.com/bslota linkedin.com/in/bslota @p_szymczyk pawel@pszymczyk.com github.com/pszymczyk

    linkedin.com/in/pszymczyk