Upload
prabhat-gangwar
View
431
Download
0
Embed Size (px)
Citation preview
API Design
APIApplication Programming InterfaceSource code interfaceFor library or OSProvides services to a program
At its base, like a header fileBut, more complete
Why is API Design Important?
Company ViewCan be asset – big user investment in
learning and usingBad design can be source of long-term
support problemsOnce used, it’s tough to changeEspecially if there are several users
Public APIs – One chance to get it right
Characteristics of Good APIs
Easy to learnEasy to use even without documentationHard to misuseEasy to read and maintain code that uses itSufficiently powerful to satisfy requirementsEasy to extendAppropriate to audience
Designing an APIGather requirements Don’t gather solutions Extract true requirements Collect specific scenarios where it will be used
Create short specification Consult with users to see whether it works Flesh it out over time
Hints: Write plugins/use examples before fully designed and
implemented Expect it to evolve
Broad Issues to Consider in Design
1. Interface The classes, methods, parameters, names
2. Resource Management How is memory, other resources dealt with
3. Error Handling What errors are caught and what is done
Information Hiding How much detail is exposed Impacts all three of the above
1. Interface PrinciplesSimpleGeneralRegularPredictableRobustAdaptable
SimpleUsers have to understand!Do one thing and do it well Functionality should be easy to explain
As small as possible, but never smaller Conceptual weight more important than providing
all functionality Avoid long parameter lists
Choose small set of orthogonal primitives Don’t provide 3 ways to do the same thing
GeneralImplementation can change, API can’tHide Information! Don’t let implementation detail leak into API Minimize accessibility (e.g. private classes and
members) Implementation details can confuse users
Be aware of what is implementation Don’t overspecify behavior of modules Tuning parameters are suspect
RegularDo the same thing the same way everywhere Related things should be achieved by related means
Consistent parameter ordering, required inputs Functionality (return types, errors, resource management)
Names matter Self explanatory Consistent across API
Same word means same thing in API Same naming style used Consistent with related interfaces outside the API
PredictableDon’t violate the principle of Least AstonishmentUser should not be surprised by behaviorEven if this costs performance
Don’t reach behind the user’s backAccessing and modifying global variablesSecret files or information writtenBe careful about static variables
PredictableTry to minimize use of other interfacesMake as self-contained as possibleBe explicit about external services required
Document!Every class, method, interface, constructor,
parameter, exceptionWhen states are kept, this should be very
clearly documented
RobustAble to deal with unexpected inputError Handling (see later)
AdaptableAPI can be extended, but never shortenedHeavily used APIs likely will be extended
Information Hiding Implementation details should not affect
API
2. Resource ManagementDetermine which side is responsible for Initialization Maintaining state Sharing and copying Cleaning up
Various resources Memory Files Global variables
Resource ManagementGenerally, free resources where they were allocatedReturn references or copies? Can have huge performance and ease of use impact
Multi-threaded code makes this especially critical Reentrant: works regardless of number of
simultaneous executions Avoid using anything (globals, static locals, other
modifications) that others could also use Locks can be important
3. Error HandlingCatch errors, don’t ignore them“Print message and fail” is not always good Especially in APIs Need to allow programs to recover or save data
Detect at low level, but handle at high level Generally, error should be handled by calling
routine The callee can leave things in a “nice” state for
recovery, though Keep things usable in case the caller can recover
Fail FastReport as soon as an error occursSometimes even at compile time!Use of static types, generics
Error ManagementReturn values Should be in form the calling function can use Return as much useful information as possible Sentinel values only work if function cannot return all
possible values of that type Define pairs, or return another parameter to indicate
errorsUse error “wrapper function” if needed Consistent way of marking, reporting error status Encourages use But, can add complexity
ExceptionsGenerally indicate a programming errorProgramming construct Set exception value (e.g. as return) Other program operation when exception thrown Exceptions usually in global registry
Include information about failure For repair and debugging
Exceptions should generally be unchecked Automatically process globally, rather than require
explicit checks over and over
ExceptionsOnly use in truly exceptional situationsNever use as a control structureThe modern GOTO
Never use exceptions for expected return valuese.g. Invalid file name passed to library is
“common”, not an exception