Slide 1

Slide 1 text

IT'S A KOTLIN, KOTLIN, KOTLIN WORLD! JAKE WHARTON PRESENTS

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

X

Slide 4

Slide 4 text

X O X X X O

Slide 5

Slide 5 text

X O X X X O O O X

Slide 6

Slide 6 text

XOPlayer X X X O O O X XOPlayer

Slide 7

Slide 7 text

iOS Web Server / API Android

Slide 8

Slide 8 text

app/

Slide 9

Slide 9 text

app/ wear/

Slide 10

Slide 10 text

app/ wear/ common/

Slide 11

Slide 11 text

app/ wear/ common/

Slide 12

Slide 12 text

wear/ common/ app/

Slide 13

Slide 13 text

app/ wear/ common/

Slide 14

Slide 14 text

app/ wear/ common/

Slide 15

Slide 15 text

app/ wear/ util/ common/

Slide 16

Slide 16 text

app/ wear/ common/ util/ models/

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

package xo; public enum Mark { X, O; }

Slide 19

Slide 19 text

package xo; import java.util.Arrays; public final class Board { private static final int SIZE = 3; private final Mark[][] cells; public Board() { this.cells = new Mark[3][3]; } // TODO mutator methods... @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Board)) return false; Board other = (Board) o; return Arrays.deepEquals(cells, other.cells); } @Override public int hashCode() { return Arrays.deepHashCode(cells);

Slide 20

Slide 20 text

package xo; import static java.util.Objects.requireNonNull; public final class Player { public final String name; public final Mark mark; public Player(String name, Mark mark) { this.name = requireNonNull(name, "name == null"); this.mark = requireNonNull(mark, "mark == null"); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Player)) return false; Player other = (Player) o; return name.equals(other.name) && mark == other.mark; } @Override public int hashCode() { return 31 * name.hashCode() + mark.hashCode(); }

Slide 21

Slide 21 text

package xo; public enum State { PLAYER_1_MOVE, PLAYER_2_MOVE, PLAYER_1_WIN, PLAYER_2_WIN, DRAW, }

Slide 22

Slide 22 text

package xo; import static java.util.Objects.requireNonNull; public final class Game { private final Board board; private final Player player1; private final Player player2; private State state = State.PLAYER_1_MOVE; public Game(Board board, Player player1, Player player2) { this.board = requireNonNull(board, "board == null"); this.player1 = requireNonNull(player1, "player1 == null"); this.player2 = requireNonNull(player2, "player2 == null"); } // TODO mutator methods... @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Game)) return false; Game other = (Game) o; return board.equals(other.board) && player1.equals(other.player1)

Slide 23

Slide 23 text

Game Board Mark State Player

Slide 24

Slide 24 text

public final class Player { public final String name; public final Mark mark; public Player(String name, Mark mark) { this.name = requireNonNull(name, "name == null"); this.mark = requireNonNull(mark, "mark == null"); }A @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Player)) return false; Player other = (Player) o; return name.equals(other.name) && mark == other.mark; }B @Override public int hashCode() { return 31 * name.hashCode() + mark.hashCode(); }C @Override public String toString() { return "Player{name='" + name + ", mark=" + mark + '}'; }D }E

Slide 25

Slide 25 text

data class Player(val name: String, val mark: Mark) public final { public final ; public final ; public Player(String name, Mark mark) { this.name = requireNonNull(name, "name == null"); this.mark = requireNonNull(mark, "mark == null"); }A @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Player)) return false; Player other = (Player) o; return name.equals(other.name) && mark == other.mark; }B @Override public int hashCode() { return 31 * name.hashCode() + mark.hashCode(); }C @Override public String toString() { return "Player{name='" + name + ", mark=" + mark + '}'; }D }E

Slide 26

Slide 26 text

Game Mark State Board Player

Slide 27

Slide 27 text

State Board Game Mark Player

Slide 28

Slide 28 text

Game Mark State Board *.java *.kt Player

Slide 29

Slide 29 text

*.kt Game Mark State *.java

Slide 30

Slide 30 text

kotlinc *.kt Game Mark State *.java

Slide 31

Slide 31 text

*.kt Game Mark State *.java kotlinc

Slide 32

Slide 32 text

javac *.kt Game Mark State *.java kotlinc

Slide 33

Slide 33 text

javac *.kt Game Mark State *.java kotlinc

Slide 34

Slide 34 text

kotlinc javac *.kt Game Mark State *.java

Slide 35

Slide 35 text

