Java静态方法可能会产生代码异味

代码气味的定义 (来自维基百科):

“程序源代码中任何可能表明存在更深层问题的症状。”

在Java中, 静态方法允许您在“类范围”内执行代码,而不是像成员方法这样的实例范围。 这意味着,它们依赖于类级别的变量(如果有),传递给静态方法的参数或任何其他全局可访问的数据。 它们不是面向对象的。 对象具有与之关联的状态,并且只能通过实现该对象“行为”的方法进行操作。 静态方法不在状态上操作,它们不是面向对象的,实际上它们是过程式的。

这不好吗?

不会。尽管Java是面向对象的,但有时还是需要和/或首选Java中的类似于过程的编程。 任何面向对象的语言的真正威力在于能够在代码中紧密实现现实生活中的系统模型的能力(请参阅我有关面向对象建模的文章 )。 但是,即使在最核心的对象模型中,也很可能会有一些粘合代码或将以过程样式实现的基础结构代码。

因此,如果Java中的类似于过程的编程不是“那么糟糕”并且静态方法是过程编程的一种形式,那么静态方法是否不好?

嗯……答案并不像是“是”或“否”那么简单,无论您在其他博客上会读到什么,但我可能会不断争论着为什么这实际上是必须在上下文中做出的决定,因此,让我们重点关注一下我在Michael Minella博客的“如何模拟静态方法”中遇到的一组语句:

“已经成为该语言基础知识的部分(您要做的只是看一下Apache Commons项目以了解这一点)非常糟糕,以测试为名必须不惜一切代价避免。 Gosling(或其团队中的某人)出于某种原因将其放入语言中,并且仅由于您的工具集不支持对它的测试是无稽之谈而避免使用这些语言。 是时候获得新的工具集了。”

首先,我想指出的是,仅仅因为某种东西已经成为一种语言的基本组成部分,并不意味着它就是“好”或应该做的事情。 查看已检查的异常以供参考。 我记得EJB 1.x和2.x在过去成为Java EE的“基础”部分,因此也请参考一下。

其次,尽管我在理论上确实同意Michael的观点,即由于您的工具不支持某种特定的语言功能而使其愚蠢,但他的前提是静态方法。 避免使用静态方法是因为您的工具不支持静态方法,这根本不是胡说。 实际上,由一些好的测试和/或模拟框架( Mockito是我最喜欢的框架)引起的阻抗类型 :) )和静态方法可以确定地识别为代码异味。 这并不意味着我们不应该这样做,而是应该付出更多的努力来理解我们为什么这样做,并在存在“更深层次的问题”时探索替代方法。

我想指出,至少有两种类型的静态方法通常不会在测试/模拟框架中表现出太大的阻力。 第一种类型是用作实用程序方法的静态方法,就像在许多apache commons库或您自己的内部commons库中找到的方法一样。 这些通常是支持特定方法目标的例程,并且将它们模拟/存根到单元测试之外是没有意义的。 它们是实现的一部分,因此应进行测试。 第二种类型是静态方法,用于代替构造函数,如Joshua Bloch在他的书《 Effective Java》中所展示的。 静态方法的这种使用使您可以使用名称具有非常描述性的方法来构造新对象,以及其他一些优点。 第二种静态方法的分支可能包括工厂方法,但这取决于上下文。

当单元依靠静态方法执行超出该单元职责范围的逻辑时,由于静态方法和测试框架阻抗而产生的最明显的代码异味。 在这些情况下,您的测试框架将对您不利,因为您无法对范围外的逻辑进行存根/模拟,因为它是通过静态方法“硬编码”的。 这可以被视为“更深层的问题”,并且是大多数博客的焦点,这些博客告诉您不要使用静态方法,因为测试变得异常困难或不可能。 更改设计方法以遵循依赖性反转原则是另一种选择。 对如何测试单元的更好的理解是另一个。

