Account的简单架构
前几天,有园友私下问我,博客中的AccountDemo后端架构为什么是那样的,是不是分层太多太冗余,故这里简单介绍下。先看解决方案工程截图:

每个工程的含义,见https://www.cnblogs.com/guokun/p/7082987.html。运行时,请求处理流程,这里再贴出来:

这里,园友主要不解的是,为什么会有两个接口层,Account.Repository.Contract和Account.Service.Contract,是不是太多了。最近几年,在后端架构中,出现了一种称之为六边形架构的架构模式,这货之前曾被叫做洋葱架构、端口适配器架构,反正大家知道都是它就是了。六边形架构的核心,就是应用程序业务逻辑处于架构的核心,而上层的视图、控制器、数据访问等,都属于基础设施,是用来辅助实现业务逻辑的,他们都依赖于核心业务逻辑。这些基础设施是易变或者说很可能被频繁替换的,例如应用层今天可能是MVC,明天可能是WebAPI,数据访问今天可能是EF,明天可能是Dapper,甚至CSRedis,MongoDB。。。
六边形架构最终要实现的效果就是,解耦应用核心业务逻辑与基础设施,其整体架构与依赖如下图:

蓝色箭头方向代表依赖方向,而非运行时数据流向或请求处理流向,请特别注意。ApplicationCore处于整个架构的中心,周边都是依赖于它的,这也是这一层名称ApplicationCore的由来,其核心特征是:1、用用层及基础设施层都依赖核心业务层;2、业务逻辑保持不变,应用层或基础设施层,比如切库、切ORM、切应用层框架,随便搞;3、有别于传统三层架构,数据层提供什么,业务层就有什么或用什么,六边形架构是业务层需要什么,就定义什么契约,数据层就实现什么或提供什么。
介绍完了六边形架构,接下来回答,为什么有两个接口层。本质上,Account.Repository.Contract和Account.Service.Contract两层契约均归属于核心业务层,Account.Service.Contract用于对应用层承诺,提供什么服务,Account.Repository.Contract和Account.Service.Contract则规定基础设施层必须给自己提供什么操作。如果你愿意,那么这两个接口层完全可以融入Account.Service工程中,这都是没问题的,本来他们就属于业务逻辑的范畴,但我还是把它单独分出来,否则便是应用层、基础设施层直接硬依赖Account.Service,一者太重,二者不符合将面向接口编程。
最后,说下,为什么Account.Repository.EF仓储工程中,一个实体类,对应了一个仓储对象。严格来讲,这么做是不合适的,设想一下,假如数据库表很多,那这里岂不膨胀得厉害。要弄明白这个问题,首先得知道仓储的由来。这玩意儿来自领域驱动架构,一般来讲,一个仓储是一一对应一个聚合根,这个聚合根是业务上功能聚合的一系列领域对象的,例如一个学生,对应一个宿舍,同时这个学生是个高富帅,他他妈的比较花心,身边有N个白富美女朋友。如果系统要维护这么样一个对应关系或信息,这里学生就是一个聚合根。具体表现在代码中,直观看就类似一个复杂对象,这个复杂对象的最外边就是学生,里边嵌套啥宿舍啊,女朋友集合啊,什么的。正常情况下,应该是学生这个聚合根才对应一个仓储类的,什么宿舍,女朋友都不应该有仓储类(假设没有其他需求导致他们需要上升为聚合根)。解释完了聚合根,这里回到刚才那问题,为什么搞成了一个数据库实体一个仓储类。主要在于,示例中抽象出了这么一个仓储基类:

