Refactoring, - UdL...

36
Refactoring So#ware Quality Quality Audit and Cer4fica4on Master in Computer Engineering Roberto García ([email protected] )

Transcript of Refactoring, - UdL...

Page 1: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Refactoring  

So#ware  Quality  Quality  Audit  and  Cer4fica4on  

 Master  in  Computer  Engineering  

   

Roberto  García  ([email protected])        

Page 2: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Introduc4on  

•  When  considering  soAware  evolu4on,  the  key  dis4nc4on  is:    – Program's  quality  improves  or  degrades?  

•  Treat  modifica4ons  as  opportuni4es  to  improve  quality  

•  Monitor  project  quality  regularly  – Warning  if  it  degrades  

Page 3: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Introduc4on  

•  A  second  dis4nc4on:  –  Changes  made  during  construc8on    –  Changes  made  during  maintenance  

•  Construc8on  changes  are  usually  made  by  the  original  developers  – Done  under  less  pressure  than  maintenance  changes  

•  Profit  soAware  changes  to  improve  the  code  and  its  internal  quality,  so  that  future  changes  are  easier  

Page 4: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Introduc4on  

•  The  key  strategy  in  achieving  soAware  evolu8on  is  refactoring  

•  Fowler  (1999):  –  “a  change  made  to  the  internal  structure  of  the  soAware  to  make  it  easier  to  understand  and  cheaper  to  modify  without  changing  its  observable  behaviour”  

•  Reasons  to  Refactor  –  Some4mes  code  degenerates  under  maintenance,  and  some4mes  the  code  just  wasn't  very  good  in  the  first  place    

Page 5: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

When  Refactoring  

•  Warning  signs  that  indicate  where  refactorings  are  needed:  –  Code  is  duplicated  –  A  rou8ne  is  too  long    

•  In  object-­‐oriented  programming,  rarely  rou4nes  longer  than  a  screen  

–  A  loop  is  too  long  or  too  deeply  nested  •  Loop  innards  tend  to  be  good  candidates  for  being  converted  into  rou4nes  

–  A  class  has  poor  cohesion  •  It  takes  ownership  for  a  mix  of  unrelated  responsibili4es  

–  A  class  interface  does  not  provide  a  consistent  level  of  abstrac8on  –  A  parameter  list  has  too  many  parameters  –  Changes  require  parallel  modifica4ons  to  mul4ple  classes  

Page 6: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

When  Refactoring  

•  Refactoring  warning  signs  (cont.):  –  Related  data  items  that  are  used  together  are  not  organized  into  

classes  –  A  rou8ne  uses  more  features  of  another  class  than  of  its  own  class  –  A  primi8ve  data  type  is  overloaded  

•  If  using  Integer  for  money,  temperature,…  create  separate  classes  for  them  

–  A  class  doesn't  do  very  much  •  Move  responsibili4es  to  other  and  remove  it    

–  A  chain  of  rou4nes  just  passes  data  along  –  A  middleman  object  isn't  doing  anything  –  One  class  knows  too  much  about  another  

•  Stronger  encapsula4on  preferred  to  weaker  

Page 7: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

When  Refactoring  

•  Refactoring  warning  signs  (cont.):  –  A  rou4ne  has  a  poor  name  

•  Rename  it  wherever  defined  or  used  and  recompile  

–  Data  members  are  public  •  Hide  data  behind  ge^ers  and  se^ers  

–  A  subclass  uses  only  a  small  percentage  of  its  parents'  rou8nes  •  Change  rela4on  to  “has-­‐a”  

–  Comments  are  used  to  explain  difficult  code  –  Global  variables  are  used  –  A  rou4ne  uses  setup  code  before  a  rou4ne  call  or  takedown  code  

a#er  a  rou4ne  call  •  Avoid  crea4ng  an  object  just  to  call  it  and  aAer  that  unpack  some  of  its  fields  

–  A  program  contains  code  that  seems  like  it  might  be  needed  someday  

Page 8: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  Data  •  Main  ones  from  “Refactoring”  (Fowler  1999)  –  h^p://www.refactoring.com/catalog    

•  Data  Refactorings:  –  Replace  a  magic  number  with  a  named  constant  