我强烈断言,在使用静态方法的情况下,您可能会从测试框架中得到的回退表示代码有气味,而不是您需要尝试找到一个使用复杂的欺骗手段并将类加载器重新映射作为解决方案的框架。 应该准备评估一种特殊方法在其设计中的用途和基本缺陷。 Michael的博客文章使读者太容易采用新的工具/框架,仅因为Java支持静态方法并且您当前的测试框架阐明了一个阻抗-在这种情况下,阻抗反映了代码的味道,需要一些更深入,更批判性的思考。

参考: Java静态方法可能是 JCG合作伙伴 Christian Posta在Christian Posta Software博客上的代码味道 。


翻译自: https://www.javacodegeeks.com/2012/05/java-static-methods-can-be-code-smell.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373093.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Node Express4.x 片段视图 partials

1.在Express 4.x使用片段视图,需要引入partials模块 步骤: 1.在全局中安装express-partials模块: 2.在本地模块中安装express-partials,将模块安装到package.json中: 3.在入口文件(如:app.js)中引入模块: v…

bzoj1690:[Usaco2007 Dec]奶牛的旅行(分数规划+spfa判负环)

PS:此题数组名皆引用:戳我 题目大意:有n个点m条有向边的图,边上有花费,点上有收益,点可以多次经过,但是收益不叠加,边也可以多次经过,但是费用叠加。求一个环使得收益和/花费和最大&…

红米note4x Android7,红米Note4X能升级安卓7.0吗?红米Note4X如何升级Android7.0?

欢迎来到PPL网站的行业资讯知识分类,你现在观看的这篇文章要和大家分享的是关于红米Note4X能升级安卓7.0吗?红米Note4X如何升级Android7.0?的一些相关内容,希望大家能够感兴趣,并且希望我们能够帮助到你!在…

java基础----数字签名算法的介绍

数字签名(又称公钥数字签名)是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术实现,用于鉴别数字信息的方法。关于数字签名的介绍,可以参见百度百科:http://baike.baidu.com/view/7626.htm…

Android宫格自动换行,九宫格视图的布局及展示(相册选择)

上周一个朋友带的项目出了点问题,招的ios开发人员在实现选取相册图片后用九宫格的样式展示时遇到了瓶颈,花了将近2周都没有解决。后来在跟我交流的过程中他把项目的图片发给我看了下,看完我就笑了,这就只是个算法的问题&#xff0…

具有LCS方法的通用文本比较工具

常见的问题是检测并显示两个文本(尤其是几百行或几千行)的差异。 使用纯java.lang.String类方法可能是一种解决方案,但是对于此类操作最重要的问题是,“性能”将不能令人满意。 我们需要一种有效的解决方案,其可能具有…

eclipse 开发 scala

(环境:jdk1.7,scala插件scala-2.1.1.2-site.zip) 1:下载scala插件 http://download.scala-ide.org/sdk/helium/e38/scala211/stable/site2:解压到本地将这两个文件里的jar包全部复制到eclipse的安装目录对应的文件夹里三:重启eclipse这时会提…

Quartz Scheduler失火指令说明

有时,Quartz无法在您需要的时间运行您的工作。 这有三个原因: 所有工作线程都忙于运行其他作业(可能具有更高的优先级) 调度程序本身已关闭 该作业是在过去的开始时间安排的(可能是编码错误) 您可以通过…

改进租房练习

代码基本没有改动&#xff0c;函数有变化&#xff0c;老师只用了一个函数&#xff0c;自己做写了4个function&#xff0c;减少了代码量 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitio…

Google App Engine JAX-RS REST服务

在本文中&#xff0c;您将学习如何使用JAX-RS参考实现&#xff08;Jersey&#xff09;创建REST服务并将其部署在Google AppEngine上。 先决条件 对于本教程&#xff0c;您将需要&#xff1a; Google AppEngine帐户 Eclipse Galileo&#xff08;3.5.x&#xff09; 适用于Java的…

鸿蒙系统的全面开源,华为:打造全球的操作系统,鸿蒙今日全面开源!

