Use cases
            are
         important

Andrzej Krzywda
Use cases
in the code
     are
 even more
 important
class PlayTeamGameUseCase

  constructor: (@game, @player) ->
    Role(@player, PlayerWithFriends)
    Role(@game,   TeamCompetition)

  tryToEnterGameArea: () =>
    if @amIEnteringGameFirstTime()
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

      @teachPlayerHowToPlay()

    else #n-th time...
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

    if @haveNotYetPickedFavPizzaCountry()
      @askPlayerToDeclareHisFavPizzaCountry()

  (more methods here)
Name
class PlayTeamGameUseCase

  constructor: (@game, @player) ->
    Role(@player, PlayerWithFriends)
    Role(@game,   TeamCompetition)

  tryToEnterGameArea: () =>
    if @amIEnteringGameFirstTime()
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

      @teachPlayerHowToPlay()

    else #n-th time...
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

    if @haveNotYetPickedFavPizzaCountry()
      @askPlayerToDeclareHisFavPizzaCountry()

  (more methods here)
Name
class PlayTeamGameUseCase

  constructor: (@game, @player) ->      Actors
    Role(@player, PlayerWithFriends)
    Role(@game,   TeamCompetition)

  tryToEnterGameArea: () =>
    if @amIEnteringGameFirstTime()
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

      @teachPlayerHowToPlay()

    else #n-th time...
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

    if @haveNotYetPickedFavPizzaCountry()
      @askPlayerToDeclareHisFavPizzaCountry()

  (more methods here)
Name
class PlayTeamGameUseCase

  constructor: (@game, @player) ->      Actors
    Role(@player, PlayerWithFriends)
    Role(@game,   TeamCompetition)      Roles
  tryToEnterGameArea: () =>
    if @amIEnteringGameFirstTime()
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

      @teachPlayerHowToPlay()

    else #n-th time...
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

    if @haveNotYetPickedFavPizzaCountry()
      @askPlayerToDeclareHisFavPizzaCountry()

  (more methods here)
Name
class PlayTeamGameUseCase

  constructor: (@game, @player) ->      Actors
    Role(@player, PlayerWithFriends)
    Role(@game,   TeamCompetition)      Roles
  tryToEnterGameArea: () =>
    if @amIEnteringGameFirstTime()
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

      @teachPlayerHowToPlay()          Algorithm
    else #n-th time...
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

    if @haveNotYetPickedFavPizzaCountry()
      @askPlayerToDeclareHisFavPizzaCountry()

  (more methods here)
Name
class PlayTeamGameUseCase

  constructor: (@game, @player) ->      Actors
    Role(@player, PlayerWithFriends)
    Role(@game,   TeamCompetition)      Roles
  tryToEnterGameArea: () =>
    if @amIEnteringGameFirstTime()
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

      @teachPlayerHowToPlay()          Algorithm
    else #n-th time...
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()
                                                uses domain objects
    if @haveNotYetPickedFavPizzaCountry()
      @askPlayerToDeclareHisFavPizzaCountry()

  (more methods here)
Name
class PlayTeamGameUseCase

  constructor: (@game, @player) ->      Actors
    Role(@player, PlayerWithFriends)
    Role(@game,   TeamCompetition)      Roles
  tryToEnterGameArea: () =>
    if @amIEnteringGameFirstTime()
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

      @teachPlayerHowToPlay()          Algorithm
    else #n-th time...
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()
                                                uses domain objects
    if @haveNotYetPickedFavPizzaCountry()
      @askPlayerToDeclareHisFavPizzaCountry()

  (more methods here)       Nothing about GUI or persistence!
Where is?

• GUI
• Persistence
• API calls
• events
A clean use case code
   is the main goal
AOP + DCI
Aspect Oriented
 Programming
