Webcast: Identify and Correct Common Code Smells

Preview:

DESCRIPTION

Featuring Steve Smith - CTO, Falafel Software; Microsoft Regional Director; Microsoft MVP Refactoring is a critical developer skill that helps keep code from collapsing under its own weight. Steve is the author of "Refactoring Fundamentals," available on Pluralsight, which covers the subject of code smells and refactoring in depth. This webinar will provide an introduction to the topics of code smells and refactoring, and should help you improve your existing code. Join Steve Smith as he shows some common code issues, and how to identify and refactor them with SubMain's CodeIt.Right code quality tool. In this webcast Steve will cover: » What are Code Smells » Principle of Least Surprise » Rules of Simple Design » Explain code smells like, Long Method, Large Class, Primitive Obsession, Data Clumps, Poor Names, Inappropriate Abstraction Level and more » Demo using CodeIt.Right to find and resolve code issues Visit http://submain.com/webcasts/identify-and-correct-common-code-smells/ for the webcast recording and slides download.

Citation preview

Identify and CorrectCommon Code Smells

11/12/2014

http://submain.com/webcasts/identify-and-correct-common-code-smells/

for the webcast recording and slides download

Webcast Housekeeping

Audio Connect via VoIP (default) Plug in a headset or turn up your speakers Select “User Mic and Speakers” in Camera and Voice

Connect via Phone Select “Dial In” in Audio Options Call 1 (206) 453-2087 (see confirmation email for local numbers) PIN: 685568#

Asking A Question Use the Chat window in the bottom left corner

Questions will be addressed at the end of the webcast

Recording A recording download link will be sent to all registrants within a few days

11/12/2014 Copyright © SubMain 2014 Slide 2

Introduction

Presenter

Steve Smith

Microsoft MVP, RDCTO, Falafel Software

(g)host

Serge Baranovsky

Chief Strategy Officer, SubMain

11/12/2014 Copyright © SubMain 2014 3

Steve Smith

Pluralsight Author SOLID Principles, Design Patterns

DDD, N-Tier Architecture

Kanban, Web Performance Tuning/Testing

Refactoring and Code Smells

Blog Ardalis.com

More http://about.me/stevenasmith

11/12/2014 Copyright © SubMain 2014 4

@ardalis

StevenAndrewSmith

stevenandrewsmith

What are ‘Code Smells’ ?

11/12/2014 Copyright © SubMain 2014 5

Bad Smells in Code

Described by Kent Beck and Martin Fowler in Refactoring Fundamentals

Intentionally vague term

Context-dependent; use your judgment

11/12/2014 Copyright © SubMain 2014 Slide 6

Principle of Least Surprise

Design your API to behave as programmers would expect

11/12/2014 Copyright © SubMain 2014 Slide 7

Kent Beck’s Rules of Simple Design

Well-designed code should:

Run all the tests (successfully)

Contain no duplicate code

Express all the ideas its authors wish to express

Minimize classes and methods

11/12/2014 Copyright © SubMain 2014 Slide 8

Code Smell: Long Method

Prefer short methods to long methods Smaller methods can have more descriptive names

Smaller methods are easier to understand at a glance

Less likely to duplicate code between small methods

Strive for no more than 10 lines of code per method

Do not tolerate methods that do not fit on one screen

11/12/2014 Copyright © SubMain 2014 Slide 9

Example: Long Method

11/12/2014 Copyright © SubMain 2014 Slide 10

Code Smell: Large Class

Similar to Long Method

Usually violates Single Responsibility Principle

May have Too many instance variables Too many methodsAll of the above

Typically lacks cohesion Several classes baked into one

11/12/2014 Copyright © SubMain 2014 Slide 11

Code Smell: Primitive Obsession

Abusing primitives instead of using better abstractions

Less intention-revealing

Leads to scattered business logicGuard clauses

Validation

11/12/2014 Copyright © SubMain 2014 Slide 12

Example: Primitive Obsession

// method call relying on primitives only

AddHoliday(7,4);

11/12/2014 Copyright © SubMain 2014 Slide 13

Example: Primitive Obsession

// method call relying on primitives only

AddHoliday(7,4);

// use a higher level type

Date independenceDay = new Date(7,4);

AddHoliday(independenceDay);

11/12/2014 Copyright © SubMain 2014 Slide 14

Example: Primitive Obsession

// go even further

public class July {

private const int _month = 7;

public static readonly Date Fourth {

get { return new Date(_month, 4); } } }

AddHoliday(July.Fourth);

11/12/2014 Copyright © SubMain 2014 Slide 15

Example: Primitive Obsession

// method call relying on primitives

DrawLine(5,20,25,40);

3/25/2014 Copyright © SubMain 2014 Slide 16

Example: Primitive Obsession

// method call relying on primitives

DrawLine(5,20,25,40,0,0,255);

11/12/2014 Copyright © SubMain 2014 Slide 17

Example: Primitive Obsession

// method call relying on primitives

TransferFunds(23423, 23434, 48432);

