Tuesday, November 17, 2009

Experimentation with Design Pattern

Note: Download the source code from https://github.com/sommukhopadhyay/SalesTax

I am yet to study the book Pattern Hatching. However, i tried to accumulate all my knowledge on Design Pattern and solved a problem of Accountancy. i would like to share it with you. Let me, first of all, state the problem.

The Problem :

Basic sales tax is applicable at a rate of 10% on all goods, except books, food, and medical products that are exempt. Import duty is an additional sales tax applicable on all imported goods at a rate of 5%, with no exemptions. Also the Sales Tax should be rounded off to the nearest 0.05.

This being the problem, we need to come out with a solution for this problem.

Now let me tell you how my thought process went into it to think it at an abstract level.

First of all, i thought to make two top level classes. One that will define the Items having different benchmarks for Sales Tax and Import Duty; i.e.

1. Food, Medical and Book items which are not imported and hence exempted from both sales tax and import duty
2. Non Food Book and Medical items which are not imported and hence will have just the Sales Tax
3. Food Book and Medical items which are imported and hence will have only import duty
4. Non food book and medical items which are imported and hence will have both Sales Tax and Import Duty

And the other for the Tax Calculation algorithm for different items.

Then i thought this is a perfect match for Strategy Pattern that i had studied in the GoF book. I thought about that pattern keeping in mind for the future expansion of the Tax Calculation Algorithm. What i mean is that for the present problem, the calculation is simple. And hence it does not need any other Strategy. However, for the future purpose if the Tax Calculation Algorithm is changed to some complicated one, then we can just Subclass the Tax Calculation class and attach that strategy to the Item Class.

Next i thought, won't it be nice to get a Factory Class through which the client can create different Items on the fly. Hence i have decided to create an ItemCreator class which is nothing but a parameterized factory class for creating different Items on the fly.

And i came out with the following solution.

The Item class Hierarchy:


File: Item.h

#ifndef ITEM_H
#define ITEM_H

class SalesTax;

//This represents the Items which don't have an Import duty or any sales tax
class Item
{
public:

//Constructors
Item();
Item (SalesTax* aSalesTax);

//Interface Functions for Item

//To calculate the price after tax and import duty
virtual void CalculateTotalPrice();

//To calculate the total tax and import duty
virtual void CalculateTotalTax();

//To set the price of the Items
void SetPrice(double aPrice);

//To get the price of the Items before tax
double getPrice();

//To get the price of the items after tax
double getTotalPrice();

//To get the total tax and import duty of the items
double getTax();

//Data
protected:
//Works as the Strategy of the Sales Tax problem.
//If in future the tax calculation becomes more complicated for different Items
//we will just have to change this Strategy. We can also subclass this Strategy class
//for future expansion of the tax calculation strategy
SalesTax* iSalesTax;
//Data
protected:

//These are the basic properties of any Item.
//Hence these are made protected members so that the subclasses of Item can inherit
//these properties
double iPrice;
double iTotalPrice;
double iTotalTax;
};

//This class represents the Items which have only Import Duty
class ImportedItem : virtual public Item
{
public:
//Constructors
ImportedItem();

//This constructor helps to create Items having only Import duty
ImportedItem(SalesTax* aSalesTax, double aImportDuty);

//Override
virtual void CalculateTotalTax();

protected:
double iImportDuty;
};

//This class represents the Items which have only Sales Tax but no Import Duty

class NonFoodBookMedicalItem : virtual public Item
{
public:
//Constructors
NonFoodBookMedicalItem();

//This constructor helps to create Items having only Sales tax
NonFoodBookMedicalItem(SalesTax* aSalesTax, double aRate);
//Override
virtual void CalculateTotalTax();

protected:
double iRate;
};



//This class represents the Items which have got both Import Duty as well as sales Tax
class NormalItem: public ImportedItem, public NonFoodBookMedicalItem
{
public:
NormalItem();
//This constructor helps to create Items having both Sales tax and Import duty
NormalItem(SalesTax* aSalesTax, double aRate, double aImportDuty);

//Override
virtual void CalculateTotalTax();
};

