Remote Pair Programming (Agile India)

Post on 28-Oct-2014

738 views 0 download

Tags:

description

My talk on Superfying your team with (remote) pair programming at #AgileIndia2014 with Niruka Ruhunage

transcript

Remote Pair Programming

Agile India 2014Johannes Brodwall

Exilesoft Chief scientist

@jhannes

Guest starring: Niruka Ruhunage

How can a distributed team

still collaborateclosely?

How can a team collaborate well?

But first

But first – a competition:

Competition:Find the blue sentence

This talk is a talkfor you if you…

You work in a team, but...

Your team doesn’t feel like a team

Your distributed team doesn’t feel like a team

After this talk you will…

Be motivated to start using pair programming, possibly remotely

Have seen remote pair programming

Know how to get started

Who is using pair programming as their preferred approach?

1. What is a super team2. Building a super team

with pairing3. Getting the benefits4. Summary

Part I

What is a super team?

Sharing the burden

The fun remote team

Rabbit hole!

Shared context

Sharing experience

Whops! No!

Working baseline

“That’s strange…”

“Eureka!”

20 minutes fix (where 10 was

waiting)

Problem solved

The sad team

Planning

The sad team

JohannesJohannes

Backend dev

“Scrum” “Master”

Johannes: You’ll create CRUD SOAP service for projects

with applications

Okay

Planning

The sad team

JohannesJohannes

Backend dev

“Scrum” “Master”

How long will it take?

Um…

Planning

Backend dev 2

The sad team

JohannesJohannes

Backend dev

“Scrum” “Master”

It’s pretty easy with Hibernate

Okay, 8 hours for each of Create…

then

!

Stand-up

The sad team

Designer

Frontend devDatabase dev

Today, I will work on Create Project

JohannesJohannes

Backend dev

Scrum master

Stand-up

The sad team

Designer

Frontend devDatabase dev

No impediments

JohannesJohannes

Backend dev

Scrum master

Behold – the uber coder

The sad team

Exception!

The sad team

org.hibernate.PropertyValueException: not-null property references a null or transient value: ....common.entities.Application._applicationsBackref org.hibernate.engine.Nullability.checkNullability(Nullability.java:95) org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:313) org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204) org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210) org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56) org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195) org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50) org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)

The sad team

Exception

Google

Stack overflow

Tweak

Deploy

Poke

The sad team

Exception

Google

Stack overflow

Tweak

Deploy

Poke

The sad team

Exception

Google

Stack overflow

Tweak

Deploy

Poke

The sad team

Exception

Google

Stack overflow

Tweak

Deploy

Poke

Stand-up

The sad team

Designer

Frontend devDatabase dev

Yesterday, I worked on Create Project

JohannesJohannes

Backend dev

Scrum master

Stand-up

The sad team

Today, I will hopefully fix the

exception and also do Delete Project

JohannesJohannesScrum master

Designer

Frontend devDatabase dev

Backend dev

Stand-up

The sad team

No impediments

JohannesJohannesScrum master

Designer

Frontend devDatabase dev

Backend dev

Stand-up

The sad teamJohannesJohannesScrum master

Designer

Frontend devDatabase dev

Backend dev

How could they help anyway

The sad team

Behold – the uber coder

The sad team

Exception!

The sad team

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [Person[id=22]] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:927) at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:844) at javax.servlet.http.HttpServlet.service(HttpServlet.java:653) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796) at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:152) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:119) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at filter.NoCacheFilter.doFilter(NoCacheFilter.java:102) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)

The sad team

Stand-up

The sad teamJohannesJohannesScrum master

Yesterday, I finally finished Delete after 3 days of «coding»

Designer

Frontend devDatabase dev

Backend dev

I didn’t need the Delete service

Stand-up

The sad teamJohannesJohannesScrum master

Designer

Frontend devDatabase dev

Backend dev

I didn’t need the Delete service

Yesterday, I finally finished Delete after 3 days of «coding»

The sad team

STOP

Imagine you should carry 10 pieces of timber

Each is 3 meters and 30 kg

The fun team

Stand-up

The sad team

I’m ready for a new task.What’s on the board..

JohannesJohannes

Johannes

Scrum master

Stand-up

The sad team

«Let’s users administrate their projects»

JohannesJohannes

Johannes

Scrum master

Stand-up

The sad team

I haven’t done any Hibernate tasks before.

Who can I pair with?

JohannesJohannes

Johannes

Scrum master

I can work together with you

Exception!

The sad team