kotlin-stdlib kotlinc javac *.kt Game Mark State *.java

Slide 36

Slide 36 text

kotlin-stdlib kotlinc javac *.kt Game Mark State *.java models/

Slide 37

Slide 37 text

kotlin-stdlib kotlinc javac *.kt Game Mark State *.java models/

Slide 38

Slide 38 text

kotlin-stdlib kotlinc javac *.kt Game Mark State *.java models/

Slide 39

Slide 39 text

kotlin-stdlib kotlinc javac *.kt Game Mark State *.java

Slide 40

Slide 40 text

kotlin-stdlib kotlinc Game Mark State javac *.kt *.java

Slide 41

Slide 41 text

kotlin-stdlib kotlinc Game Mark State javac *.kt *.java

Slide 42

Slide 42 text

kotlin-stdlib kotlinc State Mark Game javac *.kt *.java

Slide 43

Slide 43 text

kotlin-stdlib kotlinc State *.java Mark Game javac *.kt

Slide 44

Slide 44 text

kotlin-stdlib kotlinc *.java State Mark Game *.kt

Slide 45

Slide 45 text

app/ wear/ common/ util/ models/ kotlin-stdlib kotlinc *.java State Mark Game *.kt

Slide 46

Slide 46 text

app/ wear/ common/ util/ models/

Slide 47

Slide 47 text

Server / API iOS Web Android app/ wear/ common/ util/ models/

Slide 48

Slide 48 text

Server / API iOS Web Android app/ wear/ util/ models/ common/

Slide 49

Slide 49 text

Server / API iOS Web Android app/ wear/ util/ models/ common/

Slide 50

Slide 50 text

Server / API iOS Web Android app/ wear/ util/ models/ common/

Slide 51

Slide 51 text

Server / API iOS Web Android app/ wear/ util/ models/ common/ protos

Slide 52

Slide 52 text

iOS Web Server / API Android

Slide 53

Slide 53 text

iOS Web Server / API Android

Slide 54

Slide 54 text

iOS Web Server / API Android View Models

Slide 55

Slide 55 text

iOS Web Server / API Android View Models Presenters

Slide 56

Slide 56 text

iOS Web Server / API Android View Models Presenters

Slide 57

Slide 57 text

iOS Web Server / API Android View Models Presenters Client Backend

Slide 58

Slide 58 text

iOS Web Server / API Android View Models Presenters Client Backend

Slide 59

Slide 59 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic

Slide 60

Slide 60 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 61

Slide 61 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 62

Slide 62 text

data class NewGameUiModel( val winTotal: Long, val lossTotal: Long )

Slide 63

Slide 63 text

data class NewGameUiModel( val winTotal: Long, val lossTotal: Long ) data class GameUiModel( val game: Game )

Slide 64

Slide 64 text

data class NewGameUiModel( val winTotal: Long, val lossTotal: Long ) data class GameUiModel( ) val game: Game

Slide 65

Slide 65 text

data class NewGameUiModel( val winTotal: Long, val lossTotal: Long ) data class GameUiModel( val game: Game )

Slide 66

Slide 66 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 67

Slide 67 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 68

Slide 68 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 69

Slide 69 text

class NewGamePresenter {C fun model(): NewGameUiModel { }B }A

Slide 70

Slide 70 text

class NewGamePresenter(private val gameStore: GameStore) {C fun model(): NewGameUiModel { }B }A

Slide 71

Slide 71 text

class NewGamePresenter(private val gameStore: GameStore) {C fun model(): NewGameUiModel { val totals = gameStore.totals() return NewGameUiModel(totals.wins, totals.losses) }B }A

Slide 72

Slide 72 text

class GamePresenter {D fun model(): GameUiModel {C }B }A

Slide 73

Slide 73 text

class GamePresenter(private val gameId: Long) {D fun model(): GameUiModel {C }B }A

Slide 74

Slide 74 text

class GamePresenter( private val gameId: Long, private val gameStore: GameStore ) {D fun model(): GameUiModel {C }B }A

Slide 75

Slide 75 text

class GamePresenter( private val gameId: Long, private val gameStore: GameStore ) {D fun models(): Observable {C }B }A

Slide 76

Slide 76 text

class GamePresenter( private val gameId: Long, private val gameStore: GameStore ) {D fun move(row: Int, col: Int)Z{C }G fun models(): Observable {C }B }A

Slide 77

Slide 77 text

