电商退货处理流程_多个退货单
电商退货处理流程
我曾经听说过,人们过去一直在努力使方法具有单个出口点。 我知道这是一种过时的方法,从未认为它特别值得注意。 但是最近,我与一些仍坚持该想法的开发人员进行了联系(最后一次是在这里),这让我开始思考。
因此,我第一次真正坐下来比较了这两种方法。
总览
文章的第一部分将重复针对和反对多个return语句的参数。 它还将确定干净代码在评估这些论点中的关键作用。 第二部分将归纳得益于早日返回的情况。
为了不总是写“带有多个return语句的方法”,我将这种方法称为通过模式构造方法的方法。 虽然这可能有点过分,但肯定会更简洁。
讨论
我正在讨论一个方法是应该始终运行到最后一行,从那里返回结果,还是可以有多个return语句并“尽早返回”。
这当然不是新的讨论。 参见,例如Wikipedia , Hacker Chick或StackOverflow 。
结构化程序设计
单个return语句是可取的想法源于1960年代开发的结构化编程范式。 关于子例程,它提倡它们具有单个入口和单个出口点。 尽管现代编程语言可以保证前者,但是出于某些原因,后者有些过时了。
单个出口点解决的主要问题是内存或资源泄漏。 当方法内部某处的return语句阻止执行位于其末尾的某些清除代码时,就会发生这种情况。 如今,其中大部分由语言运行时处理(例如,垃圾回收),并且可以使用try-catch-finally编写显式清除块。 因此,现在的讨论主要围绕可读性。
可读性
坚持单个return语句可能导致嵌套增加,并需要其他变量(例如,中断循环)。 另一方面,使方法从多个点返回可能导致其控制流程混乱,从而使其难以维护。 重要的是要注意,这两个方面在代码的整体质量方面的行为非常不同。
考虑一种遵循简洁的编码准则的方法:它简短且具有明确的名称和意图揭示结构。 通过引入更多的嵌套和更多的变量,在可读性方面的相对损失非常明显,并且可能使干净的结构混乱。 但是由于该方法的简洁性和形式使其易于理解,因此忽略任何返回声明的风险不大。 因此,即使存在不止一个,控制流程仍然显而易见。
与较长的方法(可能是复杂或优化算法的一部分)进行对比。 现在情况逆转了。 该方法已经包含许多变量,并且可能包含一些嵌套级别。 引入更多内容在可读性方面几乎没有相对成本。 但是,忽视多个回报之一从而误解控制流程的风险是非常现实的。
因此,问题就在于方法是否简短易读。 如果是这样,通常使用多个return语句是一种改进。 如果不是,则最好使用单个return语句。
其他因素
但是,可读性可能不是唯一的因素。
讨论的另一方面可以是日志记录。 如果要记录返回值但不求助于面向方面的编程,则必须在方法的出口点手动插入记录语句。 使用多个return语句执行此操作很繁琐,而忘记一个则很容易。
同样,如果要在从方法返回之前声明结果的某些属性,则可能希望使用单个退出点。
多个退货报表的情况
在几种情况下,一种方法可以从多个返回语句中获利。 我试图在这里对它们进行分类,但没有声称有完整的列表。 (如果您遇到另一种重复出现的情况,请发表评论,我将在此附上。)
每种情况都会附带一个代码示例。 请注意,缩短了这些内容可以使观点更清楚,并且可以通过多种方式进行改进。
由JDHancock在CC-BY 2.0下发布
警卫条款
保护子句位于方法的开头。 他们检查其参数,并在某些特殊情况下立即返回结果。
防范条款无效或空集合
private Set<T> intersection(Collection<T> first, Collection<T> second) {// intersection with an empty collection is emptyif (isNullOrEmpty(first) || isNullOrEmpty(second))return new HashSet<>();return first.stream().filter(second::contains).collect(Collectors.toSet());
}
在一开始就排除边缘情况有几个优点:
- 它将特殊情况和常规情况的处理完全分开,从而提高了可读性
- 它提供了用于其他检查的默认位置,从而保持了可读性
- 这使得实施常规案例的错误更少
- 它可能会提高那些特殊情况下的性能(尽管这很少相关)
基本上,适用于该模式的所有方法都将从其使用中受益。
值得一提的是后卫条款的支持者是马丁·福勒(Martin Fowler),尽管我会在分支的边缘考虑他的例子(见下文)。
分枝
一些方法的职责要求分支到几个通常专用的子例程之一。 通常最好自行将这些子例程实现为方法。 然后,原始方法仅负责评估某些条件并调用正确的例程。
委托专门方法
public Offer makeOffer(Customer customer) {boolean isSucker = isSucker(customer);boolean canAffordLawSuit = customer.canAfford(legalDepartment.estimateLawSuitCost());if (isSucker) {if (canAffordLawSuit)return getBigBucksButStayLegal(customer);elsereturn takeToTheCleaners(customer);} else {if (canAffordLawSuit)return getRid(customer);elsereturn getSomeMoney(customer);}
}
(我知道我可以省略所有else
行。有一天,我可能会写一篇帖子解释为什么在这种情况下我不这样做。)
与结果变量和单个返回相比,使用多个return语句具有多个优点:
- 该方法更清楚地表达了其打算跳转到子例程并仅返回其结果的意图
- 在任何理智的语言中,如果分支不能涵盖所有可能性,则该方法不会编译(在Java中,如果未将变量初始化为默认值,也可以通过一次返回来实现)
- 结果没有额外的变量,几乎可以覆盖整个方法
- 被调用方法的结果不能在返回之前进行操作(在Java中,如果变量是
final
并且其类是不可变的,也可以通过单次返回来实现;但是,这对于读者而言并不明显) - 如果将switch语句用于具有穿透性的语言(例如Java),则由于无需
break
,即时返回语句可按情况节省一行,这减少了样板并提高了可读性
此模式仅应应用于除分支以外无所作为的方法。 分支机构涵盖所有可能性尤其重要。 这意味着分支语句下没有代码。 如果有的话,将需要更多的精力来推理该方法的所有路径。 如果一种方法满足这些条件,那么它将很小且具有凝聚力,这很容易理解。
级联检查
有时,一种方法的行为主要由多个检查组成,其中每个检查的结果可能使进一步检查变得不必要。 在这种情况下,最好尽快返回(也许在每次检查之后)。
寻找锚定父级时进行级联检查
private Element getAnchorAncestor(Node node) {// if there is no node, there can be no anchor,// so return nullif (node == null)return null;// only elements can be anchors,// so if the node is no element, recurse to its parentboolean nodeIsNoElement = !(node instanceof Element);if (nodeIsNoElement)return getAnchorAncestor(node.getParentNode());// since the node is an element, it might be an anchorElement element = (Element) node;boolean isAnchor = element.getTagName().equalsIgnoreCase("a");if (isAnchor)return element;// if the element is no anchor, recurse to its parentreturn getAnchorAncestor(element.getParentNode());
}
其他示例是Java中equals
或compareTo
的常规实现。 它们通常还包含一系列检查,其中每个检查都可以确定方法的结果。 如果是这样,则立即返回该值,否则该方法继续进行下一个检查。
与单个return语句相比,此模式不需要您跳过箍来防止更深的缩进。 它还使直接添加新的检查和在检查并返回块之前放置注释成为可能。
与分支一样,多个return语句仅应应用于短而几乎没有其他作用的方法。 级联检查应该是它们的主要内容,或者更好的是它们的唯一内容(除了输入验证之外)。 如果检查或返回值的计算需要两到三行以上,则应将其重构为单独的方法。
正在搜寻
在具有数据结构的地方,可以找到具有特殊条件的项目。 搜索它们的方法通常看起来很相似。 如果这种方法遇到了要搜索的项目,则通常最容易立即返回它。
立即返回找到的元素
private <T> T findFirstIncreaseElement(Iterable<T> items, Comparator<? super T> comparator) {T lastItem = null;for (T currentItem : items) {boolean increase = increase(lastItem, currentItem, comparator);lastItem = currentItem;if (increase) {return currentItem;}}return null;
}
与单个return语句相比,这使我们免于寻找摆脱循环的方法。 这具有以下优点:
- 没有其他布尔变量可以打破循环
- 循环没有其他条件,它很容易被忽略(尤其是在for循环中),因此会引发错误
- 最后两点使循环更容易理解
- 结果很可能没有其他变量,几乎涵盖了整个方法
像大多数使用多个return语句的模式一样,这也需要干净的代码。 该方法应该很小,除了搜索外别无其他责任。 非平凡的检查和结果计算应具有自己的方法。
反射
我们已经看到了支持和反对多个return语句的参数,以及干净代码所起的关键作用。 分类应有助于识别重复出现的情况,在这种情况下,一种方法将从早期返回中受益。
翻译自: https://www.javacodegeeks.com/2015/01/multiple-return-statements.html
电商退货处理流程
电商退货处理流程_多个退货单相关推荐
- 电商平台搭建流程是怎样的_不懂编程怎么搭建_OctShop
电商平台搭建流程是怎样的?不懂编程,不懂代码可以吗?如果搭建与建设自己的商城平台网站? 首先要明白的是,不同需要的角色对电商平台的需求是不一样的.大中型企业.个人.夫妻店开的电商平台是有着很大的区别的 ...
- 数据仓库电商建模_真实电商数据仓库全流程开发详解,资源教程下载
课程名称 Hadoop大数据视频教程-第一季:真实电商数据仓库全流程开发详解(共46讲),资源教程下载 课程目录 第一部分:数据仓库基础理论与技术圈 第一章:互联网电商大数据环境 第二章:商业智能与数 ...
- 08-Flutter移动电商实战-dio基础_伪造请求头获取数据
08-Flutter移动电商实战-dio基础_伪造请求头获取数据 在很多时候,后端为了安全都会有一些请求头的限制,只有请求头对了,才能正确返回数据.这虽然限制了一些人恶意请求数据,但是对于我们聪明的程 ...
- 退货表mysql_openant电商-退货 - 数据库设计 - 数据库表结构 - 果创云
-- 数据库大全:openant电商-退货 -- 来源:YesApi.cn CREATE TABLE `yesapi_openant_return` ( `id` bigint(20) unsigne ...
- 05-Flutter移动电商实战-dio基础_引入和简单的Get请求
05-Flutter移动电商实战-dio基础_引入和简单的Get请求 这篇开始我们学习Dart第三方Http请求库dio,这是国人开源的一个项目,也是国内用的最广泛的Dart Http请求库. 1.d ...
- 小红书电商入驻全流程指南
小红书电商入驻全流程指南#小红书 五类店铺入驻要求可售卖类目你知道吗?#运营#干货 你知道小红书的 5 类店铺的入驻要求以及可售卖类目吗?hello,大家好,我是专注搞流量的百收编辑狂潮老师.小红书目 ...
- 电商平台资金结算流程是什么样的?
(图源:pexels网站) 在疫情的影响下,越来越多的传统企业开始转向电商,希望通过互联网来拓展业务,开拓新市场.同时,也有越来越多的新兴企业从事电子商务,利用互联网的优势快速发展壮大.而电商的快速发 ...
- 电商退货退款处理服务流程,快递鸟提供最有效的解决方案(内附教程)
近几年来,我国电子商务交易规模越来越大,线上订单越来越多,退换货的情况也越来越常见.今天就来讲讲电商退换货的问题. 订单退货,作为订单出库的逆向流程,其实还是蛮复杂的.他可以是单纯退款,或者退货退款, ...
- 电商扣减库存_以电商为例 | B端产品经理,怎么做好库存系统设计
库存,是仓库中实际储存的货物.可以分两类:一类是生产库存,即直接消耗物资的基层企业.事业的库存物资,它是为了保证企业.事业单位所消耗的物资能够不间断地供应而储存的:一类是流通库存,即生产企业的原材料或 ...
最新文章
- 机器学习数据预处理之缺失值:固定值填充
- docker 错误 request canceled while waiting for connection 或 TLS handshake timeout 解决方案
- 用boolalpha输出true或false的问题
- ssh-add ssh-agent使用
- 删除链表的倒数第N个节点—leetcode19
- 与其他Javascript类库冲突解决方案
- 揭秘北京2022冬奥会背后的技术
- WTM系列视频教程:View和Taghelper
- uva 10622——Perfect P-th Powers
- dj打碟怎么学_学DJ要不要去培训学校?
- 录像的视频如何在画面中实时加上时间戳
- MyBatis插件开发:简单分页插件
- Unity3D开发Android游戏(二)Hello world
- h5页面如何切图_切图与CSS入门
- mysql数据库置疑_SQL数据库置疑 823 824 错误修复 无法附加处理
- 笨办法学python习题1-10
- 前端请求报:NET::ERR_INCOMPLETE_CHUNKED_ENCODING,响应200,但接收不到正常响应
- 2022-2028年全球与中国鸟类保健品行业发展趋势及竞争策略研究
- 正则表达式,Date,StringBuilder,StringTest,包装类
- matlab 相乘掩蔽图像,MATLAB逻辑掩蔽
热门文章
- 分布式锁的几种实现方式
- 基于UDP的socket客户服务器编程
- 【集合框架】JDK1.8源码分析之IdentityHashMap(四)
- 神经网络:多层网络与C++实现
- [WPF]winfom中ShowWPF新窗口时TextBox等控件无法输入问题解决方法 .
- linux 内存管理中的 rss 和 vsz
- linux 路由跟踪表满错误 nf_conntrack: table full, dropping packet 原理解决方法
- linux tomcat 隐藏版本号
- python3 字符串总结
- HTTP/2 h2 协议简介