Use Case with 2 ways for the same action

后端 未结 4 1797
梦谈多话
梦谈多话 2021-02-10 09:57

Question 1: What is the correct way to build a Use Case (or more than one) with 2 ways to do the same action?

For example:

I have a 3 screens in

4条回答
  •  难免孤独
    2021-02-10 10:28

    Use Case Modeling and VIPER Design considerations for - Create, Edit and View "A Place on Map" for a iOS based mobile application

    Your questions

    1. What to do if - Create, Edit and View actions end-up in the same ViewController?

    2. Is it a good idea if MapViewController uses PlacesInteractor to retrieve the places and the CurrentLocationInteractor to request user's location authorization and getting the most updated coordinates?

    It is not a problem to combine related logic into single Interactor. But it will not longer be an "Interactor". It will become a "service" or "manager" as in MapPlaceManager/MapPlaceService which will have methods such as:

    canCreateMapPlace
    createMapPlace(Details)
    
    getMapPlaceCount
    getMapPlaceIDs
    getMapPlaceDetails(ID)
    
    canUpdateMapPlace
    updateMapPlace(ID, NewDetails)
    

    I think the idea was to expose only the intended APIs per use case and hence Interactor - which can clearly state what the user of that Interactor is going to do with it. If it has multiple APIs that can do different things like create/edit/delete map places, then we have to check the method calls in the caller to know what the caller is going to do. Interactors in this sense to me are very high level - business/requirements level interfaces. You can hide your back-end services and managers inside these individual Interactors.

    You can take this notion to as far as possible and/or feasible - Feasible rather possible. There will be an extreme where we draw the line, instead of following it too religiously. Business systems tend to be more formal and methodical to give you an example.

    In your case, when a button is pressed on your main view that changes your MapPlaceView into MapPlaceEditView, you are changing the use case that the new view is going to satisfy. Such in-place view changes are appropriate view design considerations for mobile and also it is use friendly. However, often it encourages complex GUI and messy presenter logic. If it is manageable, cleaner and easier for your ViewController/Presenter to switch "modes" between "Create, View, Edit" - you are good to go. It is not perfect, but it is not wrong. They are Front-End-Participants and have the highest level of freedom and frequency of changes anyway.

    An alternate good UI design I have found useful instead of in-place fields editing, is "flipping" the views or any such view transition effect. You can have a MainMapPlacePresenter/ViewController and it has 3 sub views - for Create, Edit and View. This main view is then responsible for switching between these three views. It enables cleaner navigation, cleaner use case implementations and neat design.

    Similarly for CurrentLocationInteractor, it does two things - 1. request permission to use "device location service" and 2. use "device location service". Now, it seems it is not an Interactor at all. It is Front-End functionality. But you can use SaveAuthorizationInteractor to save user's choice. But that is different thing. The more I think, Interactors are responsible for things that deal with your system and not with your user.

    Presenter does all the "user-talking" and "decision-making" work - they may use device APIs if they need e.g. Location Service. You can create abstract interface ILocationService and wrapper implementation called LocationService that will absorb user's device location service - low level implementation and platform-specific detail.

    In implementation terms: You can have:

    MainPresenter/MainViewController
    On Load - Show MapView along with Buttons for Edit and Create Map Place
    
    MapPresenter/MapViewController
    On Load - Show Map
        Navigations - login, authorization, create, edit
        Interactions - none
    
    MapPlaceCreatePresenter/MapPlaceCreateViewController
        On Load - call MapPlaceCreateInteractor.canCreateMapPlace - Response = {AllGood, UserNotLoggedIn, LocationIsNotAuthorized}
        Interaction - MapPlaceCreateInteractor.createMapPlace - Responses = {PlaceCreatedSuccessfully}
        Navigations - Login, Location Authorization, Back to Main View (With Response - UserLoginNeeded, UserAuthorizationForLocationAccessNeeded)
    
    MapPlaceUpdatePresenter/MapPlaceUpdateViewController
        On Load - call MapPlaceUpdateInteractor.canUpdateMapPlace
        Interaction - MapPlaceUpdateInteractor.updateMapPlace(ExistingMapPlaceID, NewDetails) - Responses = {PlaceUpdatedSuccessfully}
        Navigations - Login, Location Authorization, Back to Main View (With Response - UserLoginNeeded, UserAuthorizationForLocationAccessNeeded)
    

提交回复
热议问题