98 votes

Comment créer l'application OOP parfaite

Récemment, j'ai été l'essayer pour une société "x". Ils m'ont envoyé une série de questions et m'a dit de le résoudre seul.

Le problème, c'est comme ça -

De base de la taxe de vente est applicable au taux de 10% sur toutes les marchandises, à l'exception des livres, de la nourriture et de soins médicaux, les produits qui en sont exemptés.
Droit à l'importation additionnel de la taxe de vente applicable sur toutes les marchandises importées à un taux de 5%, sans exception.

Quand j'ai acheter des articles que je reçois un reçu qui indique le nom de tous les articles et leur prix (y compris l'impôt) avec, pour finir, le coût total des items, et le total des montants de taxes de vente payées.
Les règles d'arrondi pour la taxe de vente sont que pour un taux d'imposition de n%, un prix de vente de p contient (np/100 arrondi à 0,05) du montant de la taxe de vente.

"Ils m'ont dit, ils sont intéressés par l' Aspect de la Conception de votre solution et vous souhaitez évaluer mon Orientée Objet de la Programmation des Compétences."

C'est ce qu'ils ont dit dans leurs propres mots

  • Pour la solution, nous voudrions vous utilisez Java, Ruby ou C#.
  • Nous nous sommes intéressés à l'ASPECT de la CONCEPTION de votre solution et souhaitez évaluer votre la Programmation Orientée Objet, des Compétences.
  • Vous pouvez utiliser des bibliothèques externes ou des outils pour construire ou à des fins de test. Plus précisément, vous pouvez utiliser les tests unitaires des bibliothèques ou de construire des outils disponibles pour la langue de votre choix (par exemple, JUnit, Ant, NUnit, NAnt, Test::Unit, Râteau, etc.)
  • Vous pouvez également inclure une brève explication de votre conception et les hypothèses ainsi que votre code.
  • Veuillez noter que nous n'attendons PAS une application web ou complète de l'INTERFACE utilisateur. Plutôt, nous nous attendons à une simple console en fonction de l'application et de l'intéressé dans votre code source.

Donc, je fournis ci-dessous de code, vous pouvez juste copier coller le code et l'exécuter dans 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
     }
 }

vous pouvez uncommnet de saisie et d'exécution pour les différentes entrées.

J'ai fourni la solution, mais j'ai été refusée.

"Ils ont dit, ils sont incapables de me considérer pour nos positions ouvertes au fait que le code de la solution n'est pas satisfaisante."

Merci de me guider ce qui manque ici. Est-ce la solution n'est pas une bonne OOAD solution.
Comment puis-je améliorer mon OOAD compétences.
Mes aînés dit aussi parfait OOAD application ne fonctionnera pas pratiquement.

Merci

246voto

Eric Lippert Points 300275

Tout d'abord bonne cieux ne pas faire des calculs financiers en double. Faire des calculs financiers en décimal; qu'est ce que c'est. Utilisation double pour résoudre la physique des problèmes, pas financier problèmes.

Les principaux défauts de conception dans votre programme, c'est que la politique est au mauvais endroit. Qui est en charge du calcul des impôts? Vous avez mis le produit en charge du calcul des impôts, mais quand vous achetez une pomme ou un livre ou une machine à laver, la chose que vous vous apprêtez à acheter n'est pas responsable pour vous dire combien d'impôts que vous allez payer. La politique du gouvernement est responsable pour vous dire que. Votre conception massivement bafoue les OO principe de conception que les objets doivent être responsables de leurs propres préoccupations, et pas quelqu'un d'autre. La préoccupation d'une machine à laver est de laver vos vêtements, ne charge pas le droit d'importer en franchise de droits. Si les lois fiscales changent, vous ne voulez pas changer la machine à laver objet, vous souhaitez modifier l'objet de stratégie.

Alors, comment aborder ces sortes de problèmes dans le futur?

J'aurais commencé par mettre en exergue tous les grands nom dans la description du problème:

