我问this question有关Microsoft .NET库及其源代码的复杂性。从我正在阅读的内容来看,编写通用库和编写应用程序可能是两回事。在编写库时,您必须考虑可以成为每个人的客户端(假设我发布库以供普通公众使用)。
学习编写图书馆时,哪种做法或理论或技术有用?你在哪里学习编写像.NET库中的代码?这看起来像一个我不太了解的“黑色艺术”。
答案 0 :(得分:9)
这是一个非常主观的问题,但这是客观答案。 Framework Design Guidelines书(一定要获得第2版)是一本关于如何编写有效类库的非常好的书。内容非常好,经常不同的注释是发人深省的。每个商店都应该有这本书的副本。
答案 1 :(得分:6)
你肯定需要在他的演讲中How to Design a Good API & Why it Matters(1小时9米长)观看Josh Bloch。他是一名Java大师,但图书馆设计和面向对象是普遍的。
答案 2 :(得分:5)
图书馆作者经常忽略的一条建议是将成本内部化。如果有些事情很难做,那么图书馆应该这样做。我经常看到图书馆的作者向API的消费者推送一些东西,而不是自己解决它。相反,寻找最难的事情,并确保图书馆能够做到这些,或者至少让它们变得非常简单。
答案 3 :(得分:4)
我将由Scott Meyers从Effective C++解释,我发现这是我得到的最佳建议:
坚持最不惊讶的原则:努力提供其运算符和函数具有自然语法和直观语义的类。保持与内置类型行为的一致性:如果有疑问,请按照内注进行操作。
认识到任何人都可以做的事情,他们会这样做。他们会抛出异常,他们会将对象分配给自己,他们会在给出值之前使用对象,他们会给对象值而不会使用它们,它们会给它们巨大的值,它们会给它们很小的值,他们会给他们空值。一般来说,如果它会编译,有人会这样做。因此,使您的课程易于正确使用且难以正确使用。接受客户端会犯错误,并设计您的类,以便您可以预防,检测或纠正此类错误。
争取可移植代码。编写可移植程序并不比编写不可移植的程序困难得多,而且性能上的差异很小,足以证明不可移植的构造的合理性。
即使是为自定义硬件设计的程序也经常最终被移植,因为库存硬件通常会在几年内达到相同的性能水平。编写可移植代码可以让您轻松切换平台,扩大客户群,并吹嘘支持开放系统。如果您在操作系统抽奖活动中打赌错误,它也可以更容易恢复。
设计代码,以便在需要更改时,影响已本地化。尽可能多地封装;将实施细节设为私有。
答案 4 :(得分:4)
修改:我刚注意到我非常重复what cherouvim had posted;对于那个很抱歉!但事实证明,即使主题完全相同,布洛赫也会链接到不同的演讲。 (cherouvim与2005年12月的一次谈话有关,我到2007年1月一次。)好吧,我会在这里留下这个答案 - 你可能最好看看两个并看看他的信息和方式如何呈现它已经发展了:))
FWIW,我想指出Joshua Bloch的Google Tech Talk,他是Java世界备受尊敬的人,也是一位发表过演讲并撰写有关API设计的人。 (哦,设计了一些非常好的通用库,比如Java Collections Framework!)
Joshua Bloch,Google Tech Talks,2007年1月24日:
“How To Design A Good API and Why it Matters”(视频大约1小时)
您还可以在他的文章Bumper-Sticker API Design中阅读许多相同的想法(但我仍然建议您观看演示文稿!)
(看到你来自.NET方面,我希望你不要让他的Java背景太过分了:-)这真的是而不是 Java特定的大部分。)
编辑:这是乔什布洛赫的另一个1½ minute bit of wisdom关于为什么写图书馆很难,以及为什么它仍然值得投入其中(规模经济) - 回答一个问题,基本上,“有多难是真的吗”。 (关于Google Collections库的演示文稿的一部分,这也是值得关注的,但更多以Java为中心。)
答案 5 :(得分:2)
Krzysztof Cwalina的博客是一个很好的起点。他的书“框架设计指南:可重用.NET库的约定,习惯和模式”可能是.NET库设计最佳实践的权威性工作。
答案 6 :(得分:2)
最重要的规则是将API设计视为UI设计:收集有关用户如何真正使用UI / API的信息,他们认为有用的内容以及阻碍他们前进的方式。使用该信息来改进设计。从能够忍受API流失的用户开始,逐渐稳定API。
我在这里写了一些关于API设计的知识:http://www.natpryce.com/articles/000732.html
答案 7 :(得分:0)
我开始更多地关注设计模式。你可能不会对它们中的一些有太多用处,但随着你对图书馆设计的深入了解,模式将变得更加适用。我还要拿一份NDepend - 一个很棒的代码测量实用程序,它可以帮助你更好地分解事物。您可以使用.NET库作为示例,但就个人而言,我认为它们不是很好的设计示例,主要是因为它们的复杂性。此外,开始查看一些开源项目,看看它们是如何分层和结构化的。
答案 8 :(得分:0)
几个不同的观点:
.NET Framework不是类库。这是一个框架。它是一组类型,不仅意味着提供功能,还可以通过您自己的代码进行扩展。例如,它确实为您提供了Stream
抽象类,并提供了类似NetworkStream
类的具体实现,但它还为您提供了WebRequest
类以及扩展它的方法,因此WebRequest.Create("myschema://host/more")
可以生成自己的类的实例,该实例派生自WebRequest
,它可以拥有自己的GetResponse
方法,返回自己派生自WebResponse
的类,这样就可以调用GetResponseStream
1}}将返回从Stream
派生的自己的类!
你的来电者不需要知道幕后会发生这种情况!
另一点是,对于大多数开发人员来说,创建可重用的库不是,也不应该是目标。目标应该是编写满足要求所需的代码。在此过程中,可以找到可重用的代码。在这种情况下,它应该重构为一个单独的库,以便将来可以重用。
我走得更远(如果允许的话)。我通常会等到找到两段实际上做同样事情或重叠的代码。据推测,这两段代码都通过了所有的单元测试。然后,我将公共代码分解为一个单独的类库,并再次运行所有单元测试。假设它们仍然通过,我已经开始创建一些可用的可重用代码(因为单元测试仍然通过)。
这与我在学校学到的课程形成对比,当时整个项目的结果是一个漂亮的可重用库 - 没有代码可以重复使用它。
(当然,如果任何代码 使用它,我相信它会有效...)