#endif

As you can see the four classes solve the hierarchy for different items having different benchmark for Sales Tax and import Duty.

The Item.cpp file looks like the following:

File: Item.cpp
#include "SalesTax.h"
#include "Item.h"

Item::Item(){}

Item::Item(SalesTax* aSalesTax):iSalesTax(aSalesTax),iPrice(0),iTotalPrice(0),iTotalTax(0)
{
}

void Item::CalculateTotalPrice()
{
iTotalPrice = iPrice + iTotalTax;
}

double Item::getTotalPrice()
{
return iTotalPrice;
}


void Item::CalculateTotalTax()
{
iTotalTax = iSalesTax->ComputeSalesTax(iPrice, 0, 0);
}

void Item::SetPrice(double aPrice)
{
iPrice = aPrice;
}

double Item::getPrice()
{
return iPrice;
}

double Item::getTax()
{
return iTotalTax;
}
ImportedItem::ImportedItem(){}

ImportedItem::ImportedItem(SalesTax* aSalesTax, double aImportDuty):Item(aSalesTax)
{
iImportDuty = aImportDuty;
}
void ImportedItem::CalculateTotalTax()
{
iTotalTax = iSalesTax->ComputeSalesTax(iPrice, 0, iImportDuty);

}
NonFoodBookMedicalItem::NonFoodBookMedicalItem(){}

NonFoodBookMedicalItem::NonFoodBookMedicalItem(SalesTax* aSalesTax, double aRate):Item(aSalesTax)
{
iRate = aRate;
}

void NonFoodBookMedicalItem::CalculateTotalTax()
{
iTotalTax = iSalesTax->ComputeSalesTax(iPrice, iRate, 0);

}
NormalItem::NormalItem() {}

NormalItem::NormalItem(SalesTax* aSalesTax, double aRate, double aImportDuty):Item(aSalesTax)
{
iRate = aRate;
iImportDuty = aImportDuty;
}
void NormalItem::CalculateTotalTax()
{
iTotalTax = iSalesTax->ComputeSalesTax(iPrice, iRate, iImportDuty);
}

Now let us concentrate on the Sales Tax class

file: SalesTax.h

//This class works as the Strategy of the Sales tax problem
class SalesTax
{
public:

//Default constructor
SalesTax();

//This function helps to compute the Sales Tax
virtual double ComputeSalesTax(double aPrice, double aRate, double aImportduty);

private:
//This is an helper function which will round off the sales tax
double RoundOff(double aTax);
};


And the implementation of the Sales tax is as follow:

file: SalesTax.cpp

#include "SalesTax.h"

SalesTax::SalesTax(){}

double SalesTax::ComputeSalesTax(double aPrice, double aRate, double aImportduty)
{
double tx = (aPrice*aRate/(double(100))) + (aPrice*aImportduty/(double(100)));
return RoundOff(tx);
}
//private:
double SalesTax::RoundOff(double aTax)
{
int taxTemp = (int)aTax;

double decimaltaxTemp = (double)(aTax - (int)taxTemp);

int tempy = (int)(1000*decimaltaxTemp)/100;

int tempz = (int)(1000*decimaltaxTemp - tempy*100);

int temp = (int)(tempz/10);

int t = tempz%10;

if (t >= 5)
temp+=1;

return (double)(taxTemp + tempy*(0.1) + temp*(0.01));
}

As you can see the the data for calculation are being passed from the Item class.

Hence we can say this is in abstract form an implementation of the Strategy Pattern where the Item class is working as the Context and the Sales Tax class is acting as the sole Strategy interface.

Now lets concentrate on the creation of the Items.

As i have already mentioned, this is done through a Parameterized factory class called ItemCreator.

This class looks like the following:

File: ItemCreator.h

#include "Item.h"

