有流畅界面的经验吗?我需要你的意见!

2023-12-23

抱歉这个很长的问题,它被标记为维基百科,因为我要求的东西可能没有非常具体的答案。既然关了,那就这样吧。

我的主要问题是:

如何编写一个在基类中未完全定义的流畅接口,以便使用流畅接口的程序可以在现有结构中添加新单词,并且仍然保持一个引导界面,以便在点之后,智能感知仅列出此时实际适用的关键字。


我正在进行第三次重写 IoC 容器。第二次迭代是为了提高性能,第三次迭代将是为了解决一些可扩展性问题和分离问题。

基本上,可扩展性的问题是不存在。我最近想使用一个有生命周期的服务,在生命周期到期后,解析一个新的副本。例如,每分钟读取一个配置文件,但不要更频繁。我当前的 IoC 解决方案不支持这一点,但添加它的唯一方法是进入基类库并在那里添加对其的支持。这对我来说意味着我未能构建可扩展的类库。平心而论,我并不打算在其中构建可扩展性,但后来我并没有完全意识到稍后添加类似的东西会带来多大的痛苦。

我正在查看流畅的配置界面,因为我也想在界面中构建完整的可扩展性(或者摆脱它,我不愿意这样做),所以我需要以不同的方式做事。

因此,我需要你的意见。我实际上没有使用流畅界面的经验,但我见过很多使用它们的代码,因此有一个开箱即用的明显好处:

  • 使用流畅界面的代码通常非常容易阅读

换句话说,这个:

ServiceContainer.Register<ISomeService>()
    .From.ConcreteType<SomeService>()
    .For.Policy("DEBUG")
    .With.Scope.Container()
    .And.With.Parameters
        .Add<String>("connectionString", "Provider=....")
        .Add<Boolean>("optimizeSql", true);

比这个更容易阅读:

ServiceContainer.Register(typeof(ISomeService), typeof(SomeService),
    "DEBUG", ServiceScope.Container, new Object[] { "Provider=...", true });

所以可读性是一个问题。

然而,程序员指导是另一回事,通过阅读网络上或编辑器中的现有代码很难理解。

基本上,当我输入以下内容时:

ServiceContainer.Register<ISomeService>()
    .From.|
          ^-cursor here

然后智能感知将显示可用的分辨率类型。在我选择了那个之后,写下:

ServiceContainer.Register<ISomeService>()
    .From.ConcreteType<SomeService>()
    .For.|

然后我只能在“For”关键字之后获得可用的内容,例如“Policy”等。

然而,这是一个大问题吗?你用过的流畅界面是这样的吗?定义接口的明显逃避是创建一个类或接口,包含所有关键字和所有内容,以便每个逗号后面的智能感知包含所有内容,但这也可能导致这是合法的(例如,它编译)代码:

ServiceContainer.Register<ISomeService>()
    .From.ConcreteType<SomeService>()
    .From.Delegate(() => new SomeService())
    .From.With.For.Policy("Test");

所以我想构建流畅的界面,以便在您指定之后how要解决某个服务,您不能再这样做。

  • 换句话说,流畅的界面非常易于使用,因为它们会引导您做什么。

但这是典型的吗?因为我希望能够添加一堆这样的关键字,比如解析器的类型(ConcreteType、Delegate 等)、作用域的类型(Factory、Container、Singleton、Cache 等)作为扩展方法,这样程序可以定义自己的方法来执行此操作,而无需进入并更改基类,这意味着我需要为所有中间站点提供接口,并保留实际重要的关键字。然后,这些关键字的实现必须根据需要选择一个中间停止接口来返回。

所以看来我需要定义一个接口:

  • xyz.来自。
  • xyz.From.<Resolver here>.
  • <Resolver here>.With.
  • <Resolver here>.For.

等等,但对我来说这看起来是支离破碎的。

任何有流畅界面经验的人都可以回去阅读我在顶部引用的答案并尝试给我一个简短的答案吗?


