WhitestarMediaLibrary – database management, Oh CRUD.

As part of implementing the WhitestarMediaLibary project once it had been reviewed using SOLID principles, In this post I will cover adding a database interface and implementation.

The first thing that I realised when I came to implement the database interface is I had not considered the update and delete operators. This would be in keeping with the CRUD paradigm. Creating the interface was standard fare, as was moving the database parts of the WhitestarMusicLibrary to a new class DB40MusicDatabase.

Another item I noticed was missing from the design stage was exceptions so I created 2 exceptions: MediaNotFound and UnsupportedMedia. The class structure is now:

In addition to this a general search method has been added to the Database interface. This search method takes a predicate WhitestarMedia instead of using method overloading e.g search(String track), search(Date year) etc. The only issue this presents if one wanted to search for a date range. However at this stage I am trying to focus on structure (SOLID) and not creating functionality.

 

 

Implementation – It is easy to have ideas but practicing them can be hard.

Constantine Stanislavski once wrote:

It is easy to have ideas in art but it can be hard to put them into practice.

I have long learnt that this applies to everything, not just art. In recent posts I have reviewed a project, WhitestarMediaLibrary, using SOLID and other design principles. I have got to the stage where I feel I should start writing some code and altering the project so it reflects the new structure.

However, there are issues with the implementation and over the next couple of posts I will cover these.  The first of these problems is in regard to the libraries. In previous posts I discussed using a Properties object that contains the class to be injected and any configuration that is required for the object is then fed the same properties object. What I did not decide in previous posts is which class is responsible for instantiating the library.  I also added two custom exception classes if an error occurs when instantiating the library. The resulting class diagram is below:

 

 

I am now thinking, was this the best way to do this? Could I have used a factory method where a class takes the config object instantiates the library and the factory feeds the library the properties file? This would be more in keeping with Single Responsibility Principle. Now the WhitestarLibrary class retrieves libraries but delegates the creation and initialisation to a factory class e.g. LibraryFactory. The resulting structure is now:

 

 

Further Design Priniciples

As part of refining the design of the WhiteStarMediaLibrary, what other design principles could I apply?

 

Encapsulate what changes

This is defined by JPassion.com as:

“Encapsulate the code that is expected to change in the future.”

So when looking at the WhitestarMediaLibrary the areas I would expect to change are the MediaType, CatagoryOption and the Library implementation classes. I have already used an interface for the library class with this very thought in mind. However the MediaType and CatagoryOption classes are Enums. How would I add Book to the MediaType or add a new music genre e.g. grime? Enums, by their very nature, are static and so it would be impossible to do this at run time unless we used dependency injection. But this is then reliant on the developer to add this every time a new genre comes out. The original reason I picked Enums was for their speed, how I could use them to group subgenres together and how I could have consistency in music types between differing libraries. This will require further thought.

Don’t Repeat Yourself (DRY)

It is recommended that abstraction is used to group common functionality in one place. This design already incorporates this in the abstraction of whitestarmedia. From looking at the design I cannot see at this stage what other functionality is to be abstracted.  I do feel there should be more than just the whitestarmedia. Perhaps when I start to finish the implementation further examples will come to light.

 

Don’t look for things. Ask for things – Dependency Injection.

When I was looking at ‘Encapsulating what changes’ in a previous post, I discussed the MediaType and CategoryOptions and how changes with introductions of new media types or music genres could be included without having to use dependency injection.  However, if I chose dependency injection and used this to add new genres for example, this could cause problems.

Imagine a new music genre is created called ‘crocky’ (county rocking yelping), a new module is written which is used to replace the existing CategoryOptions class. However ‘Crocky’ never takes off and it is removed from the next version of CategoryOptions. You can guarantee that somewhere, someone will be a Crocky fan and find their favourite media player can no longer find their tracks because the library will not be able to understand the category retrieved by the whitestarlibrary.  However there could be an abstract method for when media is retrieved that checks the category type is valid. Then it is up to the library implementation how this is handled. Until I can think of a better solution the CategoryOptions shall use dependency injection.

Dependency injection is also vaunted as an aid to testing. I will therefore have to return to this topic once I move on to the’ Jpassion JUnit, Mocking, TDD and refactoring’ course. For next post I will concentrate on design patterns.

There is a good article regarding dependency injection at the codewhisperer’s blog which can be found here:

http://blog.thecodewhisperer.com/permalink/keep-dependency-injection-simple