const int ITEM_WITH_NOSALESTAX_AND_IMPORTDUTY = 1;
const int ITEM_WITH_NOSALESTAX_ONLY_IMPORTDUTY = 2;
const int ITEM_WITH_ONLY_SALESTAX_AND_NOIMPORTDUTY = 3;
const int ITEM_WITH_BOTH_SALESTAX_AND_IMPORTDUTY = 4;

const double SALES_TAX_RATE = 10;
const double IMPORT_DUTY_RATE = 5;

class Not_A_Standard_Item_Type_Exception
{
public:
void printerrormsg();
};
class ItemCreator
{
public:
virtual Item* Create(int aItemId);
};

And the implementation of this ItemCreator is as follow:

file: ItemCreator.cpp


#include "ItemCreator.h"
#include "Item.h"
#include "SalesTax.h"

using namespace std;

void Not_A_Standard_Item_Type_Exception::printerrormsg()
{
cout <<"Not the right Item Type..." <<endl;
}

Item* ItemCreator::Create(int aItemId)
{
SalesTax* st = new SalesTax();

switch(aItemId)
{
case ITEM_WITH_NOSALESTAX_AND_IMPORTDUTY:
return new Item(st);
break;

case ITEM_WITH_NOSALESTAX_ONLY_IMPORTDUTY:
return new ImportedItem(st,IMPORT_DUTY_RATE);
break;

case ITEM_WITH_ONLY_SALESTAX_AND_NOIMPORTDUTY:
return new NonFoodBookMedicalItem(st,SALES_TAX_RATE);
break;

case ITEM_WITH_BOTH_SALESTAX_AND_IMPORTDUTY:
return new NormalItem(st,SALES_TAX_RATE,IMPORT_DUTY_RATE);
break;

default:
throw Not_A_Standard_Item_Type_Exception();
}
}

And the client program will look like the following:



#include "SalesTax.h"
#include "Item.h"
#include "ItemCreator.h"

#include <vector>

using namespace std;

void main()
{
typedef vector&lt;Item*&gt;  listOfItem; 
listOfItem::iterator theIterator;

listOfItem Basket;
char answer = 'n';

double totalprice = 0;
double totaltax = 0;

do
{
int type_of_item;

cout <<"Enter the type of Item...1,2,3,4" <<endl;

cout <<"1 for ITEM_WITH_NOSALESTAX_AND_NOIMPORTDUTY"  <<endl;

cout <<"2 for ITEM_WITH_NOSALESTAX_ONLY_IMPORTDUTY"<<endl;

cout <<"3 for ITEM_WITH_ONLY_SALESTAX_AND_NOIMPORTDUTY"<<endl;

cout<<"4 for ITEM_WITH_BOTH_SALESTAX_AND_IMPORTDUTY" <<endl;

cin>>type_of_item;

ItemCreator* itemCreator = new ItemCreator();

try 
{
Item* item = itemCreator->;Create(type_of_item);

cout <<"Enter the price of the Item" <<endl;

double price;

cin >>price;

item->SetPrice(price);

Basket.push_back(item);
}

catch(Not_A_Standard_Item_Type_Exception&amp; e)
{
e.printerrormsg();
}

cout<<"Do you want to continue... Y/N" <<endl;
cin>>answer;
}
while (answer =='y');

theIterator = Basket.begin();

int pos = 0;
while (theIterator != Basket.end())
{
Basket.at(pos)->CalculateTotalTax();
totaltax+=Basket.at(pos)->getTax();

Basket.at(pos)->CalculateTotalPrice();

double price = Basket.at(pos)->getPrice();

double price_after_tax = Basket.at(pos)->getTotalPrice();

totalprice+=price_after_tax;
cout<<"Item"  <<pos+1 <<" price " <<price  <<endl;
theIterator++;
pos++; 
}
cout<<"------------" <<endl;
cout<<"Toal tax " <<totaltax <<endl;
cout<<"Total price "<<totalprice<<endl;
}



 Fig : The Class Diagram
Thus the problem is solved using two common design pattern concepts - Strategy Pattern and Parameterized Factory Pattern.

