[LRUG] Objects and on Hexagonal Rails

Tim Cowlishaw tim at timcowlishaw.co.uk
Wed Jul 24 02:26:37 PDT 2013


Hi Tom and all,


On 23 July 2013 14:26, Tom Cartwright <tecartwright at gmail.com> wrote:

>
> I am about to start a new rails project. I have read objects-on-rails and
> watched the Hexagonal rails talk and the techniques make a lot of sense.
> "Great!" thought I, I can build this new app with lots of those patterns
>

I've actually just finished working on a project where I attempted to do
this, and the results were overall very good, with a couple of caveats.

In general, I was able to ship features faster, with better test coverage,
and therefore more confidence that the app was doing what was expected.
Another nice side effect was that the fact that my views had no logic *at
all* in them, I could introduce a designer / front-end-dev to everything he
needed to work directly in erb templates within about 5 minutes, ensuring
that we were both more productive and that it was virtually impossible for
him to unintentionally break anything.

However, one thing that I noticed, is that there is a slower 'ramp-up' to
this speed of development than with the traditional rails way. This wasn't
such a problem with this project, as the delivery schedule was fairly
amenable to that, but the first couple of features I shipped took a
comparatively long time, although this was more than mitigated by the gains
I made later.

You may also find that your design precludes the use of some plugins to
perform common tasks - carrierwave for file uploads and rinku for
pagination both fit very well within this style of development, and you can
use devise for auth without compromising your design as it doesn't touch
much of your codebase, but I couldn't find a solution for either authz or
building a page navigation tree that didn't introduce a lot of unnecessary
coupling and general ugliness, so I ended up rolling my own. YMMV here
though, obviously.

Finally, to do this effectively, you need to refactor ruthlessly and
continuously. This certainly adds an overhead (which in my experience was
more than mitigated by increase in development speed), but it's key to
driving a sane design for your app. The 'Hexagonal Rails' way isn't a
silver bullet, just as the trad Rails way isn't, but it provides a *much*
more effective starting point to drive out a decent design.



> they had concerns about moving away from the rails conventions as it would
> take time to get developers up to speed with the techniques.
>

...and here's the main rub, for me - After I finished working on this
project, it was handed off to another developer, who's continued to add
features in the standard 'rails' style, rather than following the design
I'd so lovingly developed! This was mostly a communication problem on my
part, and I suspect I could have convinced him to try out the hexagonal
style if I'd been there to oversee some of the transition, and explain the
'whys' of some of my design choices, but yeah. In your case, it sounds like
you'll be able to work alongside other developers working on the
application, so will be able to do this no problem. However, I think it's
crucial that your other devs are at least receptive to the *idea* of doing
things in an OO style, and understand the benefits. If this is the case,
they'll be able to pick up the 'how' no problem.



> One reason (and I can definitely see their point here) is that intentions
> can get obfuscated when using lots of loosely coupled objects and this can
> lead to confusion.
>

Interestingly, I totally disagree with this. I find lots of tiny classes
interacting with each other in cohesive, well defined ways to be far easier
to  grok than large classes with lots of imperative spaghetti. Maybe that's
just me though!


> One way to strike a balance would be to develop the app in the canonical
> fashion and then use these techniques as and when. E.g. Use the publish
> subscribe pattern when controllers/models start to get bloated. However, by
> that point it could be a bit too late and I might be reluctant to make
> changes that major. My integration tests would catch most stuff, but I will
> have to be confident that they will catch all the edge cases.
>

This is also a great approach, and one that I've used with success on
'legacy' projects. The key things here are to have acceptance tests for
*everything* that conceivably break when refactoring a given area (ideally
100% coverage of the whole app), and to not get too attached to your
existing implementation. There's also some easy OO wins you can apply here
-for instance presenters/decorators/view models/whatever you want to call
them are a very easy pattern to introduce to existing 'rails-y' code, and
provide a lot of benefit in terms of reduced coupling and increased
cohesion for the effort. The main thing (as is also true with 'greenfield'
projects) though is to refactor continuously and ruthlessly. Ultimitely the
architecture of your app will be something you derive yourself, 'rails' or
'hexagonal / oop' are just starting points, and a set of principles to
guide you.

I can't open-source the work I've talked about above as it's for clients,
but I'd be happy to show you some of it in person if you'd be interested in
examples (although I am planning to write a blog post with some examples at
some point, and possibly abstract out some of it into plugins that I can
open up, this might take me a little while!)

Cheers,

Tim
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20130724/3bca6451/attachment.html>


More information about the Chat mailing list