Hacker News new | ask | show | jobs
by programminggeek 4639 days ago
Pluggable systems (loose coupling) are the easiest way to create a system that is cheap and easy to maintain. I've found that a lot of Rails developers in particular don't see the benefits of this and they really, really like tightly coupled systems because of the convenience of it all.

Benefits like fast, easy testing, easier maintenance, swappable external things like databases, queues, external api's are apparently not enough of a benefit to change away from rails.

I wrote a pattern (http://obvious.retromocha.com) that makes pluggable systems easy based off of ideas from Uncle Bob, Alistair Cockburn, and Kent Beck which I think makes writing pluggable systems a lot easier, but as with all similar structures like Hexagonal Architecture and the like, Rails devs seem to not see the value in it until their app is a complete mess, at which point they would rather add more rails code than fix the underlying problems.

For a lot of developers, now that rails is popular, rails IS the architecture and things that go off the rails are either a waste of energy or too difficult.

Rails is what Kent Beck calls a connected architecture and as his incredibly scientific graph describes, the cost of change spikes dramatically over time compared to a modular architecture: http://www.threeriversinstitute.org/blog/wp-content/uploads/...

Until developers adopt modular or at least more service oriented designs, nobody should be surprised by slow tests, features taking too long to ship, the cost to ship code to rise dramatically over time. It's mostly our own fault.

4 comments

Here's Uncle Bob talking on his version of the idea extensively: https://www.youtube.com/watch?v=WpkDN78P884 The main idea is to separate the system into entities, interactors and boundaries, which correspond roughly to model, controllers and interfaces+DTOs (Data Transfer Objects), but with the difference that model classes are not exposed through the interfaces. Rather, the DTOs are used to communicate the changes in the data.

We have been using this approach for a year now, with REST on top, and it so far has worked beautifully. The entities map naturally to REST resources and DTOs makes nice request and response classes.

Armed with CQRS (now I sound enterprise-y), the data storage is easy to work with using the same DTOs (the data storage and its interface do not know anything about the entities either). On the DB implementation level, we work on the DTOs, which are trivial to store to the database (even without ORM, although it does remove much of the boilerplate). Only one class - the entity repository - is needed to convert the DTOs to entities, and this only happens on create, update, and delete. Reads (due to CQRS) go directly to DB without instantiating any entities - neat. We also use 'unit of work' -pattern to abstract the notion of transaction on create, update, and delete operations, which simplifies the interactor code, hiding the nature of the data storage (making it a swappable in this respect too).

But to stay on topic, our tests are fast too as the interactors can be tested by injecting an in-memory database as a data storage to test the business logic, and the interactors have no dependencies on any frameworks, web or otherwise. Testing the interfaces makes BDD feel natural and also supports clear separation of the REST layer (the communication channel) and the interactors (business logic).

Where I work, we just had a long internal debate about the usefulness of monolithic frameworks such as Rails and Symfony. I argued against the frameworks, but much of the team is committed to using them. The convenience of having everything in one place apparently is important to a lot of people, despite all the problems that are caused by that. I posted the debate here:

http://www.smashcompany.com/technology/an-architecture-of-sm...

It's not actually Rails that's the problem, often: it's a cultural issue. You can build a Rails app that has a very thin 'rails' layer and has a super well decoupled domain model layer.
Absolutely, the Rails app I'm working on right now is just like this. Still feels like Rails but the complex logic and interactions can run without it.
I would be interested to more details on how your architect things - we've been in the process of moving the business logic of our app into service objects as 2000 line models have become a bit unmanageable :D
May I advert to you the recorded mutterings of a Gentleman named Fred George who advocates for "Programmer Anarchy" and "micro-web-services" (the last of which is a nice idea)

* http://www.infoq.com/news/2012/02/programmer-anarchy

* http://www.youtube.com/watch?v=uk-CF7klLdA

Edit: would help if I actually added some links

Obvious looks great. Can't wait to try it on a project actually. Do you know anyone who's used it out in the wild to build cool stuff?
Surprisingly, even though the original version was built in ruby, people are taking the structure and using it in .NET, Java, etc. A lot of things we had to build in ruby already exist as things like interfaces in other statically typed languages.

In a language like Scala Obvious is literally just a way you would organize your program, not so much a library. It already has everything else you need, even things like immutability (if you're into that kind of thing). I just wish it compiled faster.

Obviouscasts is built on Obvious. I built a cool pluggable newsletter tool that you could trivially plug in Mailchimp, Mailgun, Sendgrid, or just your boring SMTP stuff to it. It was a heroku deployable newsletter so that you didn't have to pay monthly fees to a company like AWeber, Mailchimp, etc. just to collect emails for a list that won't be used very often.

I'm working on building out some new things in go with Obvious architecture behind them.

At my old job, some of the Obvious structure ended up powering the ruby services behind StBaldricks.org, which does $30+ million in donations and millions of page views a year.

I honestly don't know of many more examples beyond that, but it's a very small project and it was open sourced in January.

I looked at the source and saw that you basically built a way to declare a method which asserts a contract at runtime.

I like the idea of an object or collection of objects having a generic interface that can be mapped to all sorts of things such as a commandline or an HTTP POST etc... I am also at a job where we are struggling with the ol' "monolithic codebase" and we're investigating solutions such as this architecture.