Sustainable Agile Development
-
Upload
gabriele-lana -
Category
Technology
-
view
2.751 -
download
0
description
Transcript of Sustainable Agile Development
Sustainable Agile Development
a case study with chess
We havean Idea
We want tomake it work
We know thatAgile works in acorporate world
Can Agile workfor us/you too?
Eric Ries: “a startup is a human institution designed to deliver a new product or
service under conditions of extreme uncertainty”
Traditional Product Development(Progress: Advance To Next Stage)
Eric Ries @ http://startuplessonslearned.blogspot.com/
Requirements
Design
Implementation
Verification
Manteinance
Problem: Known
Solution: Known
Agile Development(Progress: Running Tested Features)
Eric Ries @ http://startuplessonslearned.blogspot.com/
Problem: Known
Solution: Unknown
"Product Owner" or
in-house customer
we should be able toEmbrace Change
Cos
t of
Chan
ge Traditional Development
Agile Development
Time
we should be able toEmbrace Change
• Refactoring• Simple Design• Test-Driven Development• Continuous Integration• Collective Code Ownership• Incremental Design• Emergent Design• Pair Programming• Project Automation• Definition of Done• Exploratory Testing
We know how to do it, But...
Do you really know what
customers want?
Do you really think customers know what they
need?
Do you thinkimplementing
features isreal progress?
7%
13%
16%
19%
45%
Use of Requested Features
Standish Group, CHAOS Report 2006
The biggest source of waste isimplementation of features nobody wants
They could even
hate some “features”
Steve Blank:“software
development is a discovery and a
learning process”
Lean Startup Development(Progress: Validated Learning about Customers)
Eric Ries @ http://startuplessonslearned.blogspot.com/
Problem: Unknown
Solution: UnknownCustomer Development
Agile in a Waterfall world
ConceptAgile
Development
Test
Alpha/Beta
Maintenance
and Marketing
Debug, Fix
and Patch
Agile in a Waterfall world
ConceptAgile
Development
Test
Alpha/Beta
Maintenance
and Marketing
Debug, Fix
and Patch
Agile in a Waterfall world
ConceptAgile
Development
Test
Alpha/Beta
Maintenance
and Marketing
Debug, Fix
and Patch
Lean Startup Development(Progress: Validated Learning about Customers)
Eric Ries @ http://startuplessonslearned.blogspot.com/
IDEAS
CODEDATA
BUILD
MEASURE
LEARN
• Reduce the cycle time
• Eliminate waste• Optimize the
whole• Amplify learning
MinimumMarketable
Feature
How can we support the
learning process?
Domain Composability: the Domain Model
should beextremely flexibleand “exposed”
web applicationsInformation Flow
HTTPOOP
RDB
MS
Impedance Mismatchcan slow you down
HTTPOOP
RDB
MS
Accidental Complexity
Resource Oriented Architectures
HTTP ROA DATA
Essential Complexity
Identify Resourcesin your Domain
Resource Oriented Architectures
Resource Oriented Architectures
BoardGame
Position
Move
FileRankPlayer
Square
Knight
Queen
Rook
Pawn Bishop
Resource Oriented Architectures
Design the URIs (Ubiquitous Language)
Resource Oriented Architectures
GET /position/wqd3,wkd2,bke8 HTTP/1.1Accept: text/plain
HTTP/1.1 200 OKContent-Type: text/plain;format=fen\n5k2/8/8/8/8/3Q4/8/3K4
Resource Oriented Architectures
GET /position/wqd3,wkd2,bke8 HTTP/1.1Accept: image/png;q=0.8, text/plain;q=0.2
HTTP/1.1 200 OKContent-Type: image/png\nPNG...
Resource Oriented Architectures
GET /board/4815162342 HTTP/1.1
HTTP/1.1 200 OK\n.../position/wqd3,wkd1,bke7/position/wqd3,wkd1,bke8
Resource Oriented Architectures
HTTP/1.1 201 Created\n.../position/wqd3,wkd1,bke8/position/wqe8,wkd1,bke8
POST /board/4815162342 HTTP/1.1\nmove = d3-e8
Resource Oriented Architectures
HTTP/1.1 200 OK\nboard = /board/4815162342white = /player/50298black = /player/48192
GET /game/42 HTTP/1.1
no Web Servicesbut how the web
should be
Resource Oriented Architectures
Resource Oriented Architectures
Tim Berners-Leeon Linked Data
“... almost 20 years ago I wanted to reframe the way we use informations ... I invented the Word Wide Web ... now is time for a new reframing...”
Tim Berners-Lee @ http://linkeddata.org
Resource Oriented Architectures
for each Resourcedesign the
Representationsfrom and to the Client
Resource Oriented Architectures
GET /game/42 HTTP/1.1Accept: application/xhtml+xml
<html> ... <a rel=”owner” href=”/player/1001”>...</a> ... <ul class=”moves”> <li><image src=”/position/initial.png”/></li> </ul></html>
now we have aGood Domain
but anUgly Interface
Ajax to rescue
// Interface can have its state// but actually consumes many serverside// resources in background
var game = { "game": "/game/42", "board": "/board/4815162342", "position": "/position/” + “rnbqkbnr-pppp1ppp-8-4p3-4P3-8-PPPP1PPP-RNBQKBNR"}
var req = YAHOO.util.Connect.asyncRequest;
req('GET', position + '/piece/g1/moves', callback);// 200 OK; moves = g1-e2, g1-f3, g1-h3board.highlightSquares("g1", "e2", "f3", "h3");
req('POST', '/board/4815162342', callback, "move=g1-f3");// 200 OK; position = // rnbqkbnr-pppp1ppp-8-4p3-4P3-5N2-PPPP1PPP-RNBQKB1R
John Maeda’sLaws of Simplicity
Law 3: TIMESavings in time feels like simplicity.
John Maeda @ http://lawsofsimplicity.com
...ok, we need real-time
Comet to rescue
• “Reverse Ajax”• Push over Pull• Long-lived HTTP
But which Comet way?
Long pollingForever FrameScript tagsWebSocketsHtmlfileMime MessagingFlash Remoting
Transport APISocketPublish/SubscribeAPI basedData syncREST?
Joe Walker @ http://www.slideshare.net/joewalker/comet-and-the-rise-of-highly-interactive-websites-presentation
HTTP Channelsis RESTful Comet
“The primary purpose of HTTP Channels is to provide an application-level Comet
protocol for live data synchronization that leverages the widely understood semantics
and vocabulary of HTTP/REST.”
Kris Zyp:
Kris Zyp @ http://cometdaily.com/2008/06/05/intended-usage-of-http-channels/
Http Channels 2
Kris Zyp @ http://cometdaily.com/2008/05/13/http-channels-2/
POST /channels HTTP/1.1Accept: application/httpX-Create-Client-Id: 123123
GET /foo HTTP/1.1Accept: */*X-Subscribe: *X-Client-Id: 123123
PUT /foo HTTP/1.1\n{ data: “foobar” }
HTTP/1.1 200 OKX-Event: PUTContent-Location: /foo \n{ data: "foobar" }
Http Channels 3
X-Client-Id: 124124 X-Client-Id: 126126X-Client-Id: 125125
X-Client-Id: 123123
HTTP/1.1 200 OKX-Event: POSTContent-Location: /board/4815162342 \nmove = g1-f3
POST /board/4815162342 HTTP/1.1\nmove = g1-f3
How can wespeed up the
learning process?
Continuous Deployment reduces the time from
code check-in to production
Testabilitytells if it’s a good
change or a bad change as quickly as possible
Continuous Deployment
Continuous Deployment (testability)
HTTP
View Model
Control
Continuous Deployment (testability)too much code untested
HTTP
View Model
Control
HTTP
View Model
Control
Continuous Deployment (testability)too fragile and unreliable
Continuous Deployment (testability)Ruby with Rspec and Cucumber
HTTP
Board
Game
Player
Position
Move
Js
Continuous Deployment (testability)
Feature: change the position on board
Scenario: change position with a correct move Given board with position wqd3,wkd1,bke8 When move to position wqd8,wkd1,bke8 Then response should be 201 And board should be in position wqd8,wkd1,bke8
Scenario: change position with a correct move Given board with position wqd3,wkd1,bke8 When move to position wqd7,wkd1,bke8 Then response should be 403 And board should be in position wqd3,wkd1,bke8
Scenario: change position with a correct move Given board with position wqd3,wkd1,bke8 When move to position wqd8,wkd1,bke8 Then response should be 201 And board should be in position wqd8,wkd1,bke8
Continuous Deployment (testability)
Given /^board with position (.+?)$/ do | from_position | response = @client.post("/board", "position = #{from_position}") response.status.should == 201 @board = response.header["Location"]end
Continuous Deployment (testability)
When /^move to position (.+?)$/ do | to_position | move_reponse = @client.post(@board, "position = #{to_position}") @move_response_status = move_response.statusend
Scenario: change position with a correct move Given board with position wqd3,wkd1,bke8 When move to position wqd8,wkd1,bke8 Then response should be 201 And board should be in position wqd8,wkd1,bke8
Scenario: change position with a correct move Given board with position wqd3,wkd1,bke8 When move to position wqd8,wkd1,bke8 Then response should be 201 And board should be in position wqd8,wkd1,bke8
Continuous Deployment (testability)
Then /^response should be (\d{3})$/ do | expected_response_status | @move_response_status.should == expected_response_statusend
Scenario: change position with a correct move Given board with position wqd3,wkd1,bke8 When move to position wqd8,wkd1,bke8 Then response should be 201 And board should be in position wqd8,wkd1,bke8
Continuous Deployment (testability)
Then /^board should be in position (.+?)$/ do | expected_position | current_position = @client.get("#{@board}/position") current_position.content.should == expected_positionend
Continuous Deployment (testability)
Feature: change the position on board
Scenario: change position with a correct move Given board with position wqd3,wkd1,bke8 When move to position wqd8,wkd1,bke8 Then response should be 201 And board should be in position wqd8,wkd1,bke8
Scenario: change position with a correct move Given board with position wqd3,wkd1,bke8 When move to position wqd7,wkd1,bke8 Then response should be 403 And board should be in position wqd3,wkd1,bke8
Continuous Deployment (testability)coder@apollo ~/dev/cucumber/features $ cucumber change_position_on_board.feature Feature: change the position on board
Scenario: change position with a correct move # change_position_on_board.feature:3 Given board with position wqd3,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:5 When move to position wqd8,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:9 Then response should be 201 # step_definitions/change_position_on_board_steps.rb:14 And board should be in position wqd8,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:19
Scenario: change position with a correct move # change_position_on_board.feature:9 Given board with position wqd3,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:5 When move to position wqd7,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:9 Then response should be 403 # step_definitions/change_position_on_board_steps.rb:14 And board should be in position wqd3,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:19
2 scenarios (2 passed)8 steps (8 passed)
Continuous Deployment (testability)what about the view?
HTTP
Board
Game
Player
Position
Move
Js
Continuous Deployment (testability)
If i click to drag a piece, does the board highlight
reachable squares?
Continuous Deployment (testability)
Position on board is context (fixture)
We don’t care of
Model is already tested (mock)
// fixturevar piece_square = "g1"var position = "rnbqkbnr-pppp1ppp-8-4p3-4p3-8-PPPP1PPP-RNBQKBNR"
// mockvar valid_moves_url = "/position/" + position + "/piece/" + piece_square + "/moves"var YAHOO.util.Connection.asyncRequest = Chess.test.ServerMock([{ method: "GET", url: valid_moves_url, response: { code: 200 body: "moves = g1-e2, g1-f3, g1-h3" } }])
Continuous Deployment (testability)new YAHOO.tool.TestCase({ name : "testMove",
setUp: function() { this.board = Chess.board(); this.board.setupPosition(position); this.board.render("mydiv"); }, tearDown: function() { this.board.destroy(); } test_highlightReachableSquares: function() { var whiteKnight = this.board.pieceElementAt(piece_square); YAHOO.util.UserAction.mousedown(whiteKnight); this.wait(function(){ // for each g1, e2, f3, h3 YAHOO.util.Assert.isTrue( YAHOO.util.Dom.hasClass( this.board.squareElementAt("g1"), "highlight" ); ); }, 500); }}
Erlangthe secret weapon
no assignment but Pattern Matching
Continuous Deployment (testability)
1> X.* 1: variable 'X' is unbound
2> X = 5.5
3> X.5
4> X = 6.** exception error: no match of right hand side value 6
Continuous Deployment (testability)
Referentially Transparent:if a function can be
replaced with its value without changing the
program
Continuous Deployment (testability)
the function behavior is defined purely in terms of its input parameters
and return value.
Continuous Deployment (testability)
no Las Vegas
effect!
Continuous Deployment (scalability)
processes in Erlang are very cheap1> processes:profileSpawnFor(1000). Spawned 1000 processes in 10 (4) millisecondsok
2> processes:profileSpawnFor(10000). Spawned 10000 processes in 96 (40) millisecondsok
3> processes:profileSpawnFor(100000).Spawned 100000 processes in 884 (510) millisecondsok
Continuous Deployment (scalability)profileSpawnFor(Number) -> Processes = for(1, Number, fun() -> spawn(fun() -> wait() end) end), lists:foreach(fun(Pid) -> Pid ! die end, Processes).
wait() -> receive die -> void end.
Continuous Deployment (scalability)
factorials(Numbers) -> map(fun(Number) -> factorial(Number) end, Numbers).
Continuous Deployment (scalability)
factorials(Numbers) -> map(fun(Number) -> factorial(Number) end, Numbers).
factorials(Numbers) ->
pmap(fun(Number) -> factorial(Number)
end, Numbers, 20).
Distributed on20 different
processes
Continuous Deployment (scalability)
factorials(Numbers) -> map(fun(Number) -> factorial(Number) end, Numbers).
factorials(Numbers) ->
pmap(fun(Number) -> factorial(Number)
end, Numbers, 20, nodes()).
Distributed on 20 different processes for each available nodes
on the cluster
Continuous Deployment (hot-swap)
player:authorize(Request, Context).
1> c(“/home/coder/upload/player.erl”). 2> code:load_file(player).
code to update
compileand load
player:authorize(Request, Context). code updatedwithout
down-time
Continuous Deployment (hot-swap)
deploy(File) -> { ok, Module, Binary } = compile:file(File), foreach(fun(Node) -> rpc:call(Node, code, load_binary, [ Module, File, Binary ] ) end, nodes()). compile and deploy on
every node in the cluster
Conclusion
We want to create products that really satisfy our customers
... so we needa product
development methodology
... so we needa product
implementation methodology
... so we needappropriate
technologies and practices
We betterget ready because...
at the end of the day customer’s happiness is the only thing that
matters