De base de la taxe de vente est applicable à un taux de 10% sur toutes les marchandises, à l'exception des livres, de la nourritureet de produits médicaux qui sont exonérées. Droit à l'importation additionnel de la taxe de vente applicable sur toutes les marchandises importées à un taux de 5%, avec pas d' exemptions. Quand j'ai acheter des articles - je recevoir un reçu qui indique le nom de tous les articles et leurs prix (y compris l'impôt) avec, pour finir, le coût total des articles, et le total des montants de taxes de vente payées. Les règles d'arrondi pour la taxe de vente sont que pour un taux d'imposition de n%, un prix de vente de p contient (np/100 arrondi à 0,05) du montant de la taxe de vente.

Maintenant, quelles sont les relations entre tous ces noms?

  • De base de la Taxe de Vente est une sorte de Taxe de Vente
  • Droit à l'importation est une sorte de Taxe de Vente
  • Une Taxe de Vente a un Taux qui est un nombre Décimal
  • Les livres sont un type d'Élément
  • La nourriture est une sorte de Point
  • Produits médicaux sont un type d'Élément
  • Les articles peuvent être des Marchandises Importées
  • Un Élément a un Nom qui est une Chaîne
  • Un Article a un Prix de vente qui est un nombre Décimal. (Note: un élément vraiment un prix? deux identiques machines à laver peut être pour la vente à des prix différents à différents magasins, ou dans le même magasin à des moments différents. Une meilleure conception pourrait être de dire qu'une Politique de Prix concerne un Élément de son Prix.)
  • Une Exemption de Taxe de Vente de la Politique décrit les conditions dans lesquelles la Taxe de Vente est inapplicable sur un Élément.
  • Un accusé de Réception est une liste d'Éléments, de leurs prix et de leurs impôts.
  • Une Réception a un total
  • Une Réception a un total de l'impôt

... et ainsi de suite. Une fois que vous avez toutes les relations entre tous les noms fonctionné, alors vous pouvez commencer à concevoir une hiérarchie de classe. Il y a une classe de base abstraite de l'Élément. Livre en hérite. Il y a une classe abstraite Tva; BasicSalesTax en hérite. Et ainsi de suite.

38voto

Radek Points 894

Si la société dit quelque chose à propos des bibliothèques comme NUnit, JUnit ou de Test::Unit est plus que probable que le DRT est vraiment importation. Dans votre exemple de code est pas de tests à tous.

Je voudrais essayer de démontrer une connaissance pratique de:

  • Les tests unitaires (par exemple. NUnit)
  • Moqueur (eg. RhinoMocks)
  • La persistance (eg. NHibernate)
  • Cio Conteneurs (par exemple. NSpring)
  • les modèles de conception
  • Principe SOLIDE

Je tiens à recommander l' www.dimecasts.net aussi impressionnante source de gratuit, bonne qualité des screencasts qui couvre tous les sujets mentionnés ci-dessus.

19voto

xxbbcc Points 7324

C'est très subjectif, mais voici quelques points que je voudrais faire au sujet de votre code:

  • À mon avis, vous mélangés Product et ShoppingCartItem. Product devrait avoir le nom du produit, le statut fiscal, etc. mais pas la quantité. La quantité n'est pas une propriété d'un produit - elle sera différente pour chaque client de la société qui achète ce produit en particulier.

  • ShoppingCartItem devrait avoir un Product et la quantité. De cette façon, le client peut librement acheter plus ou moins le même produit. Avec votre configuration actuelle, ce n'est pas possible.

  • Le calcul de l'impôt final ne devrait pas être une partie de l' Product - , il devrait être une partie de quelque chose comme ShoppingCart depuis le dernier calcul de l'impôt peut impliquent tous les produits dans le panier.

14voto

Jordão Points 29221

Tout d'abord, c'est une très bonne question d'entrevue. C'est un bon indicateur de nombreuses compétences.

Il y a beaucoup de choses que vous devez comprendre pour fournir une bonne réponse (il n'y a pas de réponse parfaite), à la fois de haut niveau et de bas niveau. Ici, êtes un couple:

  • Domaine de la Modélisation -> comment créer un bon modèle de la solution? Quels objets avez-vous créer? Comment vont-ils résoudre les exigences? La recherche de noms est un bon début, mais comment décidez-vous si votre choix d'entités est bon? Ce que d'autres entités avez-vous besoin? Ce domaine de connaissances avez-vous besoin pour le résoudre?
  • La séparation des préoccupations, couplage lâche, une forte cohésion -> Comment avez-vous séparer les parties de la conception qui ont des préoccupations différentes, les taux de changement, et comment les percevez-vous? Comment voulez-vous garder votre conception flexible et de courant?
  • Les tests unitaires, refactoring, TDD -> Quel est votre processus pour trouver une solution? Avez-vous écrire des tests, l'utilisation des objets fantaisie, refactoriser, itérer?
  • Nettoyer le code, les idiomes de la Langue -> utilisez-vous les caractéristiques de votre langage de programmation pour vous aider? Pouvez-vous écrire de code compréhensible? Vos niveaux d'abstraction du sens? Comment maintenable est le code?
  • Outils: utilisez-vous de contrôle à la source? Construire des outils? IDEs?

À partir de là, vous pouvez avoir beaucoup de discussions intéressantes, impliquant des principes de conception (comme les principes SOLIDES), des modèles de conception, les modèles d'analyse, le domaine de la modélisation, choix de la technologie, de l'évolution future des chemins (par exemple ce que si j'ajoute une base de données, ou une riche couche d'INTERFACE utilisateur, ce qui doit changer?), les échanges, les exigences non-fonctionnelles (performance, maintenabilité, sécurité, ...), les essais d'acceptation, etc...

Je ne vais pas commenter sur la façon dont vous devriez changer votre solution, c'est juste que vous devriez vous concentrer plus sur ces concepts.

Mais, je peux vous montrer comment j'ai (partiellement) a résolu ce problème, tout comme un exemple (en Java). Regarder dans l' Program de la classe pour voir comment tout cela se rassemble pour imprimer cette recette:

------------------ C'EST VOTRE COMMANDE ------------------
(001) Domain Driven Design ----- $69.99
(001) De La Croissance De L'Objet Logiciel Orienté ----- $49.99
(001), House M. D. Saison 1 ----- $29.99
(001), House M. D. Saison 7 ----- $À 34,50
(IMD) de plus en plus l'Objet de Logiciels Orientés ----- $2.50
(BST) House M. D. Saison 1 ----- $3.00
(BST) House M. D. Saison 7 ----- $3.45
(IMD), House M. D. Saison 7 ----- à 1,73 $
 SOUS-TOTAL ----- $184.47
 L'IMPÔT TOTAL ----- $10.68
 TOTAL ----- $195.15
---------------- MERCI DE NOUS AVOIR CHOISIS ----------------

Vous devriez certainement jeter un oeil à ces livres :-)

Tout comme une mise en garde: ma solution est encore très incomplet, j'ai juste concentré sur le chemin d'accès joyeux scénario afin d'avoir une bonne base pour construire sur.

12voto

Andrei G Points 1336

À l'exception du fait que vous utilisez une classe appelée produit, vous n'avez pas démontré que vous savez ce que l'héritage est, vous n'avez pas créé de multiples classé héritant de Produit, pas de polymorphisme. Le problème aurait pu être résolu à l'aide de plusieurs concepts de programmation orientée objet (même juste pour montrer que vous les connaissez). C'est une interview de problème si vous voulez vous montrer comment beaucoup vous savez.

Je ne voudrais cependant pas se transformer en dépression juste maintenant. Le fait que vous n'avez pas démontrer ici ne signifie pas que vous ne savez pas encore ou ne sont pas en mesure de les apprendre.

Vous avez juste besoin d'un peu plus d'expérience avec soit de la programmation orientée objet ou d'entrevues.

Bonne chance!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X