introduction to software technology software...

Post on 22-May-2020

12 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

IntroductiontoSoftwareTechnologySoftwareQuality

KlausOstermann

SomeslidesonrefactoringadaptedfromCS246courseatUWaterloo

EinführungindieSoftwaretechnik1

SoftwareQuality

EinführungindieSoftwaretechnik2

}  Howcanwemaintainorimprovethequalityofsoftware?

}  Whatissoftwarequality,anyway?}  Correctimplementationofrequirementsspecification}  Designquality,modularity

}  Extensibility,Maintainability,Understandability,Readability,Reusability…

}  Robustnesstochange}  LowCoupling,HighCohesion

}  Reliability,FaultTolerance,Testability,Performance,…

SoftwareQuality

EinführungindieSoftwaretechnik3

}  Howcanwemeasuresoftwarequality?

}  Whataboutsoftwaremetrics?Whatisasoftwaremetric?

“Youcan’tcontrolwhatyoucan'tmeasure”TomDeMarco,1986

Measurementistheempirical,objectiveassignmentofnumbers,accordingtoarulederivedfromamodelor

theory,toattributesofobjectsoreventswiththeintentofdescribingthem.

Kaner&Cem,“SoftwareEngineerMetrics:Whatdotheymeasureandhowdoweknow?”

ExamplesofSoftwareMetrics

EinführungindieSoftwaretechnik4

}  LinesofCode(LoC)}  Bugsperlineofcode}  Commentdensity}  Cyclomaticcomplexity

}  measuresthenumberoflinearlyindependentpathsthroughaprogram'ssourcecode

}  Halsteadcomplexitymeasures}  Derivesoftwarecomplexityfromnumbersof(distinct)operandsand

operators}  Programexecutiontime}  TestCoverage}  Numberofclassesandinterfaces}  Abstractness=ratioofabstractclassestototalnumberofclasses}  …

Metricsarerarelyused

EinführungindieSoftwaretechnik5

}  Fewcompaniesestablishmeasurementprograms,evenfewersucceedwiththem

}  ThosethatusemetricsoftendosoonlytoconformtocriteriaestablishedincertainqualitystandardssuchasCMM}  seeN.E.Fenton,"SoftwareMetrics:Successes,Failures&New

Directions”,1999

}  Onecouldinterpretthisasevidenceoftheimmaturityandunprofessionalismofthefield}  Aren’ttheengineerssosuccessfulbecausetheycanmeasure

quality?}  Butthisisagainthemisleading“softwareasengineeringproduct”

analogythatwasalreadyrefutedinthefirstlectureofthiscourse

Metricsarerarelyuseduseful!

EinführungindieSoftwaretechnik6

}  Formallydefinedmetricsareobjective,butwhatdothesemeasurementsmean?}  Whatcanweconcludeaboutqualityifthecyclomaticcomplexityofourcodeis12?

}  Answer:Nothing.

}  Problem:Oftenunclearwhetherthemetriccorrelatestoanyusefulqualityfactor}  Similartotheattemptofmeasuringtheintelligenceofapersonintermsoftheweightorcircumferenceofthebrain

}  Ifafuturepotentialemployertellsyouabouttheirextensivesoftwaremetricssuite,run!J

TomDeMarco23yearslater…

EinführungindieSoftwaretechnik7

“Thebook’smostquotedlineisitsfirstsentence:“Youcan’tcontrolwhatyoucan’tmeasure.”Thislinecontainsarealtruth,butI’vebecomeincreasinglyuncomfortablewithmyuseofit.Implicitinthequoteisthatcontrolisanimportantaspect,maybethemostimportant,ofanysoftwareproject.Butitisn’t.Manyprojectshaveproceededwithoutmuchcontrolbutmanagedtoproducewonderfulproducts.”TomDeMarco,“SoftwareEngineering:AnIdeaWhoseTimeHasComeandGone”,2009.

SoftwareQuality

EinführungindieSoftwaretechnik8

}  Ifmetricsdon’twork,howdoweassessthequalityofsoftware?

}  Answer:Byacase-by-caseanalysisofeachindividualsoftwareproject}  Reasonaboutdesignquality,extensibility,…}  Reasonbycomparingtodesignsthathaveprovenuseful

}  Designpatternsetc.

}  Reasonbylookingfor“codesmells”andanti-patterns}  Byextensivetestsuites}  Byusinganalysistools:Staticanalysis,dynamicanalysis,formalverification

CodeSmells

EinführungindieSoftwaretechnik9

}  Codesmell:Anysymptominthecodeofaprogramthatpossiblyindicatesadeeperproblem}  TermpopularizedbyKentBeckinhis“Refactoring”book

}  Commoncodesmells}  Duplicatedcode}  Longmethod,Largeclass}  Featureenvy,inappropriateintimacy}  Contrivedcomplexity

Anti-Pattern

EinführungindieSoftwaretechnik10

}  Ananti-patternisapatternthatmaybecommonlyusedbutisineffectiveand/orcounterproductiveinpractice.

}  Adescriptionofanti-patternsisuseful}  Onecanrecognizetheforcesthatleadtotheirrepetitionandlearnhowothershaverefactoredthemselvesoutofthesebrokenpatterns.

}  Examples:}  Actionatadistance:Unexpectedinteractionbetweenotherwiseseparatedpartsofasystem

}  Sequentialcoupling:Aclassthatrequiresitsmethodstobecalledinaparticularorder

}  Circulardependency:Unnecessarydirectorindirectmutualdependenciesbetweensoftwaremodules

Anti-Pattern

EinführungindieSoftwaretechnik11

}  MoreExamples:}  AbstractionInversion:Re-implementlow-levelfunctionsusinghigh-levelfunctions

}  Interfacebloat:Makinganinterfacesopowerfulthatitistoohardtoimplement

}  Busyspinorbusywaiting:ConsumingCPUwhilewaitingforsomethingtohappen

}  Seehttp://c2.com/cgi/wiki?AntiPatternsCatalogforanextensiveoverviewovercommonantipatterns

Whattodoaboutanti-patternsandcodesmells?

EinführungindieSoftwaretechnik12

}  Refactoringsformalizetheideatosystematicallyremoveanti-patternsandcodesmells}  Oftenformalizedtoadegreethatitcanbeautomatedintheformof

anIDEtool}  Standardreference:à}  Refactoringscanoftenbeunderstoodtoimprovethemodularityofthecode

}  Refactoringsdonotchangethebehaviorofcode,e.g.,addafeature

}  Let’slookatsomesmellsandassociatedrefactoringsinmoredetail!

Badsmellsandassociatedrefactorings

EinführungindieSoftwaretechnik13

}  Duplicatedcode–“The#1badsmell”}  Wehavealreadydiscussedhowtoabstractoverdifferentformsofduplicatedcodeinthelectureonreuse

}  Sameexpressionintwomethodsinthesameclass?}  Makeitaprivateauxiliaryroutineandparameterizeit

(Extract method refactoring)

}  Samecodeintworelatedclasses?}  Pushcommonalitiesintoclosestmutualancestorandparameterize}  UsetemplatemethodDPforvariationinsubtasks

(Form template method refactoring)

Badsmellsandassociatedrefactorings

14

} Duplicatedcode}  Samecodeintwounrelatedclasses?

}  Oughttheyberelated?¨  Introduceabstractparent(Extract class, Pull up method)

}  Doesthecodereallybelongtojustoneclass?¨ Maketheotherclassintoaclient(Extract method)

}  Canyouseparateoutthecommonalitiesintoasubpartorotherfunctionobject?¨ Makethemethodintoasubobjectofbothclasses.¨  StrategyDPallowsforpolymorphicvariationofmethods-as-objects

(Replace method with method object) = apply strategy pattern

ExtractClassRefactoring

EinführungindieSoftwaretechnik15

You have one class doing work that should be done by two. Create a new class and move the relevant fields and methods from the

old class into the new class.

Pull-UpMethodRefactoring

EinführungindieSoftwaretechnik16

You have methods with identical results on subclasses. Move them to the superclass

ExtractMethod Refactoring

EinführungindieSoftwaretechnik17

void printOwing() { printBanner(); //print details System.out.println ("name: " + _name); System.out.println ("amount " + getOutstanding()); }

void printOwing() { printBanner(); printDetails(getOutstanding()); } void printDetails (double outstanding) { System.out.println ("name: " + _name); System.out.println ("amount " + outstanding); }

You have a code fragment that can be grouped together. Turn the fragment into a method whose name explains the purpose of the method.

18

Badsmellsincode

}  Long method }  Oftenasignof:

}  Tryingtodotoomanythings}  Poorlythoughtoutabstractionsandboundaries

}  Besttothinkcarefullyaboutthemajortasksandhowtheyinter-relate.Beaggressive!}  Breakupintosmallerprivatemethodswithintheclass

(Extract method) }  Delegatesubtaskstosubobjectsthat“knowbest”(i.e.,templatemethodDP)(Extract class/method, Replace data value with object)

ReplaceDataValuewithObjectRefactoring

EinführungindieSoftwaretechnik19

You have a data item that needs additional data or behavior. Turn the data item into an object.

20

Badsmellsincode

}  Long method }  Fowler’sheuristic:

} Whenyouseeacomment,makeamethod.}  Often,acommentindicates:

¨  Thenextmajorstep¨  Somethingnon-obviouswhosedetailsdetractfromtheclarityoftheroutineasawhole.

}  Ineithercase,thisisagoodspotto“breakitup”.

21

Badsmellsincode}  Large class

}  i.e.,toomanydifferentsubpartsandmethods}  Twostepsolution:

1.  Gatherupthelittlepiecesintoaggregatesubparts.(Extract class, replace data value with object)

2.  Delegatemethodstothenewsubparts.(Extract method)

}  Likely,you’llnoticesomeunnecessarysubpartsthathavebeenhidingintheforest!

}  Resisttheurgetomicromanagethesubparts!

22

Badsmellsincode

}  Large class }  Counterexample:

}  Libraryclassesoftenhavelarge,fatinterfaces(manymethods,manyparameters,lotsofoverloading)¨  Ifthemanymethodsexistforthepurposeofflexibility,that’s

OKinalibraryclass.

23

Badsmellsincode

}  Long parameter list }  Longparameterlistsmakemethodsdifficultfor

clientstounderstand}  Thisisoftenasymptomof

}  Tryingtodotoomuch}  …toofarfromhome}  …withtoomanydisparatesubparts

"ifyourprocedurehasmorethanabouthalfadozenparameters,youprobablyforgotafew.“–AlanPerlis

24

Badsmellsincode

}  Long parameter list }  Intheolddays,structuredprogrammingtaught

theuseofparameterizationasacureforglobalvariables.}  Withmodules/OOP,objectshavemini-islandsof

statethatcanbereasonablytreatedas“global”tothemethods(yetarestillhiddenfromtherestoftheprogram).

}  i.e.,Youdon’tneedtopassasubpartofyourselfasaparametertooneofyourownmethods.

25

Badsmellsincode}  Long parameter list

}  Solution:}  Tryingtodotoomuch?

¨  Breakupintosub-tasks(Extract method)

}  …toofarfromhome?¨  Localizepassingofparameters;don’tjustpassdownseverallayers

ofcalls(Preserve whole object, introduce parameter object)

}  …withtoomanydisparatesubparts?¨  Gatherupparametersintoaggregatesubparts¨  Yourmethodinterfaceswillbemucheasiertounderstand!

(Preserve whole object, introduce parameter object)

PreserveWholeObjectRefactoring

EinführungindieSoftwaretechnik26

int low = daysTempRange().getLow(); int high = daysTempRange().getHigh(); withinPlan = plan.withinRange(low, high);

withinPlan = plan.withinRange(daysTempRange());

You are getting several values from an object and passing these values as parameters in a method call.

Send the whole object instead.

IntroduceParameterObjectRefactoring

EinführungindieSoftwaretechnik27

You have a group of parameters that naturally go together. Replace them with an object.

28

Badsmellsincode

}  Divergent change }  Occurswhenoneclassiscommonlychangedindifferentwaysfor

differentreasons}  Likely,thisclassistryingtodotoomuchandcontainstoomany

unrelatedsubparts}  Overtime,someclassesdevelopa“Godcomplex”

}  Theyacquiresdetails/ownershipofsubpartsthatrightlybelongelsewhere

}  Thisisasignofpoorcohesion}  Unrelatedelementsinthesamecontainer

}  Solution:}  Breakitup,reshuffle,reconsiderrelationshipsandresponsibilities

(Extract class)

29

Badsmellsincode}  Shotgun surgery

}  …theoppositeofdivergentchange}  Eachtimeyouwanttomakeasingle,seeminglycoherent

change,youhavetochangelotsofclassesinlittleways

}  Alsoaclassicsignofpoorcohesion}  Relatedelementsarenotinthesamecontainer!

}  Solution:}  Looktodosomegathering,eitherinaneworexistingclass.

(Move method/field)

MoveMethodRefactoring

EinführungindieSoftwaretechnik30

A method is, or will be, using or used by more features of another class than the class on which it is defined.

Create a new method with a similar body in the class it uses most. Either turn the old method into a simple delegation, or remove it altogether

MoveFieldRefactoring

EinführungindieSoftwaretechnik31

A field is, or will be, used by another class more than the class on which it is defined. Create a new field in the target class, and change all its users.

32

Badsmellsincode}  Feature envy

}  Amethodseemsmoreinterestedinanotherclassthantheoneit’sdefinedine.g.,amethodA.m()callslotsofget/setmethodsofclassB

}  Solution:}  Movem()(orpartofit)intoB!

(Move method/field, extract method) }  Exceptions:

}  Visitor/iterator/strategyDPwherethewholepointistodecouplethedatafromthealgorithm¨  FeatureenvyismoreofanissuewhenbothAandBhaveinterestingdata

33

Badsmellsincode}  Data clumps

}  Youseeasetofvariablesthatseemto“hangout”togethere.g.,passedasparameters,changed/accessedatthesametime

}  Usually,thismeansthatthere’sacoherentsubobjectjustwaitingtoberecognizedandencapsulated

void Scene::setTitle (string titleText, int titleX, int titleY, Colour titleColour){…}

void Scene::getTitle (string& titleText,

int& titleX, int& titleY, Colour& titleColour){…}

34

Badsmellsincode}  Data clumps

}  Intheexample,aTitleclassiswaitingtobeborn}  Ifaclientknowshowtochangeatitle’sx,y,text,andcolour,

thenitknowsenoughtobeableto“rollitsown”Titleobjects.}  However,thisdoesmeanthattheclientnowhastotalktoanother

class.

}  Thiswillgreatlyshortenandsimplifyyourparameterlists(whichaidsunderstanding)andmakesyourclassconceptuallysimplertoo.

}  Movingthedatamaycreatefeature envyinitially}  Mayhavetoiterateonthedesignuntilitfeelsright.(Preserve whole object, extract class, introduce parameter

object)

35

Badsmellsincode}  Primitive obsession

}  Allsubpartsofanobjectareinstancesofprimitivetypes(int, string, bool, double, etc.)e.g.,dates,currency,SIN,tel.#,ISBN,specialstringvalues

}  Often,thesesmallobjectshaveinterestingandnon-trivialconstraintsthatcanbemodellede.g.,fixednumberofdigits/chars,checkdigits,specialvalues

}  Solution:}  Createsome“smallclasses”thatcanencapsulatecoherent

subsetsoftheprimitivedataandvalidateandenforcetheconstraints.

(Replace data value with object, extract class, introduce parameter object)

36

Badsmellsincode}  Switch statements

}  Wesawthisbefore;here’sFowler’sexample:

Double getSpeed () { switch (_type) {

case EUROPEAN: return getBaseSpeed(); case AFRICAN: return getBaseSpeed() – getLoadFactor() * _numCoconuts; case NORWEGIAN_BLUE: return (_isNailed) ? 0 : getBaseSpeed(_voltage);

} }

37

Badsmellsincode}  Switch statements

}  Thisisanexampleofalackofunderstandingpolymorphismandalackofencapsulation.

}  Solution:}  RedesignasapolymorphicmethodofPythonBird (Replace conditional with polymorphism, replace type code with

subclasses)

Replace conditional with polymorphism, replace type code with subclasses

EinführungindieSoftwaretechnik38

Replace conditional with polymorphism

replace type code with subclasses

39

Badsmellsincode}  Lazy class

}  Classesthatdoesn’tdomuchthat’sdifferentfromotherclasses.}  Ifthereareseveralsiblingclassesthatdon’texhibitpolymorphic

behaviouraldifferences,thenconsiderjustcollapsingthembackintotheparentandaddsomeparameters

}  Often,lazy classesarelegaciesofambitiousdesignorarefactoringthatguttedtheclassofinterestingbehaviour

(Collapse hierarchy, inline class)

Collapse hierarchy, inline class

EinführungindieSoftwaretechnik40

A class isn't doing very much. Move all its features into another class and delete it.

A superclass and subclass are not very different. Merge them together.

41

Badsmellsincode}  Speculative generality

}  “Wemightneedthisoneday…”}  Fairenough,butdidyoureallyneeditafterall?}  Extraclassesandfeaturesaddtocomplexity.

}  “ExtremeProgramming”philosophy:}  “Assimpleaspossiblebutnosimpler.”}  “Ruleofthree”.

}  Keepinmindthatrefactoringisanongoingprocess.}  Ifyoureallydoneeditlater,youcanadditbackin.(Collapse hierarchy, inline class, remove parameter)

42

Badsmellsincode}  Message chains

}  Aclientasksoneobjectforanotherobject,whichtheclientthenasksforyetanotherobject,whichtheclientthenasksforyetanotheranotherobject,

}  Navigatingthiswaymeanstheclientiscoupledtothestructureofthenavigation.

}  Anychangetotheintermediaterelationshipscausestheclienttohavetochange(cf.LawofDemeter)

}  Solution:Hide delegate

Hide delegate refactoring

EinführungindieSoftwaretechnik43

A client is calling a delegate class of an object. Create methods on the server to hide the delegate.

44

Badsmellsincode}  Middle man

}  “Allhardproblemsinsoftwareengineeringcanbesolvedbyanextralevelofindirection.”}  OODPsprettywellallboildowntothis,albeitinquitecleverand

elegantways.

}  Ifyounoticethatmanyofaclass’smethodsjustturnaroundandbegservicesofdelegatesubobjects,thebasicabstractionisprobablypoorlythoughtout.

}  Anobjectshouldbemorethanthesumofitspartsintermsofbehaviours!

(Remove middle man, replace delegation with inheritance)

RemoveMiddleManRefactoring

EinführungindieSoftwaretechnik45

A class is doing too much simple delegation. Get the client to call the delegate directly

ReplaceDelegationwithInheritance

EinführungindieSoftwaretechnik46

You're using delegation and are often writing many simple delegations for the entire interface.

Make the delegating class a subclass of the delegate

47

Badsmellsincode}  Inappropriate intimacy

}  Sharingofsecretsbetweenclasses,esp.outsideoftheholyboundsofinheritancee.g.,publicvariables,indiscriminatedefinitionsofget/setmethods,C++

friendship,protecteddatainclasses}  Leadstodatacoupling,intimateknowledgeofinternalstructures

andimplementationdecisions.}  Makesclientsbrittle,hardtoevolve,easytobreak.

}  Solution:}  Appropriateuseofget/setmethods}  Rethinkbasicabstraction.}  Mergeclassesifyoudiscover“truelove”(Move/extract method/field, change bidirectional association to

unidirectional, hide delegate)

48

Badsmellsincode

}  Alternative classes with different interfaces }  Classes/methodsseemtoimplementthesame

orsimilarabstractionyetareotherwiseunrelated.

}  Solution:}  Movetheclasses“closer”together.

¨  Findacommoninterface,perhapsanABC.¨  Findacommonsubpartandremoveit.

(Extract[super]class,movemethod/field,renamemethod)

ExtractSuperclassRefactoring

EinführungindieSoftwaretechnik49

You have two classes with similar features. Create a superclass and move the common features to the superclass.

50

Badsmellsincode

}  Data class }  Classconsistsof(simple)datafieldsandsimpleaccessor/mutator

methodsonly.}  Solution:

}  Havealookatusagepatternsintheclients}  Trytoabstractsomecommonalitiesofusageintomethodsofthedata

classandmovesomefunctionalityover}  “Dataclassesarelikechildren.TheyareOKasastartingpoint,but

toparticipateasagrownupobject,theyneedtotakeonsomeresponsibility.”

(Extract/move method)

51

Badsmellsincode}  Comments

}  XPphilosophydiscouragescomments,ingeneral:}  Instead,makemethodsshortanduselongidentifiers

}  Inthecontextofrefactoring,Fowlerclaimsthatlongcommentsareoftenasignofopaque,complicated,inscrutablecode.}  Theyaren’tagainstcommentssomuchasinfavourofself-

evidentcodingpractices.}  Ratherthanexplainingopaquecode,restructureit!(Extract method/class, [many others applicable] …)

}  Commentsarebestusedtodocumentrationalei.e.,explainwhyyoupickedoneapproachoveranother.

52

Summary}  Fowleretal.‘sRefactoringisawell-writtenbookthatsummarizesalotof

“bestpractices”ofOOD/OOPwithniceexamples.}  ManybooksonOODheuristicsarevagueandlackconcreteadvice.}  Mostoftheadviceinthisbookisaimedatlow-levelOOprogramming.

}  i.e.,loops,variables,methodcalls,andclassdefinitions.}  Nextobviousstepupinabstraction/scaleistoOODPs.

}  i.e.,collaboratingclasses

}  Thisisanexcellentbookfortheintermediate-levelOOprogrammer.}  ExperiencedOOprogrammerswillhavediscoveredalotofthetechniques

alreadyontheirown.

}  Manysourcesaboutrefactoringontheweb:}  http://refactoring.com/

Testing

SomeslidesbyT.BallandJ.Aldrich

EinführungindieSoftwaretechnik53

Whytest?

EinführungindieSoftwaretechnik54

Testing:Challenges

EinführungindieSoftwaretechnik55

}  Testingiscostly}  Testeffectivenessandsoftwarequalityhardtomeasure}  Incomplete,informalandchangingspecifications}  Downstreamcostofbugsisenormous}  Lackofspecandimplementationtestingtools}  Integrationtestingacrossproductgroups}  Patchingnightmare}  Versionsexploding

Example:TestingMSWord

EinführungindieSoftwaretechnik56

}  inputs}  keyboard}  mouse/pen}  .doc,.htm,.xml,…

}  outputs(WYSIWYG)}  Printers}  displays}  doc,.htm,.xml,…

}  variables}  fonts}  templates}  languages}  dictionaries}  styles

}  Interoperability}  Access}  Excel}  COM}  VB}  sharepoint

}  Otherfeatures}  34toolbars}  100sofcommands}  ?dialogs

}  Constraints}  hugeuserbase

FromMicrosoftOfficeEULA…

EinführungindieSoftwaretechnik57

FromGPL

EinführungindieSoftwaretechnik58

Thegoalsoftesting

EinführungindieSoftwaretechnik59

}  Not-quite-rightanswers}  Makesureitdoesn’tcrash}  Regressiontesting–nonewbugs}  Makesureyoumeetthespec}  Makesureyoudon’thaveharmfulsideeffects

}  Actualgoals}  Revealfaults}  Establishconfidence}  Clarifyorrepresentthespecification

THElimitationoftesting

EinführungindieSoftwaretechnik60

Testingcanonlyshowthepresenceoferrors,nottheirabsence

-E.W.Dijkstra

…tobecontinuedinthenextlecture!

top related