5 ms·
I think the underlying principles of DDD and Hexagonal Architecture are sound, but man, they make it so complicated. A good serving of KISS always helps. - Kee
by davedx 5y ago
I think the underlying principles of DDD and Hexagonal Architecture are sound, but man, they make it so complicated. A good serving of KISS always helps.
- Keep your domain models separate from infra implementation stuff
- Architect your applications in sensible layers
- Decouple stuff that doesn't strictly belong together
This stuff should not need lists of XML config to get right, it's portable to any language or framework, and not just web applications.
- royjacobs 5y agoThe only XML in this article is about configuring Maven, the build system, though?
- shoo 5y ago> Keep your domain models separate from infra implementation stuff this is a corollary of the S in SOLID -- domain models and infra implementations will have different reasons to change at different times, so they should be decoupled > Architect your applications in sensible layers > Decouple stuff that doesn't strictly belong together Agreed, but this isn't prescriptive enough, if you put 5 opinionated stakeholders in a room, they may argue over 25 different incompatible ideas of "sensible". Parnas suggests arranging things into modules so that changes or difficult decisions are isolated to single modules. Basically the same idea as S in SOLID. The D in SOLID suggests a concrete way to decouple things (interfaces!). > This stuff should not need lists of XML config to get right agreed. the key idea is to think about the dependency graph between modules. XML config & dependency injection & so on are some techniques for managing dependencies, but it is less important that figuring out a clean module design and module dependency structure that decouples the application. Many possible candidate dependencies between pairs of modules should be banned as they would erode the architecture and add unnecessary coupling between things that need to change in response to different forces. With some extra knowledge about the purpose of each module, it should be possible to write a small validation tool that can inspect module dependencies and automatically fail the build if someone proposes to add a bad dependency. https://en.wikipedia.org/wiki/SOLID https://en.wikipedia.org/wiki/SOLID http://sunnyday.mit.edu/16.355/parnas-criteria.html http://sunnyday.mit.edu/16.355/parnas-criteria.html
- berkes 5y ago> This stuff should not need lists of XML config to get right I'm "doing" DDD in "hexagonal monoliths" for years now. And have never touched a line of XML. The XML is caused by Java (more specific its Maven build system). You'll hardly touch any XML when you build your projects in Go, Ruby (not rails!), Rust or many other languages or platforms.
- regularfry 5y agoFor the record you won't touch XML in Rails either!
- berkes 5y agoCorrect! Why I emphasized the not rails! part was to avoid confusion about DDD, Hexagonal and Rails. I'm convinced Rails cannot and will not be usable in a DDD setup, or Hexagonal architecture. Well, maybe if Rails is the "HTTP interface", but you'll be fighting tooth and nails to make it not use a database.
- Tabular-Iceberg 5y agoI haven't used Rails before, so I may be missing something, but is this necessarily the case? If I remember correctly the blue book isn't too keen on modelling your domain in your database, but rather build it out of POJOs and then build a separate layer. But at the same time it's open to using DDD with a logic paradigm, which is eerily similar to a relational database. If, after you've done the necessary work with the domain experts, you have determined that Rails is the right tool for a job, I think you can safely call it a paradigm and carry on.
- berkes 5y agoI'm quite certain that with some effort, and possibly some stretching of definitions, one can "do DDD with Rails". But at that point you are going against the grain. You are both missing out on some good parts of Rails and spending a lot of time to work around or against what Rails wants and needs: Rails is very opinionated, don't forget that. From https://en.wikipedia.org/wiki/Active_record_pattern#Criticism https://en.wikipedia.org/wiki/Active_record_pattern#Criticis... > Another critique of the active record pattern is that, also due to the strong coupling of database interaction and application logic, an active record object does not follow the single responsibility principle and separation of concerns as opposed to multitier architecture which properly addresses these practices.[citation needed][clarification needed] Because of this, the active record pattern is best and most often employed in simple applications that are all forms-over-data with CRUD functionality, or only as one part of an architecture.[citation needed] Typically that part is data access and why several ORMs implement the active record pattern. And a Rails without ActiveRecord, while technically possible, leaves you with a Rails that is hardly workable -if at all- and brings a lot of pain. Your application will live in ActiveRecord models, spread all over: > ActiveRecord is meant to become the central part of your domain logic. -- https://solnic.codes/2016/05/22/my-time-with-rails-is-up/ https://solnic.codes/2016/05/22/my-time-with-rails-is-up/ So the answer would be: yes, this is necessarily the case. In practice and even in theory.
- regularfry 5y agoIt's not just keeping things separate, though. It's getting the dependencies in the right direction too. I'd argue that's actually the most important part. A lot of people would look at the decoupling in a hexagonal app (or something along the Clean Architecture lines - they're very similar) and say that you don't need that much decoupling, but the patterns are very powerful; deciding to opt into that power early is a good choice to make more times than you'd think.
- rapnie 5y agoIt helps to separate DDD strategical parts from DDD tactical patterns. The first is really intuitive and broadly applicable, while on the second you get bombarded with a flood of information, opinionated approaches and OOP-y design complexity.
- Kototama 5y agoYes, incredible what years of Java Enterprise can inflict to the brain :-). It reminds me of the whole dependency injection circus where in the end it's just the equivalent of passing a function constructing an instance to another function in FP.
- cztomsik 5y agoexcept the container can do whatever mumbo-jumbo you may want/need, like declarative transactions, declarative permission checks, logging, publishing events to external systems, etc. and then you have async constructed dependencies, for example when you need to ask some server for configuration first, before service can be started, and with a good DIC the whole app will just wait automatically and you don't have to worry about any of that anywhere in your app (aka you are abstracted from this) what you have said is not technically wrong but it also over-simplifies what DI is and it brings to the table EDIT: that said, I agree in general, that java projects are over-engineered
- Tainnor 5y agoMost of these things can be done with higher-order functions too. I think that if Java had had lambdas earlier, Spring and other such frameworks might look very different. You can see that already, Spring is adding (experimental?) support for more declarative styles of configuration instead of the rather slow and hard-to-debug reflection magic: https://github.com/spring-projects-experimental/spring-fu https://github.com/spring-projects-experimental/spring-fu
- cztomsik 5y agoYes but unfortunately I don't see how it invalidates my point. a) you either replace DIC with custom hard-wired functions (composed using any-order custom helpers) and then it's still hard-wired at one place b) you reinvent DI with functions but it's still some magic, late-configurable, easy-to-plugin container (aka the circus which I think you were referring to and which I have said it's actually useful and worth) EDIT: or what exactly are you complaining about?