Principles of Software Construction: Objects, Design, and ...charlie/courses/17-214/... · Why is API design important? • A good API is a joy to use; a bad API is a nightmare •
Post on 25-Mar-2020
2 Views
Preview:
Transcript
117-214
PrinciplesofSoftwareConstruction:Objects,Design,andConcurrency
APIDesign1:processandnaming
JoshBlochCharlieGarrod
217-214
Administrivia
• Homework4bdueToday(11:59PM)• Springbreaknextweek– enjoy!
317-214
Review:libraries,frameworksbothdefineAPIs
Library
Framework
public MyWidget extends JContainer {
ublic MyWidget(int param) {/ setup internals, without rendering}
/ render component on first view and resizingprotected void paintComponent(Graphics g) {// draw a red box on his componentDimension d = getSize();g.setColor(Color.red);g.drawRect(0, 0, d.getWidth(), d.getHeight()); }}
public MyWidget extends JContainer {
ublic MyWidget(int param) {/ setup internals, without rendering}
/ render component on first view and resizingprotected void paintComponent(Graphics g) {// draw a red box on his componentDimension d = getSize();g.setColor(Color.red);g.drawRect(0, 0, d.getWidth(), d.getHeight()); }}
your code
your code
API
API
417-214
Today’stopic:APIDesignReview:whatisanAPI?
• ShortforApplicationProgrammingInterface• Componentspecificationintermsofoperations,inputs,&outputs– Definesasetoffunctionalitiesindependentofimplementation
• Allowsimplementationtovarywithoutcompromisingclients• Definescomponentboundariesinaprogrammaticsystem• Apublic APIisonedesignedforusebyothers
517-214
ExponentialgrowthinthepowerofAPIs
’50s-’60s– Arithmetic.Entirelibrarywas10-20calls!
’70s– malloc,bsearch,qsort,rnd,I/O,systemcalls,formatting,earlydatabases
’80s– GUIs,desktoppublishing,relationaldatabases
’90s– Networking,multithreading
’00s– Datastructures(!),higher-levelabstractions,WebAPIs:socialmedia,cloudinfrastructure
’10s– Machinelearning,IOT,prettymucheverything
This list is approximate and incomplete, but it tells a story
617-214
WhatthedramaticgrowthinAPIshasdoneforus
• Enabledcodereuseonagrandscale• Increasedthelevelofabstractiondramatically• Asingleprogrammercanquicklydothingsthatwouldhave
takenmonthsforateam• Whatwaspreviouslyimpossibleisnowroutine• APIshavegivenussuper-powers
717-214
WhyisAPIdesignimportant?
• AgoodAPIisajoytouse;abadAPIisanightmare• APIscanbeamongyourgreatestassets
– Usersinvestheavily:acquiring,writing,learning– Costtostop usinganAPIcanbeprohibitive– SuccessfulpublicAPIscaptureusers
• APIscanalsobeamongyourgreatestliabilities– BadAPIcancauseunendingstreamofsupportrequests– Caninhibitabilitytomoveforward
• PublicAPIsareforever– onechancetogetitright
817-214
WhyisAPIdesignimportanttoyou?
• Ifyouprogram,youareanAPIdesigner– Goodcodeismodular– eachmodulehasanAPI
• Usefulmodulestendtogetreused– Goodreusablemodulesareanasset– Oncemodulehasusers,can’tchangeAPIatwill
• ThinkingintermsofAPIsimprovescodequality
917-214
CharacteristicsofagoodAPI
• Easytolearn• Easytouse,evenwithoutdocumentation• Hardtomisuse• Easytoreadandmaintaincodethatusesit• Sufficientlypowerfultosatisfyrequirements• Easytoevolve• Appropriatetoaudience
1017-214
Outline
• TheProcessofAPIDesign• Naming• Documentation
1117-214
Gatherrequirements–skeptically
• Oftenyou’llgetproposedsolutionsinstead– Bettersolutionsmayexist
• Yourjobistoextracttruerequirements– Shouldtaketheformofuse-cases
• Canbeeasier&morerewardingtobuildmoregeneralAPI
Whattheysay:“WeneednewdatastructuresandRPCswiththeVersion2attributes”
Whattheymean:“Weneedanewdataformatthataccommodatesevolutionofattributes”
1217-214
Anoftenoverlookedpartofrequirementsgathering
• AskyourselfiftheAPIshould bedesigned• Hereareseveralgoodreasonsnot todesignit
– It’ssuperfluous– It’simpossible– It’sunethical– Therequirementsaretoovague
• Ifanyofthesethingsaretrue,now isthetimetoraiseredflag• Iftheproblemcan’tbefixed,failfast!
– Thelongeryouwait,themorecostlythefailure
1317-214
Startwithshortspec– 1pageisideal
• Atthisstage,agilitytrumpscompleteness• Bouncespecoffasmanypeopleaspossible
– Listentotheirinputandtakeitseriously
• Ifyoukeepthespecshort,it’seasytomodify• Fleshitoutasyougainconfidence
1417-214
SampleearlyAPIdraft
// A collection of elements (root of the collection hierarchy)public interface Collection<E> {
// Ensures that collection contains oboolean add(E o);
// Removes an instance of o from collection, if presentboolean remove(Object o);
// Returns true iff collection contains oboolean contains(Object o) ;
// Returns number of elements in collectionint size() ;
// Returns true if collection is emptyboolean isEmpty();
... // Remainder omitted}
1517-214
WritetoyourAPIearlyandoften
• Startbefore you’veimplementedtheAPI– Savesyoudoingimplementationyou'llthrowaway
• Startbefore you’veevenspecifieditproperly– Savesyoufromwritingspecsyou'llthrowaway
• ContinuewritingtoAPIasyoufleshitout– Preventsnastysurprisesrightbeforeyouship
• Codelivesonasexamples,unittests– Amongthemostimportantcodeyou’lleverwrite– FormsthebasisofDesignFragments[Fairbanks,Garlan,&Scherlis,OOPSLA‘06,P.75]
1617-214
TryAPIonatleast3usecasesbeforerelease
• Ifyouwriteone,itprobablywon’tsupportanother• Ifyouwritetwo,itwillsupportmorewithdifficulty• Ifyouwritethree,itwillprobablyworkfine• Ideally,getdifferentpeopletowritetheusecases
– Thiswilltestdocumentation&giveyoudifferentperspectives• Thisisevenmoreimportantforplug-inAPIs• TedBiggerstaffcalledthisthe“RuleofThree”
1717-214
Maintainrealisticexpectations
• MostAPIdesignsareover-constrained– Youwon'tbeabletopleaseeveryone– don’ttry!– Comeupwithaunified,coherentdesignthatrepresentsacompromise– Itcanbehardtodecidewhich“requirements”areimportant
• Expecttomakemistakes– Real-worldusewillflushthemout– ExpecttoevolveAPI
1817-214
Issuetracking
• Throughoutprocess,maintainalistofdesignissues– Individualdecisionssuchaswhatinputformattoaccept
• Writedownalltheoptions• Saywhichwereruledoutandwhy• Whenyoudecide,saywhichwaschosenandwhy
• Preventswastingtimeonsolvedissues• ProvidesrationalefortheresultingAPI
– Remindsitscreators– Enlightensitsusers
1917-214
Keydesignartifacts
1. Requirementsdocument2. Issueslist3. Use-casecode
Maintainthroughoutdesignandretainwhendone– Theyguidethedesignprocess– WhenAPIisdone,they’rethebasisofthedesignrationale
• Publicexplanationfordesign• Foranexample,see
https://docs.oracle.com/javase/8/docs/technotes/guides/collections/designfaq.html
2017-214
Disclaimer– onesizedoesnotfitall
• Thisprocesshasworkedforme• Othersdevelopedsimilarprocessesindependently• ButI’msurethereareotherwaystodoit• ThesmallertheAPI,thelessprocessyouneed
2117-214
TheprocessofAPIdesign– SummaryNot sequential; if you discover shortcomings, iterate!
1. Gatherrequirementsskeptically,includingusecases2. Chooseanabstraction(model)thatappearstoaddressuse
cases3. ComposeashortAPIsketchforabstraction4. ApplyAPIsketchtousecasestoseeifitworks
– Ifnot,fixAPIsketch,orgobacktostep3,2,oreven1.
5. ShowAPItoanyonewhowilllookatit6. WriteprototypeimplementationofAPI7. Fleshoutthedocumentation&hardenimplementation8. Keeprefiningitaslongasyoucan
2217-214
Puzzler:“BigTrouble”
public static void main(String [] args) {BigInteger fiveThousand = new BigInteger("5000");BigInteger fiftyThousand = new BigInteger("50000");BigInteger fiveHundredThousand = new BigInteger("500000");
BigInteger total = BigInteger.ZERO;total.add(fiveThousand);total.add(fiftyThousand);total.add(fiveHundredThousand);
System.out.println(total);}
2317-214
WhatDoesItPrint?
public static void main(String [] args) {BigInteger fiveThousand = new BigInteger("5000");BigInteger fiftyThousand = new BigInteger("50000");BigInteger fiveHundredThousand = new BigInteger("500000");
BigInteger total = BigInteger.ZERO;total.add(fiveThousand);total.add(fiftyThousand);total.add(fiveHundredThousand);
System.out.println(total);}
(a) 0(b) 500000(c) 555000(d) Other
2417-214
(a)0(b)500000(c)555000(d)Itvaries
BigInteger isimmutable!
WhatDoesItPrint?
2517-214
AnotherLook
public static void main(String [] args) {BigInteger fiveThousand = new BigInteger("5000");BigInteger fiftyThousand = new BigInteger("50000");BigInteger fiveHundredThousand = new BigInteger("500000");
BigInteger total = BigInteger.ZERO;total.add(fiveThousand); // Ignores resulttotal.add(fiftyThousand); // Ignores resulttotal.add(fiveHundredThousand); // Ignores result
System.out.println(total);}
2617-214
Howdoyoufixit?
public static void main(String [] args) {BigInteger fiveThousand = new BigInteger("5000");BigInteger fiftyThousand = new BigInteger("50000");BigInteger fiveHundredThousand = new BigInteger("500000");
BigInteger total = BigInteger.ZERO;total = total.add(fiveThousand);total = total.add(fiftyThousand);total = total.add(fiveHundredThousand);
System.out.println(total);} Prints 555000
2717-214
Themoral
• BlametheAPIdesigner– (Infairness,thiswasmyfirstOOAPI,1996)
• Nameslikeadd,subtract,negate suggestmutation• Betternames:plus,minus,negation• Generally(andloosely)speaking:
– Actionverbsformutation– Prepositions,linkingverbs,nouns,oradjectivesforpurefunctions
• Namesareimportant!
2817-214
Outline
• TheProcessofAPIDesign• Naming• Documentation
2917-214
NamesMatter– APIisalittlelanguage
• Primarygoals– Clientcodeshouldreadlikeprose(“easytoread”)– Clientcodeshouldmeanwhatitsays (“hardtomisread”)– Clientcodeshouldflownaturally(“easytowrite”)
• Tothatend,namesshould:– belargelyself-explanatory– leverageexistingknowledge– interactharmoniouslywithlanguageandeachother
NamingisperhapsthesinglemostimportantfactorinAPIusability
3017-214
Theeasypart:typographicalnamingconventions
• Packageormodule– org.junit.jupiter.api,com.google.common.collect
• ClassorInterface– Stream,FutureTask,LinkedHashMap,HttpClient
• MethodorField– remove,groupingBy,getCrc• Parameter– numerator,modulus• ConstantField– MIN_VALUE,NEGATIVE_INFINITY• TypeParameter– T,E,K,V,X,R,U,V,T1,T2
Thelanguagespecificationdemandsthatyoufollowthese
3117-214
Howtochoosenamesthatareeasytoread&write
• Choosekeynounscarefully!– Relatedtofindinggoodabstractions,whichcanbehard– Ifyoucan’t findagoodname,it’sgenerallyabadsign
• Ifyougetthekeynounsright,othernouns,verbs,andprepositionstendtochoosethemselves
• Namescanbeliteralormetaphorical– Literalnameshaveliteralassociations
• e.g.,Matrix→inverse,determinant,eigenvalue,etc.– Metaphoricalnamesenablereasoningbyanalogy
• e.g.,Publication,Subscriber→publish,subscribe,cancel,issue,issueNumber,circulation,etc.
3217-214
Anotherwaynamesdrivedevelopment
• NamesmayremindyouofanotherAPI• Considercopying itsvocabularyandstructure• PeoplewhoknowotherAPIwillhaveaneasytimelearningyours• Youmaybeabletodevelopitmorequickly• YoumaybeabletousetypesfromtheotherAPI• Youmayevenbeabletoshareimplementation
3317-214
Namesdrivedevelopment,forbetterorworse
• Goodnamesdrivegooddevelopment• Badnamesinhibitgooddevelopment• BadnamesresultinbadAPIsunlessyoutakeaction• TheAPItalksbacktoyou.Listen!
3417-214
Vocabularyconsistency
• UsewordsconsistentlythroughoutyourAPI– Neverusethesamewordformultiplemeanings– Neverusemultiplewordsforthesamemeaning– i.e.,wordsshouldbeisomorphictomeanings
3517-214
Vocabularyconsistencyasitrelatestoscope
• Thetighterthescope,themoreimportantisconsistency– WithinAPIs,consistencyiscritical– InrelatedAPIsonaplatform,it’shighlydesirable– Acrosstheplatform,it’sdesirable– Betweenplatforms,it’snice-to-have
• Ifforcedtochoosebetweenlocal&platformconsistency,chooselocal• Butlooktoplatformlibrariesforvocabulary
– Ignoringobsoleteandunpopularlibraries
• Finally,looktosimilarAPIsonotherplatformsfornamingideas
APIsareactuallylittlelanguageextensions
3617-214
Avoidabbreviationsexceptwherecustomary
• Backintheday,storagewasscarce&peopleabbreviatedeverything– Somecontinuetodothisbyforceofhabitortradition
• Ideally,usecompletewords• Butsometimes,namesjustgettoolong
– Ifyoumustabbreviate,doittastefully– Noexcuseforcrypticabbreviations
• Ofcourseyoushouldusegcd,Url,cos,mba,etc.
3717-214
Grammarisapartofnamingtoo
• Nounsforclasses– BigInteger,PriorityQueue
• Nounsoradjectivesforinterfaces– Collection,Comparable
• Nouns,linkingverbsorprepositionsfornon-mutativemethods– size,isEmpty,plus
• Actionverbsformutativemethods– put,add,clear
• Ifyoufollowthese,theyquicklybecomesecondnature
3817-214
Namesshouldberegular– striveforsymmetry
• IfAPIhas2verbsand2nouns,supportall4combinations– Unlessyouhaveaverygoodreasonnotto
• Programmerswilltrytouseall4combinations– Theywillgetupsetiftheonetheywantismissing
• Inotherwords,goodAPIsaregenerallyorthogonal
addRow removeRowaddColumn removeColumn
3917-214
Don’tmisleadyouruser
• Nameshaveimplications– LearnthemandupholdtheminyourAPIs
• Don’tviolatetheprincipleofleastastonishment• Ignorethisadviceatyourownperil
– Cancauseunendingstreamofsubtlebugs
public static boolean interrupted()
Testswhetherthecurrentthreadhasbeeninterrupted.Theinterruptedstatusofthethreadisclearedbythismethod....
4017-214
Don’tlietoyouruser
• Namemethodforwhatitdoes,notwhatyouwishitdid• Ifyoucan’tbringyourselftodothis,fixthemethod!• Again,ignorethisatyourownperil
public long skip(long n) throws IOException
Skipsoveranddiscardsn bytesofdatafromthisinputstream.Theskipmethodmay,foravarietyofreasons,endupskippingoversomesmallernumberofbytes,possibly0. Thismayresultfromanyofanumberofconditions;reachingendoffilebefore n byteshavebeenskippedisonlyonepossibility.Theactualnumberofbytesskippedisreturned…
4117-214
Goodnamingtakestime,butit’sworthit
• Don’tbeafraidtospendhoursonit;Ido.– AndIstillgetthenameswrongsometimes
• Discussnameswithcolleagues;itreallyhelps.
4217-214
Lecturesummary
• APIstookoffinthepastthirtyyears,andgaveussuper-powers• GoodAPIsareablessing;badones,acurse• FollowinganAPIdesignprocessgreatlyimprovesAPIquality• NamingiscriticaltoAPIusability
4317-214
Tobecontinued…
top related