两件事:扩展方法和嵌套闭包。它们应该满足您所有的可扩展性和智能感知清晰度需求。


如果您有兴趣,这里有一些我的经验积累中的提示流畅的NHibernate http://fluentnhibernate.org.

方法链接应保持在最低限度。除其他外,它会导致调用链的死胡同和无限期结束。更喜欢嵌套闭包。

例如,死胡同:

Database
  .ConnectionString
    .User("name")
    .Password("xxx")
  .Timeout(100) // not possible

你无法回到Database一旦你进入了链条ConnectionString链,因为没有办法备份所有连接字符串相关的方法返回的实例ConnectionString.

你可以用明确结束的方法重写它,但它们很丑陋。

Database
  .ConnectionString
    .User("name")
    .Pass("xxx")
    .Done()
  .Timeout(100)

在这种情况下,Done将返回Database例如,将您返回到主链。再说一遍,丑。

正如建议的那样,更喜欢嵌套闭包.

Database
  .ConnectionString(cs =>
    cs.User("name");
      .Pass("xxx"))
  .Timeout(100);

这几乎涵盖了您的智能感知问题,因为闭包是相当独立的。您的顶级对象将仅包含采用闭包的方法,并且这些闭包仅包含特定于该操作的方法。这里的可扩展性也很容易,因为您可以将扩展方法添加到闭包内公开的类型。

您还应该注意不要尝试让你的界面读起来像英语一样流畅。 UseThis.And.Do.That.With.This.BecauseOf.That当动词就足够时,链只会使你的界面变得复杂。

Database
  .Using.Driver<DatabaseDriver>()
  .And.Using.Dialect<SQL>()
  .If.IsTrue(someBool)

Versus:

Database
  .Driver<DatabaseDriver>()
  .Dialect<SQL>()
  .If(someBool)

智能感知的可发现性降低了,因为人们倾向于寻找动词却找不到它。 FNH 的一个例子是WithTableName方法,人们倾向于寻找这个词table并没有找到它,因为该方法以with.

对于非英语母语人士来说,您的界面也变得更加难以使用。虽然大多数非母语人士都知道他们要查找的内容的技术术语,但他们可能不清楚额外的单词。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有流畅界面的经验吗?我需要你的意见! 的相关文章