•  Replace  literal  like  3.14  with  named  constant  like  PI  –  Rename  a  variable  with  a  clearer  or  more  informa8ve  name    •  The  same  applies  to  renaming  constants,  classes  and  rou4nes  

– Move  an  expression  inline  •  Replace  an  intermediate  variable  that  was  assigned  the  result  of  an  expression  with  the  expression  itself  

Page 9: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Inline  Temps  

!!double basePrice = anOrder.basePrice();!return (basePrice > 1000)!!!return (anOrder.basePrice() > 1000)!

Page 10: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  Data  •  Data  Refactorings  (cont.):  

–  Replace  an  expression  with  a  rou8ne    •  Replace  an  expression  with  a  rou4ne  (usually  so  that  the  expression  isn't  duplicated  in  the  code)  

–  Introduce  an  intermediate  variable    •  Assign  an  expression  to  an  intermediate  variable  whose  name  summarizes  the  purpose  of  the  expression  

–  Convert  a  mul8use  variable  to  mul8ple  single-­‐use  variables    •  Create  separate  variables  for  each  usage  with  a  more  specific  name  

–  Use  a  local  variable  for  local  purposes  rather  than  a  parameter  –  Convert  a  data  primi8ve  to  a  class    

•  If  a  data  primi4ve  needs  addi4onal  behaviour  (e.g.  Temperature)  

Page 11: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Split  Temporary  Variable  

double temp = 2 * (_height + _width);!System.out.println (temp);!temp = _height * _width;!System.out.println (temp);!!!final double perimeter = 2 * (_height + _width);!System.out.println (perimeter);!final double area = _height * _width;!System.out.println (area);!

Page 12: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  Data  •  Data  refactorings  (cont.):  –  Convert  a  set  of  type  codes  to  a  class  or  an  enumera8on    •  Like:  const  int  SCREEN  =  0;  const  int  PRINTER  =  1;  const  int  FILE  =  2;  

–  Convert  a  set  of  type  codes  to  a  class  with  subclasses    •  A  base  class  for  the  type  with  subclasses  for  each  type  code  

–  Change  an  array  to  an  object    •  If  different  elements  in  the  array  are  different  types,  create  an  object  with  fields  

–  Replace  a  tradi8onal  record  with  a  data  class    •  Centralize  opera4ons  concerning  the  record  (error  checking,  persistence,…)  

Page 13: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Replace  Type  Code  with  Subclasses  

Page 14: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  Statement-­‐Level  •  Statement-­‐Level  Refactorings:  –  Decompose  a  boolean  expression    

•  Simplify  a  boolean  expression  by  introducing  well-­‐named  intermediate  variables  

– Move  a  complex  boolean  expression  into  a  well-­‐named  boolean  func8on    •  Improve  readability  and  if  used  more  than  once,  eliminate  parallel  modifica4ons  

–  Consolidate  fragments  that  are  duplicated  within  different  parts  of  a  condi8onal    •  Move  code  repeated  at  the  end  of  an  else  and  if  block  to  the  end  of  the  en4re  if-­‐then-­‐else  block  

–  Use  break  or  return  instead  of  a  loop  control  variable    

Page 15: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Decompose  Condi4onal  

!if (date.before (SUMMER_START) || date.after(SUMMER_END))!! !charge = quantity * _winterRate + _winterServiceCharge;!else !! !charge = quantity * _summerRate;!!!!if (notSummer(date))!! !charge = winterCharge(quantity);!!else!! !charge = summerCharge (quantity);!

Page 16: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  Statement-­‐Level  •  Statement-­‐Level  Refactorings  (cont.):  

–  Return  as  soon  as  you  know  the  answer  instead  of  assigning  a  return  value  within  nested  if-­‐then-­‐else  statements    

–  Replace  condi8onals  (especially  repeated  case  statements)  with  polymorphism    •  Implement  condi4onal  logic  into  inheritance  hierarchy  and  polymorphic  rou4ne  calls  

–  Create  and  use  null  objects  instead  of  tes8ng  for  null  values    •  Consider  moving  the  responsibility  for  handling  null  values  out  of  the  client  code  and  into  the  class  –  Example:  referring  to  a  resident  whose  name  is  not  known  as  "occupant."  

Have  the  Customer  class  define  the  unknown  resident  as  "occupant"  instead  of  having  Customer's  client  code  repeatedly  test  for  whether  the  customer's  name  is  known  and  subs4tute  "occupant"  if  not  

Page 17: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Decompose  Condi4onal  double getSpeed() {! switch (_type) {! case EUROPEAN: return getBaseSpeed();! case AFRICAN: return getBaseSpeed() - getLoadFactor();! case NORWEGIAN: return getBaseSpeed(_voltage);! }! throw new RuntimeException ("Should be unreachable");!}!

Page 18: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  Rou4ne-­‐Level  •  Rou4ne-­‐Level  Refactorings:  

–  Extract  rou8ne/extract  method    •  Remove  inline  code  from  one  rou4ne,  and  turn  it  into  its  own  rou4ne  

–  Move  a  rou8ne's  code  inline    •  Take  code  from  a  rou4ne  whose  body  is  simple  and  self-­‐explanatory,  and  move  that  rou4ne's  code  inline  where  it  is  used  

–  Convert  a  long  rou8ne  to  a  class    •  For  a  long  rou4ne,  turn  it  into  a  class  and  factor  it  into  mul4ple  rou4nes  

–  Add  a  parameter    •  When  rou4ne  needs  more  informa4on  from  its  caller,  add  a  parameter  

–  Remove  a  parameter    •  If  a  rou4ne  no  longer  uses  a  parameter,  remove  it  

Page 19: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Extract  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);!!}!

