02 | 架构分层:我们为什么一定要这么做?
02 | 架构分层:我们为什么一定要这么做?
讲述:唐扬
时长11:00大小10.07M
什么是分层架构
分层有什么好处
如何来做系统分层
分层架构的不足
课程小结
一课一思
赞 46
提建议
精选留言(93)
- 饭团2019-09-21明白了一些东西,老师比如我做一个接口,这个实现可以放在server层! 之后公司内部调用逻辑可以放在web层!而哪一天公司要开放这个接口,那我最好是新抽象一层出来(一个新的服务)就是开放平台层!这样做的好处是,可以讲自家使用和第三方使用做隔离!比如在提供服务时,为了保证自家接口性能,对开放平台层做限流处理!
作者回复: 👍
共 2 条评论46 - fish2019-09-20希望每篇都结合一点点实例程序架构
作者回复: 好的👌
共 2 条评论24 - 那一夜2019-09-24老师你好,我之前也看过很多次阿里的代码分层规范,一直对service层和manager层有点混淆不清,所以想请教一下老师我下面理解的分层是不是合理的 1. controller层接收客户端的请求 2. service层调用manager层和dao层处理业务 3. manager主要对service层通用的代码的沉淀,例如对多个dao调用的组合(逻辑意义上的连接查询),以及缓存等中间件的调用,并且在manager层处理事务 4. dao层主要放mybatis逆向工程生成的代码以及自己写的查询方法 不知道自己这样理解正不正确,还有就是事务处理应该放在哪一层,是在manager层还是应该在service层?展开
作者回复: 在我来看业务逻辑放在manager,service来编排manager的原子服务
共 5 条评论21 - can2019-09-21参数校验,放在哪
作者回复: 业务类的校验放在service层,一般性的参数校验可以放在web层,可以通用化
共 5 条评论20 - AaronM2019-09-26getuser之后创建user的案例,如果不加manager层,在service的getuser方法中做以下逻辑判断呢 if(未获取到用户){ this.createuser(); } 这样做有什么不妥吗~~望指教展开
作者回复: controller层的逻辑有区别,一种是需要创建用户,一种是不需要,需要提供两个service方法,每个方法编排不同的manager层的原子方法。当然也可以提供一个service方法,使用不同的参数来区分。但这是一个简单的例子,引申来看,同一个服务接口,针对不同的场景可能会有一些差异,这种差异要在service层屏蔽,不应该蔓延到controller层
11 - xu晓晨2019-09-20架构不分语言。我司主力语言php 架构至上而下是这样controller+module(service)+class(manager)+dao。第三方的调用服务也都封成基础类来调用了。基本上跟您讲的思路一样呢
作者回复: 是的呢
共 4 条评论10 - aaaaaaaaaaaas2019-11-28老师,可以这样理解吗。manager放的都是单一功能的接口,service层去组装manager的接口,这样service层只需要注入manager层的接口就可以了,但是service层接口也会有复用的情况,相当于service还是要互相注入的
作者回复: 是的
8 - Jxin2019-09-23感觉图有点问题。补下个人理解,共同探讨。 1.通用层改名领域层,个人习惯。 2.数据层同领域层也有交互。领域层交互数据层主要做业务;service层交互数据层主要开放接口,提供外部支撑。这块还涉及crud,读与命令分离。 3.第三方和外部接口,进入系统加入一层防腐层,千万别用第三方的实体bean去写自己项目的业务,千万别,千万别。这种依赖外部bean写业务的操作,接手的人深感绝望。 4.防腐层和第三方层也可以直接与service层交互。这里涉及胖领域和瘦领域的权衡了。个人偏向业务重就直接胖领域,没啥业务或跟本没有业务,瘦领域我也不要了,直接service层走你。这里的选择主要看当下业务情况和个人对将来的预期。 5.简单一定优雅,优雅不一定简单。k8s的容器编排很复杂,麻烦,但它的开放思想和架构抽象,真心让人惊叹。展开
作者回复: 我理解你说的防腐层就是manager层,而我说的manager层也封装了数据访问层,提供原子的服务接口,而service层是对这些原子接口的编排,所以说尽量不要数据层打交道。 当然每个团队可能有更合适的分层方式
共 3 条评论8 - 何磊2019-09-20这里有个误导?我们所谓的独立部署并不是按照层次来部署。而是服务。因为不可能一个项目只部署controller,一个服务只部署dao层的。更多的是每一个服务按照这种层次来写。
作者回复: 可以的呀 数据访问层也是可以独立部署的,controller也是独立部署的web服务
共 15 条评论7 - hex2020-05-06第一遍看没看出门道。最近换了份工作。才发现原来老师讲的是非常有道理的。设置前置网关开放接口给外部调用,前置做验签,权限,封装对象,然后才调用服务。自己调用的话不经过前置网关直接调用服务。这样做可以给外部提供出统一的加解密以及权限接口。并且不影响自己内部调用逻辑!!6
- W2019-10-11老师,我看阿里分层图中,service层是可以直接调用dao层的,manager层也是可以直接调用dao层的,这两种调用分别是针对什么情况的呢
作者回复: 我理解简单的业务可以不抽取manager,直接调用dao
6 - 那一夜2019-09-26老师你好,请问你说的业务逻辑放在manager,service来编排manager的原子服务,所谓的业务逻辑是指?manager的原子服务是指?如果这样处理的话,事务应该放在哪一层处理
作者回复: 业务逻辑就是你的产品逻辑,比如创建用户要做些啥。 manager层的原子服务指的是实现单一功能的服务。 事务应该是在service层
共 3 条评论6 - 桂城老托尼2019-12-22有一本书叫,大型网站实战与Java中间件实践,和老师课程里的知识异曲同工之妙。学习了
作者回复: 相关领域的知识的确是大同小异~大厂的实践也基本类似~多学、多看、多练、多思,不久就会成为更好的你
5 - 李米2019-09-21请问下老师用的什么工具画图?很漂亮
作者回复: 是苹果自带的keynote
共 2 条评论5 - 堵车2019-09-20老师您看下我理解的有没有问题。manager是用来控制事务,缓存外部调用的层。service层才是业务层。service调用dao和manager。manager要不要分一个事务类,一个缓存类,一个外部交互类呢?
作者回复: 缓存可以放在存储层,manager可以分为业务类和外部交互类
5 - 吃饭饭2019-09-20有人说传统的 MVC 是贫血模式,与之对立的是充血模式,边界划分衍生出 DDD ,优劣到底是哪一个,弄不清楚呐,老师的观点是什么?
作者回复: 贫血模型把数据和行为区分开,层次上更清晰,但是呢不够面向对象,因为对象肯定是有数据和行为的 充血模型是把数据和行为混在一起,缺点是我就不知道业务逻辑是写在biz层还是领域模型里面。 我更倾向于贫血模型吧,因为我觉得大团队里面很难规范哪些放在领域模型里面,哪些放在biz层,所以干脆就都放在biz层就好了
共 5 条评论5 - Toutoublue2019-09-21我们公司电商平台原来是经典三层,后来加了一层,统一做process。大家刚开始觉得没用,后来发现有了process层后,很方便扩展业务渠道,不同业务渠道的逻辑层和process层对接,然后再到统一的数据层。
作者回复: 对滴
4 - 段启超2019-09-20mvc这种结构让太多的人觉得项目工程结构理所应当就是这样的,然后呢,一大堆的业务逻辑就随意的堆砌在了service中,对象啥的,只是单纯的数据传输作用,出现了用面向对象的语言,写面向过程的程序的普遍现象。按照领域驱动设计的思路,最重要的还要有领域模型层。当然manage层这种方案也是一种思路,但是我觉得,这种方式,还不够,必须有清晰的业务模型和合理的分层结构配合,才能更好的提现分层的作用。
作者回复: 是的,分层的方式也是不断演进的
共 3 条评论4 - 寒溪2019-09-24传统公司很多是分层部署的,比如保险和金融公司。service和dao部署在比较严密的网络区域,controller层部署在一个较宽松的网络区域,对外提供服务。等于在网络上增加了一个缓冲区,来保证服务的安全;而且可以通过单向网络规范层级调用,controller可以调用服务层,而服务层是不能调用web层的。
作者回复: 是的
共 3 条评论3 - ly2019-09-20目前有个业务(下单业务)**不知道这样的分层是否合理。 OrderServiceFacade: 接受Controller的调用,具体是一些组织逻辑,组织数据等,然后调用OrderService的创建订单方法. OrderBillService.createBill(): 具有统一事务,具体把order入库,另外它依赖了库存服务(InventoryService), InventoryService.reduce(): 来减少库存 ( OrderBillService 依赖自己的OrderDao,但依赖了库存Service而不是库存DAO ) // 订单门面 public class OrderServiceFacade { @Autowrited private OrderBillService orderBillService; public boolean submitOrder(Dto dto) { // TODO 组织数据 一些特殊验证check // TODO 其他非事务性逻辑代码 String billNo = orderBillService.createBill(dto); // TODO 后续工作 return billNo != null; } } // 订单服务 public class OrderBillService { @Autowrited private OrderDao orderDao; @Autowrited private InventoryService inventoryService; @Transaction public String createBill(Dto dto) { Bill bill = dto.convertToBill(); orderDao.insert(bill); // 保存订单 inventoryService.reduce(); // 扣减库存服务 return bill.getBillNo(); } } // 库存服务 public class InventoryService { @Autowrited private InventoryDao inventoryDao; @Transaction public void reduce() { int updateCount = inventoryDao.decrease(); if( updateCount != 1 ) { throw new BizException("扣减库存失败"); } //TODO 记录库存日志 } }展开
作者回复: 是合理的呀~
3