Office Hours — Today, December 29

Yesterday, December 28

Mark M.
has entered the room
Dec 29
7:25 PM
Mark M.
turned on guest access
7:35 PM
Aaron
has entered the room
Mark M.
hello, Aaron!
how can I help you today?
Aaron
hello, Mark, I have 3 miscellaneous questions today, here they are:
View paste
1. My RecyclerView.Adapter gets passed references to the fragment it's in, as well as the activity's ViewModel. This seems bad. I should be able to eliminate most this by passing the needed data in through the Adapter's constructor instead, except for one piece: the Adapter needs to call a method in the ViewModel to update the Room database whenever a row in the RV is clicked. I am not sure how this can be accomplished without a reference to the ViewModel. Any thoughts? https://github.com/ajh3/NoSurfForReddit/blob/master/app/src/main/java/com/aaronhalbert/nosurfforreddit/adapters/PostsAdapter.java

2. I have a question about Dagger2 components and modules, which I've already posted here. https://stackoverflow.com/questions/53952669/how-and-why-should-dagger2-components-and-modules-be-subdivided I was going to submit it to the StackOverflow bump service, but it would be helpful to go ahead talk about it in a chat context if possible. 

3. Not really an Android-specific question, with regard to Exceptions, I think I am underusing them in my code. The usual advice is to throw one in response to an "exceptional" situation, but I've found it difficult to pin down a definition of what th
...
7:40 PM
Mark M.
whew, I was afraid you were going to ask how Notre Dame might stage a comeback against Clemson...
Aaron
LOL
Mark M.
regarding #1, PostsAdapter is used in a RecyclerView that is shown by PostsFragment, right?
Aaron
exactly
Mark M.
if so, then it's reasonable for PostsAdapter to have a reference to its hosting fragment
Aaron
I see
Mark M.
if you wanted, you could pass in more focused things, like a LayoutInflater and Lifecycle
and whatever settingsStore is
those are the three things that you are using on PostsFragment
Aaron
yeah, those are the objects I was saying I could pass in through the constructor, exactly
Mark M.
or, you could say that PostsAdapter takes in a PostsAdapterHost parameter, where that is an interface that PostsFragment implements and exposes those three methods that you're calling
Aaron
OK, that also makes sense
Mark M.
either of those approaches would isolate PostsAdapter from the detail of *exactly* what's hosting it
that becomes important if the adapter might be used in multiple places, but it can be a bit of YAGNI if there are no plans to have another host
7:45 PM
Aaron
yes, unlikely
Mark M.
regarding #2, my Dagger-fu is weak, so I can't really provide advice for that, sorry
Aaron
how about line 131? that call inserts a record into Room, that's the only thing I am using the ViewModel reference for that can't be replaced by passing things into the constructor
is it reasonable to reference the VM from the adapter?
would it be...nicer...to put the method in the host fragment and just call it through that?
Mark M.
AFAIK, you're not aiming to follow some specific GUI architecture here (MVC, MVP, MVVM, MVI, etc.)
Aaron
yes, I am, MVVM
Mark M.
what are you considering your presenter to be? MVVM, despite the name, still usually has some sort of presenter/controller element
s/usually/often
Aaron
I can't really answer that. I kind of understand the role of a presenter in MVP but TBH that's new info to me that there should be a presenter in MVVM
7:50 PM
Mark M.
then, kinda by default, you're lumping that role into the view, which isn't unreasonable
particularly for a smaller app
in which case, I usually think of a RecyclerView.Adapter and similar things to be simply an extension of the activity/fragment
and that's serving as your view
so, it seems reasonable for the adapter to have a reference to the viewmodel
if you want to isolate all viewmodel interactions to the hosting fragment, that's fine, but I'm not sure it's buying you a lot
this is where MV* starts to become soup
Aaron
I guess the way I am thinking of it, the activity/fragments are performing the role of controller as well as the view
Mark M.
and it's why I try to generally steer clear of GUI architecture debates :-)
right
Aaron
I'm not super sure how "Presenter" would fit into that
Mark M.
don't worry about it
Aaron
lol, yeah, I'm sure it will become clearer as I get more experience, fair enough
Mark M.
if anything, IMHO, it'll get murkier, as your experience will differ from everyone else's
7:55 PM
Aaron
heh, or that
Mark M.
while we try to talk a good game about these things being formal GUI architectures, if you ask six developers to define MVVM, you might get six different answers
Aaron
yes, I have noticed that
Mark M.
that's one of the reasons why I try not to get hung up on that aspect of app architecture
having clean separations between the UI and backend concerns (e.g., repository pattern) are easier to get agreement on
everything else, on a team project, I'll usually let others decide, as usually they care way more than I do
regarding #3, in many cases, it depends on what the problem is and where you detect it
if you are in position to handle it without an exception, that's generally a good thing
OTOH, sometimes you can't -- you try to read in the file and it is corrupt, for example
or you make the Web service request and Reddit is having a bad day and returns a 500
or stuff like that
in the case of the Reddit 500, the exception would be thrown by OkHttp/Retrofit, and so long as you're handling it properly, life is fine
8:00 PM
Mark M.
in the case of the corrupt data, though, your own code may be the one that is defining "good" versus "corrupt", and so you may need to throw your own exception to say "halp!"
by the time the problem gets to the GUI, we need it to no longer be an exception, because we don't want the app to crash
but it may be that the simplest way for code deep in a repository to point out a problem is to throw an exception
you're probably already dealing with other exceptions (the Reddit 500 response, FileNotFoundException, etc.)
so adding another one just adds to an existing communications channel
in an app, that's the sort of scenario where I see manual exceptions being thrown
libraries might use exceptions as part of their API, particularly custom exceptions, and so they're a different beast
Aaron
right, so, I'm comfortable enough with handling exceptions thrown by other code, that's not my issue, the issue is identifying scenarios when I should throw them manually, for example:
line 139
Mark M.
onNewIntent()?
Aaron
this function handles a new intent when the user logs in, yes
(typing)
8:05 PM
Mark M.
onNewIntent(), being a framework callback method, is not the sort of place you want to be throwing an eception
er, exception
Aaron
the intent contains a code from the Reddit API that is used to log the user in
Mark M.
all that will do is crash the app
or are you referring to the exceptions that you're catching there?
Aaron
my extractCodeFromIntent() method throws a couple different exceptions, depending on whether there is a valid code or not
yes
but thing is, I could just as easily accomplish the same thing without throwing any exceptions
Mark M.
right
Aaron
I could just use some if/else logic to see whether the code is valid
Mark M.
how complicated is extractCodeFromIntent()?
Aaron
that's just one example of a place where I am not sure whether I should be using exceptions, or just if/else
not complicated
Mark M.
that's not a place where I would use a custom exception, off the cuff
Aaron
Mark M.
extractCodeFromIntent() is basically a utility function
IMHO, it should just be returning some sort of result, both for success and failure scenarios
but, if you had a similar algorithm that needed to operate on a Web service response, so you're deep inside a repository, then an exception might be reasonable
it's not the algorithm so much as it is where it is being used
8:10 PM
Mark M.
my question about the complexity was trying to figure out if the exceptions were being thrown several layers deep
and in this case, they're not
there's no particular *harm* in throwing an exception, so long as you're really sure that you're going to handle it
Aaron
thinking
Mark M.
to draw an analogy, throwing an exception is like lighting the fuse on the cartoon stick of dynamite, then handing the dynamite to a befuddled coyote, then dashing off -- so long as the coyote can do something useful with that dynamite, it's OK
if, OTOH, all the dynamite is going to do is blow up in the coyote's face, well, that's not very nice :-)
and so the tendency is to throw exceptions when better alternatives either do not exist or would require tons o' work
in your case, extractCodeFromIntent() has a simpler, less-explosive alternative
(NOTE: no actual coyotes were harmed in the creation of this chat)
Aaron
lol, I do appreciate the cartoon analogy though, that is firmly on my level :p
let me pose this another way
8:15 PM
Aaron
returning to this: "you try to read in the file and it is corrupt, for example"
Mark M.
not sure what you want me to say about the corrupt-file scenario
8:20 PM
Aaron
sorry, I lost my internet connection
what was the last message received?
Mark M.
you wrote: eturning to this: "you try to read in the file and it is corrupt, for example"
(give or take an "r")
Aaron
yeah, sorry, I am home for the holidays and my parents installed a bunch of smart devices, I think the house is now a Russian botnet
here is what I tried to send
View paste

I am just not getting what is substantially different about an example like that, that would make an exception more appropriate there. you could just as easily say, if corrupt then display an error message and show the file picker again, with no exception at all
Mark M.
well, you're not likely to be reading a file in one function deep from a framework GUI callback
my corrupt-file scenario is for a case where you have some code, buried in a repository, that runs into a problem
Aaron
hmm, so is the point, throwing exceptions is more about transferring the program control flow to somewhere else, and less about the complexity of the error?
Mark M.
that's a reasonable description
Aaron
hmm, OK, I need to think about that, it might be the missing piece that makes it click
8:25 PM
Aaron
alright, I will let you go a whole 5 minutes early, thanks as always for your help, no more questions at this time
Mark M.
OK
Aaron
have a good new year!
Mark M.
chats next week are also on an altered schedule, due to the holidays
you too!
Aaron
no problem, good night
Aaron
has left the room
Mark M.
turned off guest access

Yesterday, December 28

 

Office Hours

People in this transcript

  • Aaron
  • Mark Murphy