develop maintainable apps

Post on 14-Apr-2017

8.582 Views

Category:

Mobile

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Be a Good Citizen: !

Develop Maintainable Apps

“…a high probability of determining the cause of a problem in a timely manner… and a high

probability of being able to modify the program without causing an error in some other part…”

— IEEE

Why Care?

What’s involved…

@brwngrldev

What’s involved…

Libraries

1

@brwngrldev

What’s involved…

Libraries

1

Domain Design

2

@brwngrldev

What’s involved…

Libraries

1

Domain Design

2

Code Quality

3

@brwngrldev

What’s involved…

Libraries

1

Domain Design

2

Code Quality

3

Testing

4

@brwngrldev

Choosing the Right Library

So many options

So many options

What to consider

@brwngrldev

What to consider

Documentation

@brwngrldev

What to consider

Documentation

Project Stability

@brwngrldev

What to consider

Documentation

Project Stability

Fulfills a Need

@brwngrldev

What to consider

Amazing App

!

Documentation

Project Stability

Fulfills a Need

@brwngrldev

Example

So you need images…

So you need images…

Volley

!

Fresco

!

Glide

!

Picasso

!

Volley

!

Documentation s

Volley

!

Documentation s

Volley

!

Documentation s

W Project Stability

Volley

!

Documentation s

W Project Stability

Volley

!

Documentation s

W Project Stability

p Fulfills a need

Volley

!

@brwngrldev

Rinse & Repeat

Volley

!

Fresco

!

Glide

!

Picasso

!

Review…

• Documentation

• Repository Check-ins

• Fulfills a Need

Libraries

1

@brwngrldev

Domain Design

Doing too much

Doing too much

Seen this?

Seen this?

Seen this?

Seen this?

How to fix this

Clean It Up!

How to fix this

Clean It Up!

How to fix this

MVP

MVVM

OO

Foo

What’s involved…

What’s involved…

Foo Bar

Baz Lol

Omg

Example

Remember this?

We need tests

We need tests

We need tests

Extract a Presenter

Create an Interface

Reference the Interface

Implement the Interface

Foo Bar

Baz Lol

Omg

@brwngrldev

Review…

• Keep Code Simple

• Use MV* Pattern

• Functional Tests

• Use the Tools

@brwngrldev

Domain Design

2

Code Quality

Poor Readability

Poor Readability

Increase Readability?

Increase Readability?

“Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard.”

Source

Files

config.xml

Checkstyle Tool

!

Modules

Design

Formatting

Code Complexity

apply plugin: ‘checkstyle’ !

