53
1 15-214 School of Computer Science Principles of Software Construction: How to Design a Good API and Why it Matters Josh Bloch Charlie Garrod

Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

115-214

SchoolofComputerScience

PrinciplesofSoftwareConstruction:HowtoDesignaGoodAPIandWhyitMatters

JoshBloch CharlieGarrod

Page 2: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

215-214

Administrivia

• Homework4bduenextThursday• HW4afeedbackavailableafterclass

Page 3: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

315-214

KeyconceptsfromTuesday…

• Multiplethreadsruninsameprogramconcurrently– Canimprovestyleandperformance– Butyoumustavoidsharedmutablestate…– Orsynchronizeproperly

• GUIprogrammingasimplecaseofmultithreading– EventdispatchthreadhandlesallGUIevents– Swingcallsmustbeon EDT– Time-consuming(non-Swing)mustbeoffEDT

Page 4: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

415-214

Today’stopicAPIDesignWhatisanAPI?• ShortforApplicationProgrammingInterface• Acomponentspecificationintermsofitsoperations,theirinputs,andtheiroutputs– Definesasetoffunctionalitiesindependentofimplementation– Allowsimplementationtovarywithoutcompromisingclients

• Definesboundarybetweencomponentsinaprogrammaticsystem– Intermodular boundary

• Apublic APIisonedesignedforusebyothers

Page 5: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

515-214

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

Page 6: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

615-214

WhyisAPIdesignimportant?

• APIscanbeamongyourgreatestassets– Usersinvestheavily:acquiring,writing,learning– Costtostop usinganAPIcanbeprohibitive– SuccessfulpublicAPIscaptureusers

• Canalsobeamongyourgreatestliabilities– BadAPIcancauseunendingstreamofsupportcalls– Caninhibitabilitytomoveforward

• PublicAPIsareforever– onechancetogetitright

Page 7: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

715-214

WhyisAPIdesignimportanttoyou?

• Ifyouprogram,youareanAPIdesigner– Goodcodeismodular– eachmodulehasanAPI

• Usefulmodulestendtogetreused– Goodreusablemodulesareanasset– Oncemodulehasusers,can’tchangeAPIatwill

• ThinkingintermsofAPIsimprovescodequality

Page 8: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

815-214

CharacteristicsofagoodAPI

• Easytolearn• Easytouse,evenwithoutdocumentation• Hardtomisuse• Easytoreadandmaintaincodethatusesit• Sufficientlypowerfultosatisfyrequirements• Easytoevolve• Appropriatetoaudience

Page 9: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

915-214

Outline

• TheProcessofAPIDesign• GeneralPrinciples• ClassDesign• MethodDesign• ExceptionDesign

Page 10: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

1015-214

Gatherrequirements–skeptically

• Oftenyou'llgetproposedsolutionsinstead– Bettersolutionsmayexist

• Yourjobistoextracttruerequirements– Shouldtaketheformofuse-cases

• Canbeeasier&morerewardingtobuildmoregeneralAPI

Whattheysay:“WeneednewdatastructuresandRPCswiththeVersion2attributes”

Whattheymean:“Weneedanewdataformatthataccommodatesevolutionofattributes”

Page 11: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

1115-214

Startwithshortspec– 1pageisideal

• Atthisstage,agilitytrumpscompleteness• Bouncespecoffasmanypeopleaspossible– Listentotheirinputandtakeitseriously

• Ifyoukeepthespecshort,it’seasytomodify• Fleshitoutasyougainconfidence

Page 12: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

1215-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}

Page 13: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

1315-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]

Page 14: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

1415-214

Write3implementationsofeachabstractclassorinterfacebeforerelease• Ifyouwrite1,itprobablywon’tsupportanother• Ifyouwrite2,itwillsupportmorewithdifficulty• Ifyouwrite3,itwillworkfine• WillTraczcallsthis“TheRuleofThrees• ConfessionsofaUsedProgramSalesman,Addison-Wesley,1995)

Page 15: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

1515-214

Maintainrealisticexpectations

• MostAPIdesignsareover-constrained– Youwon'tbeabletopleaseeveryone– Aimtodispleaseeveryoneequally

• Expecttomakemistakes– Afewyearsofreal-worldusewillflushthemout– ExpecttoevolveAPI

Page 16: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

1615-214

Outline

• TheProcessofAPIDesign• GeneralPrinciples• ClassDesign• MethodDesign• ExceptionDesign

Page 17: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

1715-214

APIshoulddoonethinganddoitwell

• Functionalityshouldbeeasytoexplain– Ifit'shardtoname,that'sgenerallyabadsign– Goodnamesdrivedevelopment– Beamenabletosplittingandmergingmodules

• Good:Font,Set,PrivateKey,Lock,ThreadFactory,TimeUnit,Future<T>

• Bad:DynAnyFactoryOperations,_BindingIteratorImplBase,ENCODING_CDR_ENCAPS,OMGVMCID

Page 18: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

1815-214

APIshouldbeassmallaspossiblebutnosmaller• APIshouldsatisfyitsrequirements• Whenindoubtleaveitout– Functionality,classes,methods,parameters,etc.– Youcanalwaysadd,butyoucanneverremove

• Conceptualweightmoreimportantthanbulk• Lookforagoodpower-to-weightratio

Page 19: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

1915-214

ImplementationshouldnotimpactAPI

• ImplementationdetailsinAPIs areharmful– Confuseusers– Inhibitfreedomtochangeimplementation

• Beawareofwhatisanimplementationdetail– Donotoverspecify thebehaviorofmethods• Forexample:donotspecifyhashfunctions

– Alltuningparameters aresuspect• Don'tletimplementationdetails“leak”intoAPI– Serializedforms,exceptionsthrown

Page 20: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

2015-214

Minimizeaccessibilityofeverything

• Makeclasses,membersasprivateaspossible• Publicclassesshouldhavenopublicfields(withtheexceptionofconstants)

• Maximizesinformationhiding [Parnas]• Minimizescoupling– Allowsmodulestobe,understood,used,built,tested,debugged,andoptimizedindependently

Page 21: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

2115-214

Namesmatter– APIisalittlelanguage

• NamesShouldBeLargelySelf-Explanatory– Avoidcrypticabbreviations

• Beconsistent– SamewordmeanssamethingthroughoutAPI– (andideally,acrossAPIsontheplatform)

• Beregular– striveforsymmetry• Ifyougetitright,codereadslikeprose

for (List<Integer> proposedSolution : Permutations.of(digits))if (isSolution(proposedSolution))

solutions.add(proposedSolution);

Page 22: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

2215-214

Grammarisapartofnaming

• Nounsforclasses– BigInteger,PriorityQueue

• Nounsoradjectivesforinterfaces– Collection,Comparable

• Nouns,linkingverbsorprepositionsfornon-mutativemethods– size,isEmpty,plus

• Actionverbsformutativemethods– put,add,clear

Page 23: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

2315-214

Documentationmatters

Reuseissomethingthatisfareasiertosaythantodo.Doingitrequiresbothgooddesignandverygooddocumentation.Evenwhenweseegooddesign,whichisstillinfrequently,wewon'tseethecomponentsreusedwithoutgooddocumentation.

– D.L.Parnas,SoftwareAging.Proceedingsofthe16thInternationalConferenceonSoftwareEngineering,1994

Page 24: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

2415-214

Documentreligiously

• Documentevery class,interface,method,constructor,parameter,andexception– Class:whataninstancerepresents–Method:contractbetweenmethodanditsclient• Preconditions,postconditions,side-effects

– Parameter:indicateunits,form,ownership• Documentthreadsafety• Ifclassismutable,documentstatespace

Page 25: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

2515-214

Considerperformanceconsequences

• Baddecisionscanlimitperformance–Makingtypemutable– Providingconstructorinsteadofstaticfactory– Usingimplementationtypeinsteadofinterface

• DonotwarpAPItogainperformance– Underlyingperformanceissuewillgetfixed,butheadacheswillbewithyouforever

– Gooddesignusuallycoincideswithgoodperformance

Page 26: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

2615-214

PerformanceeffectsofabadAPIdecisionscanberealandpermanent• Component.getSize() returnsDimension• Dimension ismutable• EachgetSize callmustallocateDimension • Causesmillionsofneedlessobjectallocations• Alternativeaddedin1.2;oldclientcodestillslow– getX(),getY()

Page 27: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

2715-214

APImustcoexistpeacefullywithplatform

• Dowhatiscustomary– Obeystandardnamingconventions– Avoidobsoleteparameterandreturntypes– MimicpatternsincoreAPIsandlanguage

• TakeadvantageofAPI-friendlyfeatures– Generics,varargs,enums,functionalinterfaces

• KnowandavoidAPItrapsandpitfalls– Finalizers,publicstaticfinalarrays,etc.

• Don’ttransliterateAPIs

Page 28: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

2815-214

Outline

• TheProcessofAPIDesign• GeneralPrinciples• ClassDesign• MethodDesign• ExceptionDesign

Page 29: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

2915-214

Minimizemutability

• Classesshouldbeimmutableunlessthere’sagoodreasontodootherwise– Advantages:simple,thread-safe,reusable– Disadvantage:separateobjectforeachvalue

• Ifmutable,keepstate-spacesmall,well-defined– Makeclearwhenit'slegaltocallwhichmethod

Bad:Date,CalendarGood:TimerTask

Page 30: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

3015-214

Subclassonlywhereitmakessense

• Subclassing impliessubstitutability(Liskov)– Don’tsubclassunlessanis-arelationshipexists– Otherwise,usecomposition

• Don’tsubclassjusttoreuseimplementation

Bad:Properties extendsHashtableStack extendsVector

Good:Set extendsCollection

Page 31: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

3115-214

Design&documentforinheritanceorelseprohibitit• Inheritanceviolatesencapsulation(Snyder,‘86)– Subclassesaresensitivetoimplementationdetailsofsuperclass

• Ifyouallowsubclassing,documentself-use– Howdomethodsuseoneanother?

• Conservativepolicy:allconcreteclassesfinal

Bad:ManyconcreteclassesinJ2SElibrariesGood:AbstractSet,AbstractMap

Page 32: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

3215-214

Outline

• TheProcessofAPIDesign• GeneralPrinciples• ClassDesign• MethodDesign• ExceptionDesign

Page 33: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

3315-214

Don'tmaketheclientdoanythingthemodulecoulddo• Reduceneedforboilerplatecode– Generallydoneviacut-and-paste– Ugly,annoying,anderror-prone

import org.w3c.dom.*;import java.io.*;import javax.xml.transform.*;import javax.xml.transform.dom.*;import javax.xml.transform.stream.*;

/** DOM code to write an XML document to a specified output stream. */static final void writeDoc(Document doc, OutputStream out)throws IOException{

try {Transformer t = TransformerFactory.newInstance().newTransformer();t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());t.transform(new DOMSource(doc), new StreamResult(out)); // Does actual writing

} catch(TransformerException e) {throw new AssertionError(e); // Can’t happen!

}}

Page 34: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

3415-214

Don’tviolatetheprincipleofleastastonishment

• UserofAPIshouldnotbesurprisedbybehavior– It'sworthextraimplementationeffort– It'sevenworthreducedperformance

public class Thread implements Runnable {// Tests whether current thread has been interrupted.// Clears the interrupted status of current thread.public static boolean interrupted();

}

Page 35: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

3515-214

Here’swhathappensifyouviolatebothofthelasttworulesatthesametime// Spec says: "Skips over n bytes of data from this input."// But this is a a lie. Ignore return value at your peril!public long skip(long n) throws IOException;

Theonly correctwaytouseInputStream.skip:static void skipFully(InputStream in, long nBytes)

throws IOException {long remaining = nBytes;while (remaining != 0) {

long skipped = in.skip(remaining);if (skipped == 0) // EOF

throw new EOFException();remaining -= skipped;

} }

Page 36: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

3615-214

APIsshouldfailfast:reporterrorsassoonaspossible• Compiletimeisbest– statictyping,generics

public int max(int... args);public int max(int first, int... rest);

• Atruntime,firstbadmethodinvocationisbest–Methodshouldbefailure-atomic

/** A Properties instance maps strings to strings */public class Properties extends Hashtable {

public Object put(Object key, Object value);

// Throws ClassCastException if this properties// contains any keys or values that are not stringspublic void save(OutputStream out, String comments);

}

Page 37: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

3715-214

Provideprogrammaticaccesstoalldataavailableinstringform• Otherwise,clientswillparsestrings– Painfulforclients–Worse,turnsstringformatintodefactoAPI

public class Throwable {public void printStackTrace(PrintStream s);public StackTraceElement[] getStackTrace(); // Since 1.4

}public final class StackTraceElement {public String getFileName();public int getLineNumber();public String getClassName();public String getMethodName();public boolean isNativeMethod();

}

Page 38: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

3815-214

Overloadwithcare

• Avoidambiguous overloadings–Multipleoverloadings applicabletosameactuals

• Justbecauseyoucandoesn'tmeanyoushould– Oftenbettertouseadifferentname

• Ifyoumustprovideambiguousoverloadings,ensuresamebehaviorforsamearguments

public TreeSet(Collection<E> c); // Uses natural orderingpublic TreeSet(SortedSet<E> s); // Uses ordering from s

Page 39: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

3915-214

Useappropriateparameter&returntypes

• Favorinterfacetypesoverclassesforinput– Providesflexibility,performance

• Usemostspecificpossibleinputparametertype– Moveserrorfromruntimetocompiletime

• Don'tuseString ifabettertypeexists– Stringsarecumbersome,error-prone,andslow

• Don'tusefloatingpointformonetaryvalues– Binaryfloatingpointcausesinexactresults!

• Usedouble (64bits)ratherthanfloat (32bits)– Precisionlossisreal,performancelossnegligible

Page 40: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

4015-214

Useconsistentparameterorderingacrossmethods

• Especiallyimportantifparametertypesidentical#include <string.h>char *strncpy(char *dst, char *src, size_t n);void bcopy (void *src, void *dst, size_t n);

java.util.Collections – firstparameteralwayscollectiontobemodifiedorqueried

java.util.concurrent – timealwaysspecifiedaslongdelay,TimeUnit unit

Page 41: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

4115-214

Avoidlongparameterlists

• Threeorfewerparametersisideal– Moreanduserswillhavetorefertodocs

• Longlistsofidenticallytypedparams harmful– Programmerstransposeparametersbymistake– Programsstillcompileandrun,butmisbehave!

• Techniquesforshorteningparameterlists– Breakupmethod– Createhelperclasstoholdparameters– BuilderPattern

// Eleven (!) parameters including > four consecutive intsHWND CreateWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle,

int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);

Page 42: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

4215-214

Avoidreturnvaluesthatdemandexceptionalprocessing• Returnzero-lengtharrayoremptycollection,notnull

package java.awt.image;public interface BufferedImageOp {// Returns the rendering hints for this operation,// or null if no hints have been set.public RenderingHints getRenderingHints();

}

Page 43: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

4315-214

Outline

• TheProcessofAPIDesign• GeneralPrinciples• ClassDesign• MethodDesign• ExceptionDesign

Page 44: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

4415-214

