disclaimer disclaimer
play

Disclaimer Disclaimer This talk is not about the front end - PowerPoint PPT Presentation

Disclaimer Disclaimer This talk is not about the front end Disclaimer This talk is about software architecture Disclaimer This talk is about software architecture (Yes, at 18:00 on a Saturday. Sorry not sorry) BACK We asked for


  1. Disclaimer

  2. Disclaimer This talk is not about the front end

  3. Disclaimer This talk is about software architecture

  4. Disclaimer This talk is about software architecture (Yes, at 18:00 on a Saturday. Sorry not sorry)

  5. BACK

  6. We asked for responsibilities

  7. The Art(?) of Front-end Architecture

  8. 👌 Hi! I’m Adrià Fontcuberta Senior(?) Software Engineer @ Holaluz Member of the o ffi cial Vue Test Utils Member of Testing Library Co-organizer of VueJS Barcelona @afontq afontcu.dev

  9. HLFF20

  10. What are* we aiming for?

  11. What are* we aiming for? Write maintainable, scalable apps

  12. What are* we aiming for? Write maintainable, Stay away from the scalable apps framework

  13. What are* we aiming for? Write maintainable, Stay away from the scalable apps framework Share knowledge between teams and areas

  14. What are* we aiming for? Write maintainable, Stay away from the scalable apps framework Share knowledge Reduce the gap between between teams and areas Front and Back

  15. This is not about writing good software, but how to build software that can change over time

  16. Business stuff Delivery stuff

  17. Business stuff Delivery stuff

  18. Business stuff Delivery stuff

  19. Business stuff Delivery stuff

  20. Delivery stuff

  21. Domain Use cases Delivery stuff

  22. Domain

  23. Domain Use cases

  24. Domain Use cases Delivery

  25. This layer has two streams of data

  26. Infrastructure

  27. Infrastructure UI / Input

  28. Infrastructure API repositories Cookies Web Storage

  29. UI ¯ \_( ツ )_/ ¯

  30. What does layer really mean?

  31. Dependencies only point inwards

  32. Dependencies only point inwards An inner layer should never rely on anything from an outer layer.

  33. Dependencies only point inwards An inner layer should never rely on anything from an outer layer.

  34. Use case “ Get user information ” depends on “ User ”

  35. Use case “ Get user information ” depends on “ User ”

  36. Use case “ Get user information ” depends on “ User ”

  37. Use case “ Get user information ” depends on “ User ” Use case “ Get user information ” depends on the UI framework

  38. Use case “ Get user information ” depends on “ User ” Use case “ Get user information ” depends on the UI framework

  39. Use case “ Get user information ” depends on “ User ” Use case “ Get user information ” depends on the UI framework

  40. BACK

  41. The Web is a delivery mechanism

  42. It is not the center . It is external.

  43. It is really, really hard to get it right

  44. We need to adapt its content for our inner layers

  45. We need to adapt its content for our inner layers

  46. Domain Use cases Infrastructure Adapter UI

  47. Domain Use cases Infrastructure Adapter UI

  48. Domain Independent of Use cases the framework Infrastructure Adapter UI

  49. Domain Independent of Use cases the framework Infrastructure Adapter The framework™ UI

  50. Domain Independent of Use cases the framework Infrastructure

  51. Domain Independent of Use cases the framework Infrastructure

  52. infra UI adapter app* domain

  53. infra 👪 UI adapter app* domain

  54. Actions Mutations State Actions Reducers State View View

  55. infra UI adapter app domain

  56. infra 👪 UI adapter app domain

  57. infra state mutations UI app domain actions

  58. infra state 👪 mutations UI app domain actions

  59. type Coordinate = 0 | 1 | 2 type Sign = "X" | "O" | "" class Board { public isFull() : boolean {} public isPositionTaken(cell: Cell) : boolean {} public fillPosition(cell: Cell, player: Player) : void {} } class Cell { private row: Coordinate private col: Coordinate } class Player { public sign: Sign public equals(player: Player) : boolean {} }

  60. type Coordinate = 0 | 1 | 2 type Sign = "X" | "O" | "" class Board { THIS IS NOT public isFull() : boolean {} public isPositionTaken(cell: Cell) : boolean {} public fillPosition(cell: Cell, player: Player) : void {} } "THE RITE WAY” class Cell { private row: Coordinate private col: Coordinate } class Player { public sign: Sign public equals(player: Player) : boolean {} }

  61. type Coordinate = 0 | 1 | 2 type Sign = "X" | "O" | "" class Board { public isFull() : boolean {} public isPositionTaken(cell: Cell) : boolean {} public fillPosition(cell: Cell, player: Player) : void {} } class Cell { private row: Coordinate private col: Coordinate } class Player { public sign: Sign public equals(player: Player) : boolean {} }

  62. class Game { private board: Board private isEnded: () : boolean private getLastPlayer() : Player public makeMove(player: Player, cell: Cell) : void { if (this.isEnded()) throw new FinishedGameException() if (player.equals(this.getLastPlayer())) throw new AlreadyPlayedException() if (this.board.isPositionTaken(cell)) throw new AlreadyTakenException() this.board.fillPosition(cell, player) } }

  63. function makeMoveUseCase({ game, player, cell }, { onSuccess, onError }) { try { game.makeMove(player, cell) } catch (error) { onError(error) return } onSuccess(player, cell) }

  64. function makeMoveUseCase({ game, player, cell }, { onSuccess, onError }) { try { game.makeMove(player, cell) } catch (error) { onError(error) return } onSuccess(player, cell) }

  65. function makeMoveUseCase({ game, player, cell }, { onSuccess, onError }) { try { game.makeMove(player, cell) } catch (error) { onError(error) return } onSuccess(player, cell) }

  66. import { makeMoveUseCase } from 'application/ ��../ ' const actions = { makeMove({ state, commit }, cell) { commit('MAKE_MOVE_REQUEST') makeMoveUseCase({ player: state.currentPlayer, game: state.game, cell }, { onSuccess: (player) �=? commit('MAKE_MOVE_SUCCESS', player), onError: (error) �=? commit('MAKE_MOVE_ERROR', error.message) }) } }

  67. import { makeMoveUseCase } from 'application/ ��../ ' const actions = { makeMove({ state, commit }, cell) { commit('MAKE_MOVE_REQUEST') makeMoveUseCase({ player: state.currentPlayer, game: state.game, cell }, { onSuccess: (player) �=? commit('MAKE_MOVE_SUCCESS', player), onError: (error) �=? commit('MAKE_MOVE_ERROR', error.message) }) } }

  68. import { makeMoveUseCase } from 'application/ ��../ ' $(‘#submit_move’).click(function() { makeMoveUseCase( { player: $('#current_player').val(), game: window.game, cell: [$('input[name="row"]').val(), $('input[name="col"]').val()] }, { onSuccess: () �=? $('#success_message').fadeIn('slow'), onError: () �=? window.alert('oops something went wrong') } ) })

Recommend


More recommend