The Shopper Development Update – C

This morning was by far one of the most productive mornings I’ve had in quite a while. I posted on Google+ that I was definitely in workaholic mode and that certainly wasn’t a lie.

So where to begin with The Shopper…

As a developer, I have a really nasty habit of incorporating test code into production code. This particular type of injection is required sometimes when I’m testing out a portion of the API that I’m unsure of which is fine. However what isn’t fine is when that code sticks without any type of polish. It then sticks out like a sore thumb and begins to pollute the rest of the project.

I like to think of the theory of broken windows here which I first heard of reading The Pragmatic Programmer.

So I sat back and literally, on my dry erase, sketched out the workflow as it should be at this point and catered the code to match. The results were astounding. I was actually seeing a performance gain on certain methods. Importantly I didn’t feel like I wanted to rip my hair out thinking about the mess I’d made.

A very important feature was completed and that is contextually sensitive menu items in the ActionBar. Logically it doesn’t make sense for all of the icons in the ActionBar to be present all of the time. It makes even more sense to only have certain icons present when certain conditions are satisfied. The benefits here are batch operations and to prevent users from doing something that, at that time, doesn’t make any sense (also eliminating exceptional circumstances). For example, you should be able to add an item at any point in time so the add item icon is present at all times. You can’t edit an item without first selecting one so that icon is hidden until an item is selected. You should be able to delete any number of items so when at least one item is selected, the delete icon is present. However you can’t batch edit so when more than one item is selected, the edit icon disappears (this is something that I think would be nice but would be difficult to express cohesively via UI).

For the time being, all custom styling has been dropped and the theme reverted back to the default Android Holo Light theme. Styling is a little more involved than I’m willing to give time to right now so it’s going to have to wait until a later date when more important things are complete.

The last big thing that was finished was a bit more technical.

Google has openly admitted that using the findViewById API is a bit expensive. More importantly, it can become cumbersome and redundant. A while ago I devised my own fix to the problem: why not store single references to the Views that are relevant per Fragment and Activity and issue calls to findViewById just once post inflation? The references were wrapped in a static class that was unique to each Activity and Fragment and this worked for some time. However some things were painfully obvious about the design here. This was taking redundancy to an extreme. Each Activity and Fragment had their own class which had the same design and same interface just different members. Typing this thing out over and over again was tiring but more importantly it wasn’t very good practice.

A thought occurred to me this morning: why not parameterize the members of this class? Seeing as how that was the last “least common denominator” challenge yet to be tackled, overcoming that meant that a separate entity could be created that could be distributed to each Activity or Fragment that required it. More importantly, if designed properly, it could hold instance-based references to other things like MenuItems. Thus ReferencePool was born.

The details are simple really. ReferencePool contains a collection that stores a nested collection (more specifically a LinkedHashMap that stores a SparseArray). The key for the parent collection is a Class instance while the key for the nested collection is an integer ID which is expected to be the Android-generated ID found in R. The reason for this is that neither collection should be explicitly tied to any one particular descendant class (with the exception of SparseArray but it stores Objects). That being the case, it would be really easy to lose the meaning of the object in syntax if the interface were not designed properly. Using a Class as a key helps to enforce, logically, that one SparseArray is linked to a specific type while making sense syntactically (derived contextually from reading the source). The method that gets an object from the collection uses generics (actually the whole class does) to return an Object casted specifically to the Class used as the collection key.

Despite my efforts to keep the collections as type-agnostic as possible it would be a valid statement to say that to some degree they aren’t. SparseArrays store Objects thus regardless of the Class key used in LinkedHashMap, you realistically could dump anything in there so long as you remembered the integer key for the Object in SparseArray. The goal was more syntactic. Originally I left it up to the client to cast out to whatever they needed by simply returning Object from the get method. So you either had one of two client situations: declaration with casted assignment or anonymous classes with nested parentheses; neither of which I wanted in client code and didn’t really suit the intended nature of the class and its interface. What I got instead, after implementing generics for the get method, was an inline generics declaration before the method call which looks a lot nicer and does what you would expect it to do. An example is here:

referencePool.<EditText>getReference(...).someMethodFromEditText()

So far this is working out nicely.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s