AOP gives us
method hooks
After, Before, Around
GUI & persistence
class GameUseCaseGlue
  constructor: (@gameUseCase, @game, @gui) ->

    execute: () =>
      Around(@gameUseCase,   'tryToEnterGameArea',                  @checkFbInvitation)
      After (@gameUseCase,   'tryToEnterGameArea',                  @showTeamArea)
      After (@gameUseCase,   'tryToEnterGameArea',                  @showButtonInviteOrPostPicture)
      Around(@gameUseCase,   'tellPlayerHeIsPartOfTeam',            @showTeamPopup)
      Around(@gameUseCase,   'askPlayerToLikeFanpage',              @showLikePopup)
      Around(@gameUseCase,   'teachPlayerHowToPlay',                @showTutorialPopup)
      Around(@gameUseCase,   'playerWantsToKnowWinnersWithPrize',   @showWinnersPopup)
      Around(@gameUseCase,   'playerWantsToKnowPrizes',             @showPrizesPopup)
      Around(@gameUseCase,   'askPlayerToDeclareHisFavCountry',     @showDeclareCountryPopup)
      Around(@gameUseCase,   'iAcceptMyFriendInvitationToATeam',    @onIAcceptMyFriendInvitationToATeam)

      Around(@gui, 'inviteClicked',    @inviteFriends)    # gameUseCase.inviteFriends
	
      Around(@gameUseCase, 'inviteFriends',    @storeInvitationInTheDB)     DB here

                                        Glue code
Around(@gameUseCase, 'tellPlayerHeIsPartOfTeam', @showTeamPopup)
(still glue code)

showTeamPopup: (proceed, friendsInviting) =>
  data = {inviting_friends: friendsInviting}
  popup = @popupsComponent.showPopup('team_popup', data)
  popup.onClose => proceed(friendsInviting))
DCI
class PlayTeamGameUseCase                 Use case == context
  constructor: (@game, @player) ->
    Role(@player, PlayerWithFriends)
    Role(@game,   TeamCompetition)         Roles injected runtime
  tryToEnterGameArea: () =>
    if @amIEnteringGameFirstTime()
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()
                                       data objects interact with
      @teachPlayerHowToPlay()
                                              each other
    else #n-th time...
      if @amICommingFromInvitation()
        @tellPlayerHeIsPartOfTeam()

    if @haveNotYetPickedFavPizzaCountry()
      @askPlayerToDeclareHisFavPizzaCountry()

  (more methods here)
class PlayerWithFriends
  setup: =>                                a role
    @friends = []
    @invitedFriends = []
    @acceptedFriends = []

  setInvitedFriends: (facebookUids) =>
    for facebookUid in facebookUids
      friend = new Friend({facebookUid: facebookUid})
      @invitedFriends.push(friend)

  setFriends: (friends) =>
    @friends = friends

  addFriend: (friend) =>
    existing = @getFriendByFacebookUid(friend?.facebookUid)
    if not existing?
      @friends.push(friend)
not only for
Single Page Applications
What use cases are in
   your project?
learn more about AOP and DCI and ...



   Enjoy writing
      elegant
     use cases!

