← Extractions

The Curse of Service Object — Ivan Nemytchenko at wroclove.rb 2024

Ivan Nemytchenko argues that the Rails service-object pattern is a controversial, harmful abstraction with no unified definition, contradicting what Fowler, Evans and Martin meant by 'service'. Using his 'OOP in Pictures' visualization and examples from GitLab's codebase, he shows service objects absorb controller responsibilities, mix application and domain logic, and grow inward in complexity. He proposes replacing them with a layered architecture of procedural services, mutators, managers, and models — giving each kind of work its own shelf.

Model
claude-opus-4-7
Ingestion
a9ef4ecc
Input tokens
561,610
fresh
421,970
cached
129,765
cache write
9,875
Output tokens
16,874
Duration
574.2s
Roundtrips
10
Tool calls
27
Cost
$0.00
Nodes/edges extracted
25 / 49
Read set (nodes/edges)
158 / 2

Nodes (25)

update Ivan Nemytchenko person
attrs {"role" => "GitLab developer advocate (European)", "nationality" => "Russian", "rails_since" => "2006"} {"role" => "Ruby on Rails agency owner", "location" => "Serbia", "nationality" => "Russian", "rails_since" => "2006",...
description Russian Rails developer who started using Rails in 2006. Has done freelancing, agency work, conference organizing, Le... Russian Rails developer who has lived in Serbia for 10 years. On Rails since 2006. Owns a small Ruby on Rails agency ...
short_description Russian Ruby/Rails developer, GitLab developer advocate, conference speaker. Russian Ruby/Rails developer, agency owner, ex-GitLab, conference speaker.
create Patterns of Enterprise Application Architecture resource
kind (empty) resource
name (empty) Patterns of Enterprise Application Architecture
slug (empty) patterns-of-enterprise-application-architecture
attrs (empty) {"type" => "book", "author" => "Martin Fowler"}
description (empty) Book by Martin Fowler referenced in The Curse of Service Object as a primary source on the Service Layer pattern. Des...
short_description (empty) Martin Fowler's canonical book on enterprise application architecture patterns.
update The Curse of Service Object talk
attrs {"type" => "talk"} {"date" => "2024-03-22", "type" => "talk"}
description Talk at wroclove.rb 2024. Ivan Nemytchenko's wroclove.rb 2024 single-speaker talk. Argues service objects are a 'strange, controversial and har...
short_description Talk at wroclove.rb 2024. Ivan Nemytchenko's wroclove.rb 2024 talk critiquing Rails service objects.
create OOP in Pictures concept
kind (empty) concept
name (empty) OOP in Pictures
slug (empty) oop-in-pictures
attrs (empty) {"category" => "practice"}
description (empty) Teaching and analysis method Ivan Nemytchenko invented while teaching students object-oriented programming. Classes a...
short_description (empty) Ivan Nemytchenko's visual ontology representing OOP constructs as cartoon dudes.
update Mutator Layer concept
description Ivan Nemytchenko's proposed layer between services and Active Record. A mutator handles a single purpose — creating, ... Ivan Nemytchenko's proposed layer between services and Active Record. A mutator is a plain procedure (module or class...
create Manager Layer concept
kind (empty) concept
name (empty) Manager Layer
slug (empty) manager-layer
attrs (empty) {"category" => "architecture"}
description (empty) Ivan Nemytchenko's proposed architectural building block for code that interacts with external systems (APIs, mailers...
short_description (empty) Architectural layer wrapping interactions with external systems.
create Service Layer concept
kind (empty) concept
name (empty) Service Layer
slug (empty) service-layer
attrs (empty) {"category" => "architecture"}
description (empty) Concept from Martin Fowler's Patterns of Enterprise Application Architecture. Defines the application boundary and th...
short_description (empty) Fowler's architectural layer defining application boundary and available operations.
create Domain Service concept
kind (empty) concept
name (empty) Domain Service
slug (empty) domain-service
attrs (empty) {"category" => "pattern"}
description (empty) Concept from Eric Evans' Domain-Driven Design book, cited as the closest DDD analogue to the Rails 'service object'. ...
short_description (empty) Eric Evans' DDD construct for stateless operations representing significant domain processes.
create Clean Code resource
kind (empty) resource
name (empty) Clean Code
slug (empty) clean-code
attrs (empty) {"type" => "book", "author" => "Robert C. Martin"}
description (empty) Book by Robert C. Martin (Uncle Bob). Referenced in The Curse of Service Object for its comments on services: a servi...
short_description (empty) Robert C. Martin's book on writing clean, maintainable software.
create Robert C. Martin person
kind (empty) person
name (empty) Robert C. Martin
slug (empty) robert-c-martin
description (empty) Software author ('Uncle Bob') referenced in The Curse of Service Object for his book Clean Code. Cited for the ideas ...
short_description (empty) Software author known as 'Uncle Bob'; wrote Clean Code and championed SOLID.
update Eric Evans person
description Author of 'Domain-Driven Design: Tackling Complexity in the Heart of Software' (2003/2004), the foundational DDD text... Author of 'Domain-Driven Design: Tackling Complexity in the Heart of Software' (2003/2004), the foundational DDD text...
update Martin Fowler person
description Software author and thought leader. Referenced by Davydov as having described a 'reactive' approach to deleting user-... Software author and thought leader. Author of Patterns of Enterprise Application Architecture, where he defines the S...
short_description Software author, referenced for reactive GDPR-deletion approach. Software author; wrote Patterns of Enterprise Application Architecture.
update GitLab company
description DevOps platform company. Mentioned in Counterintuitive Rails pt. 1 as Ivan Nemytchenko's employer (European developer... DevOps platform company. Mentioned in Counterintuitive Rails pt. 1 as Ivan Nemytchenko's employer (European developer...
create Painless Rails resource
kind (empty) resource
name (empty) Painless Rails
slug (empty) painless-rails
attrs (empty) {"type" => "book", "status" => "unfinished"}
description (empty) Ivan Nemytchenko's unfinished book on Rails patterns. Referenced in the Q&A of The Curse of Service Object: an audien...
short_description (empty) Ivan Nemytchenko's unfinished book on Rails patterns.
update Stateless Service Object concept
description Ivan Nemytchenko's take on services, aligned with DDD's 'service is an action, not a thing'. Implement services as cl... Ivan Nemytchenko's take on services, aligned with DDD's 'service is an action, not a thing'. Implement services as cl...
update Service Object concept
description Long-standing Rails pattern Krzywda once advocated and calls a 'gateway drug' to DDD. Known under many names (service... Long-standing Rails pattern Krzywda once advocated and calls a 'gateway drug' to DDD. Known under many names (service...
create Complexity Grows Inward in Service Objects takeaway
kind (empty) takeaway
name (empty) Complexity Grows Inward in Service Objects
slug (empty) complexity-grows-inward-in-service-objects
attrs (empty) {"type" => "warning"}
description (empty) Observation from Ivan Nemytchenko's tour of GitLab service objects: a service that starts with two private methods gr...
short_description (empty) Left unchecked, service objects accrete responsibilities and become large internal monsters.
create Give Each Kind of Work Its Own Shelf takeaway
kind (empty) takeaway
name (empty) Give Each Kind of Work Its Own Shelf
slug (empty) give-each-kind-of-work-its-own-shelf
attrs (empty) {"type" => "recommendation"}
description (empty) Ivan Nemytchenko's central recommendation: instead of putting different kinds of code into building blocks of the sam...
short_description (empty) Route each kind of code (business rules, mutations, external calls, app logic) to a dedicated layer.
create Service Objects Are Not Domain Services takeaway
kind (empty) takeaway
name (empty) Service Objects Are Not Domain Services
slug (empty) service-objects-are-not-domain-services
attrs (empty) {"type" => "insight"}
description (empty) When the service objects from ~a dozen developer articles are measured against the combined 'service ruler' (stateles...
short_description (empty) Real-world Rails service objects fail most of Fowler/Evans/Martin's criteria.
create Prefer Procedural Code For Everyday Rails takeaway
kind (empty) takeaway
name (empty) Prefer Procedural Code For Everyday Rails
slug (empty) prefer-procedural-code-for-everyday-rails
attrs (empty) {"type" => "recommendation"}
description (empty) Ivan Nemytchenko's answer to a Q&A challenge: OOP is appropriate when extending frameworks or writing libraries/gems,...
short_description (empty) Most daily Rails code should be simple procedures, not OOP machinery.
create Don't Use Interactors takeaway
kind (empty) takeaway
name (empty) Don't Use Interactors
slug (empty) don-t-use-interactors
attrs (empty) {"type" => "recommendation"}
description (empty) Ivan Nemytchenko's Q&A recommendation: the interactor gem adds even more boilerplate than plain service objects and a...
short_description (empty) The interactor gem adds boilerplate with no real benefit over plain functions.
create Over-engineering risk of inventing layers question
kind (empty) question
name (empty) Over-engineering risk of inventing layers
slug (empty) over-engineering-risk-of-inventing-layers
attrs (empty) {"answer_summary" => "No — the approach mostly reuses Rails' existing service layer and only introduces the Mutator l...
description (empty) Audience question: GitLab is a sophisticated application with complex login logic, but most people will never work on...
short_description (empty) Won't developers just invent layers and classes for the sake of it?
create When to use OOP vs procedural question
kind (empty) question
name (empty) When to use OOP vs procedural
slug (empty) when-to-use-oop-vs-procedural
attrs (empty) {"answer_summary" => "Use OOP for framework/library development and internals. Daily application code should be proce...
description (empty) Audience question: one of Ivan's arguments is that service objects aren't really objects, yet his own approach goes f...
short_description (empty) If service objects aren't object-oriented, when do you use OOP?
create Real large apps using this pattern question
kind (empty) question
name (empty) Real large apps using this pattern
slug (empty) real-large-apps-using-this-pattern
attrs (empty) {"answer_summary" => "The two startups he's been helping. In practice it's imperfect; pragmatic dirty solutions are f...
description (empty) Audience question asking for a large Rails application where Ivan's pattern has actually been applied. Ivan answers t...
short_description (empty) Any large Rails app applying this layered approach?
create Relation to Painless Rails book question
kind (empty) question
name (empty) Relation to Painless Rails book
slug (empty) relation-to-painless-rails-book
attrs (empty) {"answer_summary" => "Yes — the talk is the evolution of the book's patterns; Ivan plans to rewrite it. 'Shapes' are ...
description (empty) Audience question: is The Curse of Service Object's approach an extension of the patterns in Ivan's Painless Rails bo...
short_description (empty) Is this approach an extension of the patterns in Painless Rails?

Edges (49)

update Ivan NemytchenkoauthoredThe Curse of Service Object
context (empty) Ivan delivered this talk at wroclove.rb 2024.
update The Curse of Service Objectpresented_atwroclove.rb 2024
context (empty) Talk was given at the 2024 edition of wroclove.rb.
update Ivan Nemytchenkoworks_atGitLab
attrs {"role" => "developer advocate (European)"} {"role" => "developer advocate", "status" => "former"}
context European GitLab developer advocate at the time of the talk. Ivan mentions he used to work for GitLab; now a former employer.
update Ivan NemytchenkousesRuby on Rails
attrs (empty) {"since" => "2006"}
context Rails developer since 2006; main framework discussed in the talk. On Rails since 2006; runs a small Ruby on Rails agency.
create Ivan NemytchenkoauthoredOOP in Pictures
context (empty) Ivan invented this visual teaching method and presented a dedicated talk on it at RailsClub.
relation (empty) authored
source_node_id (empty) 042242c9-ad5a-4afd-a4f3-196eb52fec1d
target_node_id (empty) 2b9400f0-40a7-4b85-81bc-96bee5f753d2
create The Curse of Service ObjectaboutService Object
context (empty) The talk's central subject is the Rails service-object pattern.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) b8d19b36-ebfb-4be1-bba5-790358c566d1
create The Curse of Service ObjectaboutOOP in Pictures
context (empty) Ivan introduces and uses his OOP in Pictures method throughout the talk.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) 2b9400f0-40a7-4b85-81bc-96bee5f753d2
create The Curse of Service ObjectaboutService Layer
context (empty) Talk analyzes Fowler's Service Layer as a source for the 'service ruler'.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) 9c8c9a20-ad17-4b6e-9ef5-faab5c5b0d1e
create The Curse of Service ObjectaboutDomain Service
context (empty) Talk analyzes Evans' Domain Service as a source for the 'service ruler'.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) a1dcf1f7-5c49-4556-a0ce-5ce0fab00c1b
create The Curse of Service ObjectaboutPatterns of Enterprise Application Architecture
context (empty) Ivan discusses Fowler's book as a primary source on service layers.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) 02897ded-a1fa-4d97-a1f2-758f03357d4f
create The Curse of Service ObjectaboutClean Code
context (empty) Ivan extracts Robert Martin's comments on services and SRP from Clean Code.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) ef6e9ee7-2193-44b4-a6b8-981d203624e3
create The Curse of Service ObjectaboutSingle Responsibility Principle
context (empty) SRP (single reason to change) is a core measure in the talk's service ruler.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) aa71b064-e663-4a43-b25d-ea26e256fc27
create The Curse of Service ObjectaboutMutator Layer
context (empty) Ivan proposes the Mutator layer as the right shelf for complex creation/edit/delete procedures.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) 94a8394a-b926-4dc0-a97f-b88e2acbef27
create The Curse of Service ObjectaboutManager Layer
context (empty) Ivan proposes the Manager layer for encapsulating external-system interactions.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) 31a6e197-de54-45d2-b017-857e8ffb7320
create The Curse of Service ObjectaboutStateless Service Object
context (empty) The talk advocates stateless procedural services as the replacement for stateful service objects.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) 983561ee-b05e-4222-852e-cbb810c95643
create The Curse of Service ObjectaboutApplication Logic vs Business Logic
context (empty) Ivan stresses keeping application logic (permissions, session, response prep) out of services.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) e79c288b-9149-42ba-a299-547c1819b819
create The Curse of Service ObjectaboutGitLab
context (empty) Examples of real-world service objects are drawn from GitLab's open-source Rails codebase.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) 2051dd64-70af-4d5f-9f67-c4401c69a0cd
create The Curse of Service Objectaboutinteractor
context (empty) In Q&A Ivan recommends against using the interactor gem.
relation (empty) about
source_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
target_node_id (empty) 047e3d48-95ea-4128-81f7-18166f44c711
create Martin FowlerauthoredPatterns of Enterprise Application Architecture
context (empty) Fowler is the book's author.
relation (empty) authored
source_node_id (empty) 33f22dea-eae4-4b70-969f-4d51b3c8924c
target_node_id (empty) 02897ded-a1fa-4d97-a1f2-758f03357d4f
update Eric EvansauthoredDomain-Driven Design: Tackling Complexity in the Heart of Software
context Wrote the foundational DDD book. Evans is the DDD book's author; domain services come from this book.
create Robert C. MartinauthoredClean Code
context (empty) Clean Code is Robert C. Martin's book.
relation (empty) authored
source_node_id (empty) 7705840d-8648-4807-ae7f-5f52fba7ff33
target_node_id (empty) ef6e9ee7-2193-44b4-a6b8-981d203624e3
create Service Layerrelated_toPatterns of Enterprise Application Architecture
context (empty) Service Layer pattern is defined in Fowler's book.
relation (empty) related_to
source_node_id (empty) 9c8c9a20-ad17-4b6e-9ef5-faab5c5b0d1e
target_node_id (empty) 02897ded-a1fa-4d97-a1f2-758f03357d4f
create Domain Servicerelated_toDomain-Driven Design: Tackling Complexity in the Heart of Software
context (empty) Domain Service is defined in Evans' DDD book.
relation (empty) related_to
source_node_id (empty) a1dcf1f7-5c49-4556-a0ce-5ce0fab00c1b
target_node_id (empty) 48659931-177d-43aa-a529-8bde7532565a
create Mutator Layerrelated_toStateless Service Object
context (empty) Mutators are called by stateless services to handle persistence.
relation (empty) related_to
source_node_id (empty) 94a8394a-b926-4dc0-a97f-b88e2acbef27
target_node_id (empty) 983561ee-b05e-4222-852e-cbb810c95643
create Manager Layerrelated_toStateless Service Object
context (empty) Managers are called by stateless services to handle external-system interactions.
relation (empty) related_to
source_node_id (empty) 31a6e197-de54-45d2-b017-857e8ffb7320
target_node_id (empty) 983561ee-b05e-4222-852e-cbb810c95643
create Stateless Service Objectrelated_toService Object
context (empty) Ivan's stateless procedural services replace stateful service objects.
relation (empty) related_to
source_node_id (empty) 983561ee-b05e-4222-852e-cbb810c95643
target_node_id (empty) b8d19b36-ebfb-4be1-bba5-790358c566d1
update Ivan NemytchenkorecommendsStateless Service Object
context Prefers class-method services over instantiable, stateful ones. Core recommendation of The Curse of Service Object.
update Ivan NemytchenkorecommendsMutator Layer
context Ivan Nemytchenko recommends introducing a mutators layer for atomic persistence operations. Ivan proposes the Mutator layer as the only genuinely new layer on top of Rails defaults.
create Ivan NemytchenkorecommendsManager Layer
context (empty) Ivan recommends isolating external-service interactions into managers.
relation (empty) recommends
source_node_id (empty) 042242c9-ad5a-4afd-a4f3-196eb52fec1d
target_node_id (empty) 31a6e197-de54-45d2-b017-857e8ffb7320
create Ivan Nemytchenkorelated_tointeractor
context (empty) Ivan explicitly recommends against using the interactor gem; converting to plain functions is better.
relation (empty) related_to
source_node_id (empty) 042242c9-ad5a-4afd-a4f3-196eb52fec1d
target_node_id (empty) 047e3d48-95ea-4128-81f7-18166f44c711
create Ivan NemytchenkoauthoredPainless Rails
context (empty) Ivan's unfinished book; the talk is the evolution of its patterns.
relation (empty) authored
source_node_id (empty) 042242c9-ad5a-4afd-a4f3-196eb52fec1d
target_node_id (empty) 20daf9c4-8b01-45e1-9ad7-8d6e92eed7d7
create Complexity Grows Inward in Service Objectsfrom_talkThe Curse of Service Object
context (empty) Observation derived from the talk's tour of GitLab service objects.
relation (empty) from_talk
source_node_id (empty) 56e4344f-e173-4c93-b729-d43d0f7f9ef2
target_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
create Give Each Kind of Work Its Own Shelffrom_talkThe Curse of Service Object
context (empty) Central recommendation of the talk.
relation (empty) from_talk
source_node_id (empty) 91c536b3-282a-4574-9201-703061581e4e
target_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
create Service Objects Are Not Domain Servicesfrom_talkThe Curse of Service Object
context (empty) Conclusion from measuring the example service objects against Fowler/Evans/Martin criteria.
relation (empty) from_talk
source_node_id (empty) e8518b4d-58e0-47e2-8b04-ef9b9c18688f
target_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
create Prefer Procedural Code For Everyday Railsfrom_talkThe Curse of Service Object
context (empty) Drawn from Ivan's Q&A answer on OOP vs procedural.
relation (empty) from_talk
source_node_id (empty) 49d3004d-e935-4999-84e4-83c196be798e
target_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
create Don't Use Interactorsfrom_talkThe Curse of Service Object
context (empty) Q&A recommendation against the interactor gem.
relation (empty) from_talk
source_node_id (empty) 3696bbc6-708d-471c-92ed-77eecd31d7f3
target_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
create Give Each Kind of Work Its Own ShelfaboutMutator Layer
context (empty) Mutator layer is one of the shelves Ivan proposes.
relation (empty) about
source_node_id (empty) 91c536b3-282a-4574-9201-703061581e4e
target_node_id (empty) 94a8394a-b926-4dc0-a97f-b88e2acbef27
create Give Each Kind of Work Its Own ShelfaboutManager Layer
context (empty) Manager layer is one of the shelves Ivan proposes.
relation (empty) about
source_node_id (empty) 91c536b3-282a-4574-9201-703061581e4e
target_node_id (empty) 31a6e197-de54-45d2-b017-857e8ffb7320
create Give Each Kind of Work Its Own ShelfaboutStateless Service Object
context (empty) Services-as-procedures are one of the shelves Ivan proposes.
relation (empty) about
source_node_id (empty) 91c536b3-282a-4574-9201-703061581e4e
target_node_id (empty) 983561ee-b05e-4222-852e-cbb810c95643
create Complexity Grows Inward in Service ObjectsaboutGitLab
context (empty) Observation drawn from GitLab's real service-object evolution.
relation (empty) about
source_node_id (empty) 56e4344f-e173-4c93-b729-d43d0f7f9ef2
target_node_id (empty) 2051dd64-70af-4d5f-9f67-c4401c69a0cd
create Service Objects Are Not Domain ServicesaboutDomain Service
context (empty) Takeaway compares real service objects to Evans' Domain Service criteria.
relation (empty) about
source_node_id (empty) e8518b4d-58e0-47e2-8b04-ef9b9c18688f
target_node_id (empty) a1dcf1f7-5c49-4556-a0ce-5ce0fab00c1b
create Don't Use Interactorsaboutinteractor
context Takeaway is specifically about the interactor gem. Q&A specifically recommended against interactors.
create Over-engineering risk of inventing layersasked_atThe Curse of Service Object
context (empty) Q&A question at the talk.
relation (empty) asked_at
source_node_id (empty) 10f61074-9c9e-40e6-8085-bbd091522771
target_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
create When to use OOP vs proceduralasked_atThe Curse of Service Object
context (empty) Q&A question at the talk.
relation (empty) asked_at
source_node_id (empty) 930979ee-9d39-4a16-85c5-44d74f629b67
target_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
create Real large apps using this patternasked_atThe Curse of Service Object
context (empty) Q&A question at the talk.
relation (empty) asked_at
source_node_id (empty) feb670f0-309d-48d4-848a-19c0daee1753
target_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
create Relation to Painless Rails bookasked_atThe Curse of Service Object
context (empty) Q&A question at the talk.
relation (empty) asked_at
source_node_id (empty) 62106709-1fc6-4778-8df3-06b89acfdedd
target_node_id (empty) 315c2af8-8b52-4852-bd41-6c183109890d
create Relation to Painless Rails bookaboutPainless Rails
context (empty) Question is about Ivan's book.
relation (empty) about
source_node_id (empty) 62106709-1fc6-4778-8df3-06b89acfdedd
target_node_id (empty) 20daf9c4-8b01-45e1-9ad7-8d6e92eed7d7
create Over-engineering risk of inventing layersaboutGitLab
context (empty) Question frames GitLab as the sophisticated kind of app most developers won't work on.
relation (empty) about
source_node_id (empty) 10f61074-9c9e-40e6-8085-bbd091522771
target_node_id (empty) 2051dd64-70af-4d5f-9f67-c4401c69a0cd
create When to use OOP vs proceduralaboutStateless Service Object
context (empty) Question challenges the talk's procedural, non-OOP approach.
relation (empty) about
source_node_id (empty) 930979ee-9d39-4a16-85c5-44d74f629b67
target_node_id (empty) 983561ee-b05e-4222-852e-cbb810c95643

Read set

158 nodes

takeaway Mutant as complexity metric and refactoring guide search_nodes concept Contextualized Complexity search_nodes resource Grokking Simplicity search_nodes talk Offline Sandwich Focus Workflow search_nodes tool Reform search_nodes tool Active Admin search_nodes resource Rails Architect Master Class search_nodes question What is an enterprise Rails application? search_nodes concept Application Logic vs Business Logic search_nodes takeaway Stop Building Web Apps, Build Software search_nodes concept Saga Pattern search_nodes concept Reservation Pattern search_nodes takeaway Don't Bring MVC-CRUD Thinking To Services search_nodes concept Application Layer vs Domain Layer search_nodes concept CQRS search_nodes concept Mutator Layer search_nodes concept Method References in Ruby search_nodes talk Methods Gem for Ruby Method References search_nodes resource 12 Ways to Call a Method in Ruby search_nodes person Ivan Nemytchenko search_nodes tool Ruby on Rails search_nodes resource nemytchenko.ru search_nodes resource Woman on Rails search_nodes project Ruby Romania search_nodes talk Counterintuitive Rails pt. 1 search_nodes event Rails World search_nodes resource Short Ruby Newsletter search_nodes person Julik Tarkhanov search_nodes tool IronRuby search_nodes concept Service Object search_nodes concept Stateless Service Object search_nodes talk The Curse of Service Object search_nodes+get_node_edges concept Null Object Pattern search_nodes takeaway Don't reuse service objects across applications search_nodes question Wrapper Job vs Logic In Job search_nodes takeaway Prefer class-method services over stateful service objects search_nodes tool interactor search_nodes takeaway Service objects are mappers from params to commands search_nodes question Can service objects and command handlers call each other? search_nodes person Martin Fowler search_nodes resource Domain-Driven Design: Patterns, Principles and Practices search_nodes concept Architecture Drivers search_nodes question Risk of misidentifying domains during legacy re-architecture search_nodes resource Domain-Driven Design: Tackling Complexity in the Heart of Software search_nodes concept DDD Whirlpool search_nodes concept Structural Physics of Software search_nodes resource Implementing Domain-Driven Design search_nodes concept Data-Dictated Development search_nodes concept Distributed Monolith search_nodes concept Domain-Driven Design search_nodes person Eric Evans search_nodes talk Strategic Domain Event Design Lightning Talk search_nodes talk Might & Magic of Domain-Driven Design search_nodes talk The pillars of Domain Driven Design search_nodes resource Domain-Driven Rails search_nodes resource Practical Object-Oriented Design in Ruby search_nodes takeaway Mentor by Guiding, Not Coding search_nodes takeaway Prefer conventions over custom code search_nodes resource awesome-ddd search_nodes question How to detect coupling in a large existing project? search_nodes resource 99 Bottles of OOP search_nodes resource Object-Oriented Software Construction search_nodes question Phrases to avoid in code review search_nodes talk Ever shorter feedback loop search_nodes event wroclove.rb 2024 search_nodes event wroclove.rb 2022 search_nodes event wroclove.rb 2023 search_nodes event wroclove.rb 2019 search_nodes event wroclove.rb 2018 search_nodes event wroclove.rb 2025 search_nodes event wroclove.rb 2026 search_nodes talk Building LLM powered applications in Ruby search_nodes talk How wroclove.rb impacts developers and companies search_nodes talk Towards the post framework future search_nodes company GitLab search_nodes tool GitHub Actions search_nodes concept GitHub Self-Hosted Runner search_nodes tool CircleCI search_nodes tool PR Labeler search_nodes tool GitHub Releases search_nodes tool Release Drafter search_nodes tool Codecov search_nodes tool reviewdog search_nodes concept Timeline Visualization search_nodes concept Domain Storytelling search_nodes concept Call Graph Visualization search_nodes question How to do DDD remotely? search_nodes concept Distance From The Main Sequence search_nodes takeaway Add Fun to Keep Remote Workshops Human search_nodes question Does DDD require object-oriented programming? search_nodes takeaway Draw Call Graphs To Expose Wrong-Way Dependencies search_nodes takeaway Mentorship Grows Both Sides search_nodes concept Developer vs Programmer search_nodes person Bertrand Meyer search_nodes talk Fantastic Databases and Where to Find Them search_nodes talk Building Beautiful UIs with Ruby A Rails-Native Approach search_nodes event EmberConf search_nodes talk Configuration Again Lightning Talk search_nodes resource The Rails and Hotwire Codex search_nodes resource Stefan Wintermeyer's Rails 5.2 Book search_nodes takeaway Rails Way vs Design Way search_nodes talk When REST is Not Enough: Implementing Alternative Protocols in Ruby on Rails search_nodes talk Securing Rails applications search_nodes talk No-build Utopia: Modern User Experiences with Rails & Web Standards search_nodes takeaway Give Unto Rails That Which Is Rails search_nodes person Sandi Metz search_nodes takeaway Avoid complexity before fighting it search_nodes talk Dealing With A Project's Complexity In A Changing Environment search_nodes concept Cynefin Framework search_nodes concept Namespace-Based Folder Hierarchy search_nodes tool Representable search_nodes concept Single Responsibility Principle search_nodes concept Open-Closed Principle search_nodes concept Tell Don't Ask search_nodes concept Liskov Substitution Principle search_nodes concept Minimal Interface search_nodes concept Dependency Injection search_nodes question Is the sufficient-funds check a feature envy smell? search_nodes concept Onion Architecture search_nodes concept Hexagonal Architecture search_nodes takeaway Stratified Design Applies At Every Scale search_nodes takeaway Layered DDD is junior-friendly and estimation-friendly search_nodes concept MVC Modularity Violations search_nodes question Is layered DDD really junior-friendly? search_nodes tool langchainrb search_nodes tool ruby-openai search_nodes takeaway Sign serverlessforruby.org petition search_nodes concept Mock Third-Party Services Locally search_nodes concept AI Agent search_nodes takeaway Port Python Libraries With ChatGPT search_nodes question Using external auth providers instead of Devise search_nodes concept Retrieval Augmented Generation search_nodes talk MVCC for Ruby developers search_nodes tool server-engine search_nodes project Ruby News search_nodes person Adam Okoń search_nodes tool Jumpstart Pro search_nodes talk Scientific Ruby Lightning Talk search_nodes talk Doctrine of Useful Objects Separate Fact from Fiction in OOD search_nodes tool Ruby search_nodes question How does naming an abstraction relate to OOP design? search_nodes concept Plain Old Java Object search_nodes concept Fat Model Thin Controller search_nodes takeaway Fat Model Skinny Controller Is A Design Mistake search_nodes concept Params-Driven Development search_nodes concept respond_to Anti-Pattern search_nodes takeaway Introduce bounded-context controller namespaces search_nodes takeaway Don't create controllers at Rails boot time search_nodes concept Flat Model Structure search_nodes tool acts_as_api search_nodes question Can you do DDD without event sourcing? search_nodes takeaway Event Sourcing Is About State Not Distribution search_nodes takeaway DDD Is More Than Aggregates search_nodes question Is building DDD from scratch too slow for the business? search_nodes takeaway Bounded Contexts Are Natural Microservice Seams search_nodes question Does DDD apply to startups? search_nodes question Isn't asking password confirmation business logic? search_nodes takeaway Look outside Ruby for better patterns search_nodes

2 edges