software design in practice (with java examples)

Post on 25-Jan-2017

105 Views

Category:

Software

10 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Software Design in Practice

Ganesh SamarthyamEntrepreneur; author; speakerganesh@codeops.techwww.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 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]

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 07Bangalore

www.containerconf.in

top related