HN Books @HNBooksMonth

The best books of Hacker News.

Hacker News Comments on
Domain-Driven Design: Tackling Complexity in the Heart of Software

Eric Evans · 3 HN points · 21 HN comments
HN Books has aggregated all Hacker News stories and comments that mention "Domain-Driven Design: Tackling Complexity in the Heart of Software" by Eric Evans.
View on Amazon [↗]
HN Books may receive an affiliate commission when you make purchases on sites after clicking through links on this page.
Amazon Summary
Title: Domain-Driven Design( Tackling Complexity in the Heart of Software) <>Binding: Hardcover <>Author: EricEvans <>Publisher: Addison-WesleyProfessional
HN Books Rankings

Hacker News Stories and Comments

All the comments and stories posted to Hacker News that reference this book.
>I see a pattern and I feel the older generation is way more capable and knowledgeable when it comes to Computer Science in general. I am pretty sure a lot of people are or were in the same boat as me.

The older generation are in this place because back then none of the technologies you listed existed and so they had to know the more low level things.

A book that might help some of your knowledge gaps (at least directionally) is The Imposter's Handbook[1] by Rob Conery.

If you're specifically aiming to get away from CRUD take a look at the various Domain Driven Design books by Eric Evans[2] and others. This is the opposite direction to your ask though (more high level than low level).

If you want to go deeper in Java, read Effective Java[3] and Java Concurrency in Practice (JCIP)[4]

Lastly, if you want to experience the reasons why some of that early comp-sci stuff happened the way it did, playing with expensive hardware is the least effective way to find understanding of constraints. Instead consider grabbing devices with significant limitations like an Arduino, ESP32, or similar (I'm partial to the Wio Terminal[5] and M5Stack[6] as interesting easy to get started devices, but others would suggest various Arduinos or Raspberry Pi devices). Realistically you're going to learn much more by coming up with a self-challenging project and completing it than just by learning it for the sake of learning.

[1]: https://bigmachine.io/products/the-imposters-handbook/

[2]: https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...

[3]: https://www.amazon.com/Effective-Java-Joshua-Bloch/dp/013468...

[4]: https://www.amazon.com/Java-Concurrency-Practice-CONCURRENCY...

[5]: https://www.seeedstudio.com/Wio-Terminal-p-4509.html

[6]: https://m5stack.com/

Feb 19, 2021 · pjmlp on Monolith First (2015)
It is a bit hard to just explain in a bunch of comments.

In your examples you need to add extra layers, just like you would do with the microservices.

There would be the DTOs that represent the actual data that gets across the models, the view models that package the data together as it makes sense for the views, the repository module that actually abstracts if the data is accessed via SQL, ORM, RPC or whatever.

You should look into something like:

"Domain-Driven Design: Tackling Complexity in the Heart of Software"

https://www.amazon.com/Eric-J-Evans/dp/0321125215

"Component Software: Beyond Object-Oriented Programming"

https://www.amazon.com/Component-Software-Beyond-Object-Orie...

Largely agree with this except the initial objection "Data structure and functions should not be bound together" and the "Why was OO popular?" which is missing the response - because using the notion that "objects" from the real world encapsulate state and behaviour was not only a solid premise, but it was an attempt to interface the computer world with the real. This was not a failed concept. It makes some sense. Just very few teams find the discipline to model their core domain this way.

Which brings be back to the original objection. I think this is true most of the time, except when it's not - which is your core Domain Model. The first 1/2 of the Blue Book[1] lays out straightforward means to arrange code, functions, data/state and related behaviours in a way which can be managed and maintained over time. This is pretty important as most folks who've spent any length of time maintaining vast applications will know that it's incredibly hard to reason about a first-class concept in an application without clear boundaries around said concept, it's structures and it's behaviour. Most of us are unlucky and find this scattered across the landscape. Few applications take the focus to "model" these concepts clearly.

Does this modelling have to be done with "Domain Model", or DDD, or something else that can be loosely coupled with OOD - probably not. But another developer absolutely has to be able to reason about said structures and behaviour. They have to be able to read it easily and grok it quickly. And having done that, they don't want to be surprised by some distant missing element, 20 calls or 1000 lines or 15 modules (repos, submodules, etc, etc) away! This is possibly the biggest time-sink and therefore "cost" of development. One could also take this further and postulate that about 1/2 of us are employed as a direct result of applications whose core concepts are so poorly designed or hard to reason about, that a massive volume of work (time?) is dedicated to unwinding the ambiguity that results.

I don't want to suggest that OOP or OOD/DDD/{other modelling process} would necessarily fix this, but the attempt to clarify and find a means to make modelling these critical concepts easier and less costly is admirable IMO.

It's ok if your infrastructure takes a different approach, or is "functional" or "dynamic" in nature. If your test suite uses completely different patterns and paradigms because the tooling makes that easy then - awesome! But if the core model/concepts of your application are hard to understand, reason about, and therefore maintain, then you're pretty fucked.

OO doesn't "suck". It's spirit is just largely lost and like many other things in life, it's been hijacked and mutilated into something many of us come to loathe because we've never seen it deliver on the promises. I guess we will be having this conversation again in another decade about something else that's hugely popular right now.

[1] https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...

When I shifted to Elixir/Phoenix 1.3 I found the whole naming contexts thing to be super difficult and confusing. This is the method I use now, but I'm sure it could use refinement. I still need to read Eric Evan's book [1] but I'd be open to other suggestions for further reading.

[1] https://www.amazon.com/gp/product/0321125215?ie=UTF8&tag=mar...

If you're going to dive into CQRS/ES, I'd recommend:

* Enterprise Integration Patterns (basically an entire book about messaging architectures) [1] * Vaughn Vernon's books and online writing [2], * Domain Driven Design by Eric Evans [3], * and most of what Greg Young, Udi Dahan, and that constellation of folks has done online (lots of talks and blog articles.)

Depending on your platform of choice, there may be others worth reading. For my 2¢, the dragons are mostly in the design phase, not the implementation phase. The mechanics of ES are pretty straightforward—there are a few things to look out for, like detection of dropped messages, but they're primarily the risks you see with any distributed system, and you have a collection of tradeoffs to weigh against each other.

In design, however, your boundaries become very important, because you have to live with them for a long time and evolving them takes planning. If you create highly coupled bounded contexts, you're in for a lot of pain over the years you maintain a system. However, if you do a pretty good job with them, there's a lot of benefits completely aside from ES.

[1] https://www.amazon.com/Enterprise-Integration-Patterns-Desig...

[2] https://vaughnvernon.co

[3] https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...

I can only refer you to Eric Evans book (https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...) and other domain driven design material.

Boundaries are by domain, and yes that's not a simple thing to define. Sometimes, domains have varying interfaces, which makes building micro-services more complex, especially when trying to adhere to REST/Swagger standards (something I'm not overly find of).