This is the way i am trying to move from the problem domain to the solution domain using design pattern concepts.

Hope this helps others who are studying Design Pattern.

Monday, November 9, 2009

My first experience with Ubuntu Karmic kola



I felt very excited after I read the review comments about Ubuntu 9.1, the Karmic Kola distribution of Ubuntu... However, with over-enthusiasm, I could not wait for the official release... I downloaded the release candidate a few days before the official release of Ubuntu 9.1...

As I have used only Windows so far, I was a bit worried about my transition to Ubuntu... However, so far it was smooth...

After downloading the release candidate of the Ubuntu 9.1, i had to burn the CD... I used ImgBurn to do that... What one needs is a blank 700 MB writable CD... The burning process did not take much time...

Then with caution, I inserted the CD for the installation... The installation got started... And it hardly took 20 minutes to completely install it...

I restarted my computer... There were two options to boot up - one for my old Windows XP and the other was Ubuntu... I chose the second one... The login screen came in no time... I entered my password... And voila... The system came up within a flash... I thought I needed to do a lot of configuration for my internet connection... To test it I just clicked the Firefox menu on the top of the desktop... And no wonder, the Ubuntu Google came up in a flash...

I was delighted...

With a little help through Googling, I found that for a developer, the build-essential package is a must... After that, I did some research and found the Synaptic Package Manager Under System... I opened it... Searched for build-essential... Marked it... And installed it...

Then I installed Git... And Eclipse... And yesterday I installed QTCreator IDE... And the development environment is ready...

I started gaining interest in Linux because I wanted to compile the Android source code... so far my experience with Ubuntu is very good... its update manager is working for me...The synaptic package manager is fantastic...

I can say that for me it's been a smooth transition to Ubuntu...And the best part is that neither I had to install SpyBot... nor do I have to scan with SpyWare Doctor every time I start my PC... of course, I don't have to care about Malwarebytes to fight against Virtumunde...

In 2022, in Bharat, the share of Linux desktop was 8.05% and in 2024 it is 15%.
See below...
Linux desktop share in Bharat in 2022



Linux desktop share in Bharat in 2024



Once the Government of Bharat adopts it everywhere, the ecosystem will be built around Linux.

I am happy to see that Bharat has indigenously developed #maya OS, a Linux-based OS  (DRDO project - 2021) and the Government of Bharat is eagerly supporting the deployment of this OS across defense and government offices. Once the schools and colleges adopt #Linux and the government offers a green signal for public use of Linux, there won't be any looking back. 

#JaiHind...

Here is a wiki page on adopters of #Linux


Saturday, October 24, 2009

Observer Pattern in MFC

As I walk through the different design concepts of the Design Pattern book by GoF, I usually try to find from my past experience about any practical implementation of these patterns. This way I found out one practical implementation of the Observer Pattern in microsoft foundation class (MFC) library which I would like to share with you.

Before explaining the application of Observer Pattern in MFC, let me give you a brief introduction of this pattern. Observer pattern helps you in notifying and updating all the dependent objects, if one object changes state. This pattern has two main objects – Subject and Observer. Multiple number of observers can be attached to a particular Subject. All the observers are notified and in turn gotten updated if the Subject changes its state. This is also known as the publish-subscribe. The subject is the publisher of changes, and the Observers are the subscribers to those changes.

The class diagram will look like the following.



And the sequence diagram of this pattern is like this.



What these two diagrams essentially depict is that in the Observer Pattern, we have a Subject, which can attach one or more Observers through its Attach() function. Whenever it changes its state it Notifies all the attached Observers through its Notify function. The observers in turn synchronize their states with that of the Subject through the GetSubjectState function.

Now let me dissect the MFC's Document-View architecture and explain how the Observer Pattern has been implemented there. In MFC, the Document acts as the Subject and the views attached to it act as the observers. The Document (Subject) has to notify and update the views (observers) whenever it changes its state. This is done through the function UpdateAllViews () of the CDocument class.

Let me show you the actual code of the UpdateAllViews from doccore.cpp under the MFC folder.