Page 20: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  Rou4ne-­‐Level  •  Rou4ne-­‐Level  Refactorings  (cont.):  

–  Separate  query  opera8ons  from  modifica8on  opera8ons    •  If  GetTotals()  changes  an  object's  state,  separate  the  state-­‐changing  func4onality  

–  Combine  similar  rou8nes  by  parameterizing  them    •  Example:  similar  rou4nes  differ  only  with  respect  to  a  constant  value,  combine  them  and  

pass  the  value  as  a  parameter  –  Separate  rou8nes  whose  behaviour  depends  on  parameters  passed  in    

•  Consider  the  reverse  of  the  previous  refactoring  if  the  rou4ne  is  too  complex  –  Pass  a  whole  object  rather  than  specific  fields    

•  Instead  of  passing  several  values  from  the  same  object  –  Pass  specific  fields  rather  than  a  whole  object    

•  If  the  object  is  created  just  to  pass  it  to  a  rou4ne  –  Encapsulate  downcas8ng    

•  If  a  rou4ne  returns  an  object,  return  the  most  specific  type  it  knows  about,  specially  for  iterators,  collec4ons,…  

Page 21: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Encapsulate  Downcast  &  Parameterise  Method  

Object lastReading() {!! !return readings.lastElement();!}!!!Reading lastReading() {!! !return (Reading) readings.lastElement();!}!

Page 22: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  Class  Implementa4on  •  Class  Implementa4on  Refactorings:  –  Change  value  objects  to  reference  objects    

•  Avoid  crea4ng  and  maintaining  numerous  copies  of  large  or  complex  objects,  only  one  master  copy  (the  value  object)  and  the  rest  of  the  code  uses  references  to  that  object  (reference  objects)  

–  Change  reference  objects  to  value  objects    •  Avoid  excessive  reference  housekeeping  for  small  or  simple  objects,  make  them  value  objects  

–  Replace  virtual  rou8nes  with  data  ini8aliza8on    •  Subclasses  that  vary  according  to  constant  values  they  return,  avoid  overriding  member  rou4nes  in  the  derived  classes,  ini4alise  them  with  appropriate  constant  values  and  keep  base  class  generic  code  

Page 23: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Change  Value  to  Reference  &  Reference  to  Value  

Page 24: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  Class  Implementa4on  •  Class  Implementa4on  Refactorings  (cont.):  

–  Change  member  rou8ne  or  data  placement    •  Consider  general  changes  in  an  inheritance  hierarchy  to  eliminate  duplica4on  in  derived  classes:  –  Pull  a  rou4ne  up  into  its  superclass  –  Pull  a  field  up  into  its  superclass  –  Pull  a  constructor  body  up  into  its  superclass  

•  Other  changes  made  to  support  specializa4on  in  derived  classes:  –  Push  a  rou4ne  down  into  its  derived  classes  –  Push  a  field  down  into  its  derived  classes  –  Push  a  constructor  body  down  into  its  derived  classes  