But keeping things as simple as possible is really the best approach.

All micro-services should be small. When I see someone say "big", then I'm guessing there are a lot of ad-hoc actions...those need to be broken down into their proper domain or relegated to a query service.

ChicagoDave
I wanted to add that building micro-services requires a bullet-proof security strategy, usually something like OAuth2.

Using authentication, users of an API can have "claims" that will help a micro-service delineate access and provide a way to design for varying interfaces.

This still leaves the Swagger standards in direct opposition to building a set of variant end points since it _requires_ that end points be singular (you can't have a GET api/foo/{id} and a GET api/bar/{id} on the same API without a lot of fudging. This is a distraction from building enterprise-level API's and leans far too much toward single-purpose API's.

Eric Evans' "Domain-Driven Design: Tackling Complexity in the Heart of Software" book is long and pretty dry, but it's immediately practical and opened my mind to how object-oriented design is supposed to work.

https://amzn.com/0321125215

https://en.wikipedia.org/wiki/Domain-driven_design

darethas
Is there a world of software architecture that exists outside the "OOP" patterns we have seen in the last 2 decades? A quarter of the way through my career and I have already grown weary of OOP. It's promises are never realized. It is full of zealots who can argue with you for ages but don't deliver very much on real world, performant software.
Identifying changing "stuff" in the real world is for me a fundamental topic of any serious data modeling for any kind of software (be it an API, a traditional database stuff, etc). Identity is also at the center of the entity concept of Domain-Driven Design (see the seminal book of Eric Evans on that: https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...).

I started changing my way of looking at identity by reading the rationale of clojure (https://clojure.org/about/state#_working_models_and_identity) -> "Identities are mental tools we use to superimpose continuity on a world which is constantly, functionally, creating new values of itself."

The timeless book "Data and reality" is also priceless: https://www.amazon.com/Data-Reality-Perspective-Perceiving-I....

More specifically concerning the article, I do agree with the point of view of the author distinguishing access by identifier and hierarchical compound name better represented as a search. On the id stuff, I find the amazon approach of using URN (in summary: a namespaced identifier) very appealing: http://philcalcado.com/2017/03/22/pattern_using_seudo-uris_w.... And of course, performance matters concerning IDs and UUID: https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-ca....

Happy data modeling :)

EDIT: - add an excerpt from the clojure rationale

> If you aren’t familiar with the database pattern known as event sourcing (don’t worry — it’s relatively new),

It's not relatively new. That “transaction file” thing in your database? Event Sourcing.

https://goodenoughsoftware.net/2012/03/02/case-studies/

> If you’re not looking at the public chain, you’re wasting your time

I disagree. Not having a single point of failure (one place that can get hacked) is valuable.

> From a trust perspective, it makes no difference if your banking cartel is writing to a Quorum, Hyperledger, or Kafka instance.

Of course it does. The protocol of blockchains makes them work with "proof of X". Appending to any event store, whether in Kafka or SQL does not require proof of anything.

> Blockchains are built for trust, databases for throughput. Event sourcing allows us to achieve a hybrid model with characteristics of both.

No, the reason blockchains can't have high throughpout / almost infinite horizontal scalability... is because there's a logic check. E.g. in bitcoin, you can't send more bitcoins than you have a balance. Event sourcing gives you the high throughpout if there's no logic checks across aggregates --- if there are, you won't have immediate consistency, and you have to be ready for compensating events.

I recommend two books, that cover event sourcing from a Domain Driven Design perspective. The consequences are similar.

https://www.amazon.co.uk/Domain-driven-Design-Tackling-Compl... https://www.amazon.co.uk/Implementing-Domain-Driven-Design-V...

-----------------

If that doesn't do it for you, please just remember the good old CAP theorem.

https://en.wikipedia.org/wiki/CAP_theorem

eternalban
> good old CAP theorem.

Sat in on a candidate interview recently whereby I heard the news that the blockchain "invalidates CAP". Not sure if it will also cure cancer.

hudon
>> From a trust perspective, it makes no difference if your banking cartel is writing to a Quorum, Hyperledger, or Kafka instance.

> Of course it does. The protocol of blockchains makes them work with "proof of X". Appending to any event store, whether in Kafka or SQL does not require proof of anything.

The author should have qualified that from a user's perspective, it makes no difference. If my bank decided to store its users' transactions on a proof of work database, I wouldn't even know. Which is the author's point: it makes no difference from a trust perspective, I'm still trusting the bank to store and settle my transaction either way.

It's not proof of work by itself that makes something like Bitcoin trustless (again, from the user's perspective). It's the fact that both the proof of work and blocks are public and verifiable, thus I can validate the blockchain and make sure the miners are doing the work correctly (my transactions are there and the proof of work is valid). Proof of work without making the database public and audit-able by users is pointless. But if it is public and it's shown that the miners are not settling transactions as they should, then users can fork or move to a blockchain that doesn't censor transactions.