void
CDocument :: UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint)
{
ASSERT(pSender == NULL || !m_viewList.IsEmpty());

POSITION pos = GetFirstViewPosition();
while (pos != NULL)
{
CView* pView = GetNextView(pos);
ASSERT_VALID(pView);
if (pView != pSender)
pView->OnUpdate(pSender, lHint, pHint);
}
}


As you can see from the code that UpdateAllViews function actually traverses through all the views attached through it and call the view's OnUpdate function. Hence UpdateAllViews acts as the Notify function of the Observer pattern.

Let me show you the actual code of OnUpdate from viewcore.cpp. It goes like this:

void
CView :: OnUpdate(CView* pSender,LPARAM, CObject*)
{
ASSERT(pSender != this);
UNUSED(pSender);
Invalidate(TRUE);
}

As its is clear from the above code, that the OnUpdate function will actually invalidate the view area, which will force the views to redraw themselves synchronizing their states with the current state of the Document.

This is all about the notification from Document to View. But what about the Attach and Detach function of the Subject. We have similar functions in the Document class which are as follows:

void CDocument :: AddView(CView* pView)
{
ASSERT_VALID(pView);
ASSERT(pView->m_pDocument == NULL);
ASSERT(m_viewList.Find(pView, NULL) == NULL);
m_viewList.AddTail(pView);
ASSERT(pView->m_pDocument == NULL);
pView->m_pDocument = this;

OnChangedViewList();
}

void CDocument :: RemoveView(CView* pView)
{
ASSERT_VALID(pView);
ASSERT(pView->m_pDocument == this);

m_viewList.RemoveAt(m_viewList.Find(pView));
pView->m_pDocument = NULL;

OnChangedViewList();
}

As this is clear from the above listings that CDocument :: AddView is similar to the Attach function of the Subject, and RemoveView is like the Detach function as in the Observer Pattern.

Similar to the Observer Pattern, the Document has a list of its attached views through its m_viewList member and each view has a reference to its document through its m_pDocument member.

From the above discussion, it has become clear that the MFC's Document- View architecture is one of the applications of the Observer Pattern.

Saturday, October 10, 2009

WiFi Subsystem in Android

As i was trying to understand the WiFi subsystem of Android i came out with a diagram to depict the flow of events between different functional blocks of it. I would like to share it with you.

It goes like this:



Hope it will help the Android developers' community.

Thursday, October 8, 2009

Tabs in Android - through an example

As i was trying to experiment with the different widgets of Android, i developed this example to show how Tab works in Android.

And the application looks like the following:



And the next tab looks like:



The first thing we need to to do is working on the XML layout.

The XML code of the layout my example is as follows:

(?xml version="1.0" encoding="utf-8"?)
(LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
)

(TabHost android:id="@+id/TabHost01" android:layout_width="wrap_content" android:layout_height="wrap_content")
(TabWidget android:id="@android:id/tabs" android:layout_width="wrap_content" android:layout_height="wrap_content" /)
(FrameLayout android:id="@android:id/tabcontent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="65px")
(AnalogClock android:id="@+id/AnalogClock01" android:layout_width="wrap_content" android:layout_height="wrap_content")(/AnalogClock)
(DigitalClock android:text="DigitalClock01" android:id="@+id/DigitalClock01" android:layout_width="wrap_content" android:layout_height="wrap_content")(/DigitalClock)
(/FrameLayout)
(/TabHost)
(/LinearLayout)

And the Java code for this example is as follws:

import android.app.Activity;
import android.os.Bundle;
import android.widget.TabHost;

public class tabexample extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

TabHost tabs = (TabHost)findViewById(R.id.TabHost01);

tabs.setup();

TabHost.TabSpec spec1 = tabs.newTabSpec("tag1");

spec1.setContent(R.id.AnalogClock01);
spec1.setIndicator("Analog Clock");

tabs.addTab(spec1);

TabHost.TabSpec spec2 = tabs.newTabSpec("tag2");
spec2.setContent(R.id.DigitalClock01);
spec2.setIndicator("Digital Clock");

tabs.addTab(spec2);
}
}

