Hello, dear readers, and welcome to my thoughts on the MVP (Model-View-Presenter) pattern, which I finally got around to learning. I had tried before, but everybody always explained it so abstractly that, even when compared to MVVM abstractly, I couldn’t tell what it was. But I recently got to see the pattern being implemented in some live-coding episodes I don’t really have a whole lot to share; I’m focusing on one mini anti-pattern within the typical implementation that I’d like to provide alternative ideas for.
General Thoughts on MVP
First, I will give you my overall thoughts on MVP. My first thought about it is, “Is this really any different than MVC?” And truly, MVP is pretty much what I had always thought of MVC to be. The problem wasn’t MVC, in my opinion, but what so many people had come to think MVC was. Having heard what Uncle Bob has said about MVC, it’s clear that there has been severe “evolution” to the community’s understanding of MVC, but the MVC I was taught in college is almost exactly the same thing as MVP, with all the differences being negligible compared to the differences between my understanding of MVC and so many others’ understanding.
Beyond all that, though, I do like MVP, overall. When done correctly, it follows the Clean Architecture. Unfortunately, many people’s understanding of a domain model (or “entity” in Clean Architecture) goes against what I follow, which is akin to Domain Driven Design’s understanding, which I believe Uncle Bob (the creator of Clean Architecture) leans toward as well. With that said, I’m fine with letting others do that part however they like, since there are so many conflicting ideas about it. Really, the pattern is fine, except for the one anti-pattern I’m focusing on today.
Cyclic References in MVP
From what I’ve seen, everyone implements MVP with a cyclic reference. And I can understand why, it’s the simplest and most obvious way to implement the pattern. Almost no matter what system you develop in, the View is also going to be the system that receives events, and for the events (or commands derived from the events) to get to the Presenter, the View must have a reference to the Presenter. This is all as it should be. The problem comes from the fact that the Presenter is then expected to give commands back to the View after doing its business with the Model. Typically, this is done by a simple method call on the View object that is stored on the Presenter. Boom! Cyclic reference. The View holds a reference to the Presenter, which holds a reference to the View.
How Do We Get Around This?
The most obvious way to get around a cyclic reference is to instead pass the View in as an argument to the Presenter’s methods. This is simple, straightforward, and just a tad tedious (that’s a lot of typing “this”), but if you care about avoiding cyclic references, this is certainly a way to go.
Another way to go is to return some sort of command object. This is sort of old-fashioned OO and would likely require a lot of type checking and casting to determine which kind of command is returned and grabbing the data needed to do it. I would not recommend this.
A “solution” that I’ve seen someone use is to make the reference to the View a weak reference (one that isn’t counted by the garbage collector). While this gets around the biggest reason why cyclic references are bad, it doesn’t actually get rid of the cycle. If you don’t really care about cyclic references, I would still recommend doing this at least, and if you’re doing MVP in Android, I recommend checking out the android-arch-sample repository on GitHub, as it shows how someone can use a weak reference as well as some other scaffolding to make it so the Presenter replaces its View object when there’s a configuration change (such as rotating the screen), since configuration changes cause the Activity (which doubles as the View) to be destroyed and rebuilt. It also has the single greatest use of a stateful Singleton I’ve ever seen. There’s a way around it needing to be a Singleton, I’m sure, but I don’t actually want to get around it, it’s so clever.
So, what do I think is the best solution to avoiding cyclic references? Lambdas. It’s similar to the command solution, but instead of returning a command, you returns an anonymous function via lambda or method reference which the View will then call, passing itself in as an argument. It’s more functional, and not just because it uses higher-order functions. Rather, it’s more functional because the Presenter methods now have something to return. They can be pure (though they’re not likely to be because the model will be accessing some sort of mutable data store, most likely), since they’re not calling the “void” methods on View. It leaves the impure functions to be called at the outermost layer, the View, which is ideal.
What Do I Really Think?
Now, having said that I think that lambdas are the best solution, I’m not actually convinced of that. Theoretically, it’s the best, since the Presenter never has any reference to the View, but is it actually?
- It relies on the View to call the returned function, which it can totally ignore doing, and easily forget to do.
- Even using lambdas isn’t likely to keep the Presenter pure because it accesses the Model, which is likely to use a mutable data store.
- All you’re really doing is moving the same calls you were going to make anyway, but not they’re in a lambda or method reference.
My actual suggestion, until I can come up with a better idea or better reason for something else, is to pass the View in as an argument. That is, unless you’re using Android (it’s the only system I know of that destroys and completely rebuilds its Activities – or equivalent), where I recommend following the pattern in the android-arch-sample repository.
Until next time, thank you for reading.
Last week, I showed you my new implementation for instance-level properties in Python. This week, we’ll take another look at it by implementing a few Delegated Properties and helpers to make using them just a hair nicer.
Recreating Kotlin’s Built-In Delegates
For inspiration of what Delegated Properties to create, we’ll start by recreating the ones built into Kotlin, starting with
Lazy. Continue Reading
A while back, I did a post on making instance-level properties in Python where the implementation of it required inheritance as well as messing with
__setattr__(), which are a little dangerous to mess with. Then I had another idea last night (as of the time of writing this): Use normal descriptors to delegate to “Delegated Properties” (name taken from Kotlin, the original inspiration). These Delegated Properties can be designed very simply in a way that they only have to worry about the value on one instance, instead of figuring out how to store the value per instance. Continue Reading
Well, my Watch Later playlist on YouTube is extra full now! A bunch of videos from really big programming conferences have just dropped.
PyCon 2017: 144 Videos!
Google IO 2017: 158 Videos!
Now, obviously not all videos are going to interest everyone, but there’s something for just about any Python programmer in the PyCon list, and I only went through the Android videos for GoogleIO and I got 10 videos added.
With Google IO came a really cool announcement for Kotlin-Android developers, too: Kotlin is now getting first class support from Google for Android!
Sorry about being terrible at keeping up to date with my blog; Legend of Zelda Breath of the Wild is partially to blame, but it’s still all my fault 🙂 Even this new post isn’t a proper post.
I just wanted to make sure as many people as possible have heard about the latest Humble Bundle! At the $1+ level, you get Automate the Boring Stuff with Python (a pretty decent book; I’ve looked through it), Doing Math with Python, Teach Your Kids to Code, and the No Starch Sampler (No Starch Press is the publisher of most, if not all the books in the bundle). At the $8+ level, there’s Gray Hat Python, Python Playground: Geeky Projects for the Curious Programmer, and Python for Kids. In the final, $15+ level, you get Black Hat Python, Invent Your Own Computer Games With Python, and Python Crash Course: A Hands-On, Project-Based Introduction to Programming.
This is a crazy deal, since most of these books are worth more than $10 individually. PLUS, the money you pay can be divided however you like between No Starch Press, HumbleBundle.com, and the Python Software Foundation! I focused mostly on supporting the PSF, but made sure to share some with the other two as well. I hope many of you go and purchase some level of this bundle and help support Python and Python publishers!
So, this post was going to be completely different. I was going to do a post on how you can restrict the creation and scoping of certain objects using Python’s
with code blocks. Unfortunately,
with doesn’t restrict scope. Take the following code sample: Continue Reading