原标题&#xff1a;华为&#xff1a;打造全球的操作系统&#xff0c;鸿蒙今日全面开源&#xff01;今日下午&#xff0c;2019华为全球开发者大会在华为松山湖基地正式开幕。华为正式对外推出了自研操作系统——鸿蒙系统(Harmony OS)。华为消费者业务CEO余承东指出&#xff0c;鸿…

html5 游戏制作教程,html5一步步实现超级玛丽游戏制作(新手教程源码)

【实例简介】【实例截图】【核心代码】My first Gamebody {border:none 0px;margin:0px;padding:10px;font-size : 16px;background-color : #f3f3f3;}canvas {border : 1px solid blue;}// 页面初始化函数function init(){//加载图片,并存入全局变量 ImgCache,// 加载完成后,调…

交友系统设计:哪种地理空间邻近算法更快?

小熊学Java&#xff1a;https://javaxiaobear.cn 交友与婚恋是人们最基本的需求之一。随着互联网时代的不断发展&#xff0c;移动社交软件已经成为了人们生活中必不可少的一部分。然而&#xff0c;熟人社交并不能完全满足年轻人的社交与情感需求&#xff0c;于是陌生人交友平台…

Apache Camel教程– EIP,路由,组件,测试和其他概念的简介

公司之间的数据交换增加了很多。 必须集成的应用程序数量也增加了。 这些接口使用不同的技术&#xff0c;协议和数据格式。 但是&#xff0c;这些应用程序的集成应以标准化的方式建模&#xff0c;有效实现并由自动测试支持。 企业集成模式&#xff08;EIP&#xff09;[1]中存在…

iOS开发UI篇—UITableview控件简单介绍

一、基本介绍 在众多移动应⽤用中,能看到各式各样的表格数据 。 在iOS中,要实现表格数据展示,最常用的做法就是使用UITableView&#xff0c;UITableView继承自UIScrollView,因此支持垂直滚动,⽽且性能极佳 。 UITableview有分组和不分组两种样式&#xff0c;可以在storyboard或…

动态ADF火车:以编程方式添加火车停靠站

我将展示如何以编程方式“即时”将火车停靠站添加到ADF火车中。 在我的用例中&#xff0c;我有一些票务预订应用程序。 它具有训练模型的有限任务流。 在火车的第一站&#xff0c;用户输入乘客的数量&#xff0c;在随后的站点&#xff0c;他们输入一些乘客的信息。 带有乘客信息…

关于存储过程权限

关于ORACLE账号的权限问题&#xff0c;一般分为两种权限&#xff1a; 系统权限: 允许用户执行特定的数据库动作&#xff0c;如创建表、创建索引、创建存储过程等 对象权限: 允许用户操纵一些特定的对象&#xff0c;如读取视图&#xff0c;可更新某些列、执行存储过程等 像这种查…

宁波镇海2021年高考成绩查询,最新!2021年,宁波镇海区的这14所中小学“爆了...

宁波镇海区教育局发布了2021年公办学校小学一年级、初中一年级招生第一次预警&#xff0c;这也是宁波首个发布2021年公办学校招生预警的县、市、区。根据最新数据摸排&#xff0c;宁波镇海区有8所小学红色预警、2所初中红色预警&#xff0c;1所小学黄色预警、3所初中黄色预警。…

超出了GC开销限制– Java堆分析

这篇文章是我们原来的GC超出限制的问题模式帖子的延续。 正确的Java堆分析对于消除O​​utOfMemoryError&#xff1a;GC开销问题至关重要。 如果您不熟悉此Java HotSpot 1.6错误&#xff0c;建议您首先阅读有关此主题的第一篇文章 。 本文将为您提供一个示例程序和一个教程&…

cdockpane限制调整大小_影视后期制作小伙伴必看:使用AU对声音质量进行调整的三大技巧...

一、增幅一般人进入AU的音频调整界面&#xff0c;会使用图中的旋钮进行音量调整&#xff0c;这种操作是错误的&#xff0c;因为通过拖拽并不能确定调整音量的大小幅度&#xff0c;精准度极低&#xff0c;反复操作才能试出最佳音量&#xff0c;效率极低。最优方案是使用左侧效果…