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

The Curse of Service Object

The Curse of Service Object

Demonstration of why concept of Service Object is meaningless and harmful, and what should you do instead.

Ivan Nemytchenko

April 14, 2024
Tweet

More Decks by Ivan Nemytchenko

Other Decks in Technology

Transcript

  1. Who am I painlessrails.com makefile.site UrbanConnect Setyl 🇬🇧 🇨🇭 Ivan

    Nemytchenko 🇷🇺→🇷🇸 Twitter: @inemation Github: @inem on Rails since 2006 Small agency owner ex GitLab
  2. Service Object is • a very strange, controversial, and harmful

    abstraction* • that doesn’t make any sense • contradicts with main architecture principles • and doesn’t give you any benefits*
  3. Service Object is • a very strange, controversial, and harmful

    abstraction* • that doesn’t make any sense • contradicts with main architecture principles • and doesn’t give you any benefits* * in long term
  4. What do devs say? • Maintainability, avoid code bloat •

    Single responsibility • More modular • Encapsulates business logic • Easier to test • Keeps your code clean, organized and structured
  5. What do we see? • Validation • Calculation • Creation

    of an entity (mutation) • Business scenario (mutation + notification) • Business scenario (external service + mutation) • Wrapper for external service
  6. Martin fowler Patterns of Enterprise Application Architecture Service layer: •

    separates domain logic from application logic • de fi nes application boundary
  7. Martin fowler Patterns of Enterprise Application Architecture Service layer: •

    separates domain logic from application logic • de fi nes application boundary • sets available operations
  8. Martin fowler Patterns of Enterprise Application Architecture Service layer: •

    separates domain logic from application logic • de fi nes application boundary • sets available operations • coordinates domain objects
  9. Martin fowler Patterns of Enterprise Application Architecture Service layer: •

    separates domain logic from application logic • de fi nes application boundary • sets available operations • coordinates domain objects • controls transactions
  10. Martin fowler Patterns of Enterprise Application Architecture Service layer: •

    separates domain logic from application logic • de fi nes application boundary • sets available operations • coordinates domain objects • controls transactions • encapsulates the app's business logic
  11. Martin fowler Patterns of Enterprise Application Architecture Service layer: •

    separates domain logic from application logic • de fi nes application boundary • sets available operations • coordinates domain objects • controls transactions • encapsulates the app's business logic • coordinates responses
  12. Martin fowler Patterns of Enterprise Application Architecture Service layer: •

    separates domain logic from application logic • de fi nes application boundary • sets available operations • coordinates domain objects • controls transactions • encapsulates the app's business logic • coordinates responses
  13. Martin fowler Patterns of Enterprise Application Architecture Service layer: •

    separates domain logic from application logic • de fi nes application boundary • sets available operations • coordinates domain objects • controls transactions • encapsulates the app's business logic • coordinates responses
  14. Eric Evans Domain-Driven Design Domain Services: • are stateless •

    named for an activity rather than an entity • represent signi fi cant business domain processes/operations
  15. Eric Evans Domain-Driven Design Domain Services: • are stateless •

    named for an activity rather than an entity • represent signi fi cant business domain processes/operations • are distinct from technical services
  16. Eric Evans Domain-Driven Design Domain Services: • are stateless •

    named for an activity rather than an entity • represent signi fi cant business domain processes/operations • are distinct from technical services
  17. Eric Evans Domain-Driven Design Domain Services: • are stateless •

    named for an activity rather than an entity • represent signi fi cant business domain processes/operations • are distinct from technical services • may have side effects
  18. Eric Evans Domain-Driven Design Domain Services: • are stateless •

    named for an activity rather than an entity • represent signi fi cant business domain processes/operations • are distinct from technical services • may have side effects
  19. Robert martin Clean Code • service should have well-de fi

    ned interface • can be a single component or composed of several components
  20. Robert martin Clean Code • service should have well-de fi

    ned interface • can be a single component or composed of several components separated by architectural boundaries •
  21. Robert martin Clean Code • "service should have well-de fi

    ned interface” • can be a single component or composed of several components separated by architectural boundaries • Context: SOA and Microservices
  22. Robert martin Clean Code • "service should have well-de fi

    ned interface” • can be a single component or composed of several components separated by architectural boundaries • Context: SOA and Microservices
  23. Robert martin Clean Code • "service should have well-de fi

    ned interface” • can be a single component or composed of several components separated by architectural boundaries • Context: SOA and Microservices • highlights importance of Single Responsibility Principle
  24. The message being sent to us Domain Services: • are

    stateless • named for an activity rather than an entity • represent signi fi cant business domain processes/operations • are distinct from technical services • may have side effects Service layer: • separates domain logic from application logic • de fi nes application boundary • sets available operations • coordinates domain objects • controls transactions • encapsulates the app's business logic Single Responsibility Principle !
  25. The message being sent to us Domain Services: • are

    stateless • named for an activity rather than an entity • represent signi fi cant business domain processes/operations • are distinct from technical services • may have side effects Service layer: • separates domain logic from application logic • de fi nes application boundary • sets available operations • coordinates domain objects • controls transactions • encapsulates the app's business logic Single Responsibility Principle ! 🤔 🫷 🫸
  26. Technical services == Application logic? Service Layer consists of Domain

    Services, which are: • are stateless • named for an activity rather than an entity • represent signi fi cant operations • coordinate domain objects & control transactions • comply with Single Responsibility principle • may have side effects The message being sent to us 🫷 🫸
  27. Technical services == Application logic? Service Layer consists of Domain

    Services, which are: • are stateless • named for an activity rather than an entity • represent signi fi cant operations • coordinate domain objects & control transactions • comply with Single Responsibility principle • may have side effects The message being sent to us 🫷 🫸
  28. Our Service Ruler!! Domain Service: is stateless named for an

    activity, not entity represents business operations coordinates domain objects controls transactions complies with Single Responsibility principle should theoretically have side effects no application logic 🫷 🫸
  29. Domain Service: is stateless named for an activity, not entity

    represents business operations coordinates domain objects controls transactions complies with Single Responsibility principle should theoretically have side effects no application logic
  30. ± Domain Service: is stateless named for an activity, not

    entity represents business operations coordinates domain objects controls transactions complies with Single Responsibility principle should theoretically have side effects no application logic ?
  31. ? Domain Service: is stateless named for an activity, not

    entity represents business operations coordinates domain objects controls transactions complies with Single Responsibility principle should theoretically have side effects no application logic
  32. ± ± Domain Service: is stateless named for an activity,

    not entity represents business operations coordinates domain objects controls transactions complies with Single Responsibility principle should theoretically have side effects no application logic
  33. ± Domain Service: is stateless named for an activity, not

    entity represents business operations coordinates domain objects controls transactions complies with Single Responsibility principle should theoretically have side effects no application logic
  34. Domain Service: is stateless named for an activity, not entity

    represents business operations coordinates domain objects controls transactions complies with Single Responsibility principle should theoretically have side effects no application logic
  35. Domain Service: is stateless named for an activity, not entity

    represents business operations coordinates domain objects controls transactions complies with Single Responsibility principle should theoretically have side effects no application logic
  36. Domain Service: is stateless named for an activity, not entity

    represents business operations coordinates domain objects controls transactions complies with Single Responsibility principle should theoretically have side effects no application logic Sorry, but NO!
  37. Domain Service: is stateless named for an activity, not entity

    represents business operations coordinates domain objects controls transactions complies with Single Responsibility principle should theoretically have side effects no application logic ?
  38. What do devs say? Maintainability, avoid code bloat Single responsibility

    More modular Encapsulates business logic Easier to test Keeps your code clean, organized and structured ? ± ?
  39. What is so object about them? • state? • lifecycle

    of an object? • multiple instances of a class?
  40. What is so object about them? • state? • lifecycle

    of an object? • multiple instances of a class?
  41. What is service object? • It is a technical trick

    • In the sake of • moving code from controllers? • testing it separately? (±)
  42. What we see • Proactively stealing controller’s responsibilities • Mixing

    application logic with domain logic inside service objects
  43. What we see • Code doing different types of work

    go in the same bucket. • Lots of low level code doing different types of work
  44. What we see • Code doing different types of work

    go in the same bucket. • Lots of low level code doing different types of work
  45. Validations Complex mutations Interaction with External systems Calculation logic Business

    rules Business operations Data preparation Caching Response preparation Work with session
  46. What we see • Service Layer becomes responsible for everything

    • Effectively we have killed ideas of Layered Architecture, Modularity and SRP at this point.
  47. The curse • No reason for services to be shaped

    as objects • Doesn’t match with what Fathers said • Devs do not achieve proclaimed benefits • Opposes ideas of Layered architecture, Modularity and SRP
  48. Validations Complex mutations Interaction with External systems Calculation logic Business

    rules Business operations Data preparation Caching Response preparation Work with session
  49. Services Managers Mutators Business Rules Forms "Throughout our history, it

    has always been standardisation of components that has enabled creations of greater complexity" - Simon Wardley
  50. • Long methods are fine • as long as it

    is the same type of work • and the same level of abstraction
  51. • Let’s have its own “shelf” for every type of

    work done by your app. • Some shelves we do have already
  52. • Low level details of complex mutations go into its

    own Mutator layer • Mutators are just procedures • No need for callbacks • No more half-baked objects in your system anymore
  53. • Domain services are business operations • It is just

    a procedure • But of a high level of abstraction
  54. • Keep application logic outside of services • Check permissions

    outside of service • Only call it with valid params
  55. Domain Service: is stateless named for an activity, not entity

    represents business operations coordinates domain objects controls transactions complies with Single Responsibility principle should theoretically have side effects Code of the same level of abstraction