42
Sexy Architecting VIPER: MVP on steroids Dmytro Zaitsev Mobile Team Lead

Sexy Architecting. VIPER: MVP on steroids

Embed Size (px)

Citation preview

Page 1: Sexy Architecting. VIPER: MVP on steroids

Sexy ArchitectingVIPER: MVP on steroids

Dmytro ZaitsevMobile Team Lead

Page 2: Sexy Architecting. VIPER: MVP on steroids
Page 3: Sexy Architecting. VIPER: MVP on steroids
Page 4: Sexy Architecting. VIPER: MVP on steroids
Page 5: Sexy Architecting. VIPER: MVP on steroids
Page 6: Sexy Architecting. VIPER: MVP on steroids
Page 7: Sexy Architecting. VIPER: MVP on steroids
Page 8: Sexy Architecting. VIPER: MVP on steroids

MVP/MVC/MVVM is NOT an Architecture!It’s only responsible for the presentation layer delivery mechanism

Page 9: Sexy Architecting. VIPER: MVP on steroids

Real-world Android app●Hard to understand●Hard to maintain

●The business logic is mixed in Activity/Fragment●High coupled components●MVC -> Massive View Controllers

●Hard and often impossible to test

Page 10: Sexy Architecting. VIPER: MVP on steroids
Page 11: Sexy Architecting. VIPER: MVP on steroids

Clean Architecture●Independent of Frameworks●Testable

●Independent of Database●Independent of any external agency

●Independent of UI

Page 12: Sexy Architecting. VIPER: MVP on steroids

“The Web is an I/O Device!

-Robert Martin

Page 13: Sexy Architecting. VIPER: MVP on steroids
Page 14: Sexy Architecting. VIPER: MVP on steroids
Page 15: Sexy Architecting. VIPER: MVP on steroids

What is VIPER?●A way of architecting applications which takes heavy inspiration

from the Clean Architecture●Divides an app’s logical structure into distinct layers of responsibility●Makes it easier to isolate dependencies●Makes it easier test the interactions at the boundaries between

layers●Eliminates Massive View Controllers

Page 16: Sexy Architecting. VIPER: MVP on steroids

Main parts of VIPER●View●Interactor●Presenter●Entity●Router

Page 17: Sexy Architecting. VIPER: MVP on steroids
Page 18: Sexy Architecting. VIPER: MVP on steroids

ViewDisplays what it is told to by the Presenter and relays user input back to the Presenter

Page 19: Sexy Architecting. VIPER: MVP on steroids

View●Is passive

●Waits for the Presenter to give it content to display

●Never asks the Presenter for data

●Determines how the content is displayed

●Handles user interaction and input●Simply delegates user’s actions to the Presenter

●Awaits for a response telling it what should be displayed next

Page 20: Sexy Architecting. VIPER: MVP on steroids

internal interface CheeseViewCallbacks { fun onNewCheese(cheese: Collection<CheeseViewModel>) fun showError() fun hideProgress() fun showProgress()}

Example of View

Page 21: Sexy Architecting. VIPER: MVP on steroids
Page 22: Sexy Architecting. VIPER: MVP on steroids

class CheeseView : ConstraintLayout, CheeseViewCallbacks { @Inject internal lateinit var presenter: CheesePresenter private lateinit var progressDialog : ProgressDialog private lateinit var adapter : CheeseAdapter /** ... */ override fun onNewCheese(cheese: Collection<CheeseViewModel>) { adapter.setModels(cheese) adapter.notifyDataSetChanged() } override fun showError() { Toast.makeText(context, R.string.error, Toast.LENGTH_SHORT).show() } override fun hideProgress() = progressDialog.dismiss() override fun showProgress() = progressDialog.show()}

Example of View

Page 23: Sexy Architecting. VIPER: MVP on steroids

PresenterContains view logic for preparing content for display (as received from the Interactor) and for reacting to user inputs (by requesting new data from the Interactor)

Page 24: Sexy Architecting. VIPER: MVP on steroids

Presenter●Knows about the content it maintains and when it should be

displayed●Receives input events coming from the View

●Applies view logic over this data to prepare the content●Tells the View what to display

●Sends requests to an Interactor

●Works like a bridge between the main parts of a VIPER module

●Receives the data structures coming from the Interactor

●Knows when to navigate to another screen, and which screen to navigate to

Page 25: Sexy Architecting. VIPER: MVP on steroids

