原文地址:http://theaudaciouscodeexperiment.com/blog/2014/03/17/hexagonal-architecture-guidelines-for-rails/

TL;DR

Good application design is hard and there’s no one “right” way to do it.

I often get asked the how I design decoupled applications and while there’s no easy answer I’m going to lay down the rules that have worked for me.

Background

Rails gives you a very minimal architecture of three parts (MVC) all three of which have proved inadequate to contain any real amount of complexity. Remember fat models, skinny controllers?

This is in stark contrast to ‘enterprise’ frameworks which is often criticised for providing too much complexity up front.

The key is to start with just a couple of extra layers and keep those layers decoupled so that more can be added, allowing you application to scale in complexity with ease.

The Rules

  • Controllers actions are allowed a single line of code
  • The application doesn’t return anything to controllers
  • The application has no knowledge of the framework
  • No inheritance or mixins (with two exceptions)
  • Domain objects have no knowledge of persistence
  • Separate your “wiring”

The skinniest of controllers

Your controllers should look like this

 class ThingsController
def show
app_of_things.show_thing(rails_adapter)
end def create
app_of_things.create_thing(rails_adapter)
end
end

Nothing more, just that single line. This is an example of where “Tell don’t ask” really shines.

A note on “Tell don’t ask”

As soon as an object’s method returns data back to its caller it relinquishes control of the program.

“Here’s the data, you decide what to do with it.”

In hexagon land the application is in charge until the bitter end it never returns data back to its caller, it sends messages and calls all the shots.

Don’t return anything to controllers

So how does the view or data get rendered? It’s your app’s responsibility to send a message back to the web layer instructing it to render.

The mysterious rails_adapter will be a wrap the Rails controller defining a narrow interface that your app will depend on.

I recommend you implement methods such as #success#created#not_updated and map these to redirects or appropriate HTTP status codes in your adapter.

The adapter is not part of your application, it’s the mediator that translates results or events from your application into something Rails can understand. It can and will have knowledge of the web or framework but must not leak it into the application.

The application has no knowledge of the framework

Define your own APIs for everything your application touches, do this by wrapping foreign objects in scar tissue. Use SimpleDegator or Forwardable to make proxy object quickly and easily.

No inheritance or mixins

Predictably I make exceptions for SimpleDegator and Forwardable. The Gang of Four said “Prefer composition over inheritance” so just prefer it, all the time! These two standard library tools will help you build composed objects easily.

Domain objects have no knowledge of persistence

Use a combination of the repository pattern with a simple data mapper to get your data into some PORO or Struct objects.

Writing a general purpose data mappers is hard, Ruby doesn’t have one yet and the enterprise solutions like Hibernate are not exactly loved. My advice is to write your own data mapper without making it general purpose or feature rich. If it only works just enough with your data it shouldn’t be too complex. Add the features as you need them, optimise as lazily as possible.

Separate your wiring (or inject dependencies)

Have an object whose responsibility is to wire up all the others, it will make your code simpler and more flexible. I’ve written and spoke about this before so won’t re-iterate here.

That’s it

That’s my hexagonal prescription. If you want to get in touch to nerd out and discuss these ideas I’d be more than happy to chat.

Where’s the sample app?

In the works :)

