Sunday, June 14, 2009

Parameterized factory design pattern in Android Media Service Framework

As i was going through the Media framework of Android, i have found the implementation of a parameterized factory pattern in the way MediaPlayerService class creates the concrete media players.

Let me give an idea of the parameterized factory implementation as discussed in the GoF book. It goes like this.

class Creator {

public:

virtual Product* CreateProduct( ProductId id);

};

And the implementation will look like the following:

Product* Creator :: CreateProduct (ProductId id)
{

if (id == Product1) return new Product1;

if (id == Product2) return new Product2;

//repeat for the other products

return 0;

}

Product1, Product2 etc are all derived from the base class Product.

Now let us dissect the Media Framework of Android to see how this design pattern has been implemented to create the different Media players.

The base class of all the players are MediaPlayerInterface which is again derived from MediaPlayerBase.

MediaPlayerService has got a static function called

"static sp createPlayer(player_type playerType, void* cookie, notify_callback_f notifyFunc)"

which actually takes care of the creation of the concrete players namely PVPlayer, MidiFile and VorbisPlayer.

Hence the class MediaPlayerService works as the Factory class for creating the Concrete Players besides handling other responsibilities.

The class MediaPlayerService can be found at \base\media\libmediaplayerservice of the Android source code.

The createPlayer function goes like the following :

static sp(MediaPlayerBase) createPlayer(player_type playerType, void* cookie,
notify_callback_f notifyFunc)
{
sp(MediaPlayerBase) p;
switch (playerType) {
#ifndef NO_OPENCORE
case PV_PLAYER:
LOGV(" create PVPlayer");
p = new PVPlayer();
break;
#endif
case SONIVOX_PLAYER:
LOGV(" create MidiFile");
p = new MidiFile();
break;

case VORBIS_PLAYER:
LOGV(" create VorbisPlayer");
p = new VorbisPlayer();
break;
}
if (p != NULL) {
if (p->initCheck() == NO_ERROR) {
p->setNotifyCallback(cookie, notifyFunc);
} else {
p.clear();
}
}
if (p == NULL) {
LOGE("Failed to create player object");
}
return p;
}

As we can see from the above code that MediaPlayerBase here works as the base class Product. And we create different products (different concrete media players) through the function createPlayer which works as the CreateProduct function in the example at the beginning.

The above similarity shows how a Parameterized Factory Pattern has been implemented in the Android Media Framework by MediaService layer to create different Media Players.

Wednesday, June 3, 2009

Composite Design Pattern in Android View and Widget

The Intent of this design pattern is stated in the GoF book as "Compose Objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly".

To explain it in a simpler fashion, let me give the same example as given in the GoF book. Suppose there is an object called Picture, a graphics object. This picture may consist of other pictures recursively as well as primitive objects like line, rectangle objects etc. All of these part objects which make the whole picture conform to the same Graphic interface. Hence to the client, a part object appears same as the whole picture consisted of other part objects. To draw a whole object, the client simply traverses through the whole picture and draws different parts.

The class diagram of the composite design pattern will look like the following:




The following participants take part in this design pattern:

Component -

it declares the interface for the objects ( part as well as whole)
helps in managing the objects (adding, removing)

Leaf -

represents leaf objects which don't have any children
these are the primitive objects

Composite -

defines behavior for components having children
stores the children

Client -

takes help of the Component interface to manipulate different objects

If you want to know more about the Composite Design Pattern, please have a look at

http://som-itsolutions.blogspot.in/2008/12/composite-design-pattern-is-structural.html

Its all about the theoretical side of the Composite Design Pattern. Now let us try to dissect the Android View and the Widget folders (which are available at \\base\core\java\android) to see how this design pattern has been implemented there.

In Android, the View class works as the Component class. However, the child management part (add component, remove component) has been moved to the Composite class which is the ViewGroup class. Actually the Add and Remove of a component has been declared in an interface called ViewManager and the ViewGroup implements that interface. Also the interface for a Composite object is declared as ViewParent interface and the ViewGroup (the Composite object) implements that as well.

The leaf classes like Button, ImageView etc are deduced either by directly subclassing the View (Component) or from the subclasses of the View (for example, the Button class is derived from TextView class which in turn is directly derived fron the View class). The Composite Class (ViewGroup) is deduced by directly subclassing the View and by implementing the two interfaces namely ViewParent (which defines the interface of a composite object) and ViewManager (which defines the interface from adding and removing components).

As expected the getParent function which is needed to get the Parent of a component is put in the View class (the Component).

The Composite object (ViewGroup) has an array to hold its children.

The simplified version of the class diagram of the Android View and Widgets are as follows:



For simplicity i have not shown the two interfaces namely ViewManager and ViewParent.

Now let us consider the class diagram as presented in the beginning of this discussion. There is a function called Operation. In Android implementation, the onDraw function in the Component (View) plays this role. The DispatchDraw function (which is called when the children are to be drawn) in the composite (ViewGroup) object actually traverses through the list of the objects and calls draw on each of the child object.
This becomes clear when we see the android source code of the dispatchDraw function in the andrroid.view.ViewGroup class. The code is as follows:

 @Override
 protected void More dispatchDraw(Canvas canvas) {

......................
.....................
....................

 for (int i = 0; i < count; i++) {
                final View child = children[i];
                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || 
                                              child.getAnimation() != null)
               {
                   more |= drawChild(canvas, child, drawingTime);
               }
         }
......................
......................

For simplicity, in the class diagram it is shown that the dispatchDraw function is directly calling the onDraw function. However it actually takes help of another function called drawChild which is called on each child object of the ViewGroup object.

This way we can say that Android View and Widgets are some sort of implementation of the Composite Design Pattern.