Hope this helps the newcomers of Android...

Saturday, August 15, 2009

Inter Process Communication in Android through Intent

In Android, one of the nice ways for passing data between different processes is through the help of Intent. In the following example i have tried to explain it by two different applications. One application is called the IntentSupplier. This is started from another application called IntentExample. The application IntentSupplier passes some string data to the IntentExample app through the help of an Intent object which the IntentSupplier application displays in a message box.

The IntentSupplier application looks like the following.




When we click one of the buttons it passes its string data to the IntentExample which looks like the following.



The source code for IntentSupplier is as follows:

package android.training.intentsupplier;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class IntentSupplier extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Button button1 = (Button)findViewById(R.id.Button01);

Button button2 = (Button)findViewById(R.id.Button02);

button1.setOnClickListener(onClickButton1);
button2.setOnClickListener(onClickButton2);

}

private OnClickListener onClickButton1 = new OnClickListener() {

public void onClick(View v){

if (v.getId() == R.id.Button01){

returnResult("Message1 coming from IntentSupplier");
}
}
};

private OnClickListener onClickButton2 = new OnClickListener() {

public void onClick(View v){

if (v.getId() == R.id.Button02){

returnResult("Message2 coming from IntentSupplier");
}
}
};

void returnResult(String msg) {

Intent i = new Intent();

i.putExtra("android.training.intentsupplier.resultfromintentsupplier", msg);

setResult(RESULT_OK, i);

finish();
}

}


Look at the function

void returnResult(String msg).

Here at the line i.putExtra("android.training.intentsupplier.resultfromintentsupplier", msg), we are basically parceling the data (msg) and giving it a label called resultfromintentsupplier. Please see how the package info is prefixed with this label.

The source code for the IntentExample is as follows:

package android.training.intentexample;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

public class IntentExample extends Activity {

static final int REQUEST_CODE = 1001;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Intent getMessageFromIntentSupplier = new Intent();

getMessageFromIntentSupplier.setClassName("android.training.intentsupplier", "android.training.intentsupplier.IntentSupplier");

getMessageFromIntentSupplier.setAction("android.training.intentsupplier.android.intent.action.INTENTSUPPLIERTEST");

getMessageFromIntentSupplier.addCategory("CATEGORY_DEFAULT");

getMessageFromIntentSupplier.setType("vnd.example.greeting/vnd.example.greeting-text");

try {
startActivityForResult(getMessageFromIntentSupplier,REQUEST_CODE);

}

catch(ActivityNotFoundException e) {
Log.e("IntentExample", "Activity could not be started...");
}

}
}

public void onActivityResult(int requestcode, int resultcode, Intent result ) {

if(requestcode == REQUEST_CODE){
if(resultcode == RESULT_OK){
message = result.getStringExtra("android.training.intentsupplier.resultfromintentsupplier");

new AlertDialog.Builder(this)
.setTitle("Msg from Intent Supplier")
.setMessage(message)
.setNeutralButton("Close", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dlg, int sumthin) {
// do nothing – it will close on its own
}
})
.show();
}
}
}

}

The AndroidManifest.xml file of the IntentSupplier application looks like the following:

(** Please replace the "(" & ")" brackets with the angular brackets to xmlize the file contents)

(?xml version="1.0" encoding="utf-8"?)
(manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.training.intentsupplier"
android:versionCode="1"
android:versionName="1.0")
(application android:icon="@drawable/icon" android:label="@string/app_name")
(activity android:name=".IntentSupplier"
android:label="@string/app_name")

(intent-filter)
(action android:name="android.intent.action.MAIN" /)
(category android:name="android.intent.category.LAUNCHER" /)
(/intent-filter)

(intent-filter)
(action android:name="android.intent.action.INTENTSUPPLIERTEST" /)
(category android:name="android.intent.category.DEFAULT" /)
(data android:mimeType="vnd.example.greeting/vnd.example.greeting-text" /)
(/intent-filter)
(/activity)
(/application)
(uses-sdk android:minSdkVersion="3" /)
(/manifest)

