Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create the perfect OOP application [closed]

Tags:

c#

oop

Recently I was trying for a company ‘x’. They sent me some set of questions and told me to solve only one.

The problem is like this -

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.

When I purchase items I receive a receipt which lists the name of all the items and their price (including tax), finishing with the total cost of the items, and the total amounts of sales taxes paid.
The rounding rules for sales tax are that for a tax rate of n%, a shelf price of p contains (np/100 rounded up to the nearest 0.05) amount of sales tax.

“They told me, they are interested in the Design Aspect of your solution and would like to evaluate my Object Oriented Programming Skills.”

This is what they told in their own words

  • For the solution, we would want you use either Java, Ruby or C#.
  • We are interested in the DESIGN ASPECT of your solution and would like to evaluate your Object Oriented Programming Skills.
  • You may use external libraries or tools for building or testing purposes. Specifically, you may use unit testing libraries or build tools available for your chosen language (e.g., JUnit, Ant, NUnit, NAnt, Test::Unit, Rake etc.)
  • Optionally, you may also include a brief explanation of your design and assumptions along with your code.
  • Kindly note that we are NOT expecting a web-based application or a comprehensive UI. Rather, we are expecting a simple, console based application and interested in your source code.

So I provided below code – you can just copy paste code and run in VS.

class Program  {      static void Main(string[] args)      {          try          {              double totalBill = 0, salesTax = 0;              List<Product> productList = getProductList();              foreach (Product prod in productList)              {                  double tax = prod.ComputeSalesTax();                  salesTax += tax;                  totalBill += tax + (prod.Quantity * prod.ProductPrice);                  Console.WriteLine(string.Format("Item = {0} : Quantity = {1} : Price = {2} : Tax = {3}", prod.ProductName, prod.Quantity, prod.ProductPrice + tax, tax));              }              Console.WriteLine("Total Tax : " + salesTax);              Console.WriteLine("Total Bill : " + totalBill);                         }          catch (Exception ex)          {              Console.WriteLine(ex.Message);          }          Console.ReadLine();      }      private static List<Product> getProductList()      {          List<Product> lstProducts = new List<Product>();          //input 1          lstProducts.Add(new Product("Book", 12.49, 1, ProductType.ExemptedProduct, false));          lstProducts.Add(new Product("Music CD", 14.99, 1, ProductType.TaxPaidProduct, false));          lstProducts.Add(new Product("Chocolate Bar", .85, 1, ProductType.ExemptedProduct, false));          //input 2          //lstProducts.Add(new Product("Imported Chocolate", 10, 1, ProductType.ExemptedProduct,true));          //lstProducts.Add(new Product("Imported Perfume", 47.50, 1, ProductType.TaxPaidProduct,true));          //input 3          //lstProducts.Add(new Product("Imported Perfume", 27.99, 1, ProductType.TaxPaidProduct,true));          //lstProducts.Add(new Product("Perfume", 18.99, 1, ProductType.TaxPaidProduct,false));          //lstProducts.Add(new Product("Headache Pills", 9.75, 1, ProductType.ExemptedProduct,false));          //lstProducts.Add(new Product("Imported Chocolate", 11.25, 1, ProductType.ExemptedProduct,true));          return lstProducts;      }  }  public enum ProductType  {      ExemptedProduct=1,      TaxPaidProduct=2,      //ImportedProduct=3  }  class Product  {      private ProductType _typeOfProduct = ProductType.TaxPaidProduct;      private string _productName = string.Empty;      private double _productPrice;      private int _quantity;      private bool _isImportedProduct = false;      public string ProductName { get { return _productName; } }      public double ProductPrice { get { return _productPrice; } }      public int Quantity { get { return _quantity; } }      public Product(string productName, double productPrice,int quantity, ProductType type, bool isImportedProduct)      {          _productName = productName;          _productPrice = productPrice;          _quantity = quantity;          _typeOfProduct = type;          _isImportedProduct = isImportedProduct;      }      public double ComputeSalesTax()      {          double tax = 0;          if(_isImportedProduct) //charge 5% tax directly              tax+=_productPrice*.05;          switch (_typeOfProduct)          {              case ProductType.ExemptedProduct: break;              case ProductType.TaxPaidProduct:                  tax += _productPrice * .10;                  break;          }          return Math.Round(tax, 2);          //round result before returning      }  } 

you can uncommnet input and run for different inputs.

I provided the solution but I was rejected.

"They said, they are unable to consider me for our current open positions because code solution is not satisfactory."

Please guide me what is missing here. Is this solution is not a good OOAD solution.
How can I improve my OOAD skills.
My seniors also says perfect OOAD application will also not work practically.

Thanks

like image 435
sunder Avatar asked Feb 25 '12 14:02

sunder


People also ask

What is the OOP write the application of OOP?

OOPs stands for Object-Oriented Programming. It is about creating objects that contain both data and functions. Object-Oriented programming has several advantages over procedural languages. As OOP is faster and easier to execute it becomes more powerful than procedural languages like C++.


2 Answers

First off good heavens do not do financial calculations in double. Do financial calculations in decimal; that is what it is for. Use double to solve physics problems, not financial problems.

The major design flaw in your program is that policy is in the wrong place. Who is in charge of computing the taxes? You've put the product in charge of computing the taxes, but when you buy an apple or a book or a washing machine, the thing you are about to buy is not responsible for telling you how much tax you're going to pay on it. Government policy is responsible for telling you that. Your design massively violates the basic OO design principle that objects should be responsible for their own concerns, and not anyone else's. The concern of a washing machine is washing your clothes, not charging the right import duty. If the tax laws change, you don't want to change the washing machine object, you want to change the policy object.

So, how to approach these sorts of problems in the future?

I would have started by highlighting every important noun in the problem description:

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. When I purchase items I receive a receipt which lists the name of all the items and their price (including tax), finishing with the total cost of the items, and the total amounts of sales taxes paid. The rounding rules for sales tax are that for a tax rate of n%, a shelf price of p contains (np/100 rounded up to the nearest 0.05) amount of sales tax.

Now, what are the relationships between all those nouns?

