39
Steve Rodgers [email protected] CODE QUALITY

Steve Rodgers [email protected] CODE QUALITY

Embed Size (px)

Citation preview

Page 1: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

Steve [email protected]

CODE QUALITY

Page 2: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

AN APOLOGY

Page 3: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

THE DREAM

Metronomic build/fix/deploy cycle

Bug count always low per release

End users love the app as it never crashes

Stakeholder

QA

Support team

Project Manager

Devs

Imagine a world where

Page 4: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

WHY CARE PART 1?Business *MUST* care

Page 5: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

WHY CARE PART 2Developers *SHOULD* care

Page 6: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

WHY CARE PART 3The Quality Trade Off

Page 7: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

THE MISSION: BUILD A MAINTAINABLE LEGACY

Code spends most of its life being maintained

How hard is it to learn any new code base?

What is your legacy?

My $hit code will be your problem tomorrow

Your $hit code will be my problem today

Page 8: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

MALLEABLE CODE

Code is rarely done unless it’s demo code

Business requirements change all the time

Code must therefore be engineered to handle continual refactor

Code must be thought of as highly malleableEvery line is always up for possible refactor

How will you survive dominate in this world?

In The Real World

Page 9: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: WRITE UNIT TESTS

Why write tests?Validate class behaviour now and future proof it

Domain classes with behaviour must have tests

Data classes don’t need tests

Write meaningful tests

Be highly suspicious of 100% unit test coverage

Be judicious; spend money where neededWrite tons of tests for critical algorithm

Don’t write tons of tests for 3 line method

Learn TDD then Practice TDD

Page 10: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: AVOID WRITING GOD CLASSES

