java - 想知道Microstream类StorageConfiguration

标签 java database naming-conventions microstream

微流数据库及其类StorageConfiguration有两个问题:

1)New()和Builder()方法以及DEFAULT构造方法有何区别?

2)为什么这些方法写大写?看来这不是Java命名约定。

感谢您的任何答案!

最佳答案

我是MicroStream的主要开发人员,我很乐意回答这些问题。

到1)

“ New”是类型本身的“静态工厂方法”。
“构建器”是类型的“构建器”实例的静态工厂方法。

可以完美搜索两个术语以获取有关它们的更多信息。
快速服务作为起点:

“静态工厂方法”:
https://www.baeldung.com/java-constructors-vs-static-factory-methods

“构建者模式”:
https://en.wikipedia.org/wiki/Builder_pattern

-

关于第二个问题,关于“ DEFAULT”构造:

如果可以的话,没有“默认”构造,而是“默认”。
(公约很重要……主要是。请参阅下文。)

“默认”只是接口StorageConfiguration的默认实现(=类)。
直接在类中直接构建软件体系结构很快变得过于严格,因此设计很糟糕。引用和实例化类直接为单个实现创建了许多硬编码的依赖项,这些依赖项以后将无法更改或变得更加灵活。实际上,继承很少具有足够的灵活性,足以解决出现的体系结构灵活性问题。另一方面,接口仅定义类型,实现它的实际类几乎没有关系,甚至可以轻松互换。例如,通过仅通过接口进行设计,每个实例都可以通过使用装饰器模式轻松地被任何所需的逻辑“包装”。例如。向类型添加日志记录方面。

有一篇很好的文章带有关于詹姆斯·戈斯林(Java的发明者)的轶事,名为“为什么扩展是邪恶的”,它描述了以下内容:
https://www.javaworld.com/article/2073649/why-extends-is-evil.html

所以:
“ Default”只是实现其嵌套接口的默认类。将此类命名为“ Default”是有意义的,不是吗?旁边可能还有其他类,例如“包装器”或“ LazyInitializing”或“ Dummy”或“ Randomizing”或其他任何类。

MicroStream的整个代码中都使用了这种设计模式,从而为它提供了令人难以置信的灵活和强大的体系结构。例如:
只需一行代码,MicroStream的每个部分(机器中的每个“齿轮”)都可以由自定义实现替换。可以做一些不同的事情(可能更好吗?)或修复错误,甚至不需要新的MicroStream版本。或者添加日志记录或自定义异常处理的对象,或者引入通常没有对象通信的对象的对象。也许直接使用应用程序逻辑(但后果自负!)。至少在接口边界之内,一切皆有可能。

一开始对接口的思考可能会造成混淆(这就是为什么许多开发人员使用适得其反的“ I”前缀来“烧毁”接口的原因。每次看到它都会使我感到伤害),但是它们是Java中的实际设计类型。类只是它们的实现工具,与设计水平无关。

-

至2)

我认为“静态工厂方法”更合适的术语是“伪构造函数”。这是一种充当该类型的公共API构造函数的方法,但它不是实际的构造函数。关于这种封装构造函数的静态方法的设计优点的争论之后,关于最佳,一致的命名模式的问题浮出水面。 JDK提供了一些非常糟糕的示例,不应复制。就像“ of”或“ get”一样。这些名称几乎不带有方法目的的含义。
它应尽可能短,但仍应尽可能地具有描述性。 “创建”或“构建”可以,但是它们真的是最佳选择吗? “ new”将是最好的,但具有讽刺意味的是,这是与构造函数关联的关键字,应从公共API中隐藏该关键字。 “ neW”或“ nEw”看起来非常难看,而且键入起来很麻烦。但是“新”呢?是的,这不是严格的Java命名约定。但是已经有一种方法可以做到,这是一般命名规则的例外。哪一个?构造函数!不是“新人(...)”,而是“新人(...)”。一种以大写字母开头的方法。自Java诞生以来。因此,如果应该使用静态方法代替构造函数,那么将相同的异常...或...命名约定的“扩展”应用到该结构上是否也很合逻辑并且是一个很好的信号呢?所以...是“新”。非常短,非常清晰。也不再和原始构造函数非常相似。 “ Person.New”而不是“ new Person”。
适合两个命名例外的“命名约定扩展名”是:“保证每个以大写字母开头的静态方法都将返回该类型的新实例。”不是缓存的。总是一个新的。 (这对于保证算法的正确性有时可能至关重要。)

这也有一些整洁的副作用。例如:


用于创建新实例的伪构造方法
“ StorageConfigurationBuilder”可以是“ StorageConfiguration.Builder()”。
这是不言自明的,简单的,清晰的。
或者,如果有一种方法“ public static Vector Normalized(Vector v)”,则它暗含
告诉传递的实例将不会更改,但是新实例将被更改
返回标准化向量值。就像有
为构造函数提供专有名称的选项。代替
各种各样的“ Vector(...)”方法,必须依靠
JavaDoc间接解释其含义,解释正确
那里的名字。 “新建(...)”,“规范化(...)”,“复制(...)”等。
而且它与嵌套默认类也很好地配合
模式:无需编写“ new StorageConfiguration.Default()”(其中
会很糟糕,因为无论如何都要进行硬编码),但是
“ StorageConfiguration.New”就足够了。它将在内部创建并
返回一个新的“ StorageConfiguration.Default”实例。那应该
内部逻辑会发生变化,API甚至不会注意到它
用户。


如果没有其他人这样做,我为什么要这样做?
如果考虑一下,那将不是有效的论据。我尽可能严格地遵守标准和约定。它们大约有99%的时间在执行,但是如果它们包含问题(例如禁止将静态方法称为“新”)或缺少完全合理的功能(例如PersonBuilder b = Person.Builder()”或选择正确说出的名字)然后,经过深思熟虑后,我...根据需要对其进行了扩展。这称为创新。如果到目前为止,没有其他人对此有洞察力,对他们不利,对我不利。问题不在于为什么发明家创造了一种即兴表现,但是为什么到目前为止没有人做过呢?如果有明显的改善的可能,那就是没有理由仅仅因为没有别人做就做不到的正当理由。就像在1970年代锁定40多年的数据存储技术中锁定自己一样,而不是仅仅采取明显更简单,更快速,直接,更好的方式。

我建议将大写字母方法命名为扩展来证明创新:如果一个新想法客观上带来的好处多于缺点,那么它应该-或几乎必须-完成。

我在此邀请大家采用它。

关于java - 想知道Microstream类StorageConfiguration,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59336861/

相关文章:

Spring 服务和存储库层约定

javascript - ExtJS 中的自定义类属性

php - Laravel 模式生成器将表名转换为小写

java - 在 32 位二进制数的开头添加零。

java - 仅生成随机字母字符

php - 在数据库中存储考试数据的最佳方法

java - 在 mysql 中检查用户名...如果存在则插入到其他表中否则基表

database - Cassandra 读取性能

java - jar中访问的静态方法

JAVA advice annotation 会运行两次吗?