Good Framework Rely on Good Api —— Six API Design Principles

Good Framework Rely on Good Api —— Six API Design Principles

发布于 2018-06-30 11:09 更新于 2018-08-12 08:04

We have S.O.L.I.D principles of object-oriented programming, and we also have Software design patterns to solve general, reusable solution to a commonly occurring problem. But we don’t have public-accepted API design principles or patterns for us to develop better APIs.

But we still have many API designing experiences to conclude some design principals. This post concludes them.


This post is written in multiple languages. Please select yours:

中文 English

The API design principles in this post mostly come from Practical API Design written by Jaroslav Tulach who is the NetBeans founder. I’ve read the whole book but find that most knowledge is his recommendations and are scattered to be in order. So I collect the core API design recommendations into six design principles. Maybe this post will help you to evaluate your Framework and API design quality and help you to write good APIs that gives the user better experience.

What is API?

API is the short of Application programming interface. Wikipedia has a definition for it, but it’s a bit hard to understand. See this link to view the definition: Application programming interface - Wikipedia.

We can simply treat class, interface, Property, Field, Method, and the configuration file or the protocol provided by the library as APIs.

API design principles

Even if you don’t learn anything nor read any books about API design, if you have programmed a few times long, you’ll feel that some APIs are easier to use and others are not. This means that every programmer has more or less API usage experience.

So the principals concluded in this post will help us design better API for our library users.

Easier to understand

Some users want to use a new API and find that they must learn some new knowledge about it to write correct code. The more the user should learn new knowledge the harder the API to understand.

We can follow these tips to help us design easier-to-understand APIs:

  1. Don’t introduce new concept if not necessary.
  2. Prevent the user to use it incorrectly.
    • Make the user cannot write incorrect code. It means you can make the code uncompilable when the user uses it incorrectly.
    • If you find that is hard to make the wrong code uncompilable, you can throw exceptions to warn the user and provide tips for him/her to fix it.
    • You’d better make wrong code ugly at the same time. e.g. Make the IDE display underlines in the wrong code.
    • If you can only warn the user in your documentation, you may tried less. It’s recommended to try more to do the things above.

Moq in .NET foundation is a very good practice for Prevent the user to use it incorrectly. You can install and try it in Moq in nuget.org.

Easier to find

Most of us use IDE to develop and maybe some of us use code editor such as Visual Studio Code, Sublime, Atom, Notepad++ or Vim. Whatever you use to write code, they all have IntelliSense which can help you know more context APIs and write correct API usage code.

If we can find some new API and use it correctly via IntelliSense, we can say that the API is easier to find.

How do we find the APIs via IntelliSense?

  1. When we implement a method which we don’t know anything about its parameters, we can get right values we want from the arguments via the IntelliSense.
  2. When we call a method which we don’t know anything about its parameters, we can fetch and create what it needs via the IntelliSense.
  3. When we call a method whose return value type is unfamiliar for us, we can use the return value correctly via the IntelliSense.

There is a picture below I draw to describe APIs easier or harder to find.

▲ The connection lines indicates that we can know the APIs through the method parameters and the returning value.

Related APIs are more similar

If the similar functions have similar APIs, the API users cost very less to learn the correct usage of the new API.

You may remember the Select method of LINQ. And when you use LINQ to XML to read/write XML files, you’ll find Select method, too. Their usage experiences are very similar so that you can easily know how to use Select in LINQ to XML if you know the LINQ.

Simple task have simple implementation

If you only design your APIs in the recommendation of the three principles above, your classes may be too large so that they may violate the Single Responsibility Principle of S.O.L.I.D. So there is another principle to prevent this being happen. That is, a simple task should have a simple implementation.

InkCanvas of UWP is a good practice of this principal. You can use an InkCanvas To accept inks by writing only a simple line:

<InkCanvas x:Name="inkCanvas" />

You can write more advanced functions by writing more customization code, but all of them are not necessary:

// The code below is from https://docs.microsoft.com/en-us/windows/uwp/design/input/pen-and-stylus-interactions // Set supported inking device types. inkCanvas.InkPresenter.InputDeviceTypes = Windows.UI.Core.CoreInputDeviceTypes.Mouse | Windows.UI.Core.CoreInputDeviceTypes.Pen; // Set initial ink stroke attributes. InkDrawingAttributes drawingAttributes = new InkDrawingAttributes(); drawingAttributes.Color = Windows.UI.Colors.Black; drawingAttributes.IgnorePressure = false; drawingAttributes.FitToCurve = true; inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes);

Easier to test and to be tested

Better API helps the API user easier to test his/her API usage methods.

If you provide an API with a static method such as Config.Get("SomeKey") to retrieve configuration values, the API user will find it hard to write unit test method because he/she cannot create fake configuration.

Easier to keep compatibility even if upgrading frequently

Better APIs cost less for the users to upgrade their library versions and bring less burden for the API developers to make library compatible.

There are three kind of compatibility:

  • Binary compatibility
    • When upgrading the library, the users can run their projects without a recompile.
  • Code compatibility
    • When upgrading the library, the users can recompile their project without any code modification.
  • Behavior compatibility
    • When upgrading the library, the users’ applications run the same as before.

We can follow these tips to help us design better-future-compatibility APIs:

  1. Don’t release your APIs ahead of your whole solution.
    • If you are trying to release an API for the future usage, I recommend you not to do this. Because you don’t know the future needs, the APIs have a very high probability to be changed with a heavy compatibility burden.
  2. Reserve enough extension points.
    • If an API which will have more chance to change in the future has fewer extension points, the API will change more frequently. But if you reserve some designed extension points, future change will be in the control.
  3. Give tips for the users to migrate legacy APIs.
    • If an API is obsolete, you’d better not to delete it immediately. It’s recommended to mark it obsolete and tell the users how to migrate to the new APIs.

Framework design

The framework can be understood as a set of APIs developed for the complete solution of a certain kind of problems.

Avalonia is a cross-platform UI framework and it uses ReactiveUI which is a reactive UI framework to develop MVVM pattern UI.

Hope you’ll design better APIs by reading the six API design principals.


References

  • Practical API Design by Jaroslav Tulach (The NetBeans founder)

本文会经常更新,请阅读原文: https://walterlv.com/post/framework-api-design-en.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏生信技能树

不可不知的基因组版本对应关系

不同版本对应关系 hg19,GRCH37和Ensembl75是三种国际生物信息学数据库资源收集存储单位,即NCBI,UCSC和ENSEMBL各自发布的基因组信息...

435100
来自专栏雨过天晴

原 PHP7.0的编译记录(失败)

25930
来自专栏流柯技术学院

Python WMI获取Windows系统信息 监控系统

15010
来自专栏张善友的专栏

代码转换工具 Code Converter 2013

http://www.codeproject.com/Articles/260997/Code_Converter This is a Code Conver...

23260
来自专栏技术总结

献给移动端的服务器搭建

application.properties这个是项目的一些配置,举例一下默认是8080端口,我们如果想改下端口的话,就可以在配置增加

29420
来自专栏软件开发

Spring MVC 学习总结(十一)——IDEA+Maven+多模块实现SSM框架集成

与SSH(Struts/Spring/Hibernate/)一样,Spring+SpringMVC+MyBatis也有一个简称SSM,Spring实现业务对象管...

33420
来自专栏大大的微笑

深入理解JVM原理之编译openjdk7

Java虚拟机种类很多例如:HotSpot 丶 JRockit 丶 J9等 我们一般用的就是HotSpot,如果我们电脑上装了JDK,可以运行java -ver...

30090
来自专栏技术博文

Linux命令英文全称

su:Swith user  切换用户,切换到root用户 cat: Concatenate  串联 uname: Unix name  系统名称 df: Di...

40550
来自专栏流柯技术学院

Python WMI获取Windows系统信息

13130
来自专栏流柯技术学院

Python WMI获取Windows系统信息

14230

扫码关注云+社区

领取腾讯云代金券