随机推荐

  • Chrome 扩展程序测试

    有人有 Chrome 扩展测试的经验吗 例如 我想创建一个使用的扩展 弹出浏览器操作 并自动执行一个测试用例来检查 单击时弹出窗口的行为 铬问题 http code google com p chromium issues detail i
  • Elixir 中的快速不区分大小写排序

    Elixir 程序员们大家好 我有大约 2 500 首音乐曲目的列表 我想按不同的参数 例如曲目标题 对它们进行排序 排序应不区分大小写 下面的代码可以工作 但需要大约 100 毫秒到 130 毫秒来对列表进行排序 有更快的方法吗 对我来说
  • 以编程方式添加 ARSCNView

    如何以编程方式添加 ARSCNView 如何设置宽度 高度和约束 class ViewController UIViewController var sceneView ARSCNView let configuration ARWorld
  • 由于环境错误而无法安装软件包:[WinError 5] 访问被拒绝:

    我有 Windows 10 我已完成 Tensorflow 安装 有用 它说 你好 Tensorflow 但这一切都在它面前 2018 08 18 18 16 01 500579 I T src github tensorflow tens
  • Django:向 UpdateView 生成的表单字段添加额外属性

    我使用的自定义用户是 Django AbstractUser 的子类 我试图存档的是允许用户更新他们的数据 一切正常 但表单看起来很难看 下面是我的代码 类属性未添加到表单中 forms py 简化 class AccountEditFor
  • Decorator() 得到了意外的关键字参数

    我在 Django 视图上遇到此错误 TypeError at web host 1 decorator got an unexpected keyword argument host id Request Method GET Reque
  • Fabric.js 动画对象/图像

    大家好 这是我一直在使用的代码 它将一个物体从 A 移动到 B 我想做的是让它移动到多个点 所以从起始位置 A gt B 然后从 B gt C 等等 也许有一些包含坐标集的变量 这些坐标将作为参数输入到某些动画函数中 但我尝试的任何操作都只
  • 通过映射减少图像尺寸

    我有一个 png 图像 其中有四种颜色 如果我将图像转换为 numpy 数组 我会得到一个具有以下尺寸的数组 length X height X 3 with length height 如何通过映射颜色来减少维度 这是当前的结构 arra
  • MapView:找不到方法 B 引用的类 A

    屏幕上有3个按钮 开始 查看地图 停止 当我单击 查看地图 时 它应该转到显示地图的新屏幕 但出了点问题 应用程序被强制关闭 我不断收到无法找到方法 B 引用的类 A 错误 拜托请有人纠正它 我已经被这个问题困扰三天了 Main xml
  • typedef std 容器?

    我想做 typedef deque type error use of class template requires template argument list type
  • 编写 Z80 汇编程序 - 词法 ASM 并使用组合构建解析树?

    我对编写汇编器的概念非常陌生 即使在阅读了大量材料之后 我仍然很难理解几个概念 将源文件实际分解为令牌的过程是什么 我相信这个过程称为词法分析 我已经到处搜索有意义的真实代码示例 但我找不到如此简单的代码示例 非常受欢迎 解析时 信息是否需
  • MATLAB 中的复制求和运算符

    我正在尝试在 MATLAB 中对以下时间相关函数进行建模 其中 gamma beta 和 delta 是常数 我不确定进行求和的最佳方法是什么 我可以制作 u t 和 y t 函数句柄 但 symsum 只能用于符号 我唯一的选择是使用 f
  • 浮点差异取决于调试构建的运行方式

    我正在使用调试版本并在同一台计算机上获得不同的结果 无论我是否在调试器下运行 我正在使用优秀的 TestDriven Net 来运行单元测试 使用 TestDriven Net 或外部 NUnit 运行程序 运行 会产生相同的结果 使用 T
  • .NET 日志框架 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Java:解析 ISO_DATE / ISO_OFFSET_DATE

    对于 REST Web 服务 我需要返回带时区的日期 无时间 显然不存在这样的东西ZonedDate在 Java 中 仅LocalDate and ZonedDateTime 所以我用的是ZonedDateTime作为后备 将这些日期转换为
  • 在 ASP 中上传到 IIS 5.1

    首先 我知道 XP 不太擅长托管 但由于该网站仅供我个人使用 而且我已经拥有 XP 许可证 这就是我正在使用的 我正在使用来自的纯asp上传脚本链接文本 http www asp101 com articles jacob scriptup
  • Ubuntu 中的 MySQL JDBC jar 文件在哪里?

    我已经通过安装 MySQL 5 5 32apt get install进入 Ubuntu 13 04 我想在 Java 项目中使用它 为此我必须有 MySql 连接器 jar 我找不到它 我尝试过locate mysql jar但它没有发现
  • Scalaz 中 \/ 的“ap”有什么作用?

    我正在看析取 https github com scalaz scalaz blob scalaz seven core src main scala scalaz Either scalascalaz 的类型和我注意到的方法ap Appl
  • 是否有可能在 SASS 中使用 CSS 变量?

    我有不同的树枝模板 应该用不同的颜色渲染 除了颜色主题之外 每个模板通过 SASS 的样式都是相同的 这就是为什么我想在每个模板中设置一个 CSS 变量 我认为 SASS 变量看起来像这样 pim color var color prima
  • 有流畅界面的经验吗?我需要你的意见!

    抱歉这个很长的问题 它被标记为维基百科 因为我要求的东西可能没有非常具体的答案 既然关了 那就这样吧 我的主要问题是 如何编写一个在基类中未完全定义的流畅接口 以便使用流畅接口的程序可以在现有结构中添加新单词 并且仍然保持一个引导界面 以便