这玩意儿是泛型的,因为后续仓储实现类想要用到其中的一些公用方法,实现这个基类时候,需要约定实体,所以为了偷懒,我就每个数据库表或者领域实体一个仓储类了,仅此而已。
好了,园友提到的几个问题差不多就这样。
Account的简单架构的更多相关文章
- android APP是否需要缓存?+简单架构
问题的由来 昨天,当我写完我的第一篇博客之后,我便百无聊赖的玩起了手机!当我打开Google自带的一些app的时候,发现他们直接叫我连接网络,并没有缓存上次从网络获取的数据.这就让我感到很奇怪!于是我 ...
- PHP网站简单架构 – 单独跑php-fpm
这个架构比较简单,不做过多的说明 前端1台Nginx:负载均衡+nfs 中间2台php:php-fpm 后端1台数据库:MySQL 安装略,参考<lnmp最新源码一键安装包> 192.16 ...
- 简单架构:反射实现抽象工厂+IDAL接口完全独立DAL
一.普通架构中存在的问题 StudentDB数据库,包含一张StudentInfoTB表,结构如下: s_id int primary key identity(1,1), s_name Nvarch ...
- 重构 JAVA 聊天室 —— CS 模式的简单架构实现
前言 自从开始弄起数据挖掘之后,已经很久没写过技术类的博客了,最近学校 JAVA 课设要求实现一个聊天室,想想去年自己已经写了一个了,但是有些要求到的功能我也没实现,但看着原有的代码想了想加功能好像有 ...
- [转]分享php中四种webservice实现的简单架构方法及实例
FROM : http://www.itokit.com/2012/0417/73615_2.html 本人所了解的webservice有以下几种:PHP本身的SOAP,开源的NUSOAP,商业版的P ...
- 分享php中四种webservice实现的简单架构方法及实例
一:PHP本身的SOAP所有的webservice都包括服务端(server)和客户端(client).要使用php本身的soap首先要把该拓展安装好并且启用.下面看具体的code首先这是服务端实现: ...
- 分享php中四种webservice实现的简单架构方法及实例(转)
本人所了解的webservice有以下几种:PHP本身的SOAP,开源的NUSOAP,商业版的PHPRPC,以及使用二进制传输数据流的 HessianPHP,那么一下就简单的介绍下这几种webserv ...
- 分享php中四种webservice实现的简单架构方法及实例[转载]
[转载]http://www.itokit.com/2012/0417/73615.html 本人所了解的webservice有以下几种:PHP本身的SOAP,开源的NUSOAP,商业版的PHPRPC ...
- web开发之负载均衡的简单架构
负载均衡 负载均衡的核心思想就是:请求分担 最简单的配置: 一台负载均衡服务器 两台webserver服务器 两台webserver服务器需要配置相同的服务器环境,设置相同的域名指向 负载均衡服务器需 ...
随机推荐
- 【Maven】安装配置、目录结构、配置文件、常见命令
1.下载配置maven步骤 a.windows下配置jdk的系统环境变量:java_home b.windows下配置maven的系统环境变量:maven_home或者m2_home c.window ...
- 博文中标题的样式H1H2H3H4
设置博文中标题的样式H1 设置博文中标题的样式H2 设置博文中标题的样式H3 设置博文中标题的样式H4 设置博文中标题的样式H5 设置博文中标题的样式H6
- GBDT用于分类问题
一.简介 GBDT在传统机器学习算法里面是对真实分布拟合的最好的几种算法之一,在前几年深度学习还没有大行其道之前,gbdt在各种竞赛是大放异彩.原因大概有几个 一:效果确实挺不错. 二:既可以用于分类 ...
- Scala进阶之路-Spark独立模式(Standalone)集群部署
Scala进阶之路-Spark独立模式(Standalone)集群部署 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们知道Hadoop解决了大数据的存储和计算,存储使用HDFS ...
- c# 打印 bartender
参考: 官网 https://www.seagullscientific.com/label-software/barcode-label-design-and-printing 文章 http:/ ...
- 微信接口开发之高级篇系列【微信权限封装类WechatAuth】
ThinkPHP框架目录结构: <?php /** * Created by PhpStorm. * User: Tinywan * Date: 2016/9/11 * Time: 9:55 * ...
- java AOP使用注解@annotation方式实践
java AOP使用配置项来进行注入实践 AOP实际开发工作比较常用,在此使用注解方式加深对面向切面编程的理解 废话不多少,先看下面的实例代码 场景: 1.未满一岁的小孩,在执行方法之前打印:“ ...
- 去除inline-block出现间距的几种方法
display:inline-block,简单来说就是将对象呈现为inline对象,但是对象的内容作为block对象呈现,之后的内联对象会排列在同一行 比如两个input,默认中间会产生一些间距 &l ...
- round_robin 的几种取值
ATS-6 的round_robin可以有4种算法可以选择 true Traffic Server goes through the parent cache list in a round robi ...
- bootstrap modal垂直居中 (转)
根据博友的经验,总结后请使用方法一就行了 一,修改bootstrap.js 源码 原来的: Modal.prototype.adjustDialog = function () { ].scrollH ...