class GamePresenter( private val gameId: Long, private val gameStore: GameStore ) {D fun models(events: Observable): Observable {C }B sealed class UiEvent { data class Move(val row: Int, val col: Int): UiEvent() // ... } }A fun move( )Z{C }G

Slide 78

Slide 78 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 79

Slide 79 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 80

Slide 80 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 81

Slide 81 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 82

Slide 82 text

interface GameStore { }A

Slide 83

Slide 83 text

interface GameStore { fun totals(): Single data class Totals(val wins: Long, val losses: Long) }A

Slide 84

Slide 84 text

interface GameStore { fun totals(): Single fun game(id: Long): Observable data class Totals(val wins: Long, val losses: Long) }A

Slide 85

Slide 85 text

interface GameStore { fun totals(): Single fun game(id: Long): Observable fun move(id: Long, row: Int, col: Int): Completable data class Totals(val wins: Long, val losses: Long) }A

Slide 86

Slide 86 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 87

Slide 87 text

iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 88

Slide 88 text

Android iOS Web iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 89

Slide 89 text

class SqliteGameStore(private val db: SQLiteDatabase) : GameStore { override fun totals() = TODO() override fun game(id: Long) = TODO() override fun move(id: Long, row: Int, col: Int) = TODO() }

Slide 90

Slide 90 text

class IosGameStore(private val db: CoreDataGameStore) : GameStore { override fun totals() = TODO() override fun game(id: Long) = TODO() override fun move(id: Long, row: Int, col: Int) = TODO() }

Slide 91

Slide 91 text

class IosGameStore( ) : GameStore { override fun totals() = TODO() override fun game(id: Long) = TODO() override fun move(id: Long, row: Int, col: Int) = TODO() } private val db: CoreDataGameStore

Slide 92

Slide 92 text

class IosGameStore( ) : GameStore { override fun totals() = TODO() override fun game(id: Long) = TODO() override fun move(id: Long, row: Int, col: Int) = TODO() } private val db: CoreDataGameStore // tictactoe.def headers = game_store.h

Slide 93

Slide 93 text

class StorageGameStore(private val store: Storage) : GameStore { override fun totals() = TODO() override fun game(id: Long) = TODO() override fun move(id: Long, row: Int, col: Int) = TODO() }A

Slide 94

Slide 94 text

import org.w3c.dom.Storage class StorageGameStore( ) : GameStore { override fun totals() = TODO() override fun game(id: Long) = TODO() override fun move(id: Long, row: Int, col: Int) = TODO() }A private val store: Storage

Slide 95

Slide 95 text

Android iOS Web iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 96

Slide 96 text

Android iOS Web iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 97

Slide 97 text

Android iOS Web iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 98

Slide 98 text

Android iOS Web iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 99

Slide 99 text

object TicTacToeLogic { fun validateMove( game: Game, player: Player, row: Int, col: Int): Boolean { when (game.state) { State.PLAYER_1_MOVE -> require(game.player1 == player) State.PLAYER_2_MOVE -> require(game.player2 == player) else -> error("Game is over") } return game.board[row][col] == null } fun nextState(game: Game): State { findWinner(game.board)?.let { return if (game.player1.mark == it) State.PLAYER_1_WIN else State.PLAYER_2_WIN } if (game.board.isComplete()) { return State.DRAW } return if (game.state == State.PLAYER_1_MOVE) State.PLAYER_2_MOVE else State.PLAYER_1_MOVE } fun findWinner(board: Board): Mark? = TODO() fun Board.isComplete(): Boolean = TODO() }

Slide 100

Slide 100 text

Android iOS Web iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 101

Slide 101 text

Android iOS Web iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 102

Slide 102 text

Android iOS Web iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 103

Slide 103 text

Android iOS Web iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 104

Slide 104 text

class GameView(context: Context, attrs: AttributeSet) : Consumer { fun accept(model: GamePresenter.UiModel) { // TODO bind to view... } }

Slide 105

Slide 105 text

iOS???

Slide 106

Slide 106 text

function update(model) { // TODO bind to DOM/template/JSX/whatever... }

Slide 107

Slide 107 text

@POST @Path("/api/move") fun Game move( @QueryParam("id") id: Long, @QueryParam("row") row: Int, @QueryParam("col") col: Int) { // TODO check business logic, persist, return udpated game ... }

Slide 108

Slide 108 text

Android iOS Web iOS Web Server / API Android View Models Presenters Client Backend Business Logic Models

Slide 109

Slide 109 text

X O X X X O O O X

Slide 110

Slide 110 text

IT'S A KOTLIN, KOTLIN, KOTLIN WORLD! @JAKEWHARTON