galeaspablo
May I refer you back to

>> If you’re not looking at the public chain, you’re wasting your time

> I disagree. Not having a single point of failure (one place that can get hacked) is valuable.

I.e. if your chain isn't public there are benefits to using it.

If you suddenly say the same benefits can be obtained with kafka or a relational database, you will be introducing proof of something... Which means you'll now have a blockchain / distributed system based on a relational database. Which comes with the limitations imposed by the CAP theorem.

The most popular version of event sourcing produces such a high throughput, because immediate consistency is sacrificed. I'd like to see what the author proposes in a production system. Global rules would not be enforceable (e.g. no balance under zero), unless throughput is sacrificed to allow for immediate consistency.

Two books that affected my thinking on the subject were Domain Driven Design[1] by Eric Evans and Object Thinking[2] by David West. Many years since I read the books and I don't claim to have studied them in detail so I'm not saying if they were good or bad, but at least I got some ideas out of them.

[1] https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...

[2] https://www.microsoftpressstore.com/store/object-thinking-97...

I worked with MVC before, but eventually I found that DDD (Domain Driven Design) is what I'm looking for. Domain Driven Design is more like a set of rules of how to apply the existing design partners (eg: repository, factory and aggregation) and building blocks (eg: layering architecture) to design your business models and keep the integrity, invariance between data. Moreover, it lets you easily define the boundary between your services for Microservice architecture.

