问题标签 [library-design]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 为什么标准类有时会有看似无关的方法?
在研究标准 Java 库及其类时,我不禁注意到其中一些类的方法在我看来与这些类的原因几乎无关。
例如,我正在谈论的方法是Integer#getInteger,它检索某个“系统属性”的值,或者System#arraycopy,其目的由其名称明确定义。尽管如此,这两种方法似乎都有些格格不入,尤其是第一种,它出于某种原因将使用系统资源绑定到原始类型包装类。
从我目前的观点来看,这种方法放置策略似乎违反了基本的 OOP 设计原则:每个类都必须致力于解决其特定的问题集,而不是把自己变成瑞士军刀。但是因为我不认为 Java 设计者是白痴,所以我认为将这些方法放置在它们所在的位置的决定背后有一些逻辑。所以如果有人能解释这个逻辑到底是什么,我将不胜感激。
谢谢!
更新
一些人暗示,Java 确实有一些不合逻辑的东西,它们只是动荡过去的残余。然后我重新提出我的问题:为什么 Java 如此不愿意将其架构缺陷标记为已弃用,因为现有的已弃用功能在任何可观察到的未来都不太可能停止使用,而弃用某些东西确实有助于避免在新的应用中使用它们创建代码?
c++ - 使用单个函数实现复制和移动分配
通常,给定某种类型T
,要实现复制和移动赋值,需要两个函数
最近,我开始意识到一个人就足够了
此版本利用了复制/移动构造函数。分配是复制还是移动取决于如何v
构造。这个版本甚至可能比第一个版本更快,因为按值传递为编译器优化提供了更多空间 [1]。那么,第一个版本比第二个版本甚至标准库都使用它的优势是什么?
[1] 我想这解释了为什么标记和函数对象在标准库中按值传递。
c++ - 为什么 std::vector::max_size() 是非静态的?
由于最大大小不依赖于特定std::vector
对象,我想它应该是一个静态方法。但是,标准原型仍然是非静态的,我不知道为什么。从逻辑上讲,应该在创建任何std::vector
对象之前检查最大大小。
请注意,这个问题与这个基本上是关于constexpr
.
c++ - 关于 C++11 随机分布的接口设计的困惑
让我们举个uniform_int_distribution
例子。在我看来,尽管它存储了一组默认的分布参数,但它实际上是无状态的。这样一来,把它设计成一个函数模板不是更好更方便吗?
很多时候,我发现自己写了类似的东西
或者将其压缩成一行
无论哪种方式,这都让人感觉做作和尴尬。使用函数接口,这可以很自然地完成
如果您愿意,您仍然可以存储一组默认分布参数
我错过了什么吗?
c++ - 给定一个抽象接口。需要提供自己的实现的唯一线索在于没有找到工厂函数?
诚然,一个相当理论的问题。
我想更多地从图书馆设计师的角度来问它,而不是图书馆用户。尽管目标是为用户提供最简单的设计。
是否有任何关于如何传达给定界面应该由用户始终实现的指导方针/最佳实践?或者某个地方提供了工厂函数,创建了实现该接口的合理对象?
当然,在几乎所有情况下,这都应该从上下文中清楚地看出。另一个期望这样一个接口作为参数的库函数可以不言自明地从哪里得到它。因为它只是某个链条中的一个环节。但我希望你们中的一些人能够想象一个不再那么容易理解的相当进化的系统或库。
关于在某个地方是否有一些工厂功能或用户是否总是需要提供自己的实现的基本问题,如何防止对接口的理解变得越来越困难?
答案是否存在于注释、文档或代码中?
我只是猜测工厂函数应该总是在接口附近声明。如果没有,就没有。但我不知道这是不是太软的指导方针,或者可能无论如何都无法始终实现。
scala - Scala 库设计:可以使用静态工厂方法创建对象吗?
我在 Scala 中创建了一个库。它是一个带有不同实现的解析器。从所有事物中抽象出来的特征看起来像这样(简化):
库提供的具体解析器实现扩展了上面的特征(没什么了不起的)。
因为我不希望客户端依赖于具体的实现类(我什至考虑过将它们封装为私有),所以我使用了一个特征的伴随对象,它提供对解析器的访问而不暴露它们的类型:
如果愿意,用户还应该能够使用他们自己的Parser
trait 实现。
但是,我不确定这是否是最好的方法。
- 这种方法有什么普遍的缺点吗?
- 使用访问修饰符隐藏这两个实现怎么样?从客户的角度来看,是否有理由访问实施?
您可能认为这些是关于松散耦合和抽象的非常基本的问题。情况不一定如此,我自己一直在使用依赖注入框架和类似的东西。然而; 我以前从未发布过库,并且发现很难提供每个人都可以灵活使用而又不复杂的东西。
scala - 在scala中使用ad-hoc多态性时我应该创建一个额外的类型吗?
我目前正在使用 Scala 中的临时多态性编写一些代码。
例如,我的一个类Stream[Boolean]
使用方法扩展了 a:
现在到目前为止这很好,但是当流被打印时(例如通过 specs2),它将打印整个流,如果它已经被评估过,则会向控制台的输出发送垃圾邮件。
现在我正在尝试覆盖 toString,但我想我必须为包含 Stream 的类创建一个额外的类,如下所示:
这具有很好的效果,即也使用 Stream[Boolean] 的库用户不会意外调用我的方法之一。不利的一面是,每当我使用实际的流时,我都必须在对象上调用 unwrap,这会使代码相当混乱。
我认为我的选择是:
- 教 specs2 使用猫的 Show[T] 而不是使用 toString - 可能吗?我已经看到有一个包specs2-cats - 但我似乎无法为 scala 2.12 找到它。
- 如上所述,在每次使用流时使用 unwrap
您认为以上哪个选项最适合我的情况?
非选项:
- 从 Stream 扩展我自己的课程 - 有充分的理由将其密封
- 编写流映射的所有方法来解包 - IMO 工作量太大
python - Python api 设计,添加复制方法到对象或推迟到复制库
我有一个图书馆(pymunk)正在维护。我应该在所有相关类上添加自己的copy()
方法,还是让库的用户在需要副本时使用标准库的 copy.deepcopy 方法?
最近,一位用户询问了一种复制世界对象的方法。当时图书馆不支持任何方式来做到这一点。但是,现在我添加了对 pickle 的支持,因此 copy.deepcopy 会自动工作。
问题是最好对库提供的对象使用复制方法,还是只遵循标准库中的 copy.deepcopy。其他一些库提供了自己的复制方法,例如 numpy 数组复制和 pandas 数据帧复制。
添加额外的复制方法并不是很复杂,因为我可以调用 deepcopy,如下所示:
我关心的是清晰度和易用性。(python zen“应该有一种——最好只有一种——明显的方法。”)
c++ - `gsl::string_span` 的目的是什么?
在阅读Microsoft 的 Cpp Core Guidelines 实施过程中,我遇到了两个问题:
- 为什么
gsl::string_span
在gsl::span
已经运行良好的地方提供? - 为什么
gsl::zstring_span
提供std::string
自 C++11 以来已经保证为空终止的位置?
任何说明情况都将受到高度赞赏。
c++14 - 现代 C++ 中的稀疏矩阵设计
我想使用现代 c++ 即 14 或 17 实现一个稀疏矩阵类。我知道在存储和运行时效率之间必须进行一些权衡。现在我更喜欢在存储效率方面进行更多优化。如果可能的话,我希望在编译时而不是运行时完成更多的工作。例如,vector 确实有很多运行时检查,因此它可能不是最优的。有人可以为此建议一个容器吗?我计划支持以下操作:
谢谢!