Refactoring and Code Smells Dan Fleck Spring 2010 Coming up: Where are we?
Refactoring for Software Design Smells - Tech Talk
-
Upload
ganesh-samarthyam -
Category
Software
-
view
222 -
download
12
Transcript of Refactoring for Software Design Smells - Tech Talk
Refactoring for Software Design Smells
Ganesh SamarthyamEntrepreneur; author; [email protected]
–Craig Larman
"The critical design tool for software development is a mind well educated in design principles"
Poor software quality costs more than $150 billion per year
in U.S. and greater than $500 billion per year worldwide
- Capers Jones
Source: Estimating the Principal of an Application's Technical Debt, Bill Curtis, Jay Sappidi, Alexandra Szynkarski, IEEE Software, Nov.-Dec. 2012.
Source: Consortium of IT Software Quality (CISQ), Bill Curtis, Architecturally Complex Defects, 2012
“The problem with quick and dirty...is that dirty remains long after quick has been forgotten”
Steve C McConnell
"... a delightful, engaging, actionable read... you have in your hand a veritable field guide of smells... one of the more interesting and complex expositions of
software smells you will ever find..."
- From the foreword by Grady Booch (IBM Fellow and Chief Scientist for Software Engineering, IBM Research)
"This is a good book about ‘Design Smells’ – actually a great book – nicely organized - clearly written with
plenty of examples and a fair sprinkling of anecdotes."
- Will Tracz (Principal Research Scientist & Fellow, Lockheed Martin)(review in ACM SIGSOFT Software Engineering Notes)
Fundamental Principles in Software Design
Principles*
Abstrac/on*
Encapsula/on*
Modulariza/on*
Hierarchy*
Is this a Smell?
abstract class Printer { private Integer portNumber = getPortNumber(); abstract Integer getPortNumber(); public static void main(String[]s) { Printer p = new LPDPrinter(); System.out.println(p.portNumber); } }
class LPDPrinter extends Printer { /* Line Printer Deamon port no is 515 */ private Integer defaultPortNumber = 515; Integer getPortNumber() { return defaultPortNumber; } }
prints “null”!
What’s that smell?public'Insets'getBorderInsets(Component'c,'Insets'insets){'
''''''''Insets'margin'='null;'
'''''''''//'Ideally'we'd'have'an'interface'defined'for'classes'which'
''''''''//'support'margins'(to'avoid'this'hackery),'but'we've'
''''''''//'decided'against'it'for'simplicity'
''''''''//'
''''''''if'(c'instanceof'AbstractBuEon)'{'
'''''''''''''''''margin'='((AbstractBuEon)c).getMargin();'
''''''''}'else'if'(c'instanceof'JToolBar)'{'
''''''''''''''''margin'='((JToolBar)c).getMargin();'
''''''''}'else'if'(c'instanceof'JTextComponent)'{'
''''''''''''''''margin'='((JTextComponent)c).getMargin();'
''''''''}'
''''''''//'rest'of'the'code'omiEed'…'
Refactoring
!!!!!!!margin!=!c.getMargin();
!!!!!!!!if!(c!instanceof!AbstractBu8on)!{!
!!!!!!!!!!!!!!!!!margin!=!((AbstractBu8on)c).getMargin();!
!!!!!!!!}!else!if!(c!instanceof!JToolBar)!{!
!!!!!!!!!!!!!!!!margin!=!((JToolBar)c).getMargin();!
!!!!!!!!}!else!if!(c!instanceof!JTextComponent)!{!
!!!!!!!!!!!!!!!!margin!=!((JTextComponent)c).getMargin();!
!!!!!!!!}
Discussion Example
// using java.util.Date Date today = new Date(); System.out.println(today);
$ java DateUse Wed Dec 02 17:17:08 IST 2015
Why should we get the time and timezone details if I only want a date? Can
I get rid of these parts? No!
So What!Date today = new Date(); System.out.println(today); Date todayAgain = new Date(); System.out.println(todayAgain);
System.out.println(today.compareTo(todayAgain) == 0);
Thu Mar 17 13:21:55 IST 2016 Thu Mar 17 13:21:55 IST 2016 false
What is going on here?
Refactored SolutionLocalDate today = LocalDate.now(); System.out.println(today); LocalDate todayAgain = LocalDate.now(); System.out.println(todayAgain); System.out.println(today.compareTo(todayAgain) == 0);
2016-03-17 2016-03-17 true
Works fine now!
Refactored Example … You can use only date, time, or even timezone, and combine them as
needed!
LocalDate today = LocalDate.now(); System.out.println(today); LocalTime now = LocalTime.now(); System.out.println(now);
ZoneId id = ZoneId.of("Asia/Tokyo"); System.out.println(id);
LocalDateTime todayAndNow = LocalDateTime.now(); System.out.println(todayAndNow);
ZonedDateTime todayAndNowInTokyo = ZonedDateTime.now(ZoneId.of("Asia/Tokyo")); System.out.println(todayAndNowInTokyo);
2016-03-17 13:28:06.927 Asia/Tokyo 2016-03-17T13:28:06.928 2016-03-17T16:58:06.929+09:00[Asia/Tokyo]
Liskov’s Substitution Principle (LSP)
It#should#be#possible#to#replace#objects#of#supertype#with#objects#of#subtypes#without#
altering#the#desired#behavior#of#the#program#
Barbara#Liskov#
What’s that smell?switch'(transferType)'{'
case'DataBuffer.TYPE_BYTE:'
byte'bdata[]'='(byte[])inData;'
pixel'='bdata[0]'&'0xff;'
length'='bdata.length;'
break;'
case'DataBuffer.TYPE_USHORT:'
short'sdata[]'='(short[])inData;'
pixel'='sdata[0]'&'0xffff;'
length'='sdata.length;'
break;'
case'DataBuffer.TYPE_INT:'
int'idata[]'='(int[])inData;'
pixel'='idata[0];'
length'='idata.length;'
break;'
default:'
throw' new' UnsupportedOperaQonExcepQon("This'method' has' not' been' "+' "implemented'for'transferType'"'+'transferType);'
}'
Replace conditional with polymorphism
protected(int(transferType;! protected(DataBuffer(dataBuffer;!
pixel(=(dataBuffer.getPixel();(
length(=(dataBuffer.getSize();!
switch((transferType)({(
case(DataBuffer.TYPE_BYTE:(
byte(bdata[](=((byte[])inData;(
pixel(=(bdata[0](&(0xff;(
length(=(bdata.length;(
break;(
case(DataBuffer.TYPE_USHORT:(
short(sdata[](=((short[])inData;(
pixel(=(sdata[0](&(0xffff;(
length(=(sdata.length;(
break;(
case(DataBuffer.TYPE_INT:(
int(idata[](=((int[])inData;(
pixel(=(idata[0];(
length(=(idata.length;(
break;(
default:(
throw( new( UnsupportedOperaRonExcepRon("This( method(has( not( been( "+( "implemented( for( transferType( "( +(transferType);(
}!
Language Features & Refactoring public static void main(String []file) throws Exception { // process each file passed as argument
// try opening the file with FileReader try (FileReader inputFile = new FileReader(file[0])) { int ch = 0; while( (ch = inputFile.read()) != -1) { // ch is of type int - convert it back to char System.out.print( (char)ch ); } } // try-with-resources will automatically release FileReader object }
public static void main(String []file) throws Exception { Files.lines(Paths.get(file[0])).forEach(System.out::println); }
Java 8 lambdas and streams
Refactoring Windows!
“A large number of dependencies at the module level could be reduced and optimized to: * make modular reasoning of the system more efficient* maximize parallel development efficiency* avoid unwanted parallel change interference* selectively rebuild and retest subsystems effectively”
Refactoring performed to reduce and optimize dependencies - by creating and enforcing layering
Source: Kim, Miryung, Thomas Zimmermann, and Nachiappan Nagappan. "An Empirical Study of RefactoringChallenges and Benefits at Microsoft." IEEE Transactions on Software Engineering 7 (2014): 1-1.
Refactoring Windows!
Refactoring decisions made after substantial analysis of existing dependency structure
Refactoring effort was centralized and top down with designated team for refactoring
Use of custom refactoring tools (MaX) and processes (quality gate check)
Source: Kim, Miryung, Thomas Zimmermann, and Nachiappan Nagappan. "An Empirical Study of RefactoringChallenges and Benefits at Microsoft." IEEE Transactions on Software Engineering 7 (2014): 1-1.
Which pattern is this?
a)Bridgepa+ernb)Decoratorpa+ernc)Builderpa+ernd)Strategypa+ern
LineNumberReader lnr = new LineNumberReader( new BufferedReader( new FileReader(“./test.c")));
String str = null;
while((str = lnr.readLine()) != null) System.out.println(lnr.getLineNumber() + ": " + str);
Meetups
h+p://www.meetup.com/JavaScript-Meetup-Bangalore/h+p://www.meetup.com/Container-Developers-Meetup-Bangalore/h+p://www.meetup.com/SoBware-CraBsmanship-Bangalore-Meetup/h+p://www.meetup.com/Core-Java-Meetup-Bangalore/h+p://www.meetup.com/Technical-Writers-Meetup-Bangalore/h+p://www.meetup.com/CloudOps-Meetup-Bangalore/h+p://www.meetup.com/Bangalore-SDN-IoT-NetworkVirtualizaKon-Enthusiasts/h+p://www.meetup.com/SoBwareArchitectsBangalore/
Upcoming Java 8 Bootcamp
Modern Programming with Java 8
Refactor your legacy applications using Java 8 features
Register here: https://www.townscript.com/e/java8-refactoring
[email protected] @GSamarthyam
www.codeops.tech slideshare.net/sgganesh
+91 98801 64463 bit.ly/ganeshsg