task checkstyle(type: Checkstyle) { description 'Checks if the code passes quality standards' group 'verification' configFile file(‘checkstyle.xml') …}

apply plugin: ‘checkstyle’ !

task checkstyle(type: Checkstyle) { description 'Checks if the code passes quality standards' group 'verification' configFile file(‘checkstyle.xml') …}

<module name=“MethodLength"> <property name="max" value=“60"/> </module> <module name=“LineLength"> <property name="max" value=“120"/> </module><module name=“CyclomaticComplexity"> <property name="max" value=“8"/> </module> …

<module name=“MethodLength"> <property name="max" value=“60"/> </module> <module name=“LineLength"> <property name="max" value=“120"/> </module><module name=“CyclomaticComplexity"> <property name="max" value=“8"/> </module> …

<module name=“MethodLength"> <property name="max" value=“60"/> </module> <module name=“LineLength"> <property name="max" value=“120"/> </module><module name=“CyclomaticComplexity"> <property name="max" value=“8"/> </module> …

playerControlConfig.setShowClosedCaptionsButton(a.getBoolean(R.styleable.WapoVideoView_showClosedCaptionsButton, false)); playerControlConfig.setShowClosedCaptionsButton(a.getBoolean(R.styleable.WapoVideoView_showClosedCaptionsButton, false)); !

<module name=“MethodLength"> <property name="max" value=“60"/> </module> <module name=“LineLength"> <property name="max" value=“120"/> </module><module name=“CyclomaticComplexity"> <property name="max" value=“8"/> </module> …

playerControlConfig.setShowClosedCaptionsButton(a.getBoolean(R.styleable.WapoVideoView_showClosedCaptionsButton, false)); playerControlConfig.setShowClosedCaptionsButton(a.getBoolean(R.styleable.WapoVideoView_showClosedCaptionsButton, false)); !

<module name=“MethodLength"> <property name="max" value=“60"/> </module> <module name=“LineLength"> <property name="max" value=“120"/> </module><module name=“CyclomaticComplexity"> <property name="max" value=“8"/> </module> …

<module name=“MethodLength"> <property name="max" value=“60"/> </module> <module name=“LineLength"> <property name="max" value=“120"/> </module><module name=“CyclomaticComplexity"> <property name="max" value=“8"/> </module> …

<module name=“CyclomaticComplexity"> <property name="max" value=“8"/> </module> !

M = E − N + 2P

@brwngrldev

M = E − N + 2P

@brwngrldev

Example

public void overlyComplexMethod(Video video) { if (video != null && video.getStreamUrl() != null) { switch (video.getCategory()) { case "CAT1" : playVideo(video); if (video.getLargeImageUrl() == null) { video.setLargeImageUrl("http://www.largeImage.png"); } updateMetadata(video); break; case "CAT2" : if (video.getLargeImageUrl() == null) { video.setLargeImageUrl("http://www.smallImage.png"); }

case "CAT1" : playVideo(video); if (video.getLargeImageUrl() == null) { video.setLargeImageUrl("http://www.largeImage.png"); } updateMetadata(video); break; case "CAT2" : if (video.getLargeImageUrl() == null) { video.setLargeImageUrl("http://www.smallImage.png"); } updateMetadata(video); break; …

… warning: Cyclomatic Complexity is 9

public void overlyComplexMethod(Video video) { if (video != null && video.getStreamUrl() != null) { updateVideoBasedOnCategory(video); } } !

private void updateVideoBasedOnCategory(Video video) { switch (video.getCategory()) { case "CAT1" : playVideo(video); if (video.getLargeImageUrl() == null) { video.setLargeImageUrl("http://www.largeImage.png"); } updateMetadata(video); break;

public void overlyComplexMethod(Video video) { if (video != null && video.getStreamUrl() != null) { updateVideoBasedOnCategory(video); } } !

private void updateVideoBasedOnCategory(Video video) { switch (video.getCategory()) { case "CAT1" : playVideo(video); if (video.getLargeImageUrl() == null) { video.setLargeImageUrl("http://www.largeImage.png"); } updateMetadata(video); break;

public void overlyComplexMethod(Video video) { if (video != null && video.getStreamUrl() != null) { updateVideoBasedOnCategory(video); } } !

private void updateVideoBasedOnCategory(Video video) { switch (video.getCategory()) { case "CAT1" : playVideo(video); if (video.getLargeImageUrl() == null) { video.setLargeImageUrl("http://www.largeImage.png"); } updateMetadata(video); break;

7

!

switch (video.getCategory()) { case "CAT1" : playVideo(video); updateMetaDataAndUrl(video, "http://www.largeImage.png"); break; …

@brwngrldev

!

switch (video.getCategory()) { case "CAT1" : playVideo(video); updateMetaDataAndUrl(video, "http://www.largeImage.png"); break; …

4

@brwngrldev

Review…

• Readability Matters

• Use Checkstyle

• Refactor Gradually

@brwngrldev

Code Quality

3

Unit Testing

Untested Code

Untested Code

“Every single line of code that you write should be tested. Period.”

— Robert Martin

0

9,000

18,000

27,000

36,000

Lines of Code

Production Tests

FitNesse

0

9,000

18,000

27,000

36,000

Lines of Code

Production Tests 90%FitNesse

0

9,000

18,000

27,000

36,000

Lines of Code

Production Tests 90%

2,200

FitNesse

0

9,000

18,000

27,000

36,000

Lines of Code

Production Tests 90%

2,200

90s

FitNesse

Example

Test Setup

@brwngrldev

Sample Test

@brwngrldev

Test Report

Continuous Integration

@brwngrldev

Code Coverage

@brwngrldev

Makes You Powerful

Review

• Listen to Robert Martin!

• JUnit + Mockito

• Continuous Integration

• Code CoverageTesting

4

@brwngrldev

Summary

Summary

Choose the right library

Summary

Choose the right library

Don’t do too much

Summary

Ensure code quality

Choose the right library

Don’t do too much

Summary

Ensure code quality

Choose the right library

Don’t do too much

Write unit tests

Resources

• Clean Code - http://amzn.to/1DJybxH

• Effective Java - http://amzn.to/1Ku8Xel

• Working Effectively with Legacy Code - http://amzn.to/1Jqe1PA

• Unit Testing Idioms - http://goo.gl/Bx1WbL

• Google Code Style - http://goo.gl/8Pf6J3

• Architecting Android - http://goo.gl/UKvmbq

• Conquering Cyclomatic Complexity - http://goo.gl/lRoPXN

• PostTV App - https://goo.gl/0TRsXU

@brwngrldev

Photo Credits• Slide 4 - https://www.flickr.com/photos/nikigunn/8379494330

• Slide 6 - https://www.flickr.com/photos/tracy_olson/61056391

• Slide 7 - https://en.wikipedia.org/wiki/Dominoes

• Slide 10 - https://www.flickr.com/photos/tshirbert/118250140

• Slide 24 - http://uncompromisedmen.com/2015/02/17/top-10-crazy-beards-wish-youd-seen-person/

• Slide 38 - https://www.flickr.com/photos/cast_fish/2888442781

• Slide 52 - https://www.flickr.com/photos/desertbusforhope/8207412726/

• Slide 54 - https://www.flickr.com/photos/sokabs/2668975758

• Slide 63 - https://www.flickr.com/photos/pasukaru76/5268559005

@brwngrldev

top related