  • Basic Sales Tax is a kind of Sales Tax
  • Import Duty is a kind of Sales Tax
  • A Sales Tax has a Rate which is a Decimal
  • Books are a kind of Item
  • Food is a kind of Item
  • Medical Products are a kind of Item
  • Items may be Imported Goods
  • An Item has a Name which is a String
  • An Item has a Shelf Price which is a Decimal. (Note: does an item really have a price? two identical washing machines might be for sale for different prices at different stores, or at the same store at different times. A better design might be to say that a Pricing Policy relates an Item to its Price.)
  • A Sales Tax Exemption Policy describes the conditions under which a Sales Tax is inapplicable on an Item.
  • A Receipt has a list of Items, their prices and their taxes.
  • A Receipt has a total
  • A Receipt has a total tax

... and so on. Once you have all the relationships between all the nouns worked out, then you can start designing a class hierarchy. There is an abstract base class Item. Book inherits from it. There is an abstract class SalesTax; BasicSalesTax inherits from it. And so on.

like image 144
Eric Lippert Avatar answered Nov 16 '22 00:11

Eric Lippert


If company tells something about libraries like NUnit, JUnit or Test::Unit is more than probable that TDD is really importat to them. In your code sample is no tests at all.

I would try to demonstrate practical knowledge of:

  • Unit tests (eg. NUnit, XUnit, ArchUnitNet, ...)
  • Design patterns
  • SOLID principles
  • Clean Architecture
  • Persistence (eg. Entity Framework, NHibernate)
  • IoC Containers (eg. AutoFac)

I would like to recomend the www.dimecasts.net as impressive source of free, good quality screencasts which covers all above mentioned topics.

like image 37
Radek Avatar answered Nov 16 '22 00:11

Radek