Saturday, December 8, 2012

Why getting the architecture right makes everything run better

While jogging some days ago I was, as usual, listening to music on my relatively smart phone. I have a play list for jogging with which I always use the “shuffle” option. At a certain point in time and physical exhaustion I wanted to listen to another song so I clicked “Next”.

To my surprise the next song was not part of the play list. It was a nice song from Portishead but not really good for jogging... so I had to slow down, go through the phone menus and get shuffle mode to work again. Not good.

This made me start thinking about what could be wrong with this simple app’s architecture.  I also noticed that the app doesn’t allow to shuffle within one play list – one must “shuffle all” playlists.
This is a likely implementation:
  • Shuffling in the app is done by creating a song index out of all the songs in all play lists and then playing them in a loop;
  • When the user presses the button to move to the next song the loop is broken and the next song on the database is chosen instead.

That's indicative that the layered structure is not designed to support playlists and shuffle play correctly. This is what the architecture might look like:


In this design the user can choose either a playlist or the base song catalogue to play. The “shuffleAll()” function is completely controlled by the main player app (PlayerAppUI object) and “moveNext()” just calls “play()” for the next song in the BaseSongCatalog, therefore breaking the shuffle play loop.

Here is another architecture that would make shuffling work correctly:



Here there’s an intermediate layer (with the “SongPlayer” and “ShufflePlayer” super and sub classes respectively) that is responsible for providing the services for browsing songs. In this case if a user presses “Next”, the request is deferred to the selected player which will know which song is next (in this proposal that is achieved by means of an Enumerator in each subclass). While some methods of the app will use the specialised subclass (e.g. shuffle player), most (moveNext, movePrevious) just need to use the super class and defer the specific player features to the subclass that is in use. Other players can be easily added in this design – for example one that gets songs from an internet streaming service – without affecting the general part of the user interface except for any specific functions. In shuffle play that means reshuffling; in the internet streaming case it could mean selecting the web site for example.
Meanwhile there have been a few updates to this app but there are always problems and limitations with it. When the structure is wrong, fixing it is almost impossible. 

That’s why it’s important to get the architecture right before implementation, even in a small app - which has nonetheless a huge user base. 

No comments:

Post a Comment

Comments are always welcome. They will be moderated for posts older than 14 days. In that case a delay of a few hours can be expected before publishing.