Use cases in the code with AOP

  • 1.
    Use cases are important Andrzej Krzywda
  • 2.
    Use cases in thecode are even more important
  • 3.
    class PlayTeamGameUseCase constructor: (@game, @player) -> Role(@player, PlayerWithFriends) Role(@game, TeamCompetition) tryToEnterGameArea: () => if @amIEnteringGameFirstTime() if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() @teachPlayerHowToPlay() else #n-th time... if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() if @haveNotYetPickedFavPizzaCountry() @askPlayerToDeclareHisFavPizzaCountry() (more methods here)
  • 4.
    Name class PlayTeamGameUseCase constructor: (@game, @player) -> Role(@player, PlayerWithFriends) Role(@game, TeamCompetition) tryToEnterGameArea: () => if @amIEnteringGameFirstTime() if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() @teachPlayerHowToPlay() else #n-th time... if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() if @haveNotYetPickedFavPizzaCountry() @askPlayerToDeclareHisFavPizzaCountry() (more methods here)
  • 5.
    Name class PlayTeamGameUseCase constructor: (@game, @player) -> Actors Role(@player, PlayerWithFriends) Role(@game, TeamCompetition) tryToEnterGameArea: () => if @amIEnteringGameFirstTime() if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() @teachPlayerHowToPlay() else #n-th time... if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() if @haveNotYetPickedFavPizzaCountry() @askPlayerToDeclareHisFavPizzaCountry() (more methods here)
  • 6.
    Name class PlayTeamGameUseCase constructor: (@game, @player) -> Actors Role(@player, PlayerWithFriends) Role(@game, TeamCompetition) Roles tryToEnterGameArea: () => if @amIEnteringGameFirstTime() if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() @teachPlayerHowToPlay() else #n-th time... if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() if @haveNotYetPickedFavPizzaCountry() @askPlayerToDeclareHisFavPizzaCountry() (more methods here)
  • 7.
    Name class PlayTeamGameUseCase constructor: (@game, @player) -> Actors Role(@player, PlayerWithFriends) Role(@game, TeamCompetition) Roles tryToEnterGameArea: () => if @amIEnteringGameFirstTime() if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() @teachPlayerHowToPlay() Algorithm else #n-th time... if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() if @haveNotYetPickedFavPizzaCountry() @askPlayerToDeclareHisFavPizzaCountry() (more methods here)
  • 8.
    Name class PlayTeamGameUseCase constructor: (@game, @player) -> Actors Role(@player, PlayerWithFriends) Role(@game, TeamCompetition) Roles tryToEnterGameArea: () => if @amIEnteringGameFirstTime() if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() @teachPlayerHowToPlay() Algorithm else #n-th time... if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() uses domain objects if @haveNotYetPickedFavPizzaCountry() @askPlayerToDeclareHisFavPizzaCountry() (more methods here)
  • 9.
    Name class PlayTeamGameUseCase constructor: (@game, @player) -> Actors Role(@player, PlayerWithFriends) Role(@game, TeamCompetition) Roles tryToEnterGameArea: () => if @amIEnteringGameFirstTime() if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() @teachPlayerHowToPlay() Algorithm else #n-th time... if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() uses domain objects if @haveNotYetPickedFavPizzaCountry() @askPlayerToDeclareHisFavPizzaCountry() (more methods here) Nothing about GUI or persistence!
  • 10.
    Where is? • GUI •Persistence • API calls • events
  • 11.
    A clean usecase code is the main goal
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
    class GameUseCaseGlue constructor: (@gameUseCase, @game, @gui) -> execute: () => Around(@gameUseCase, 'tryToEnterGameArea', @checkFbInvitation) After (@gameUseCase, 'tryToEnterGameArea', @showTeamArea) After (@gameUseCase, 'tryToEnterGameArea', @showButtonInviteOrPostPicture) Around(@gameUseCase, 'tellPlayerHeIsPartOfTeam', @showTeamPopup) Around(@gameUseCase, 'askPlayerToLikeFanpage', @showLikePopup) Around(@gameUseCase, 'teachPlayerHowToPlay', @showTutorialPopup) Around(@gameUseCase, 'playerWantsToKnowWinnersWithPrize', @showWinnersPopup) Around(@gameUseCase, 'playerWantsToKnowPrizes', @showPrizesPopup) Around(@gameUseCase, 'askPlayerToDeclareHisFavCountry', @showDeclareCountryPopup) Around(@gameUseCase, 'iAcceptMyFriendInvitationToATeam', @onIAcceptMyFriendInvitationToATeam) Around(@gui, 'inviteClicked', @inviteFriends) # gameUseCase.inviteFriends Around(@gameUseCase, 'inviteFriends', @storeInvitationInTheDB) DB here Glue code
  • 18.
  • 19.
    (still glue code) showTeamPopup:(proceed, friendsInviting) => data = {inviting_friends: friendsInviting} popup = @popupsComponent.showPopup('team_popup', data) popup.onClose => proceed(friendsInviting))
  • 20.
  • 21.
    class PlayTeamGameUseCase Use case == context constructor: (@game, @player) -> Role(@player, PlayerWithFriends) Role(@game, TeamCompetition) Roles injected runtime tryToEnterGameArea: () => if @amIEnteringGameFirstTime() if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() data objects interact with @teachPlayerHowToPlay() each other else #n-th time... if @amICommingFromInvitation() @tellPlayerHeIsPartOfTeam() if @haveNotYetPickedFavPizzaCountry() @askPlayerToDeclareHisFavPizzaCountry() (more methods here)
  • 22.
    class PlayerWithFriends setup: => a role @friends = [] @invitedFriends = [] @acceptedFriends = [] setInvitedFriends: (facebookUids) => for facebookUid in facebookUids friend = new Friend({facebookUid: facebookUid}) @invitedFriends.push(friend) setFriends: (friends) => @friends = friends addFriend: (friend) => existing = @getFriendByFacebookUid(friend?.facebookUid) if not existing? @friends.push(friend)
  • 23.
    not only for SinglePage Applications
  • 24.
    What use casesare in your project?
  • 25.
    learn more aboutAOP and DCI and ... Enjoy writing elegant use cases!