MartinFowler DDD blogs: http://martinfowler.com/tags/domain%20driven%20design.html Book: https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...

Oct 22, 2016 · 3 points, 0 comments · submitted by technobook
Lurk on the CQRS/DDD list [1], lots of good info there. I'm not aware of any textbooks on ES per se but there are a few good books on areas that overlap. [2] [3] [4]

[1] https://groups.google.com/forum/#!forum/dddcqrs

[2] https://www.amazon.com/Enterprise-Integration-Patterns-Desig...

[3] https://www.amazon.com/Implementing-Domain-Driven-Design-Vau...

[4] https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...

Sep 14, 2016 · wpietri on Ask HN: How to Learn OOP
This is a great explanation of how to really start seeing objects. Like you, I just look for data that travels together. Then I find code that only ever gets used on that data. I pull it out and figure out a name for it. This observational approach avoids a ton of architecture astronautics, where people dream up giant object hierarchies and stick with them no matter what the code is telling them.

The main compliment I'd suggest to this approach is Eric Evans' book Domain-Driven Design: https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...

In a bottom-up approach, you can often break things down in a variety of ways. But the most stable/useful ways are often the ones that align with the conceptual model of the domain. If I notice that certain data and behavior goes together with incoming money, I might call that an InboundMoneyWorkingUnit. But if I talk to people who've spent years working in the domain, I'll realize the object should be called Payment, and their description of what a Payment does will inform my hunt for other objects and methods.

I think the term he's struggling toward is something like "user experience debt" [1] or "product design debt" [2], an area that has been discussed for years.

I think "conceptual debt" is a poor choice of phrase here, as one important kind of technical debt is the sort of software design debt where your domain model ends up being a poor fit for your domain, often because the domain concepts themselves shift. (For those interested, "Domain-Driven Design" is a great book relating to this [3].)

I also find the "worse than technical debt" headline irritating. It's the sort of, "the thing I specialize in is way more important than the thing you specialize in" thinking that is poisonous in a team environment. Which one is actually worse depends a lot on your product and your business conditions.

[1] https://medium.com/@vijayssundaram/user-experience-debt-c9bd...

[2] http://andrewchen.co/product-design-debt-versus-technical-de...

[3] http://www.amazon.com/Domain-Driven-Design-Tackling-Complexi...

nicoslepicos
Thanks for the recommended reads, enjoyed them and they're hitting on really similar notions. Well cited comment :)

Conceptual debt is product design debt like you're suggesting. In particular, I think of it as a subset of product design debt that has to do with domain modeling as you suggest vs. having the write domain models but having poor user flows around those core concepts.

Unlike user flows, concepts are also reflected in the API & Object Models in your codebase so those may be trickier to change than the user flows that revolve around them.

nicoslepicos
Also just ordered that book. Looks like a good read
We didn't have Haskell in 1989. As I wrote, there are things I value in FP languages in general, and more specifically Backus's FP calculus inspired me to come up with Higher Order Messaging[1].

It's nice to have language support for functional style (let, for example) where that is appropriate for the problem at hand, but you can write in that style without the language support easily enough.

On the other hand, when FP style is not appropriate for the problem at hand, it really, really gets in the way, and that's the case a lot of the time. Many if not most problems (outside of writing compilers for FP languages) don't really fit the functional style, and have to be made to fit.

Experienced devs will choose appropriate tools for the problem at hand. Me, I like adaptive tooling that I can bend to fit the problem, which is why I like dynamic OO languages, internal DSLs and Domain Modeling[2] in general.

In fact, I think the current tools are still a little too inflexible for this, which is why I am creating a language to address some of these issues: http://objective.st

FP seems to be more about bending the problem to fit the tooling, which I guess may work for a specific kind of mindset.

[1] http://en.wikipedia.org/wiki/Higher_order_message