The main.xml file of the IntentSupplier application looks like the following:

(?xml version="1.0" encoding="utf-8"?)
(LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
)
(TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/)
(Button android:text="Message1" android:id="@+id/Button01" android:layout_width="fill_parent" android:layout_height="wrap_content")(/Button)
(Button android:text="Message2" android:id="@+id/Button02" android:layout_width="fill_parent" android:layout_height="wrap_content")(/Button)
(/LinearLayout)

In this example we have started the IntentSupplier app through the function startActivityForResult. It then waits for the result from the child activity, and once the result arrives, the callback function onActivityResult is called. in this function we extract the data sent from the child activity (by using the function getStringExtra) and show it in a message box.

To run this application we need to run once the IntentSupplier application first.

Hope this discussion becomes helpful for the newbies of Android.

Sunday, July 5, 2009

My first time experience with Android Webkit

As I was trying to play around with WebKit, I tried to load an web page through it in Android. A good starting point for WebKit may be found at

http://developer.apple.com/documentation/Cocoa/Conceptual/DisplayWebContent/DisplayWebContent.html .

The source code of my android application is pretty straight forward.

It goes like this:

public class WebKitExample extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

WebView webView;

setContentView(R.layout.main);

webView = (WebView)findViewById(R.id.appView);

webView.getSettings().setJavaScriptEnabled(true);

webView.loadUrl("http://www.google.com");
}
}

We need to add the XML resource in the main.layout as the following:

(WebView android:id="@+id/appView"
android:layout_height="wrap_content"
android:layout_width="fill_parent" /)

We also need to add the permission to the manifest file as the following:

(uses-permission android:name = "android.permission.INTERNET" /)

And the application will look like the following in the emulator.



Although the example shown here is pretty simple but it can be a starting point in learning Webkit in Android. Hope this helps the newbies of Android.

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.

Sunday, May 31, 2009

Observer Pattern in Java

As i was going through the different source code files of the Java Util package, i found the implementation of the Observer Pattern ( see the GoF book for more information on this pattern) in the two classes - namely Observer.java and Observable.java. i would like to throw some lights on these two classes. These two classes can be found in the Java\j2se\src\share\classes\java\util folder of the JDK source code.

But first of all, i need to give you a practical example of why we need observer pattern in the first place.

Suppose, we have a document which can be viewed simultaneously by three different views – say one view represents a line graph chart, another view represents it in a spreadsheet, yet another view represents a pie chart. Now suppose the spreadsheet view makes some modification to the document. If the other two views don't update themselves with this changed state of the document, different views will be in inconsistent states. So we need some mechanism to notify the other two views whenever the spreadsheet view updates the document. This is done through Observer pattern in which whenever the document changes stete, it notifies all of its views. The views in turn updates themselves with the latest data.
The class diagram will look like the following.




And the sequence diagram of this pattern is like this.


What these two diagrams essentially depict is that in the Observer Pattern, we have a Subject, which can attach one or more Observers through its Attach() function. Whenever it changes its state it Notifies all the attached Observers through its Notify function. The observers in turn synchronize their states with that of the Subject through the GetSubjectState function.

Now let me try to dissect the Java observer pattern.

Let us first start with the Observable.java class. As the name suggests it is the class which will implemented functionalities for being observed. Or in other words it is the class which helps in designing the Subject class of the Observer pattern discussion of the GoF book. We need to extend this class to get the Subject class.

Let us try to dissect this class. The following functions are there in this class:

Data Members: It has a vector to hold all the observers that are interested in observing this observable class. It has another boolean data member called "changed" to indicate if anything has changed in the Subject class ( which will be derived from this Observable class).

Constructor : This class has a no argument constructor to construct an empty vector of Observers.