–  Extract  specialized  code  into  a  subclass    •  Move  class  code  used  by  only  a  subset  of  its  instances  into  a  subclass  

–  Combine  similar  code  into  a  superclass    •  Combine  similar  code  from  subclasses  into  the  superclass  

Page 25: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Pull  Up  Constructor  Body  class Manager extends Employee...!

!public Manager (String name, String id, int grade) {!! !_name = name;!! !_id = id;!! !_grade = grade;!!}!!!!!public Manager (String name, String id, int grade) {!! !super (name, id);!! !_grade = grade;!!}!

Page 26: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  Class  Interface  •  Class  Interface  Refactorings:  

–  Move  a  rou8ne  to  another  class  –  Convert  one  class  to  two    

•  If  a  class  has  two  or  more  dis4nct  areas  of  responsibility  –  Hide  a  delegate    

•  Some4mes  Class  A  calls  Class  B  and  C,  when  really  it  should  call  only  Class  B  and  B  should  call  C  

–  Remove  a  middleman    •  If  Class  A  calls  Class  B  and  B  calls  Class  C,  have  Class  A  call  Class  C  directly  

–  Replace  delega8on  with  inheritance    •  If  a  class  exposes  every  public  rou4ne  of  a  delegate  class,  inherit  from  the  delegate  class  instead  of  just  using  the  class  

•  Also  possible  to  replace  inheritance  with  delega4on,  if  inheritance  effects  not  desired  

Page 27: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Replace  Delega4on  with  Inheritance  

Page 28: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  Class  Interface  •  Class  Interface  Refactorings  (cont.):  

–  Introduce  a  foreign  rou8ne    •  If  a  class  needs  an  addi4onal  rou4ne  and  you  can't  modify  the  class  to  provide  it,  you  can  

create  a  new  rou4ne  within  the  client  class  that  provides  that  func4onality.  –  Introduce  an  extension  class    

•  A  unmodifiable  class  needs  addi4onal  rou4nes,  create  a  new  class  subclassing  the  original  class  and  adding  new  rou4nes  or  wrapping  the  class  and  exposing  the  new  rou4nes  

–  Encapsulate  an  exposed  member  variable    •  Make  public  data  private  and  expose  it  through  a  rou4ne  

–  Remove  Set()  rou8nes  for  fields  that  cannot  be  changed    –  Hide  rou8nes  that  are  not  intended  to  be  used  outside  the  class  –  Encapsulate  unused  rou8nes    

•  Rou4nely  using  only  a  por4on  of  a  class's  interface,  create  a  new  interface  that  exposes  only  those  necessary  rou4nes  

–  Collapse  a  superclass  and  subclass  if  their  implementa8ons  are  very  similar  

Page 29: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Introduce  Foreign  Method  

!Date newStart = new Date (!previousEnd.getYear(),!! ! ! ! ! ! ! !previousEnd.getMonth(), !! ! ! ! ! ! ! !previousEnd.getDate() + 1);!

!!!!!

!Date newStart = nextDay(previousEnd);!!

!private static Date nextDay(Date arg) {!! !return new Date ( !arg.getYear(),!! ! ! ! ! ! !arg.getMonth(), !! ! ! ! ! ! !arg.getDate() + 1);!!}!

Page 30: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Specific  Refactorings  System-­‐Level  •  System-­‐Level  Refactorings  

–  Change  unidirec8onal  class  associa8on  to  bidirec8onal  class  associa8on  •  For  two  classes  that  need  to  use  each  other's  features  but  only  one  knows  

about  the  other  class,  change  them  so  that  they  both  know  about  each  other  –  Change  bidirec8onal  class  associa8on  to  unidirec8onal  class  

associa8on    •  For  two  classes  that  know  about  each  other's  features  but  only  one  really  

needs  to  know,  change  them  so  that  one  knows  about  the  other  but  not  vice  versa.  

–  Provide  a  factory  method  rather  than  a  simple  constructor    •  Use  a  factory  method  when  need  to  create  objects  based  on  a  type  code  or  

when  want  to  work  with  reference  objects  rather  than  value  objects  –  Replace  error  codes  with  excep8ons  or  vice  versa    

