Baru-baru ini saya mencoba untuk perusahaan 'x'. Mereka mengirimi saya beberapa pertanyaan dan mengatakan kepada saya untuk menyelesaikan hanya satu.
Masalahnya seperti ini -
Pajak penjualan dasar berlaku dengan tarif 10% untuk semua barang, kecuali buku, makanan, dan produk medis yang dikecualikan.
Bea masuk adalah pajak penjualan tambahan yang berlaku atas semua barang impor dengan tarif 5%, tanpa pengecualian.
Ketika saya membeli barang, saya menerima tanda terima yang mencantumkan nama semua barang dan harganya (termasuk pajak), diakhiri dengan biaya total barang, dan jumlah total pajak penjualan yang dibayarkan.
Aturan pembulatan untuk pajak penjualan adalah bahwa untuk tarif pajak n%, harga rak p berisi (np / 100 dibulatkan ke dekat 0,05) jumlah pajak penjualan.
"Mereka mengatakan kepada saya, mereka tertarik dengan Aspek Desain solusi Anda dan ingin mengevaluasi Keterampilan Pemrograman Berorientasi Objek saya ."
Inilah yang mereka katakan dengan kata-kata mereka sendiri
- Untuk solusinya, kami ingin Anda menggunakan Java, Ruby atau C #.
- Kami tertarik dengan ASPEK DESAIN solusi Anda dan ingin mengevaluasi Keterampilan Pemrograman Berorientasi Objek Anda .
- Anda dapat menggunakan pustaka atau alat eksternal untuk membangun atau menguji tujuan. Secara khusus, Anda dapat menggunakan pustaka pengujian unit atau alat build yang tersedia untuk bahasa pilihan Anda (misalnya, JUnit, Ant, NUnit, NAnt, Test :: Unit, Rake, dll.)
- Secara opsional, Anda juga dapat menyertakan penjelasan singkat tentang desain dan asumsi Anda bersama dengan kode Anda.
- Mohon dicatat bahwa kami TIDAK mengharapkan aplikasi berbasis web atau UI yang komprehensif. Sebaliknya, kami mengharapkan aplikasi berbasis konsol yang sederhana dan tertarik dengan kode sumber Anda.
Jadi saya berikan kode di bawah ini - Anda cukup menyalin kode tempel dan menjalankannya di 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
}
}
Anda dapat membatalkan input dan menjalankan input yang berbeda.
Saya memberikan solusinya tetapi saya ditolak.
"Mereka berkata, mereka tidak dapat mempertimbangkan saya untuk posisi terbuka kami saat ini karena solusi kode tidak memuaskan."
Tolong bimbing saya apa yang hilang di sini. Apakah solusi ini bukan solusi OOAD yang baik.
Bagaimana cara meningkatkan keterampilan OOAD saya.
Senior saya juga bilang aplikasi OOAD yang sempurna juga tidak akan bekerja secara praktis.
Terima kasih
Jawaban:
Pertama, surga tidak melakukan perhitungan keuangan dua kali lipat . Lakukan perhitungan keuangan dalam desimal ; untuk itulah. Gunakan ganda untuk memecahkan masalah fisika , bukan masalah keuangan .
Kelemahan desain utama dalam program Anda adalah kebijakan berada di tempat yang salah . Siapa yang bertugas menghitung pajak? Anda telah menempatkan produk yang bertanggung jawab untuk menghitung pajak, tetapi ketika Anda membeli apel atau buku atau mesin cuci, barang yang akan Anda beli tidak bertanggung jawab untuk memberi tahu Anda berapa banyak pajak yang akan Anda bayarkan. Itu. Kebijakan pemerintah bertanggung jawab untuk memberi tahu Anda hal itu. Desain Anda secara besar-besaran melanggar prinsip desain OO dasar bahwa objek harus bertanggung jawab atas masalah mereka sendiri , dan bukan orang lain. Masalah mesin cuci adalah mencuci pakaian Anda, bukan membebankan bea masuk yang benar. Jika undang-undang perpajakan berubah, Anda tidak ingin mengubahnyaobjek mesin cuci , Anda ingin mengubah objek kebijakan .
Jadi, bagaimana cara mengatasi masalah semacam ini di masa depan?
Saya akan mulai dengan menyoroti setiap kata benda penting dalam deskripsi masalah:
Sekarang, apa hubungan antara semua kata benda itu?
... dan seterusnya. Setelah Anda memiliki semua hubungan antara semua kata benda yang berhasil, Anda dapat mulai merancang hierarki kelas. Ada Item kelas dasar abstrak. Buku mewarisi darinya. Ada kelas abstrak SalesTax; BasicSalesTax mewarisi darinya. Dan seterusnya.
sumber
double
ideal untuk situasi di mana berada dalam 0,00000001% dari jawaban yang benar sudah lebih dari cukup. Jika Anda ingin mengetahui seberapa cepat batu bata jatuh setelah setengah detik, lakukan penghitungan ganda. Ketika Anda melakukan aritema keuangan dalam dua kali lipat, Anda akan mendapatkan jawaban seperti harga setelah pajak adalah 43.79999999999999 dolar dan itu terlihat konyol meskipun sangat dekat dengan jawaban yang benar.Jika perusahaan memberi tahu sesuatu tentang pustaka seperti NUnit, JUnit atau Test :: Unit lebih dari mungkin bahwa TDD benar-benar penting bagi mereka. Dalam contoh kode Anda tidak ada tes sama sekali.
Saya akan mencoba mendemonstrasikan pengetahuan praktis tentang:
Saya ingin merekomendasikan www.dimecasts.net sebagai sumber screencast gratis dan berkualitas baik yang mencakup semua topik yang disebutkan di atas.
sumber
Ini sangat subjektif, tetapi berikut adalah beberapa poin yang akan saya buat tentang kode Anda:
Menurut pendapat saya, Anda bercampur
Product
danShoppingCartItem
.Product
harus memiliki nama produk, status pajak, dll. tetapi bukan kuantitas. Kuantitas bukanlah properti suatu produk - akan berbeda untuk setiap pelanggan perusahaan yang membeli produk tersebut.ShoppingCartItem
harus memilikiProduct
dan kuantitas. Dengan begitu pelanggan dapat dengan bebas membeli lebih banyak atau lebih sedikit produk yang sama. Dengan penyiapan Anda saat ini, itu tidak mungkin.Menghitung pajak final juga tidak boleh menjadi bagian dari
Product
- harus menjadi bagian dari sesuatu sepertiShoppingCart
karena penghitungan pajak final mungkin melibatkan mengetahui semua produk di keranjang.sumber
Pertama-tama, ini adalah pertanyaan wawancara yang sangat bagus. Ini adalah ukuran yang bagus untuk banyak keterampilan.
Ada banyak hal yang perlu Anda pahami untuk memberikan jawaban yang baik (tidak ada jawaban yang sempurna), baik tingkat tinggi maupun tingkat rendah. Ini beberapa:
Dari sana, Anda dapat melakukan banyak diskusi menarik, yang melibatkan prinsip desain (seperti prinsip SOLID), pola desain, pola analisis, pemodelan domain, pilihan teknologi, jalur evolusi masa depan (misalnya bagaimana jika saya menambahkan database, atau lapisan UI yang kaya, apa yang perlu diubah?), kompromi, persyaratan non-fungsional (kinerja, pemeliharaan, keamanan, ...), pengujian penerimaan, dll ...
Saya tidak akan berkomentar tentang bagaimana Anda harus mengubah solusi Anda, hanya saja Anda harus lebih fokus pada konsep ini.
Tapi, saya dapat menunjukkan kepada Anda bagaimana saya (sebagian) memecahkan masalah ini , hanya sebagai contoh (di Java). Lihat di
Program
kelas untuk melihat bagaimana semuanya bersatu untuk mencetak tanda terima ini:Anda pasti harus melihat buku-buku itu :-)
Sekadar peringatan: solusi saya masih sangat belum lengkap, saya hanya fokus pada skenario jalan bahagia agar memiliki fondasi yang baik untuk membangun.
sumber
Order
mencetak tanda terima, tapiReceipt
tahu tentang formatnya sendiri. Selain itu, TaxMethodPractice adalah sejenis kebijakan pajak, yang menahan semua pajak yang berlaku untuk skenario tertentu. TaxMethods adalah kalkulator pajak. Saya merasa Anda hanya melewatkan beberapa kelas pengikatan tingkat yang lebih tinggi , seperti SalesEngine yang Anda usulkan. Itu ide yang menarik.Kecuali fakta bahwa Anda menggunakan kelas yang disebut produk, Anda belum menunjukkan bahwa Anda tahu apa itu warisan, Anda belum membuat beberapa kelas mewarisi dari Produk, tidak ada polimorfisme. Masalahnya bisa diselesaikan dengan menggunakan beberapa konsep OOP (bahkan hanya untuk menunjukkan bahwa Anda mengetahuinya). Ini adalah masalah wawancara jadi Anda ingin menunjukkan seberapa banyak Anda tahu.
Namun saya tidak akan berubah menjadi depresi sekarang. Fakta bahwa Anda tidak mendemonstrasikannya di sini tidak berarti Anda belum mengenal mereka atau tidak dapat mempelajarinya.
Anda hanya perlu sedikit lebih banyak pengalaman dengan OOP atau wawancara.
Semoga berhasil!
sumber
Orang yang telah mulai belajar pemrograman dengan OOP tidak memiliki masalah besar untuk memahami apa artinya, karena ini seperti dalam kehidupan nyata . Jika Anda memiliki keterampilan dengan famili pemrograman lain selain OO, mungkin akan lebih sulit untuk dipahami.
Pertama-tama, matikan layar Anda, atau keluar dari IDE favorit Anda. Ambil kertas dan pensil dan buat daftar entitas , relasi , orang , mesin , proses , barang , dll. Segala sesuatu yang dapat ditemukan ke dalam program akhir Anda.
Kedua, cobalah untuk mendapatkan entitas dasar yang berbeda . Anda akan memahami bahwa beberapa dapat berbagi properti atau kemampuan , Anda harus meletakkannya di objek abstrak . Anda harus mulai menggambar skema yang bagus dari program Anda.
Selanjutnya Anda harus meletakkan fonctionnalities (metode, fungsi, subrutin, panggil sesuai keinginan): misalnya, objek produk seharusnya tidak dapat menghitung pajak penjualan . Sebuah mesin penjualan objek harus.
Jangan merasa kesulitan dengan semua kata-kata besar ( antarmuka , properti , polimorfisme , warisan , dll.) Dan pola desain untuk pertama kalinya, jangan coba-coba membuat kode yang indah atau apa pun ... Pikirkan saja objek sederhana dan interaksi di antara itu seperti dalam kehidupan nyata .
Setelah itu, cobalah membaca beberapa literatur ringkas yang serius tentang ini. Saya pikir Wikipedia dan Wikibooks adalah cara yang sangat bagus untuk memulai dan kemudian membaca hal-hal tentang GoF dan Design Patterns dan UML .
sumber
Pertama, jangan gabungkan
Product
kelas dengan kelas Receipt (ShoppingCart
), yangquantity
harus menjadi bagian dariReceipItem
(ShoppingCartItem
), sertaTax
&Cost
. TheTotalTax
&TotalCost
harus menjadi bagian dariShoppingCart
.Product
Kelas saya , hanya memilikiName
&Price
& beberapa properti hanya-baca sepertiIsImported
:Bagian penghitungan pajak Anda digabungkan dengan
Product
. Produk tidak menentukan kebijakan pajak, melainkan kelas Pajak. Berdasarkan uraian masalahnya, ada dua jenis Pajak Penjualan:Basic
danDuty
Pajak. Anda dapat menggunakanTemplate Method Design Pattern
untuk mencapainya:Dan akhirnya kelas untuk menerapkan pajak:
Anda dapat mencobanya di MyFiddle .
sumber
Titik awal yang sangat baik tentang aturan desain adalah prinsip SOLID .
Misalnya prinsip Terbuka Tertutup menyatakan bahwa jika Anda ingin menambahkan fungsionalitas baru, Anda tidak perlu menambahkan kode ke kelas yang ada, melainkan menambahkan kelas baru.
Untuk aplikasi sampel Anda, ini berarti menambahkan pajak penjualan baru akan memerlukan penambahan kelas baru. Hal yang sama berlaku untuk produk berbeda yang merupakan pengecualian dari aturan tersebut.
Aturan pembulatan jelas berlaku di kelas yang terpisah - prinsip Tanggung Jawab Tunggal menyatakan bahwa setiap kelas memiliki tanggung jawab tunggal.
Saya pikir mencoba menulis kode sendiri akan membawa manfaat yang jauh lebih banyak daripada hanya menulis solusi yang baik dan menempelkannya di sini.
Algoritme sederhana untuk menulis program yang dirancang sempurna adalah:
sumber
Penerapan OOP yang sempurna masih bisa diperdebatkan. Dari apa yang saya lihat di pertanyaan Anda, Anda dapat memodularisasi kode berdasarkan peran yang mereka lakukan untuk menghitung harga akhir seperti Produk, Pajak, ProductDB, dan sebagainya.
Product
bisa menjadi kelas abstrak dan jenis turunan seperti Buku, Makanan dapat diwariskan darinya. Penerapan pajak dapat ditentukan oleh jenis turunannya. Produk akan memberi tahu apakah pajak itu berlaku atau tidak berdasarkan kelas turunannya.TaxCriteria
dapat menjadi enum dan ini dapat ditentukan selama pembelian (diimpor, penerapan Pajak Penjualan).Tax
kelas akan menghitung pajak berdasarkanTaxCriteria
.Memiliki
ShoppingCartItem
seperti yang disarankan oleh XXBBCC dapat merangkum contoh Produk dan Pajak dan ini adalah cara yang bagus untuk memisahkan detail produk dengan kuantitas, harga total dengan pajak, dll.Semoga berhasil.
sumber
Dari perspektif OOA / D yang ketat, satu masalah utama yang saya lihat adalah bahwa sebagian besar atribut kelas Anda memiliki nama kelas yang berlebihan dalam nama atribut. misalnya Harga Produk , Jenis Produk . Dalam kasus ini, di mana pun Anda menggunakan kelas ini, Anda akan memiliki kode yang terlalu bertele-tele dan agak membingungkan, misalnya product.productName. Hapus awalan / sufiks nama kelas yang berlebihan dari atribut Anda.
Selain itu, saya tidak melihat kelas yang peduli dengan pembelian dan pembuatan tanda terima seperti yang ditanyakan dalam pertanyaan.
sumber
Berikut adalah contoh yang bagus dari pola OO untuk Produk, Pajak, dll .. Perhatikan penggunaan Antarmuka, yang penting dalam desain OO.
http://www.dreamincode.net/forums/topic/185426-design-patterns-strategy/
sumber
Menghadapi Masalah Biaya dengan Pajak menggunakan pola Pengunjung.
sumber