[2] http://www.amazon.com/Domain-Driven-Design-Tackling-Complexi...

tome
> Many if not most problems ... don't really fit the functional style, and have to be made to fit

Some examples would be helpful here.

mpweiher
Hmm...didn't realize this was (or could be) a serious question.

Anything with state comes to mind. The text field I am typing this into, for example. I type on my keyboard and the state of the text field changes, and after I hit "reply", the state of the page changes with a comment appended. Before/after.

Yes, you can implement this by creating a completely new page containing the concatenation of the old page with the comment, but externally (when you visit the URL), the state of that page has changed. So if you choose to implement the problem in a functional style, you have to bridge that gap somehow between that style and the problem at hand.

Any sort of document processing done on computers in Word, Excel (regarding the document itself, not the one way dataflow constraint program inside), OpenOffice, PowerPoint, Pages, Keynote, Quark XPress, InDesign, Photoshop, Illustrator etc. People use these programs to change the state of documents. That is the purpose of these programs.

Anything that interacts with the world, for example the user interface.

Or Wikipedia. Pages change, sometimes because there is new information, sometimes because something in the world has changed. Or most any other web site.

Really, the world (a) has (a lot of) state and (b) that state is changing incessantly. It is not (a) stateless or (b) immutable.

But don't take it from me: "In the end, any program must manipulate state. If it doesn't, there is no point in running it. You hit go and the box gets hotter" - Simon Peyton-Jones. https://www.youtube.com/watch?v=iSmkqocn0oQ&t=3m20s

tome
Thank you for the food for thought.
nbevans
It's pretty rubbish food he just gave you there. This is why F# has the mutable keyword. If you are so desperate to use it, that is. Most good programmers try to avoid it.

It's funny that this guy claims fitting the problem to suit FP is a bad thing. But fitting the problem to suit OOP is seemingly a good thing. There is no difference really. All problems have to be made to fit your tooling and practices in same way. The difference is how much squashing is required and the two or three second decision it takes to select the right tool. Only performance optimisations really warrant falling back to mutation of state, other than IO of course. The default should always be immutable. Don't let some brain dead OOP-only troll deter you from seeing the light.

He is speaking is riddles, like pseudo academics love to. Seriously, he is suggesting you can't have an editable text box on a GUI, written in a language like Scala, F# or OCaml? What a moron. (This link will prove particularly embarrassing to a certain person here: http://www.scala-lang.org/api/2.10.2/index.html#scala.swing....) He is arguing an argument that doesn't even exist here, but one that only exists in his own head.

Pure FP, much like pure OOP, is utter shit and painful. The sweet spot is reached by mixing the two and using a multi-paradigm language, ala F#, Scala, OCaml, etc.

nbevans
Adaptive tooling. You mean like a FP ML then ala OCaml / F#.

I said I like hybrid OO-FP languages for business productivity, rather than concentrating on meaningless software architecture astronautics like that "Blue Book" you linked. I've read it, yes starting from chapter 11, and while I took it on board I find many of its ideas and practices completely toxic now. Just like Gang of Four patterns and the inane amount that OOP inherently relies upon them.

