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!