Skip to content

Instantly share code, notes, and snippets.

@shanewwarren
Created February 9, 2017 00:56
Show Gist options
  • Save shanewwarren/fa550740156b8dcd72e0d8a9626f5e80 to your computer and use it in GitHub Desktop.
Save shanewwarren/fa550740156b8dcd72e0d8a9626f5e80 to your computer and use it in GitHub Desktop.
Shane Warren: Olo Refactor Exercise
using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
namespace Refactoring
{
class Program
{
static void Main(string[] args)
{
var order = new Order {
Name = "John Doe",
Products = new List<Product> {
new Product {
ProductName = "Pulled Pork",
Price = 6.99m,
Weight = 0.5m,
PricingMethod = "PerPound"
},
new Product {
ProductName = "Coke",
Price = 3m,
Quantity = 2,
PricingMethod = "PerItem"
}
}
};
Console.WriteLine(order);
}
}
public class Order {
public List<Product> Products;
public string Name;
public decimal Price {
get {
if (this.Products == null) {
return 0m;
}
return this.Products.Aggregate(0m, (result, product) => result + product.ProductPrice);
}
}
public override string ToString() {
var builder = new StringBuilder();
builder.AppendFormat("ORDER SUMMARY FOR {0}:", this.Name);
builder.AppendLine();
this.Products.ForEach((product) => builder.AppendLine(product.ToString()));
builder.AppendFormat("Total Price: ${0}", this.Price);
return builder.ToString();
}
}
public class Product
{
public string ProductName;
public decimal Price;
public decimal? Weight;
public int? Quantity;
public string PricingMethod;
public decimal ProductPrice {
get {
if (this.PricingMethod == "PerPound") {
return this.Weight.Value * this.Price;
}
return this.Quantity.Value * this.Price;
}
}
public override string ToString() {
if (this.PricingMethod == "PerPound")
{
return String.Format("{0} ${1} ({2} pounds at ${3} per pound)", this.ProductName, this.ProductPrice, this.Weight, this.Price);
}
return String.Format("{0} ${1} ({2} items at ${3} each)", this.ProductName, this.ProductPrice, this.Quantity, this.Price);
}
}
}
@shanewwarren
Copy link
Author

Olo Refactor Exercise

Description

We would you like to see how you would improve this example code. Please forward your updates along with a couple of sentences describing the changes you decided to make, as well as any changes you would have wanted to make, given more time. You shouldn't have to spend more than 30 minutes on this in total.

My refactoring changes

Order class

  1. It's pretty bad precedent to use a tuple as an impromptu data structure. Therefore I abstracted out the details of the order Tuple<string, List<Product>> into an Order class. This class provides three public properties:
    • Name property to denote who the order belongs to.
    • Products property which contains a list of the products for that order.
    • Price which basically aggregates the ProductPrice for all the products in the order.
2.   Lastly, the majority of the program logic involves printing out the details of the order.  To that end I've refactored printing out the    `order` by overriding the `ToString()` method on the `Order` class to print out the details.

Product class

  1. The original code printed calculated the productPrice and used that price to calculate the price of the entire order. Therefore, I refactored the code, by providing a public property, ProductPrice, which calculates the appropriate price depending on the class's PricingMethod.

  2. Similar to the Order class, I refactored how a product details are displayed by overriding the ToString method on the Product class. The specific string is returned depending on that product's on the PricingMethod.

Additional changes I would make

  1. The Weight and Quantity properties should probably not belong on the Product class. It doesn't describe anything about the product and instead describes a specific line item of a product.

  2. The interface for adding products to the Order class should be refactored as well. Instead of having direct access to the Products property I would probably add an AddProduct method to the Order class. This would provide better interface to adding products to the order.

  3. I'd refactor the PricingMethod method to use an enumeration instead of relying on "magic strings". This would provide better intellisense and refactoring abilities as well as improve the interface for working with a Product.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment