Вы находитесь на странице: 1из 17

Code Smells

and
Refactoring
Technical Debt
A. "Ward" Cunningham (creador de la primera Wiki y uno de los pioneros en Design Pattern y
Extreme Programming) encontr conexiones entre el software y las finanzas.

Puedes encontrar esas conexiones? :
Software

Dejar o aplazar el diseo. (Technical Debt)


Mejorar el diseo, preservando el
comportamiento de la aplicacin. (Refactoring)

Desarrollo lento debido a problemas en el
diseo. (Code Smells)
Finanzas

Pagar los intereses.


Tomar dinero prestado.


Amortizar la deuda original.

B. Hay buenas razones para tomar una deuda financiera.
Nombra al menos 2 buenas razones o circunstancias para tomar una deuda tcnica.



C. Si utilizas una tarjeta de crdito. Cul es la mejor manera de pagar la deuda?
a) Pagar todo el balance en el mes.
b) Pagar cada mes una parte considerable hasta completar toda la deuda.
c) Esperar varios meses hasta pagar.

D. Acumular deuda financiera lleva a la bancarrota.
Nombra al menos 2 problemas que trae acumular deuda tcnica.


Code Smells

Long Method
Los mtodos cortos son ms fciles de leer, entender y atacar. Refactoriza
mtodos largos en varios ms cortos de ser posible.
Dead Code
Eliminar sin piedad el cdigo que no est siendo utilizado. Es por eso que
tenemos Source Control Systems.
Long Parameter List
La mayor cantidad de parmetros que tiene un mtodo origina una mayor
complejidad. Limita el nmero de parmetros que necesitas en un mtodo, o usa
un objeto que combine los parmetros.
Duplicated code
Cdigo duplicado es la perdicin en el desarrollo de software. Remueve el cdigo
duplicado apenas sea posible. Tambin deberas estar atento a casos sutiles de
duplicacin.
Data Clumps
Si siempre ves los mismos datos dando vueltas juntos, quizs deberan
pertenecer a una sola unidad. Considera juntar datos relacionados en una clase.
Primitive Obsession
No utilices variables de tipos de datos primitivos como un pobre sustituto de una
clase. Si tu tipo de dato es lo suficientemente complejo, escribe una clase que lo
represente.
Refused Bequest
Si heredas de una clase, pero nunca usas ninguna de las funcionalidades
heredadas, en realidad deberas estar usando herencia?
Switch Statements
Este smell existe cuando el mismo switch (o cadena de "ifelse ifelse if") est
duplicado a lo largo del sistema. Esta duplicacin revela la falta de orientacin a
objetos y pierde la oportunidad de confiar en la elegancia del polimorfismo.
Shotgun Surgery
Si un cambio en una clase requiere varios cambios en cascada en clases
relacionadas, considere refactorizar de manera que el cambio este limitado a una
sola clase.
Lazy Class
Las clases deben tener su propio peso. Cada clase adicional incrementa la
complejidad del proyecto. Si tienes una clase que no est haciendo lo suficiente
para sustentarse por ella misma, puede ser absorbida o combinada en otra
clase?
Indecent Exposure
Ten cuidado con las clases que innecesariamente exponen su interior. Refactoriza
agresivamente las clases para minimizar la parte pblica. Debes tener una razn
para cada item que haces pblico. Sino lo tienes, escndelo.
Feature Envy
Mtodos que hacen uso intensivo de otra clase quizs pertenezcan a otra clase.
Considera mover este mtodo a la clase a la cual le tiene envidia.
Speculative Generality
Escribe cdigo para resolver los problemas que conoces hoy y preocpate de los
problemas de maana cuando se materialicen. Todo el mundo se pierde en el
what if. You Aren't Gonna Need It" (Principio YAGNI)
Divergent Change
Si, a travs del tiempo, realizas cambios a una clase que toca completamente
diferentes partes de la clase, quizs contenga mucha funcionalidad no
relacionada. Considera aislar las partes que cambian en otra clase.
Comments
Hay una delgada lnea entre los comentarios que iluminan y los que oscurecen.
Los comentarios son innecesarios? Explican el por qu y no el qu? Puedes
refactorizar el cdigo de forma que los comentarios no sean requeridos? Y
recuerda, ests escribiendo comentarios para personas y no mquinas.

www.codinghorror.com/blog/2006/05/code-smells.html
Atributos de Calidad

Claridad
Cualquier persona puede escribir cdigo que una
mquina pueda entender, pero solo un buen
programador escribe cdigo que otra persona
entienda.
Libre de
Duplicados
Un programa debe expresar cada idea una vez y solo
una vez. El cdigo no debe ser idntico a otro ni
expresar el mismo comportamiento.
Poco
Acoplamiento
Componentes poco acoplados pueden cambiarse sin
impactar otros componentes.
Encapsulamiento
El cdigo est debidamente encapsulado y no expone
datos o comportamiento que debera ser invisible.
Simple
El cdigo refleja el camino ms corto a la solucin y
no agrega complejidad de manera innecesaria. El
cdigo simple es ms fcil de mantener y
evolucionar.
Alta Cohesin
Mtodos hacen solo una nica cosa y las clases solo
tiene una nica responsabilidad.

Extract Method
You have a code fragment that can be grouped together.
Turn the fragment into a method whose name explains the purpose of the method.
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);
}
Extract Class
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.


Extract Sub Class
A class has features that are used only in some instances.
Create a subclass for that subset of features.


Introduce Explaining Variable
You have a complicated expression.
Put the result of the expression, or parts of the expression, in a temporary variable with a name that explains the purpose.
if ((platform.toUpperCase().indexOf("MAC") > -1) &&
(browser.toUpperCase().indexOf("IE") > -1) &&
wasInitialized() && resize > 0 ) {
// do something
}

final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1;
final boolean wasResized = resize > 0;

if (isMacOs && isIEBrowser && wasInitialized() && wasResized) {
// do something
}

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


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



Rename
The name of a method does not reveal its purpose.
Change the name of the method.


Replace Conditional with Polymorphism
You have a conditional that chooses different behavior depending on the type of an object.
Move each leg of the conditional to an overriding method in a subclass. Make the original method abstract.
double getSpeed() {
switch (_type) {
case EUROPEAN:
return getBaseSpeed();
case AFRICAN:
return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts;
case NORWEGIAN_BLUE:
return (_isNailed) ? 0 : getBaseSpeed(_voltage);
}
throw new RuntimeException ("Should be unreachable");
}



Encapsulate Collection
A method returns a collection.
Make it return a read-only view and provide add/remove methods.


Push Down Field/Method
Behavior on a superclass is relevant only for some of its subclasses.
Move it to those subclasses.


Pull Up Field/Method
You have methods with identical results on subclasses.
Move them to the superclass.

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


Inline Method
A methods body is just as clear as its name.
Put the methods body into the body of its callers and remove the method.
int getRating() {
return (moreThanFiveLateDeliveries()) ? 2 : 1;
}

boolean moreThanFiveLateDeliveries() {
return _numberOfLateDeliveries > 5;
}



int getRating() {
return (_numberOfLateDeliveries > 5) ? 2 : 1;
}

Inline Temp
You have a temp that is assigned to once with a simple expression, and the temp is getting in the way of other refactorings.
Replace all references to that temp with the expression.
double basePrice = anOrder.basePrice();
return (basePrice > 1000)


return (anOrder.basePrice() > 1000)

Move Method
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.



Code Smell Donde se Encuentra (Class.Method) Refactoring
Long Method


Primitive Obsession


Long Parameter List


Dataclums


Switch Statements


Refused Bequest


Divergent Change


Lazy Class


Duplicate Code


Speculative Generality


Feature Envy


Indecent Exposure
(Inappropriate Intimacy)

Comments















MANUAL REFACTORINGS
Extract Method Step by Step

Create a new method, and name it after the intention of the method (name it by what it
does, not by how it does it).
If the code you want to extract is very simple, such as a single message or function call, you should
extract it if the name of the new method will reveal the intention of the code in a better way. If you
cant come up with a more meaningful name, dont extract the code.

Copy the extracted code from the source method into the new target method.

Scan the extracted code for references to any variables that are local in scope to the source
method. These are local variables and parameters to the method.

See whether any temporary variables are used only within this extracted code. If so, declare
them in the target method as temporary variables.

Look to see whether any of these local-scope variables are modified by the extracted code. If
one variable is modified, see whether you can treat the extracted code as a query and assign
the result to the variable concerned.

Pass into the target method as parameters local-scope variables that are read from the
extracted code.

Compile when you have dealt with all the locally-scoped variables.

Replace the extracted code in the source method with a call to the target method.
If you have moved any temporary variables over to the target method, look to see whether they
were declared outside of the extracted code. If so, you can now remove the declaration.

Compile and test.

Inverse Refactorings
A continuacin se muestra una lista de refctorings. Al lado de cada refactoring, escribe el nombre
del refactoring que revierte su cambio.
Refactoring Inverse
Collapse Hierarchy
Extract Method
Inline Class
Rename Method
Inline Temp
Pull Up Method

SmellstoRefactorings
QuickReferenceGuide
FFowler,Martin.Refactoring:ImprovingtheDesignofExistingCode.
KKerievsky,Joshua.RefactoringtoPatterns. Adaptedfromhttp://industriallogic.com/papers/smellstorefactorings.pdf
Smell Description Refactoring
AlternativeClasseswith
DifferentInterfaces
Occurswhentheinterfacesoftwoclassesaredifferentandyettheclassesarequitesimilar.If
youcanfindthesimilaritiesbetweenthetwoclasses,youcanoftenrefa
ctortheclassestomakethemshareacommoninterface[F85,K43]
UnifyInterfaceswithAdapter[K247]
RenameMethod[F273]
MoveMethod[F142]
CombinatorialExplosion
Asubtleformofduplication,thissmellexistswhennumerouspiecesofcodedothesamething
usingdifferentcombinationsofdataorbehavior.[K45]
ReplaceImplicitLanguagewithInterpreter[K269]
Comments(a.k.a.
Deodorant)
Whenyoufeellikewritingacomment,firsttry"torefactorsothatthecommentbecomes
superfluous"[F87]
RenameMethod[F273]
ExtractMethod[F110]
IntroduceAssertion[F267]
ConditionalComplexity
Conditionallogicisinnocentinitsinfancy,whenitssimpletounderstandandcontainedwithina
fewlinesofcode.Unfortunately,itrarelyageswell.Youimplementseveralnewfeaturesand
suddenlyyourconditionallogicbecomescomplicatedandexpansive.[K41]
IntroduceNullObject[F260,K301]
MoveEmbellishmenttoDecorator[K144]
ReplaceConditionalLogicwithStrategy[K129]
ReplaceStateAlteringConditionalswithState[K166]
DataClass
Classesthathavefields,gettingandsettingmethodsforthefields,andnothingelse.Suchclasses
aredumbdataholdersandarealmostcertainlybeingmanipulatedinfartoomuchdetailby
otherclasses.[F86]
MoveMethod[F142]
EncapsulateField[F206]
EncapsulateCollection[F208]
DataClumps
Bunchesofdatathatthathangaroundtogetherreallyoughttobemadeintotheirownobject.A
goodtestistoconsiderdeletingoneofthedatavalues:ifyoudidthis,wouldtheothersmake
anysense?Iftheydon't,it'sasuresignthatyouhaveanobjectthat'sdyingtobeborn.[F81]
ExtractClass[F149]
PreserveWholeObject[F288]
IntroduceParameterObject[F295]
DivergentChange
Occurswhenoneclassiscommonlychangedindifferentwaysfordifferentreasons.Separating
thesedivergentresponsibilitiesdecreasesthechancethatonechangecouldaffectanotherand
lowermaintenancecosts.[F79]
ExtractClass[F149]
DuplicatedCode
Duplicatedcodeisthemostpervasiveandpungentsmellinsoftware.Ittendstobeeither
explicitorsubtle.Explicitduplicationexistsinidenticalcode,whilesubtleduplicationexistsin
structuresorprocessingstepsthatareoutwardlydifferent,yetessentiallythesame.[F76,K39]
ChainConstructors[K340]
ExtractComposite[K214]
ExtractMethod[F110]
ExtractClass[F149]
FormTemplateMethod[F345,K205]
IntroduceNullObject[F260,K301]
IntroducePolymorphicCreationwithFactoryMethod[K88]
PullUpMethod[F322]
PullUpField[F320]
ReplaceOne/ManyDistinctionswithComposite[K224]
SubstituteAlgorithm[F139]
UnifyInterfaceswithAdapter[K247]
FeatureEnvy
Dataandbehaviorthatactsonthatdatabelongtogether.Whenamethodmakestoomanycalls
tootherclassestoobtaindataorfunctionality,FeatureEnvyisintheair.[F80]
ExtractMethod[F110]
MoveMethod[F142]
MoveField[F146]
Freeloader(a.k.a.Lazy
Class)
Aclassthatisntdoingenoughtopayforitselfshouldbeeliminated.[F83,K43]
CollapseHierarchy[F344]
InlineClass[F154]
InlineSingleton[K114]
InappropriateIntimacy
Sometimesclassesbecomefartoointimateandspendtoomuchtimedelvingintoeachothers
privateparts.Wemaynotbeprudeswhenitcomestopeople,butwethinkourclassesshould
followstrict,puritanrules.Overintimateclassesneedtobebrokenupasloverswereinancient
days.[F85]
MoveMethod[F142]
MoveField[F146]
ChangeBidirectionalAssociationtoUnidirectionalAssociation[F200]
ExtractClass[F149]
HideDelegate[F157]
ReplaceInheritancewithDelegation[F352]
SmellstoRefactorings
QuickReferenceGuide
FFowler,Martin.Refactoring:ImprovingtheDesignofExistingCode.
KKerievsky,Joshua.RefactoringtoPatterns. Adaptedfromhttp://industriallogic.com/papers/smellstorefactorings.pdf
Smell Description Refactoring
IncompleteLibraryClass
Occurswhenresponsibilitiesemergeinourcodethatclearlyshouldbemovedtoalibraryclass,
butweareunableorunwillingtomodifythelibraryclasstoacceptthesenewresponsibilities.[F
86]
IntroduceForeignMethod[F162]
IntroduceLocalExtension[F164]
IndecentExposure
ThissmellindicatesthelackofwhatDavidParnassofamouslytermedinformationhiding
[Parnas].Thesmelloccurswhenmethodsorclassesthatoughtnottobevisibletoclientsare
publiclyvisibletothem.Exposingsuchcodemeansthatclientsknowaboutcodethatis
unimportantoronlyindirectlyimportant.Thiscontributestothecomplexityofadesign.[K42]
EncapsulateClasseswithFactory[K80]
LargeClass
FowlerandBecknotethatthepresenceoftoomanyinstancevariablesusuallyindicatesthata
classistryingtodotoomuch.Ingeneral,largeclassestypicallycontaintoomanyresponsibilities.
[F78,K44]
ExtractClass[F149]
ExtractSubclass[F330]
ExtractInterface[F341]
ReplaceDataValuewithObject[F175]
ReplaceConditionalDispatcherwithCommand[K191]
ReplaceImplicitLanguagewithInterpreter[K269]
ReplaceStateAlteringConditionalswithState[K166]
LongMethod
Intheirdescriptionofthissmell,FowlerandBeckexplainseveralgoodreasonswhyshort
methodsaresuperiortolongmethods.Aprincipalreasoninvolvesthesharingoflogic.Twolong
methodsmayverywellcontainduplicatedcode.Yetifyoubreakthosemethodsintosmaller
methods,youcanoftenfindwaysforthetwotosharelogic.FowlerandBeckalsodescribehow
smallmethodshelpexplaincode.Ifyoudontunderstandwhatachunkofcodedoesandyou
extractthatcodetoasmall,wellnamedmethod,itwillbeeasiertounderstandtheoriginal
code.Systemsthathaveamajorityofsmallmethodstendtobeeasiertoextendandmaintain
becausetheyreeasiertounderstandandcontainlessduplication.[F76,K40]
ExtractMethod[F110]
ComposeMethod[K123]
IntroduceParameterObject[F295]
MoveAccumulationtoCollectingParameter[K313]
MoveAccumulationtoVisitor[K320]
DecomposeConditional[F238]
PreserveWholeObject[F288]
ReplaceConditionalDispatcherwithCommand[K191]
ReplaceConditionalLogicwithStrategy[K129]
ReplaceMethodwithMethodObject[F135]
ReplaceTempwithQuery[F120]
LongParameterList
Longlistsofparametersinamethod,thoughcommoninproceduralcode,aredifficultto
understandandlikelytobevolatile.Considerwhichobjectsthismethodreallyneedstodoitsjob
itsokaytomakethemethodtodosomeworktotrackdownthedataitneeds.[F78]
ReplaceParameterwithMethod[F292]
IntroduceParameterObject[F295]
PreserveWholeObject[F288]
MessageChains
Occurwhenyouseealongsequenceofmethodcallsortemporaryvariablestogetsomedata.
Thischainmakesthecodedependentontherelationshipsbetweenmanypotentiallyunrelated
objects.[F84]
HideDelegate[F157]
ExtractMethod[F110]
MoveMethod[F142]
MiddleMan
Delegationisgood,andoneofthekeyfundamentalfeaturesofobjects.Buttoomuchofagood
thingcanleadtoobjectsthataddnovalue,simplypassingmessagesontoanotherobject.[F85]
RemoveMiddleMan[F160]
InlineMethod[F117]
ReplaceDelegationwithInheritance[F355]
OddballSolution
Whenaproblemissolvedonewaythroughoutasystemandthesameproblemissolvedanother
wayinthesamesystem,oneofthesolutionsistheoddballorinconsistentsolution.The
presenceofthissmellusuallyindicatessubtlyduplicatedcode.[K45]
UnifyInterfaceswithAdapter[K247]
ParallelInheritance
Hierarchies
ThisisreallyaspecialcaseofShotgunSurgeryeverytimeyoumakeasubclassofoneclass,you
havetomakeasubclassofanother.[F83]
MoveMethod[F142]
MoveField[F146]


SmellstoRefactorings
QuickReferenceGuide
FFowler,Martin.Refactoring:ImprovingtheDesignofExistingCode.
KKerievsky,Joshua.RefactoringtoPatterns. Adaptedfromhttp://industriallogic.com/papers/smellstorefactorings.pdf
Smell Description Refactoring
PrimitiveObsession
Primitives,whichincludeintegers,Strings,doubles,arraysandotherlowlevellanguage
elements,aregenericbecausemanypeopleusethem.Classes,ontheotherhand,maybeas
specificasyouneedthemtobe,sinceyoucreatethemforspecificpurposes.Inmanycases,
classesprovideasimplerandmorenaturalwaytomodelthingsthanprimitives.Inaddition,once
youcreateaclass,youlloftendiscoverhowothercodeinasystembelongsinthatclass.Fowler
andBeckexplainhowprimitiveobsessionmanifestsitselfwhencodereliestoomuchon
primitives.Thistypicallyoccurswhenyouhaventyetseenhowahigherlevelabstractioncan
clarifyorsimplifyyourcode.[F81,K41]
ReplaceDataValuewithObject[F175]
EncapsulateCompositewithBuilder[K96]
IntroduceParameterObject[F295]
ExtractClass[F149]
MoveEmbellishmenttoDecorator[K144]
ReplaceConditionalLogicwithStrategy[K129]
ReplaceImplicitLanguagewithInterpreter[K269]
ReplaceImplicitTreewithComposite[K178]
ReplaceStateAlteringConditionalswithState[K166]
ReplaceTypeCodewithClass[F218,K286]
ReplaceTypeCodewithState/Strategy[F227]
ReplaceTypeCodewithSubclasses[F223]
ReplaceArrayWithObject[F186]
RefusedBequest
Thissmellresultsfrominheritingcodeyoudon'twant.Insteadoftoleratingtheinheritance,you
writecodetorefusethe"bequest"whichleadstougly,confusingcode,tosaytheleast.[F87]
PushDownField[F329]
PushDownMethod[F322]
ReplaceInheritancewithDelegation[F352]
ShotgunSurgery
Thissmellisevidentwhenyoumustchangelotsofpiecesofcodeindifferentplacessimplyto
addaneworextendedpieceofbehavior.[F80]
MoveMethod[F142]
MoveField[F146]
InlineClass[F154]
SolutionSprawl
Whencodeand/ordatausedinperformingaresponsibilitybecomessprawledacrossnumerous
classes,solutionsprawlisintheair.Thissmelloftenresultsfromquicklyaddingafeaturetoa
systemwithoutspendingenoughtimesimplifyingandconsolidatingthedesigntobest
accommodatethefeature.[K43]
MoveCreationKnowledgetoFactory[K68]
SpeculativeGenerality
Thisodorexistswhenyouhavegenericorabstractcodethatisntactuallyneededtoday.Such
codeoftenexiststosupportfuturebehavior,whichmayormaynotbenecessaryinthefuture.[F
83]
CollapseHierarchy[F344]
RenameMethod[F273]
RemoveParameter[F277]
InlineClass[F154]
SwitchStatement
Thissmellexistswhenthesameswitchstatement(orifelseifelseifstatement)isduplicated
acrossasystem.Suchduplicatedcoderevealsalackofobjectorientationandamissed
opportunitytorelyontheeleganceofpolymorphism.[F82,K44]
MoveAccumulationtoVisitor[K320]
ReplaceConditionalDispatcherwithCommand[K191]
ReplaceConditionalwithPolymorphism[F255]
ReplaceTypeCodewithSubclasses[F223]
ReplaceTypeCodewithState/Strategy[F227]
ReplaceParameterwithExplicitMethods[F285]
IntroduceNullObject[F260,K301]
TemporaryField
Objectssometimescontainfieldsthatdon'tseemtobeneededallthetime.Therestofthetime,
thefieldisemptyorcontainsirrelevantdata,whichisdifficulttounderstand.Thisisoftenan
alternativetoLongParameterList.[F84]
ExtractClass[F149]
IntroduceNullObject[F260,K301]

Feedback en Cuatro Cuadrantes


1. Mis sentimientos sobre lo que acabo de
aprender son:
2. Los conceptos ms importantes que
aprend son:
3. Lo que planeo hacer con lo que aprend
es:
4. Un comentario final, sugerencia o
pregunta que an tengo es:

Nombre, email y retrato (o autorretrato). Todo opcional.

Вам также может понравиться