原文地址: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. vue1.0到2.0

    vue1.0到2.0 vue2.0 新手教程(一)   想想自己写vue的项目也写了一年了,从vue1.0到2.0,走过不少路,填过不少坑, 下面记录一下新手从0到1的过程,本文“应该”会持续更新 首 ...

  2. 【转载】【收藏】Github上免费的编程教程【作者Victor Felder】

    原链接:https://github.com/EbookFoundation/free-programming-books/blob/master/free-programming-books-zh. ...

  3. 关于函数getline()(简单注意事项,不懂你怼我!!!)

    关于getline()函数好使但是有毒: 有两种操作需要进行特殊处理: First: #include <iostream>#include <cstring>#include ...

  4. 必读,sql加索引调优案例和explain extended说明

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 昨天分享了Mysql中的 explain 命令,使用 explain 来分析 select 语句的运行效果,如 :expl ...

  5. 【原创】MySQL Can't create a new thread报错分析

    今天有两台服务器都出现了Can't create a new thread报错. [故障处理过程] 故障发生后登录服务器,检查mysql进程正常,但登录mysql报下面错误 ERROR 1135 (H ...

  6. 10BASE

    10BASE-T,10BASE-5,10BASE-2,以太网的技术标准,10Base-2.10Base-5.10Base-T都是以太网的技术标准,传输速率为10Mbps.   10Base-2技术以细 ...

  7. 使用Metasploit工作区

    使用Metasploit工作区   Metasploit将所有数据都存储在PostgeSQL服务器中的msf数据库.渗透测试人员经常要使用Metasploit同时执行多个任务.为了避免数据混杂,Met ...

  8. C#开发Unity游戏教程之Scene视图与脚本的使用

    C#开发Unity游戏教程之Scene视图与脚本的使用 Unity中Scene视图的快捷操作 Scene视图是开发者开发游戏时,操作最频繁的视图.因为一旦一个游戏对象被添加到游戏的场景中,就需要首先使 ...

  9. android 手机不能断点

    一个安卓平板 型号 联想 .. ,用andriod studio 打断点 调试, 应用 就卡死2秒,然后就挂掉了.  不知如何解决.

  10. BZOJ4254 : Aerial Tramway

    可以修建的缆车总数不超过n,于是可以先通过$O(n^2)$的枚举求出所有可以修建的缆车. 对于一个缆车,若它仅连接i和i+1,那么它不受k的限制,把这种缆车额外取出,从大到小排序. 剩下的缆车两两之间 ...