架构:Hexagonal Architecture Guidelines for Rails(转载)
原文地址: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(转载)的更多相关文章
- 架构:The Onion Architecture : part 1(洋葱架构:第一篇)(转载)
原文地址:http://jeffreypalermo.com/blog/the-onion-architecture-part-1/. I've spoken several times about ...
- 微内核架构(Microkernel Architecture)
微内核架构(Microkernel Architecture) 微内核架构有时也被成为插件架构模式(plug-in architecture pattern),通常用于实现基于产品的应用,如Eclip ...
- 事件驱动架构 (Event-Driven Architecture,EDA) 简介
EDA 是一种侧重于以生成/消费为基础的异步通信的架构模式.这主要对照于传统的基于线程的同步系统. EDA 是一种以事件 (event)为核心,提供事件产生,路由,消费已经结果回调等机制的架构模式. ...
- 编译器架构Compiler Architecture(下)
编译器架构Compiler Architecture(下) Combining Scanning and Parsing 实际上没有必要将扫描(词法分析/标记化)与解析(语法分析/树生成)分开.基于P ...
- 编译器架构Compiler Architecture(上)
编译器架构Compiler Architecture(上) 编译器是程序,通常是非常大的程序.它们几乎都有一个基于翻译分析综合模型的结构. CONTENTS Overview • Compiler C ...
- 架构:The Onion Architecture : part 2(洋葱架构:第二篇)(转载)
原位地址:http://jeffreypalermo.com/blog/the-onion-architecture-part-2/. In part 1, I introduced an archi ...
- 架构(Architecture)和框架(Framework)杂谈
1. 架构和框架的设计层次不同 类似于硬件设计,软件设计也分为不同的层次.典型的软件设计层次如下图: 在这个图中我们可以看到,Framework处于Micro-archite ...
- ASP.NET Core 企业级开发架构简介及框架汇总 (转载)
ASP.NET Core 企业开发架构概述 企业开发框架包括垂直方向架构和水平方向架构.垂直方向架构是指一个应用程序的由下到上叠加多层的架构,同时这样的程序又叫整体式程序.水平方向架构是指将大应用分成 ...
- 架构(Architecture)随想
架构(Architecture)的意义: 先不要看什么是架构,先看下architect是什么,没有错,它是建筑师,在一块空地上build高楼大厦的人,它是一个designer,设计好整个大楼,也是一个 ...
随机推荐
- Objective-C 与JAVA的SHA1/HmacSHA1加密算法实现
最近研究IOS手机上登录的功能.由于加密方式使用SHA1算法.网上也没找到直接的例子,最终参照StackoverFlow上的大神,完成了加密实现. 先上代码: //HmacSHA1加密: +(NSSt ...
- python多个分割符split字符串
python中string自带的split不支持多个分隔符同时切分,用正则 import re line='hello,world' lineLists = re.split('[,,..??]',l ...
- java PriorityQueue(优先级队列)
先进先出描述了最典型的队列.队列规则是值在给定一组队列中的元素的情况下,确定下一个弹出队列的元素的规则,先进先出声明的是下一个元素应该是等待时间最长的元素 优先级队列声明下一个弹出的元素是最需要的元素 ...
- IntelliJ Idea中创建package的问题
在idea中创建package时,会一直往后面累加 想在com.huayang下面再新建一个service,普通的做法是选中了huayang.dao--->然后右键--->新建了一个pac ...
- IDEA中Ctrl+Shift+F快捷键无效的解决方式
某天突然发现idea非常重要的快捷键ctrl+shift+F无效了,网上搜了很多都说是qq快捷键冲突,但是找了下qq快捷键却没有解决,现在给大家一个解决快捷键冲突的思路: 1.查看QQ快捷键--> ...
- hibernate Validator 6.X 的学习,bean的约束(主要包括的是容器元素的验证)
1. 四:案例二(property的验证) 1.
- Mysql创建用户并授权以及开启远程访问
Mysql创建用户并授权以及开启远程访问 一.创建用户并授权 1.登录mysql mysql -u root -p 2.创建数据库 create database test;//以创建test ...
- 010.MySQL-Keepalived搭配脚本04
vim /etc/keepalived/check_MySQL.sh #!/bin/bash pkill keepalived
- 【Ray Tracing The Next Week 超详解】 光线追踪2-4 Perlin noise
Preface 为了得到更好的纹理,很多人采用各种形式的柏林噪声(该命名来自于发明人 Ken Perlin) 柏林噪声是一种比较模糊的白噪声的东西:(引用书中一张图) 柏林噪声是用来生成一些看似杂乱 ...
- 2018-2019-20172329 《Java软件结构与数据结构》第五周学习总结
2018-2019-20172329 <Java软件结构与数据结构>第五周学习总结 教材学习内容总结 <Java软件结构与数据结构>第九章-排序与查找 一.查找 1.查找概念简 ...