class CheesePresenter(private val getCheeseInteractor: GetCheeseInteractor) { var view: CheeseViewCallbacks? = null var router: MainRouter? = null /** ... */ fun fetchCheese(сount: Int) { view?.showProgress() getCheeseInteractor.execute({ cheese -> // onNext view?.onNewCheese(cheese) view?.hideProgress() }, { throwable -> // onError view?.showError() view?.hideProgress() }, сount) } fun onItemClicked(model: CheeseViewModel) = router?.navigateToDetails(model)}

Example of Presenter

Page 26: Sexy Architecting. VIPER: MVP on steroids

InteractorContains the business logic as specified by a use case

Page 27: Sexy Architecting. VIPER: MVP on steroids

Interactor

●Represents use cases●Regular Java object●No Android framework dependency

●Encapsulates application specific business rules

Page 28: Sexy Architecting. VIPER: MVP on steroids

class GetCheeseInteractor @Inject constructor( private val subscribeOn : Scheduler, private val observeOn : Scheduler, private val cheeseStorage: CheeseStorage) { private val subscriptions = CompositeSubscription()

fun execute(subscriber: Subscriber<Collection<Cheese>>, сount: Int) { subscriptions.add(cheeseStorage.getCheese(сount) .subscribeOn(subscribeOn) .observeOn(observeOn) .subscribe(subscriber)) }}

Example of Interactor

Page 29: Sexy Architecting. VIPER: MVP on steroids

EntityContains basic model objects used by the Interactor

Page 30: Sexy Architecting. VIPER: MVP on steroids

Entity

●POJOs●Encapsulates different types of data

●Model objects manipulated by an Interactor

Page 31: Sexy Architecting. VIPER: MVP on steroids

data class Cheese( val id : Long, val name : String, val price : Long, val description : String, val type : String, val texture : String, val fatContent : String, val animalMilk : String, val regionOfOrigin: String)

Example of Entity

Page 32: Sexy Architecting. VIPER: MVP on steroids

RouterContains navigation logic for describing which screens are shown in which order

Page 33: Sexy Architecting. VIPER: MVP on steroids
Page 34: Sexy Architecting. VIPER: MVP on steroids
Page 35: Sexy Architecting. VIPER: MVP on steroids

Router

●Responsible for passing data between screens●Receives input commands from the Presenter

●Responsible for the navigation logic between modules

Page 36: Sexy Architecting. VIPER: MVP on steroids

internal interface MainRouter { fun navigateToDetails(model: CheeseViewModel) fun navigateToPreferences() fun navigateToRegistration()}

Example of Router

Page 37: Sexy Architecting. VIPER: MVP on steroids

class MainActivity : AppCompatActivity(), MainRouter { override fun navigateToDetails(model: CheeseViewModel) { startActivity(Intent(this, DetailsActivity::class.java).apply { with(this) { putExtra(DetailsActivity.NAME, model.name) putExtra(DetailsActivity.CHECKED, model.isChecked) } }) } override fun navigateToPreferences() { startActivity(Intent(this, SettingsActivity::class.java)) } override fun navigateToRegistration() { supportFragmentManager.beginTransaction() .replace(R.id.content, LoginFragment()) .commit() }}

Example of Router

Page 38: Sexy Architecting. VIPER: MVP on steroids

Why should you use VIPER?●It’s easier to track issues via crash reports●The source code will be cleaner, more compact and reusable●Adding new features is easier●There are less conflicts with the rest of the development

team●It’s easier to write automated tests

Page 39: Sexy Architecting. VIPER: MVP on steroids

When should you NOT use VIPER?●It’s an overkill for small projects●Causes an overhead when starting new projects●MVP/MVC/MVVM-VIPER mix can cause headaches●Lots of code all over the project

Page 40: Sexy Architecting. VIPER: MVP on steroids

Testing

●Presentation layer○Espresso, Robolectric

●Domain layer○JUnit, TestNG, Mockito, PowerMock

●Data layer○Robolectric, JUnit, TestNG, Mockito, PowerMock

Page 41: Sexy Architecting. VIPER: MVP on steroids

References

●http://mutualmobile.github.io/blog/2013/12/04/viper-introduction/●http://www.mttnow.com/blog/architecting-mobile-apps-with-bviper-modu

les

●http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/●http://fernandocejas.com/2015/07/18/architecting-android-the-evolution/

●https://www.objc.io/issues/13-architecture/viper/

●https://github.com/RxViper/RxViper

●https://www.ckl.io/blog/ios-project-architecture-using-viper/

●http://luboganev.github.io/post/clean-architecture-pt2/

Page 42: Sexy Architecting. VIPER: MVP on steroids

Thank you!Questions?

Dmytro Zaitsev@DmitriyZaitsev