Mr.*_*ama 6 language-agnostic declarative naming-conventions
如何命名函数以清楚地反映它们遵循声明性范式?
上下文:我最近开始致力于创建以声明方式工作的库,但我很难提出反映它的命名约定。过去,我创建了名称类似于 的命令式函数createThing,但我发现很难在函数名称中简洁地传达“做必要的事情以返回Thing看起来像 ____”的想法。
理想情况下,我想遵循正式的标准或既定的命名约定。否则,我希望至少从预先存在的代码库中找到一些指导。
鉴于您担心有一个简洁的函数名称,我会研究您的createThing函数是否做得太多并将其拆分为几个较小的块(这在很大程度上受 C# 语法的影响):
var yourThing = new Thing()
.with(new PropertyA()).thenWith(new DependentPropertyOfA()) // digress a bit
.with(new PropertyB()) // back to main thread here
.withPieceOfLogic((parameter1, parameter2) => {define some logic here}) // so you can potentially can swap implementations as well
.create();
Run Code Online (Sandbox Code Playgroud)
在这里,我的目标是FluentInterface 的一些东西。这可能会让你达到你正在寻找的美学。
使用这种方法要记住的一件事是,这种链接使其高度线性化,如果您需要绕路定义主要对象,则可能无法很好地工作。
其他几个可以从中汲取灵感的例子:
根据我的经验,声明性框架中的主要函数没有规范的命名方案,但有许多突出的例子可以让您从中汲取灵感。
与 FluentInterface 样式关联的方法通常带有前缀“with”。例如
new HTTPClient()
.withProxy(new Proxy('localhost', 8080))
.withTimeOut(Duration.of("30s"))
.withRequestHeaders(
new Headers()
.with('User-Agent', 'FluidClient')
);
Run Code Online (Sandbox Code Playgroud)
请参阅https://martinfowler.com/bliki/FluentInterface.html
一些 FluentInterface 设计取消了函数名称前缀,只在它们所代表的声明性元素之后直接命名函数。JOOQ 的示例:( https://www.jooq.org/doc/3.12/manual/getting-started/use-cases/jooq-as-a-standalone-sql-builder/ )
String sql = create.select(field("BOOK.TITLE"), field("AUTHOR.FIRST_NAME"),
field("AUTHOR.LAST_NAME"))
.from(table("BOOK"))
.join(table("AUTHOR"))
.on(field("BOOK.AUTHOR_ID").eq(field("AUTHOR.ID")))
.where(field("BOOK.PUBLISHED_IN").eq(1948))
.getSQL();
Run Code Online (Sandbox Code Playgroud)
这样做的好处是使命令式调用链读起来像声明性 DSL。然而,避开方法的命名约定可能会降低构建器类的源代码的可读性。
上面的示例是使用构建器来构造对象,其中封装状态用于表示所声明的概念。一些面向对象框架进一步减少了这一点,以便代码仅由“细粒度”对象的构造函数组成。在大多数 C 派生语言中,构造函数需要以其关联的类型命名。
在 Flutter 中声明的 UI 小部件树的示例(来自https://flutter.dev/docs/development/ui/widgets-intro#using-material-components):
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.menu),
tooltip: 'Navigation menu',
onPressed: null,
),
title: Text('Example title'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
tooltip: 'Search',
onPressed: null,
),
],
),
// body is the majority of the screen.
body: Center(
child: Text('Hello, world!'),
),
floatingActionButton: FloatingActionButton(
tooltip: 'Add', // used by assistive technologies
child: Icon(Icons.add),
onPressed: null,
),
);
Run Code Online (Sandbox Code Playgroud)