Please review the sales tax problem which has been designed using strategy pattern.
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.
Item.h
/*
* Item.h
*
* Created on: Jun 7, 2011
* Author: som
*/
#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 /* ITEM_H_ */
Item.cpp
/*
* Item.cpp
*
* Created on: Jun 7, 2011
* Author: som
*/
#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);
}
ItemCreator.h
/*
* ItemCreator.h
*
* Created on: Jun 7, 2011
* Author: som
*/
#ifndef ITEMCREATOR_H_
#define 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);
};
#endif /* ITEMCREATOR_H_ */
ItemCreator.cpp
/*
* ItemCreator.cpp
*
* Created on: Jun 7, 2011
* Author: som
*/
#include "ItemCreator.h"
#include "Item.h"
#include "SalesTax.h"
#include <iostream>
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();
}
}
SalesTax.h
/*
* SalesTax.h
*
* Created on: Jun 7, 2011
* Author: som
*/
#ifndef SALESTAX_H_
#define 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);
};
#endif /* SALESTAX_H_ */
SalesTax.cpp
/*
* SalesTax.cpp
*
* Created on: Jun 7, 2011
* Author: som
*/
#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));
}
main.cpp
/*
* main.cpp
*
* Created on: Jun 7, 2011
* Author: som
*/
#include "SalesTax.h"
#include "Item.h"
#include "ItemCreator.h"
#include <iostream>
#include <vector>
using namespace std;
int main()
{
typedef vector<Item *> 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 &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;
return 1;
}
While pasting the source code I have found it has become unreadable. Hence please download the source code from here.