声明式函数命名

Mr.*_*ama 6 language-agnostic declarative naming-conventions

如何命名函数以清楚地反映它们遵循声明性范式

上下文:我最近开始致力于创建以声明方式工作的库,但我很难提出反映它的命名约定。过去,我创建了名称类似于 的命令式函数createThing,但我发现很难在函数名称中简洁地传达“做必要的事情以返回Thing看起来像 ____”的想法。
理想情况下,我想遵循正式的标准或既定的命名约定。否则,我希望至少从预先存在的代码库中找到一些指导。

tim*_*mur 5

鉴于您担心有一个简洁的函数名称,我会研究您的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 的一些东西。这可能会让你达到你正在寻找的美学。

使用这种方法要记住的一件事是,这种链接使其高度线性化,如果您需要绕路定义主要对象,则可能无法很好地工作。

其他几个可以从中汲取灵感的例子:

  1. https://www.entityframeworktutorial.net/efcore/fluent-api-in-entity-framework-core.aspx
  2. https://momentjs.com/docs/
  3. https://jasmine.github.io/tutorials/your_first_suite


Ric*_*ods 3

根据我的经验,声明性框架中的主要函数没有规范的命名方案,但有许多突出的例子可以让您从中汲取灵感。

与 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)