“A ‘God Class’ is an object that controls way too many other objects in the system and has grown beyond all logic to become The Class That Does Everything.” [http://c2.com/cgi/wiki?GodClass]

The signs1200 SLOC? 50 private methods? 35 fields?

No one in the team understands how it works?

The disease

Page 11: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

GOD CLASS: UNIT TESTS HARD TO WRITE?

Class is hard to test?

Lots of complicated test setup code?

Lots of Asserts per test? A unit test should only have a single Assert

Unit test on Elm Street

Page 12: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: ADOPT SINGLE RESPONSIBILITY PRINCIPLE

Class should have one responsibility

Refactor God class into multiple SRP classes

Write unit tests for each SRP class

The cure

Page 13: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: AVOID UNMANAGED COMPLEXITY

Signals: Many lines of code, tons of methods but few classes

Avoid function decompositionPrivate method syndrome

Private methods cannot be unit tested

Embrace class decomposition

Lots of little classes

Write battery of unit tests for each little class

Refactor big private methods out into their own class (see ‘method-object’ Kent Beck)

Page 14: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: USE SOFTWARE DESIGN PATTERNS

Don’t miss out on GOF patterns

Factory, Null Object, Decorator, Adapter etc

Patterns signal intent to other developers

Use only when neededDon’t force them in when not needed

Be suspicious of large code base that doesn’t use patterns

Beware Dunning-Kruger Effect

Page 15: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

CYCLOMATIC COMPLEXITY

“Cyclomatic complexity is a software metric (measurement), used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program's source code.” [https://en.wikipedia.org/wiki/Cyclomatic_complexity]

Page 16: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: REDUCE HEAVY USE OF IMPERATIVE STYLE

Complicated code is hard to understandNested if/else with lots of || and &&

Cyclomatic complexity is the work of the devil

Reduce use of imperative programming stylee.g. if/else/switch

Flock of seagulls lead to the gates to Hades {{{}}}

Challenge each other to reduce heavy use of them

Good use of OO, LINQ & patterns will help achieve this goal

Favour a functional programming stylee.g. LINQ

But avoid nested lambda hell

Page 17: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: PUBLISH CYCLOMATIC COMPLEXITY

Dashboards like Sonar publish cyclomatic complexity during the build for all to see

Visual Studio “Code Metrics” gives cyclomatic complexity drill down

ReSharper add-on can graphically show cyclomatic complexity in Visual Studio

Page 18: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

CYCLOMATIC COMPLEXITY DEMO

Page 19: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: AVOID STATIC

Static references & classes defeat unit testing

E.g. How do you mock DateTime.Now for daylight savings unit tests when they run on January 14th?

Wrap use of static classes in an injected singleton that delegates to static implementation

E.g. Define and implement IDateTime interface

Avoid ‘XyzHelper’ or ‘Util’ classes like the plague!

Page 20: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: USE AWESOME NAMES EVERYWHERE

Take time to name every artefact

Class, method, field, property, parameter, automatic variable (prod code + test code)

Class name is a noun

Method name is a verb

E.g. dog.Sleep(), table.Clear(), documentAggregator.Aggregate()

Stuck for class name? http://classnamer.com

E.g.

for(int p = 0; p < 10; p++) {}

for(int personIndex = 0; personIndex < 10; personIndex++) {}

Page 21: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: WRITE CLEAN CODE

Broken Window Theory

“maintaining and monitoring urban environments to prevent small crimes such as vandalism, public drinking and toll-jumping helps to create an atmosphere of order an

d lawfulness, thereby preventing more serious crimes from happening”

Corollary: Keep code+tests uber clean

[https://en.wikipedia.org/wiki/Broken_windows_theory]

Uncle Bob says ‘Keep it clean!’

Page 22: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: AVOID INHERITANCE

Default to avoid inheritance: ‘is-a’Why? Derived often needs to know base intimately

Default to favour composition: ‘has-a’

Only cave-in when ‘is-a’ rule satisfied

Dog is-a bone: fail

Dog has-a bone: pass

Cat is-a mammal: pass

Cat has-a mammal: fail

Page 23: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: CODE REVIEW BEFORE CHECK-IN

Ideally every check-in gets peer reviewed prior to check-in

Each check-in should have:Description + name of reviewer

Over the shoulder review preferential

Rotate reviewers and share knowledge and tips within the team == free peer training; level up

Also back up with post commit code review tool e.g. Crucible

Page 24: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: HOW TO CONDUCT CODE REVIEW

1. Park egos at the door

2. Team first attitude

3. Test coverage good?

4. Lots of private methods? God class?

5. Inheritance satisfies ‘is-a’ rule?

6. Interface based programming? Use of ‘new’ operator?

7. Good class/method/field/prop/auto names?

Page 25: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: USE INVERSION OF CONTROL

Domain class constructor takes interface parameters only (C#)

Don’t new domain class from within domain class (fine to new framework classes e.g. List<T>, Hashset<T> etc)

Why? Testing class A would be implicit test of B as well

Constructor stores interface parameter in field

Constructor does nothing elseWhy? Interface can easily be mocked therefore easy to test

Use 2-phase construction via Initialize() method if needed

Page 26: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

INVERSION OF CONTROL DEMO

Page 27: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: AVOID CODE COMMENTS

Comments are very useful for big and complicated things

Warning: Comments quickly get out of date with respect to code during refactor

Comments not necessary for small and easy to understand things

Corollary: Only create small, easy to understand well named things and therefore ditch comments

Page 28: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: AVOID EXCESSIVE NULL CHECKING

Excessive null checking is a Code smell

if (dog != null) {} OR if (dog == null)

Consider Null Object Pattern

Page 29: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

DEMO NULL OBJECT PATTERN

Page 30: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: CONFORM TO A SIMPLE CODE STANDARD

Author a 1 page annotated coding standard

Why? If it all looks like it was written by one person then it’s going to be easier maintain/learn

Get dev buy-in by building team consensus on content

Print it off for everyone to put on the wall by their desk

Police it with code review

Use tooling: e.g. Write a Resharper standard and share with the team

Page 31: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: PRACTICE INTERFACE BASED PROGRAMMING

Every domain class should should be accompanied by an interface

What is a domain class?One that has behaviour

Pass IDogController around, not DogController

Why? Decrease coupling between classes

Page 32: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: USE MULTIPLE METHOD RETURNS

In the old days single method return was Why? Because of long complicated methods in God classes

Requires carefully nested method if/else hierarchy

If you don’t have God classes with long complicated methods then you have no fear of

multiple method returns any more Why? Simpler to read due to dramatic reduction in nested if/else hierarchy

Page 33: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: AVOID C# REGIONS

Regions (#region) are a great place to hide code

Often commented out code can be found hiding in them

God classes often lurk within regions pretending to not be God classes Grrrrr

Page 34: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: AVOID SPECULATIVE GENERALITY

App developers are often wannabe framework developers

Allow base classes to emerge from ongoing requirements

Don’t try and predict the future now

Avoid marking a method as virtual unless there is a class to override it right now

Page 35: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: BUY RESHARPER LICENSES

All C# devs should use ReSharper

Essential for quick and accurate refactoring

Set up shared team coding styleReformat class(es) automatically before check-in

Find type

Find implementation of interface/method

Refactor name of class/method/field/auto etc

Page 36: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: LEARN ALL LANGUAGE FEATURES

Polymorphism: check

Interface based programming: check

Generics: check

Iterators: check

LINQ: check

async/await: check

C#

Page 37: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

TIP: HIRE QUALITY-MINDED ENGINEERS

Do they care about code quality? Ask them!

When was the last time they checked-in a unit test?

Prove it! Get them to write an algorithm on the white board and a unit test for it

Get them to come up with the list of tests they would write for the algorithm

Ensure good CS background: data structures & algorithms

Make sure they really know all the latest stuff (passion)

Never hire a ‘maybe’

Ensure good team fi t – everyone meets the candidate

Page 38: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

CALL TO ACTION

Code quality directly impacts $takeholder through to end user experience

Up the ante: Make code quality your mission

Write good quality unit tests

Maintain a hygienic code base (inc tests)

Build a legacy your team is proud of that your users will love

Page 39: Steve Rodgers steve.rodgers@gmail.com CODE QUALITY

REFERENCES

Clean Code: A Handbook of Agile Software Craftsmanship, Robert C Martin aka Uncle Bob

Awesome google talk (Misko Hevery)http://www.youtube.com/watch?v=acjvKJiOvXw