架构:Hexagonal Architecture Guidelines for Rails(转载)的更多相关文章

  1. 架构:The Onion Architecture : part 1(洋葱架构:第一篇)(转载)

    原文地址:http://jeffreypalermo.com/blog/the-onion-architecture-part-1/. I've spoken several times about ...

  2. 微内核架构(Microkernel Architecture)

    微内核架构(Microkernel Architecture) 微内核架构有时也被成为插件架构模式(plug-in architecture pattern),通常用于实现基于产品的应用,如Eclip ...

  3. 事件驱动架构 (Event-Driven Architecture,EDA) 简介

    EDA 是一种侧重于以生成/消费为基础的异步通信的架构模式.这主要对照于传统的基于线程的同步系统. EDA 是一种以事件 (event)为核心,提供事件产生,路由,消费已经结果回调等机制的架构模式. ...

  4. 编译器架构Compiler Architecture(下)

    编译器架构Compiler Architecture(下) Combining Scanning and Parsing 实际上没有必要将扫描(词法分析/标记化)与解析(语法分析/树生成)分开.基于P ...

  5. 编译器架构Compiler Architecture(上)

    编译器架构Compiler Architecture(上) 编译器是程序,通常是非常大的程序.它们几乎都有一个基于翻译分析综合模型的结构. CONTENTS Overview • Compiler C ...

  6. 架构:The Onion Architecture : part 2(洋葱架构:第二篇)(转载)

    原位地址:http://jeffreypalermo.com/blog/the-onion-architecture-part-2/. In part 1, I introduced an archi ...

  7. 架构(Architecture)和框架(Framework)杂谈

    1. 架构和框架的设计层次不同       类似于硬件设计,软件设计也分为不同的层次.典型的软件设计层次如下图:        在这个图中我们可以看到,Framework处于Micro-archite ...

  8. ASP.NET Core 企业级开发架构简介及框架汇总 (转载)

    ASP.NET Core 企业开发架构概述 企业开发框架包括垂直方向架构和水平方向架构.垂直方向架构是指一个应用程序的由下到上叠加多层的架构,同时这样的程序又叫整体式程序.水平方向架构是指将大应用分成 ...

  9. 架构(Architecture)随想

    架构(Architecture)的意义: 先不要看什么是架构,先看下architect是什么,没有错,它是建筑师,在一块空地上build高楼大厦的人,它是一个designer,设计好整个大楼,也是一个 ...

随机推荐

  1. 文件时间戳修改touch和查看stat和ls --time

    查看文件时间戳命令:stat awk.txtFile: `awk.txt'Size: 20  Blocks: 8  IO Block: 4096  regular fileDevice: 801h/2 ...

  2. 一些计数小Trick

    一些计数小Trick 虽然说计数问题如果不是特别傻逼的话想做出来基本随缘. 但是掌握一些基本的计数方法还是十分有必要的. 想到了就更新. 1. 对于排列的DP问题,一般是不能够按照位置一个一个放的,一 ...

  3. qString转char*

    char *vi_name = new char[vi_rsc_name.length()]; strcpy(vi_name,vi_rsc_name.toStdString().data()); de ...

  4. kebab HDU2883

    题意:现在有n个人要烤肉,有m个烤肉架,然后给出每个人的烤肉开始时间si,结束时间ei,以及要烤肉的串数num,还有拷一串的时间ti,然后问你能不能满足所有人的要求. 为3572的进阶题 每个人为一个 ...

  5. 002 jquery基本选择器

    1.选择器 2.基本选择器 3.程序(包含以上五种基本选择器) <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  6. Lighthouse前端性能优化测试工具

    在前端开发中,对于自己开发的app或者web page性能的好坏,一直是让前端开发很在意的话题.我们需要专业的网站测试工具,让我们知道自己的网页还有哪些需要更为优化的方面,我自己尝试了一款工具:Lig ...

  7. C++ 大学课堂知识点总结

    一.从C到C++1.引用int b;int &a = b;//a是引用类型       定义的时候加&  表示引用   其余都是取地址  a是b别名 使用a和使用b是一样的  主要用于 ...

  8. rabbitmq学习(八) —— 可靠机制上的“可靠”

    接着上一篇,既然已经有了手动ack.confirm机制.return机制,还不够吗? 以下博文转自https://www.jianshu.com/p/6579e48d18ae和https://my.o ...

  9. Android-LayoutAnimation

    Android-LayoutAnimation 学习自 <Android开发艺术探索> LayoutAnimation漫谈 LayoutAnimation 也是View动画的一种,作用是为 ...

  10. 在Activity中响应ListView内部按钮的点击事件的两种方法

    转载:http://www.cnblogs.com/ivan-xu/p/4124967.html 最近交流群里面有人问到一个问题:如何在Activity中响应ListView内部按钮的点击事件,不要在 ...