org.hibernate.PropertyValueException: not-null property references a null or transient value: ....common.entities.Application._applicationsBackref org.hibernate.engine.Nullability.checkNullability(Nullability.java:95) org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:313) org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204) org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210) org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56) org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195) org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50) org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)

That link doesn’t really seem relevant.

Are we getting anywhere? Time to ask for help?

I think Niluka has worked on this sort of thing before

Niluka

Yeah, just look at the Person HasMany Roles

mapping

That’s it!High five!

The difference

Everyone works everywhere

Knowledge is disseminated

You’re never alone

Part II

Superfyingwith

Pair programming

Pair programming styles

Debate club

“No, this variable should be called fooNumber, not fooNum”,

“But it’s a common abbreviation”

Dedicated driver

“I’ll write the parser”

“I’ll design the algorithm”

Driver-navigator

“I don’t know how to solve this, so I’ll sit at the keyboard”

Ping-pong

Ingredient #1:

Pair programming

Ingredient #2:

Test driven development

Failing test

Write code

Failing test

Write code

Failing test

Ingredient #3:

Refactoring

Failing test

Write code

Failing test

Write code

Failing test

Refactor code and tests

Refactor code and tests

Put together

Failing test

Write code

Failing test

Write code

Failing test

Failing test

Write code

Failing test

Write code

Failing test

Refactor code and tests

Refactor code and tests

Failing test

Write code

Failing test

Write code

Failing test

Refactor code and tests

Refactor code and tests

Demonstration(Guest starring

Niruka Ruhunage)

Kata: Number to text

Kata: Number to text8192 => eight thousand one hundred and ninety two

125,017 =>

one hundred and twenty five thousand and seventeen

What does it feel like?

Part III

From here to there

Make sharing into a goal

Dileepa

Johannes

Chintaka

Thomas

Sergey

Arunas

Dileepa

Johannes

Chintaka

Thomas

Sergey

Arunas

Arunas Johannes Dileepa Chinthaka Sergey Thomas

Add new company✓ ✓ ✓ ✓ ✓

Display contacts on map ✓ ✓ ✓

Filter contacts in list✓ ✓

Authenticate user by company ✓ ✓ ✓ ✓

Store password securely ✓ ✓

Usernames with Norwegian letters are rejected

Arunas Johannes Dileepa Chinthaka Sergey Thomas

Add new company✓ ✓ ✓ ✓ ✓

Display contacts on map ✓ ✓ ✓

Filter contacts in list✓ ✓

Authenticate user by company ✓ ✓ ✓ ✓

Store password securely ✓ ✓

Usernames with Norwegian letters are rejected

Arunas Johannes Dileepa Chinthaka Sergey Thomas

Add new company✓ ✓ ✓ ✓ ✓

Display contacts on map ✓ ✓ ✓

Filter contacts in list✓ ✓

Authenticate user by company ✓ ✓ ✓ ✓

Store password securely ✓ ✓

Usernames with Norwegian letters are rejected

Overcoming obstacles

JIRA

With a true team, no member owns more

than their current task

TODO DOING DONE

WAITING

AWAY

You will get more done

(But not in the first or second sprint)

Distance

• See each other• Share what we see• Share our work

• Skype (or any voice sharing)• GoToMeeting (or flexible screen

sharing)• Dropbox (or any file sharing)

Skill and tact

• Experiment with switching patterns

• Try out ping-pong• “Could we try it this way

first?”

Expect exhaustion

When

Bug fix

Training event

Practice with kata

1. Create a dropbox account

2. Share a folder with a friend

3. Put a coding project there

4. Create a screen share session

5. Call up your friend

Failing test

Write code

Failing test

Write code

Failing test

Refactor code and tests

Refactor code and tests

Set a time per week

Don’t wait to find the perfect tool

Just do it

Conclusion

What

• Two people at one codebase• No member owns a task

beyond the day• Team rotates pairing

Why

• Less Overproduction (unused functions in API)• Less Waiting (for the only person who knows X)• Less Motion (as everyone gets more skilled)• Fewer Defects (as two pair of eyes see better)• Less Over-processing (from double responsibility)• Less Inventory (as team works more focused)• Less Transportation (handoffs inside a story)

How

• Ask for help – don’t work alone

• Play with ping pong programming for two hours

• Be open, share and listen

Competition:What was the blue sentence?

A team creates together what no member could do

alone

Next week: Commit to two hours of

working together

jbr@exilesoft.com

nru@exilesoft.com

http://JohannesBrodwall.comhttp://exilesoft.com

http://twitter.com/jhannes

Thank you