Throwexceptionstoindicateexceptionalconditions• Don’tforceclienttouseexceptionsforcontrolflow

private byte[] a = new byte[CHUNK_SIZE];

void processBuffer (ByteBuffer buf) {try {while (true) {buf.get(a);processBytes(a, CHUNK_SIZE);

}} catch (BufferUnderflowException e) {int remaining = buf.remaining();buf.get(a, 0, remaining);processBytes(a, remaining);

}}

• Conversely,don’tfailsilentlyThreadGroup.enumerate(Thread[] list)

Page 45: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

4515-214

Favoruncheckedexceptions

• Checked– clientmusttakerecoveryaction• Unchecked– generallyaprogrammingerror• Overuseofcheckedexceptionscausesboilerplate

try { Foo f = (Foo) super.clone();....

} catch (CloneNotSupportedException e) { // This can't happen, since we’re Cloneablethrow new AssertionError();

}

Page 46: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

4615-214

Includefailure-captureinformationinexceptions

• Allowsdiagnosisandrepairorrecovery• Foruncheckedexceptions,messagesuffices• Forcheckedexceptions,provideaccessors

Page 47: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

4715-214

APIDesignSummary

• AgoodAPIisablessing;abadoneacurse• APIDesignishard,butyoucan’tescapeit– Acceptthefactthatweallmakemistakes– UseyourAPIsasyoudesignthem– Getfeedbackfromothers

• Thistalkcoveredsomeheuristicsofthecraft– Don'tadheretothemslavishly,but...– Don'tviolatethemwithoutgoodreason

Page 48: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

4815-214

Outline

• TheProcessofAPIDesign• GeneralPrinciples• ClassDesign• MethodDesign• ExceptionDesign• TwoAPIrefactorings (butwe’reoutoftime)–Wedidn’tgooverthissectioninclass

Page 49: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

4915-214

1.Sublist operationsinVectorpublic class Vector {

public int indexOf(Object elem, int index);public int lastIndexOf(Object elem, int index);...

}

• Notverypowerful- supportsonlysearch• Hardtousewithoutdocumentation

Page 50: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

5015-214

Sublistoperationsrefactoredpublic interface List {

List subList(int fromIndex, int toIndex);...

}

• Extremelypowerful- supportsall operations• Useofinterfacereducesconceptualweight– Highpower-to-weightratio

• Easytousewithoutdocumentation

Page 51: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

5115-214

2.Thread-localvariables

// Broken - inappropriate use of String as capability.// Keys constitute a shared global namespace.public class ThreadLocal {

private ThreadLocal() { } // Non-instantiable

// Sets current thread’s value for named variable.public static void set(String key, Object value);

// Returns current thread’s value for named variable.public static Object get(String key);

}

Page 52: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

5215-214

Thread-localvariablesrefactored(1)public class ThreadLocal {

private ThreadLocal() { } // Noninstantiable

public static class Key { Key() { } }

// Generates a unique, unforgeable keypublic static Key getKey() { return new Key(); }

public static void set(Key key, Object value);public static Object get(Key key);

}

• Works,butrequiresboilerplatecodetousestatic ThreadLocal.Key serialNumberKey = ThreadLocal.getKey();ThreadLocal.set(serialNumberKey, nextSerialNumber());System.out.println(ThreadLocal.get(serialNumberKey));

Page 53: Principles of Software Constructioncharlie/courses/15-214/2016-fall/slides/13-api design.pdfimport javax.xml.transform.stream.*; /** DOM code to write an XML document to a specified

5315-214

Thread-localvariablesrefactored(2)public class ThreadLocal<T> {

public ThreadLocal() { }public void set(T value);public T get();

}

• RemovesclutterfromAPIandclientcodestatic ThreadLocal<Integer> serialNumber =

new ThreadLocal<Integer>();serialNumber.set(nextSerialNumber());System.out.println(serialNumber.get());