Then you go off on some academic rant about "well in 1989" (no one cares) and HPC computing (no one cares, it's hardly relevant either). FP has progressed a lot since 89 but you're seemingly too old and set in your purely OOP ways to realise it. Carry on. But take a look at a modern OO-FP multi paradigm language and feel enlightened.

If you carry on down the path of ranting about FP because, shock horror, yes it is slower than imperative code then you'll look even sillier. Not that anyone really cares about some randomer making himself look silly by poo-pooing a whole programming language paradigm whilst paradoxically claiming he always likes to choose the right tool for the job. I guess your jobs have just never been varied enough then?

PS: Higher order messaging is just function composition with presumably a dash of actors. Congrats on reinventing a functional programming concept. But it perfectly illustrate the ignorance so prevalent in individuals that only know OOP and will attack anything that isn't OOP.

mpweiher
>academic rant about "well in 1989" (no one cares)

Funny, my age seemed to be important when I was "young and inexperienced". Now "no one cares"...and I am "too old and set in my ways". Which is it? Both? Does my age matter or not? Both again?

Hint: if your conclusion remains the same, but your reasons for that conclusion are this inconsistent, then your conclusions is almost certainly not supported by those reasons. In the words of Popper, an "immunized" theory, meaning it is immune to falsification by empirical evidence.

Anyway, as you gain experience, you will probably appreciate the wisdom of domain modeling. Or remain ignorant. Not sure how the GoF Pattern book got into this discussion, but note that it is largely a description of workarounds for non-dynamic OO languages.

The 6x slower performance was relevant for "Data Parallel Haskell", because performance is pretty much the only reason for doing that sort of parallelism in the first place, as I explained. HPC was relevant because they had been doing the thing that was claimed "impossible" by SPJ in languages not like Haskell...in FORTRAN (which I hope we can agree is not all that much like Haskell).

Had you paid attention, you would have noticed that I use functional techniques when appropriate. I just don't buy the inflated claims, which have been consistently inflated and consistently unsupported by evidence for well over 2 decades now ... and object to arrogant ignorance such as that which you have amply displayed and continue to display.

To call HOM derivative is not exactly a deep insight, when I very specifically told you that it was derivative (and the papers are also very clear about that). However, you display fundamental misunderstanding of not just HOM (which could be forgiven), but also OOP and FP: HOM is exactly not "function composition". OOP languages have had higher order functions ("blocks" in Smalltalk) for decades, and these can be and have been composed quite easily. The point of HOM is that the first order mechanism in an OOPL is messaging, so having functions as the higher order mechanism is inconsistent. HOM creates a HO mechanism that is based on messaging instead of functions, hence HOM. Actors are an unrelated concept.

tome
I know it's always tempting to argue vagaries with trolls, but if you have the time I would very much appreciate it if you could give a short answer to my good faith question here:

https://news.ycombinator.com/item?id=8339654

nbevans
Cheeky bugger ain't you? "Had you paid attention"? "As I gain experience"? You mean on top of the 20 I already have, and which I clearly used to better effect than yourself as I'm not still rolling around believing the DDD Blue Book is the be-all-end-all silver bullet of software development. I took it on board, and kept some of its ideas in my toolkit, but really it is a book all about over-engineering for those that don't know any better. Domain modelling gives the impression of UML diagrams and all that lark, is that you? It isn't me. My domain models are honed over time as the project evolves. You act like domain models can't be done in FP. My domain models that I write in F# are sodding impressive and they only use a quarter of the lines of code required by Obj-C, Java, C# and similar ilk.

HOM? Don't make me laugh. It's just more shit for the objective world to work around limitations of the languages. A message is just an object that can be and queued somewhere, and potentially serialized. That's not special.

- Loves dynamic languages. Check. - Loves OO. Check. - Loves DDD Blue Book. Check. - Invents "new" programming design patterns all by himself believing he is the sole inventor. Check. - Dabbled with an FP language in '89 and hasn't touched FP ever since. Check. - Created his own shitty programming language to try to improve upon OOPs limitations. Check. - Dares to talk down to anyone more experienced or that disagrees with him. Check.

Yeah, I wouldn't employ you either.

Mar 03, 2014 · ollysb on Rails – The Missing Parts
Perhaps because it's written with examples in java but I often feel like no one in the rails community has ever read Eric Evan's Domain Driven Design[1]. It's far and away the best material I've ever seen on how to organise large code bases. It covers pretty much every suggestion that I've seen from the rails community. Sometimes the rails community can feel like the fitness industry, everybody just rebranding things that have been done before.

[1] http://www.amazon.com/Domain-Driven-Design-Tackling-Complexi...

tomblomfield
Sure - I don't think anyone in the Rails world is claiming to have invented these principles.

The problem is that Rails ships with a very limited set of core architectural concepts, and many inexperienced Rails developers feel like they've got to cram all of their code into a Model, View or Controller.

Once your codebase reaches a certain complexity, principles from other programming paradigms are extremely useful.

philwelch
Interactors, domain objects, service objects, etc. are still models; people just don't generally believe that their models are allowed to inherit from things other than ActiveRecord::Base.
ulisesrmzroche
They're not models, they're Objects. A model is an object but all objects are not models. The difference is what sort of role they play in your app.

A Service Object work, could just echo hello world every 15 seconds and still be called a Service Object, while a model in your application doing the same thing can no longer be called a Model.

mst
I keep looking at interactors and thinking "I'd make this a command object and then hide it in the model" - so I'd be doing something like (inside the 'member' class)

    method confirm_grouper () {
      MyApp::Action::ConfirmGrouper->new(leader => $self)
                                   ->run
    }
and then the controller would simply do -

    my $result = $member->confirm_grouper;
pothibo
Problem with your assumptions is that inexperienced developers do not understand architectural concepts.

So you could cram every design pattern known to man and they would still cram everything in their controller.

API's are hard to discover and it takes time through trial and errors or being teached the way things are.

grey-area
To be fair, Rails does have concerns which let you easily compose your models out of modules, rather than having big god-object models, and it is easy to load other arbitrary collections of code too. So it is not really limited to MVC.

For beginners, I'm not sure it would be helpful to introduce a whole load of named patterns, as it just leads to cargo-culting and overuse of patterns without understanding whether they even apply.

It was interesting to read about a different approach though - thanks for the article.

djur
The problem with concerns is that they don't actually break down the god classes, they just separate the pieces of the god class into different files and combine them at runtime.

The important metric here isn't "wc -l app/models/god.rb", it's "God.public_instance_methods.length".

grey-area
You don't have to use them for that, you can use them for composing models out of shared bits of functionality, for example 5 of your models have a status - put all the code about statuses in one place in a concern and include Status in your models, and possibly similar for controllers - this cuts code duplication.

There is also an argument for making models smaller by splitting some of their functionality into modules too (what you're talking about), but I think that's a weaker case - better to use concerns for shared code.

rubiquity
> "The problem is that Rails ships with a very limited set of core architectural concepts, and many inexperienced Rails developers feel like they've got to cram all of their code into a Model, View or Controller."

The problem is that people think Rails is an architecture to begin with. Rails is just a framework that uses the MVC pattern (mangled slightly to fit the realm of HTTP). In the end, MVC is nothing but a directory structure for our files. What you put in those files and directories is up to you. Uncle Bob gave a great keynote on this called Architecture: The Lost Years. Here's a link: http://www.confreaks.com/videos/759-rubymidwest2011-keynote-...

tomblomfield
Yes, that's a wonderful talk
mattgreenrocks
You have to realize: Rails is incredibly populist in that it's "good enough" architecture for many devs. It's not terrible, but it's not at all the same as learning basic architectural principles for building apps. Devs don't stray outside of it much, they just deal with it when it gets to be a problem.

In this way, we've successfully commoditized another differentiating factor of developers so we can ship on Internet Time(tm).

hiphopyo
Is http://tech.taskrabbit.com/blog/2014/02/11/rails-4-engines/ another one of those?
rasur
In my first Rails job, I was handed a copy of this book to read. I would agree with your comments, although I cannot speak for the Ruby Community as such. Well worth reading.
ollysb
There's also a condensed version for free over at infoq[1](requires registration, but definitely worth it).

[1] http://www.infoq.com/minibooks/domain-driven-design-quickly

antonydenyer
probably because in most cases the domain model doesn't get that complex.
antonydenyer
probably because in most cases the domain model doesn't get that complex.
kohanz
I would argue that both the Rails community and fitness industry may operate that way, but for good reasons. Any time you have an ongoing an significant influx of beginners, looking to hit the ground running, bad practices will be everywhere. A handful of established "bibles" or textbooks aren't going to be enough to get the message out to the masses. It may not be appealing to those already "in the know", but good practice messages need to be repeated and communicated in new ways. You also see the same dynamic at the gym, of the experienced gym-rat lamenting the things that personal trainers get paid to teach newbies.

In that same vein, this may be a repeat message of a concept that is not novel, but as an experienced non-web developer who is fairly new to Rails, I learned something from reading this.

I also appreciate you pointing out what sounds like a good development resource (Domain Driven Design).

That's correct, those terms come from Domain Driven Design terminology and are not related to C#.

You can learn more about it from this book:

Domain-Driven Design: Tackling Complexity in the Heart of Software

http://www.amazon.com/Domain-Driven-Design-Tackling-Complexi...

HN Books is an independent project and is not operated by Y Combinator or Amazon.com.
~ [email protected]
;laksdfhjdhksalkfj more things
yahnd.com ~ Privacy Policy ~
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.