Member Functions :

  • addObserver : To add an observer to its list of Observers.

  • deleteObserver : To delete a particular observer from the list of the observers

  • notifyObservers : there are two overloaded versions of this function. One takes an Object parameter as an argument and the other does not take any argument. The task of this function is to notify all the attached observers when any data of the subject gets changed. To check whether the data is changed it evaluates the boolean "changed" data member. This function also calls the update function of each observer objects to ask them to get in sync with the subject's changed state. The overloaded version that takes an one argument parameter is used to let the observers know about which attribute is changed. And the other version of this function which does not take any argument does not let the observer know about which attribute is changed.
  • deleteObservers : This function removes all the observers attached to this subject.

  • setChanged : This function sets the boolean data member "changed".

  • clearChanged : This function resets the boolean data member "changed".

  • hasChanged : This function helps us to know whether the data of the subject has been changed or not. 

  • countObservers : This function returns the number of observers attached to this subject.
This is all about the Observable class which helps us to define to Subject class.

The Observer.java defines an interface called Observer having just one abstract function called update (Observable o, Object arg). As the name suggests, the Observer class that will implement this interface will override the update function to set the attribute passed as an argument (arg) from the Subject class. This method is called whenever any attribute in the Subject class gets changed.

Now let us try to see an example to understand how this Observer Pattern is used.

Let us first extend the Observable class to create the Subject class.

package com.somitsolutions.training.java.observerpattern;

import java.util.Observable;

public class Subject extends Observable {

private String name;
private float price;

public Subject(String name, float price) {
this.name = name;
this.price = price;
}

public String getName() {
return name;
}
public float getPrice() {
return price;
}
public void setName(String name) {
this.name = name;
setChanged();
notifyObservers(name);
}

public void setPrice(float price) {
this.price = price;
setChanged();
notifyObservers(new Float(price));
}
}

As this is clear from the implementation of the Subject class, that whenever we call the setter function to change the attributes of the Subject's object, we call the notifyObservers and pass that attribute as a parameter.


Now let us see how we create two different observers namely NameObserver and PriceObserver to observe these two attributes of the Subject class.

// An observer of name changes.
package com.somitsolutions.training.java.observerpattern;

import java.util.Observable;
import java.util.Observer;

public class NameObserver implements Observer {

private String name;
public NameObserver() {
name = null;
System.out.println("NameObserver created: Name is " + name);
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
if (arg instanceof String) {
name = (String)arg;
System.out.println("NameObserver: Name changed to " + name);
}
}
}


// An observer of price changes.
package com.somitsolutions.training.java.observerpattern;

import java.util.Observable;
import java.util.Observer;

public class PriceObserver implements Observer {

private float price; public PriceObserver() {
price = 0;
System.out.println("PriceObserver created: Price is " + price);
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
if (arg instanceof Float) {
price = ((Float)arg).floatValue();
System.out.println("PriceObserver: Price changed to " + price);
}
}

}

As it has become clear from the above two implementations that the update function actually helps in synchronizing the state of the concrete observers with that of the Subject.

Now the client of the Observer framework will look like the following :

package com.somitsolutions.training.java.observerpattern;

public class Main {

public static void main(String args[]) {

// Create the Subject and Observers.
Subject s = new Subject("Kheer Kadam", 20.5f);

NameObserver nameObs = new NameObserver();
PriceObserver priceObs = new PriceObserver();

// Add those Observers!
s.addObserver(nameObs);
s.addObserver(priceObs);

//Initial Subject States
System.out.println("Initial states of Subject");
System.out.println("Name : " + s.getName());
System.out.println("Price : " + Float.toString(s.getPrice()));

// Make changes to the Subject.
s.setName("Gulabjamun"); // It prints NameObserver: Name changed to Gulabjamun

s.setPrice(15.0f); //It prints PriceObserver: Price changed to 15.0

s.setPrice(30.5f); //It prints PriceObserver: Price changed to 30.5

s.setName("Rasgulla"); // It prints NameObserver: Name changed to Rasgulla
}
}

Hope the above discussion will help people understand of how the Java supports implementing the Observer pattern.