热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

探讨phpyaf框架扩展实践四——业务层

和常见的mvc框架不同,这里多了一个业务层用来封装系统业务。为什么要多一个层出来呢?以往的时候没有这个层

和常见的mvc框架不同,这里多了一个业务层用来封装系统业务。为什么要多一个层出来呢?以往的时候没有这个层,通常都把业务放在控制器层进行处理。在长期的开发app的数据接口中,发现控制器层做的事情实在是太多了,既要处理表单的验证、还要检测接口版本、还要处理业务。如果业务简单些还好,要是业务比较复杂,这个代码是惨不忍睹啊,维护起来也非常痛苦。

于是呢就考虑将业务层的的代码封装出来独立处理,这样就有了业务层。业务层的代码存放目录:application/models/Business/,有一个抽象类abstract.php,其中也没有什么代码就一个禁止clone的方法。这里更多的是分享一下关于业务层代码封装的思想。主要是包含以下三个:

  • 目录规划
  • 业务错误流程处理
  • 错误码统一管理
yaf扩展业务层

yaf扩展业务层

目录规划

目录规划如果没有规划好,随着业务的增加,还要考虑适应旧版APP,目录就会越来越复杂。在长期的开发过程总结出了一些规律,建议目录以如下方式进行组织 :

Business/功能模块/具体业务+版本号.php

其中功能模块就是指大的一个业务模块;具体业务就是指其中的一个业务操作;版本号就是对应业务操作的版本。如果用户登录业务就可以是这样:

一开始版本用: Business/User/Login.php
 V2版本: Business/User/LoginV2.php
 V3版本: Business/User/LoginV3.php
 ...

在项目前期因为对产品不熟悉,修改业务是常有的事情,为了兼容旧的app版本,就会考虑增加一个业务版本。这样就会导致一个业务操作版本越来越多,对维护会造成困难。这里建议对旧的业务版本进行清理,随着用户逐渐更新到新版app,旧版本的使用用户已经没有的时候就可以删除旧的业务版本了。

业务错误流程处理

首先先定义一下什么是业务错误:就是一个业务操作如果最终没有达成,中间一些条件判断没有通过返回的错误,和程序上的错误是不同的。例如在登录操作中,需要校验用户是否存在,用户如果存在还需要校验账号密码是否匹配。中间只有有一个校验没有通过就可以认为该业务发操作生了错误。

对于这样的业务错误流程怎么样处理比较好呢?

早先的时候想着直接返回错误信息:

if(!true){
    return"错误信息";
}
但是在开发api接口的时候经常需要给到一个错误的编码,方便客户端针对不同的错误进行处理。于是就改进成这样:

if(!true){
    returnarray("errno"=> "10010", "errmsg"=> "错误信息");
}

不幸的是这样还是碰到了问题,有时候业务特别复杂的时候,通常会将其拆分成多个函数进行处理。每个函数都可能会有一些校验,每个校验如果都这样返回信息,那调用这些函数的主业务函数内不就要判断每个函数的返回结果,岂不是太麻烦了。

后来就想到使用异常的方式来中断流程,如:

if(!true){
    thrownew\Exception("错误信息",  "10010");
}

这样当发生业务错误的时候就会直接中断,并且返回了错误信息和错误编码,在控制器层调用业务方法的时候捕获异常就可以了,这种方法在代码深层嵌套的时候特别有用,能有效减少编码量提高代码的可读性。

当然在每个操作action方法中捕获异常看起来还不是很简洁,庆幸的是yaf提供了异常捕获的控制器,在controllers目录下新建Error控制器并且实现errorAction方法,则应用内没有捕获的异常都会抛到这里,在这里就可以对应用内抛出的异常进行相应的处理。

if($exception->getCode() > 100000) {
    //这里可以捕获到应用内抛出的异常
    echo$exception->getCode();
    echo$exception->getMessage();
    return;
}

错误码统一管理

上面解决了业务错误流程的处理,再把错误码统一进行管理就比较完美了,请参考项目下的application/models/Error目录,其中有一个Error类专门用来抛出异常;CodeConfig用来管理所有的错误码。代码上都比较易读就不多做说明了。

业务层的说明到这里就告一段落了,下面一篇将说明一下数据层的的封装,这个也是其中最重要的一篇了。很多项目到后面瓶颈都会在数据上,处理好了数据层项目就可以算是成功一半了。


推荐阅读
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • Spring Boot 中静态资源映射详解
    本文深入探讨了 Spring Boot 如何简化 Web 应用中的静态资源管理,包括默认的静态资源映射规则、WebJars 的使用以及静态首页的处理方法。通过本文,您将了解如何高效地管理和引用静态资源。 ... [详细]
  • 在寻找轻量级Ruby Web框架的过程中,您可能会遇到Sinatra和Ramaze。两者都以简洁、轻便著称,但它们之间存在一些关键区别。本文将探讨这些差异,并提供详细的分析,帮助您做出最佳选择。 ... [详细]
  • 本文详细介绍了如何在Ubuntu系统中下载适用于Intel处理器的64位版本,涵盖了不同Linux发行版对64位架构的不同命名方式,并提供了具体的下载链接和步骤。 ... [详细]
  • 汇编语言等号伪指令解析:探究其陡峭的学习曲线
    汇编语言以其独特的特性和复杂的语法结构,一直被认为是编程领域中学习难度较高的语言之一。本文将探讨汇编语言中的等号伪指令及其对初学者带来的挑战,并结合社区反馈分析其学习曲线。 ... [详细]
  • 本文详细介绍了如何在Debian系统中正确配置Locale,以确保多语言支持和避免常见的警告信息。 ... [详细]
  • Win11扩展卷无法使用?解决扩展卷灰色问题的指南
    本文详细介绍了在Windows 11中遇到扩展卷灰色无法使用时的解决方案,帮助用户快速恢复磁盘扩展功能。 ... [详细]
  • 本文深入解析了宋代诗人宋史浩的《蓦山溪》,探讨其作品中的自然意象与人生哲理,带领读者领略这首词的独特魅力。 ... [详细]
  • 本文详细介绍了如何通过调整手机设置和拍摄技巧,实现高质量的俯拍横屏照片。 ... [详细]
  • 本文介绍如何使用Python进行文本处理,包括分词和生成词云图。通过整合多个文本文件、去除停用词并生成词云图,展示文本数据的可视化分析方法。 ... [详细]
  • 本文介绍了如何通过扩展 UnityGUI 创建自定义和复合控件,以满足特定的用户界面需求。内容涵盖简单和静态复合控件的实现,并展示了如何创建复杂的 RGB 滑块。 ... [详细]
  • 本文介绍如何在Linux服务器之间使用SCP命令进行文件传输。SCP(Secure Copy Protocol)是一种基于SSH的安全文件传输协议,支持从远程机器复制文件到本地服务器或反之。示例包括从192.168.45.147复制tomcat目录到本地/home路径。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 本文详细介绍了 MySQL 中 LAST_INSERT_ID() 函数的使用方法及其工作原理,包括如何获取最后一个插入记录的自增 ID、多行插入时的行为以及在不同客户端环境下的表现。 ... [详细]
  • Struts与Spring框架的集成指南
    本文详细介绍了如何将Struts和Spring两个流行的Java Web开发框架进行整合,涵盖从环境配置到代码实现的具体步骤。 ... [详细]
author-avatar
重庆垚东科技有限公司
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有