Software Design in
Practice
Ganesh Samarthyam
Entrepreneur; author; speaker
ganesh@codeops.tech
www.codeops.tech
Discussion Question
Which one of the following is MOST IGNORED aspect in
software development?
❖ Code quality
❖ Software testing
❖ Software design
❖ Programming
"... 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)
Why Care About 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
–Craig Larman
"The critical design tool for software development
is a mind well educated in design principles"
For Architects: Design is the Key!
Design Thinking
Fundamental Principles in Software Design
Principles*
Abstrac/on*
Encapsula/on*
Modulariza/on*
Hierarchy*
Proactive Application: Enabling Techniques
Reactive Application: Smells
$ cat limerick.txt
There was a young lady of Niger
Who smiled as she rode on a tiger.
They returned from the ride
With the lady inside
And a smile on the face of the tiger.
$ cat limerick.txt | tr -cs "[:alpha:]" "n" | awk '{print length(), $0}' | sort | uniq
1 a
2 as
2 of
2 on
3 And
3 Who
3 she
3 the
3 was
4 They
4 With
4 face
4 from
4 lady
4 ride
4 rode
5 Niger
5 There
5 smile
5 tiger
5 young
6 inside
6 smiled
8 returned
List<String> lines
= Files.readAllLines(Paths.get("./limerick.txt"), Charset.defaultCharset());
	 	 Map<Integer, List<String>> wordGroups
	 	 = lines.stream()
	 .map(line -> line.replaceAll("W", "n").split("n"))
	 .flatMap(Arrays::stream)
	 .sorted()
	 .distinct()
	 .collect(Collectors.groupingBy(String::length));
	 	 wordGroups.forEach( (count, words) -> {
	 	 words.forEach(word -> System.out.printf("%d %s %n", count, word));
	 	 });
1 a
2 as
2 of
2 on
3 And
3 Who
3 she
3 the
3 was
4 They
4 With
4 face
4 from
4 lady
4 ride
4 rode
5 Niger
5 There
5 smile
5 tiger
5 young
6 inside
6 smiled
8 returned
Parallel Streams
race conditions
deadlocks
I really really hate
concurrency problems
Parallel code
Serial code
long numOfPrimes = LongStream.rangeClosed(2, 100_000)
.filter(PrimeNumbers::isPrime)
.count();
System.out.println(numOfPrimes);
Prints 9592
2.510 seconds
Parallel code
Serial code
Let’s flip the switch by
calling parallel() function
long numOfPrimes = LongStream.rangeClosed(2, 100_000)
.parallel()
.filter(PrimeNumbers::isPrime)
.count();
System.out.println(numOfPrimes);
Prints 9592
1.235 seconds
Wow! That’s an awesome flip
switch!
Internally, parallel streams make
use of fork-join framework
Discussion Question
What is refactoring?
❖ Needless rework!
❖ Changing internal structure without changing external
behaviour
❖ Changing external quality (scalability, performance, etc)
❖ Fixing hidden or latent defects
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
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();!
!!!!!!!!}
Design Smells: Example
Discussion Example
Design Smells: Example
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?
Refactoring for Date
Replace inheritance
with delegation
Joda API
JSR 310: Java Date and Time API
Stephen Colebourne
java.time package!
Refactored Solution
LocalDate 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]
More classes in Date/Time API
What’s that smell?
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#
Refactoring
Replace inheritance
with delegation
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);(
}!
Discussion Question
What is the biggest deterrent to performing refactoring?
❖ Deadlines! (Lack of time and resources)
❖ Fear of breaking the working code
❖ Not able to get management buy-in for refactoring
❖ Lack of technical skills to perform refactoring
Configuration Smells!
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
Tangles in
JDK
Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Structural Analysis for Java (stan4j)
JArchitect
InFusion
SotoArc
CodeCity
Name the first
object
oriented
programming
language
BANGALORE CONTAINER CONFERENCE 2017
Sponsorship
Deck
Apr 07
Bangalore
www.containerconf.in
ganesh@codeops.tech @GSamarthyam
www.codeops.tech slideshare.net/sgganesh
+91 98801 64463 bit.ly/ganeshsg

Software Design in Practice (with Java examples)