公共静态文字......不是数据重复的解决方案

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

我在一个地方有一个 new string(array,"utf-8") ,在我的应用程序的另一个地方有完全相同的代码。实际上,我可能在很多地方都有它。每次,我都必须使用那个 "utf-8" 常量才能从字节数组创建一个 string 。在某个地方定义一次并重用它会非常方便,就像 apache commons 所做的那样;参见 charencoding.utf_8 (那里还有许多其他静态文字)。这些家伙正在树立一个坏榜样! publicstatic “属性”与实用程序类一样糟糕。


©the shining (1980) 斯坦利库布里克

这就是我所说的,具体来说:


 package org.apache.commons.lang3;
public class charencoding {
  public static final string utf_8 = "utf-8";
  // some other methods and properties
}

现在,当我需要从字节数组创建一个 string 时,我使用这个:


 package org.apache.commons.lang3;
public class charencoding {
  public static final string utf_8 = "utf-8";
  // some other methods and properties
}

假设我想将 string 转换为字节数组:


 package org.apache.commons.lang3;
public class charencoding {
  public static final string utf_8 = "utf-8";
  // some other methods and properties
}

看起来很方便对吧?这就是 apache commons 的设计者的想法(java 世界中最流行但非常 糟糕的 库之一)。我鼓励你以不同的方式思考。我不能告诉您停止使用 apache commons,因为我们还没有更好的选择(还没有!)。但在您自己的代码中,永远不要使用公共静态属性。即使这段代码对你来说可能看起来很方便,但它是一个非常糟糕的设计。

原因与具有公共静态方法的实用程序类非常相似——它们是牢不可破的硬编码依赖项。一旦你使用了 charencoding.utf_8 ,你的对象就开始依赖这个数据,并且它的用户(你的对象的用户)不能打破这种依赖。你可能会说这是你的意图,在 "utf-8" 常量的情况下——确保 unicode 被专门和排他地使用。在这个特定的例子中,这可能是正确的,但从更全球化的角度来看。

在我们继续之前,让我向您展示我想到的替代方案。这是我的建议,而不是将字节数组转换为 string


 package org.apache.commons.lang3;
public class charencoding {
  public static final string utf_8 = "utf-8";
  // some other methods and properties
}

它是伪代码,因为 java 设计者将类 string 设为 final 并且我们不能真正扩展它并创建 utf8string ,但你明白了。在现实世界中,这看起来像这样:


 package org.apache.commons.lang3;
public class charencoding {
  public static final string utf_8 = "utf-8";
  // some other methods and properties
}

如您所见,我们将“utf-8”常量封装在类 utf8string 的某处,其用户不知道这种“字节数组到字符串”的转换究竟是如何发生的。

通过引入 utf8string ,我们解决了“utf-8”文字重复的问题。但是我们以一种适当的面向对象的方式做到了——我们将功能封装在一个类中,让每个人都实例化它的对象并使用它们。我们解决了功能重复问题,而不仅仅是数据重复问题。

将数据放在一个共享位置( charencoding.utf_8 )并不能真正解决重复问题;它实际上使情况变得更糟,主要是因为它鼓励每个人使用相同的共享数据来复制功能。

我的意思是,每当您看到应用程序中有一些数据重复时,请开始考虑您正在重复的功能。您会很容易地找到一次又一次重复的代码。为此代码创建一个新类并将数据作为 private 属性(或私有 static 属性)放置在那里。这就是您改进设计并真正摆脱重复的方式。