11/12/2014 Copyright © SubMain 2014 Slide 18

Example: Primitive Obsession

// method call relying on primitives

TransferFunds(23423, 23434, 48432);

// refactored to be more clear and use higher level objects

Account transferFrom = _accountRepository.Get(23423);

Account transferTo = _accountRepository.Get(23434);

var transferAmount = new Money(48432, Currency.USD);

TransferFunds(transferFrom, transferTo, transferAmount);

3/25/2014 Copyright © SubMain 2014 Slide 19

Primitive Obsession Common Examples

Phone Numbers

Social Security Numbers

ZIP/Postal Codes

Money

Age

Temperature

Address

Credit Card Information

3/25/2014 Copyright © SubMain 2014 Slide 20

Code Smell: Data Clumps

Sets of data items that are always used together, but are not organized together

Similar to Primitive Obsession, but always deals with several items

Frequently give rise to long parameter lists (another smell)

11/12/2014 Copyright © SubMain 2014 Slide 21

Example: Data Clumps

// data clumps on an order

Order.CreditCardName = creditCardName;

Order.CreditCardNumber = creditCardNumber;

Order.ExpiresMonth = creditCardMonth;

Order.ExpiresYear = creditCardYear;

Order.SecurityCode = creditCardSecurityCode;

11/12/2014 Copyright © SubMain 2014 Slide 22

Example: Data Clumps

// data clumps on an order

Order.CreditCardName = creditCardName;

Order.CreditCardNumber = creditCardNumber;

Order.ExpiresMonth = creditCardMonth;

Order.ExpiresYear = creditCardYear;

Order.SecurityCode = creditCardSecurityCode;

// refactored by Extracting a new CreditCardInfo class

CreditCardInfo cardInfo = new CreditCardInfo(

creditCardNme, creditCardNumber, creditCardMonth,

creditCardYear, creditCardSecurityCode);

Order.CreditCard = cardInfo;

11/12/2014 Copyright © SubMain 2014 Slide 23

Code Smell: Poor Names

Names should:

Be descriptive

Be at appropriate abstraction level

Use standard terms

Be unambiguous

Avoid encodings

Describe side effects

Be longer when scope is large

11/12/2014 Copyright © SubMain 2014 Slide 24

Example: Poor Names

public static List<int> Generate(int n)

{

var x = new List<int>();

for (int i = 2; n > 1; i++)

for (; n % i == 0; n /= i)

x.Add(i);

return x;

}

11/12/2014 Copyright © SubMain 2014 Slide 25

Example: Poor Names

public static List<int> GeneratePrimeFactorsOf(int input)

{

var primeFactors = new List<int>();

for (int candidateFactor = 2; input > 1; candidateFactor++)

while (input % candidateFactor == 0)

{

primeFactors.Add(candidateFactor);

input /= candidateFactor;

}

return primeFactors;

}

// Usage:

var factors = GeneratePrimeFactorsOf(input);

11/12/2014 Copyright © SubMain 2014 Slide 26

Example: Inappropriate Abstraction Level

public class User

{

public string UserName { get; set; }

public static int GetTotalUserCountInDatabaseTable()

{

throw new NotImplementedException();

}

public static SqlDataReader GetDataReaderWithRoles(string userName)

{

throw new NotImplementedException();

}

}

11/12/2014 Copyright © SubMain 2014 Slide 27

Example: Inappropriate Abstraction Level

public class User

{

public string UserName { get; set; }

public IEnumerable<Role> IsInRoles()

{

throw new NotImplementedException();

}

}

11/12/2014 Copyright © SubMain 2014 Slide 28

public class SqlUserRepository

{

public int TotalUserCount()

{

throw new NotImplementedException();

}

public IEnumerable<Role> UserIsInRoles(string userName)

{

throw new NotImplementedException();

}

}

How CodeIt.Right Helps

11/12/2014 Copyright © SubMain 2014 29

What is CodeIt.Right

Code Quality Analysis and Metrics

Automated Code Review process

Automated way to discover and fix code smells

Automatic and safe refactoringof issues into conforming code

Ensure your code adheres to (your) predefined design requirements and best coding practices

11/12/2014 Copyright © SubMain 2014 30

What is CodeIt.Right - continued

Instant Code Review – real-time code checking

OnDemand Analysis

Source Control Check-In Policy

Build Process Integration

Hundreds of rules Security, Performance, Usage,

Design, Maintainability, Exception Handling, Globalization, Async, and more

11/12/2014 Copyright © SubMain 2014 31

Demo

Discover and Fix Code Smells

Coding Pattern Examples ISerializable/Custom Serialization

Dispose/Finalize

11/12/2014 Copyright © SubMain 2014 32

Q&A

Questions?

Email - customer-service@submain.com

Video - submain.com/codeit.right/video

Download the free CodeIt.Right trial at submain.com/codeit.right

11/12/2014 Copyright © SubMain 2014 33

1 (800) 936-2134

http://submain.com/webcasts/identify-and-correct-common-code-smells/

for the webcast recording and slides download

Recommended