发布于 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:
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.
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
interface, Property, Field, Method, and the configuration file or the protocol provided by the library as APIs.
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.
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:
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.
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?
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.
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.
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);
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.
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:
We can follow these tips to help us design better-future-compatibility APIs:
The framework can be understood as a set of APIs developed for the complete solution of a certain kind of problems.
Hope you’ll design better APIs by reading the six API design principals.
本文会经常更新，请阅读原文： https://walterlv.com/post/framework-api-design-en.html ，以避免陈旧错误知识的误导，同时有更好的阅读体验。