•  Depending  on  your  error-­‐handling  strategy,  make  sure  the  code  is  using  the  standard  approach  

Page 31: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Data  Refactoring  Replace  Constructor  with  Factory  Method  &    Change  Bidirec4onal  Associa4on  to  Unidirec4onal  !!Employee (int type) {!

!_type = type;!}!!!!static Employee create(int type) {!

!return new Employee(type);!}!

Page 32: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Refactoring  Safety  

•  If  misused,  can  cause  more  harm  than  good  •  A  few  simple  guidelines  to  prevent  missteps:  –  Save  the  code  you  start  with  –  Keep  refactorings  small    

•  Small  enough  so  easy  to  understand  all  the  impacts  of  the  changes  –  Do  refactorings  one  at  a  8me    

•  Recompiling  and  retes4ng  before  the  next  one  – Make  a  list  of  steps  you  intend  to  take  –  Keep  a  list  of  intended  refactorings    

•  Those  not  needed  immediately  – Make  frequent  checkpoints    

•  Save  checkpoints  at  various  steps  in  a  refactoring  session    

Page 33: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Refactoring  Safety  

•  Guidelines  (cont.):  – Retest    

•  Reviews  of  changed  code  should  be  complemented  by  retests  

– Add  test  cases    •  Add  new  unit  tests  for  the  new  code.  Remove  obsolete  

– Review  the  changes    •  Pair  programming,  formal  /  informal  reviews,…    

Page 34: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Refactoring  Strategies  

•  Guidelines  for  deciding  priority  refactorings:  –  Refactor  when  you  add  a  rou8ne    

•  Check  if  related  rou4nes  are  well  organized.  If  not,  refactor  them.  –  Refactor  when  you  add  a  class    

•  Opportunity  to  refactor  classes  closely  related  to  the  added  class  –  Refactor  when  you  fix  a  defect    

•  From  fixing  a  bug  to  improving  other  code  prone  to  similar  defects  –  Target  error-­‐prone  modules    

•  Modules  that  concentrate  defects  from  tes4ng  or  review  –  Target  high-­‐complexity  modules    –  Define  an  interface  between  clean  code  and  ugly  code,  and  then  move  code  across  the  interface  •  A  common  problem  with  legacy  systems  is  poorly  wri^en  produc4on  code,  which  must  remain  opera4onal  at  all  4mes    

Page 35: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Key  Points  

•  Program  changes  are  a  fact  of  life  both  during  ini4al  development  and  aAer  ini4al  release  

•  SoAware  can  either  improve  or  degrade  as  it's  changed.  The  Cardinal  Rule  of  SoAware  Evolu4on  is  that  internal  quality  should  improve  with  code  evolu4on  

•  One  key  to  success  in  refactoring  is  learning  to  pay  a^en4on  to  the  numerous  warning  signs  or  smells  that  indicate  a  need  to  refactor.  

•  Another  key  to  refactoring  success  is  learning  numerous  specific  refactorings  

•  A  final  key  to  success  is  having  a  strategy  for  refactoring  safely.  Some  refactoring  approaches  are  be^er  than  others  

•  Refactoring  during  development  is  the  best  chance  you'll  get  to  improve  your  program,  to  make  all  the  changes  you'll  wish  you'd  made  the  first  4me.  Take  advantage  of  these  opportuni4es  during  development!    

Page 36: Refactoring, - UdL OpenCourseWareocw.udl.cat/enginyeria-i-arquitectura/software-quality/Continguts/9... · Introduc4on, • Asecond,dis4ncon: – Changes,made,during,construcon((

Ac4vity  

•  Refactor  the  MiniProject  source  code  following  the  strategies:  –  Target  module/s  with  higher  concentra8on  of  defects  during  review  and  tes4ng  

–  Target  high-­‐complexity  module/s  •  For  the  selected  modules,  perform  at  least  10  refactorings  

–  The  more  diverse  in  kind  and  the  more  produc8ve  towards  soAware  quality,  the  beYer  

•  Deliverables:    –  Through  Campus  Virtual  upload  document  describing  all  refactorings:    •  class  name,  method  name,  line  number,  ini4al  code,  refactoring  applied,  result  code,  mo4va4on,…  

–  Update  resul4ng  code  at  Github