Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature [RM61] Created and Implemented CharactersViewModel #65

Merged
merged 5 commits into from
Aug 9, 2021

Conversation

swg99
Copy link
Contributor

@swg99 swg99 commented Aug 2, 2021

https://github.com/orgs/novoda/projects/1#card-65878596
The CharactersView now consumes a CharactersViewModel which is injected into the view from the ContentView. CharactersViewModel provides all the data for the CharactersView.

Built the CharactersViewModel which is injected into the CharactersView from the ContentView.
@swg99 swg99 linked an issue Aug 2, 2021 that may be closed by this pull request
Comment on lines 19 to 23
if characterType == .rick {
characters = ricks
} else {
characters = morties
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function would be more testable with return value private func fetchCharacters() -> [Character].

Also for this length of function you could use

characters = characterType == .rick ? ricks : morties

Comment on lines 26 to 32
private func getTitle() -> String {
if characterType == .rick {
return "Ricks"
} else {
return "Morties"
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar here,

return  characterType == .rick ? "Ricks" : "Morties"

Comment on lines +43 to +48
extension CharactersViewModel {
enum CharacterType {
case rick
case morty
}
}
Copy link
Member

@gbasile gbasile Aug 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting: this is violating the Open Closed principle :P
You would have to modify the ViewModel if you want to add Summer or Jerry

Why don't you define a struct instead?

struct CharacterViewState {
    let title: String
    let name: String
    let description: String
    let imageName: String
    let imagePosition: CharacterImagePosition
}

If you feed your ViewModel with an array of this model, you won't need to take decisions anymore inside your ViewModel ;)

Copy link
Contributor Author

@swg99 swg99 Aug 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created a CharacterViewState and a CharactersViewState which holds an array of CharacterViewState's (naming could probably be better).

A CharactersViewState is made for each CharacterType in the new ContentViewModel. I don't think there is a need for a CharactersViewModel anymore. Check out my new commit, it should make more sense.

fetchCharacters()
}

private func fetchCharacters() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ViewModel has 2 responsibilities:

  • Feed the views with ViewStates
  • Decide how to fetch the data

Can you imagine how you can move one of this responsibility out?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this out into a CharactersManager class. The class needs to be modified if new CharacterTypes are added, have not been able to find a way around this.

ContentViewModel is now used instead of CharactersViewModel. The ContentViewModel produces CharactersViewStates. The ContentViewModel follows the open-closed principal, however the CharactersManager, CharacterViewStateFactory and CharactersViewStateFactory do not.

All these classes and struct will need to be refactored into different files, as of now the ViewState structs, factory classes and CharactersManager are all in the ContentViewModel file.
Moved factories into a dedicated folder and moved CharactersManager into misc folder.
Comment on lines +21 to +28
/*
struct CharactersView_Previews: PreviewProvider {
static var previews: some View {
CharactersView(characters: ricks, title: "Ricks")
//CharactersView(viewModel: CharactersViewModel(characterType: .rick))
//CharactersView(viewModel: CharactersViewModel(characterType: .morty))
}
}
*/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be removed. there is no need for commented out code. You have a repo to check for old versions if you really need to :)

@swg99 swg99 merged commit 7f680b1 into scottie-main Aug 9, 2021
@swg99 swg99 deleted the feature/rm-61-CharactersViewModel branch August 9, 2021 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Build and implement CharactersViewModel
3 participants