Skip to content

Instantly share code, notes, and snippets.

@arisupriatna14
Created March 26, 2023 16:36
Show Gist options
  • Save arisupriatna14/d6ca3eeff746a46333d34d7e9362e8bc to your computer and use it in GitHub Desktop.
Save arisupriatna14/d6ca3eeff746a46333d34d7e9362e8bc to your computer and use it in GitHub Desktop.
import java.util.ArrayList;
public class Product {
private String name = "";
private double price = 0.0;
private double shippingCost = 0.0;
private int quantity = 0;
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public double getShippingCost() {
return shippingCost;
}
public int getQuantity() {
return quantity;
}
Product(String name, double price, double shippingCost, int quantity){
this.name = name;
this.price = price;
this.shippingCost = shippingCost;
this.quantity = quantity;
}
// Smell: Long Method
// Reason: The method is quite long and could be broken down into smaller method for better readability and maintainability.
// Treatment: To reduce the length a method body, use Extract Method.
public double getTotalCost(){
double quantityDiscount = 0.0;
// Smell: Magic Numbers
// Reason: A magic number is a numeric value that’s encountered in the source but has no obvious meaning. This “anti-pattern” makes it harder to understand the program and refactor the code.
// Treatment: Declare a constant and assign the value of the magic number to it.
// Smell: Decompose Conditional
// Reason: The longer a piece of code is, the harder it’s to understand.
// Treatment: Extract the conditional to a separate method via Extract Method.
if((quantity > 50) || ((quantity * price) > 500)) {
quantityDiscount = .10;
} else if((quantity > 25) || ((quantity * price) > 100)) {
quantityDiscount = .07;
} else if((quantity >= 10) || ((quantity * price) > 50)) {
quantityDiscount = .05;
}
double discount = ((quantity - 1) * quantityDiscount) * price;
return (quantity * price) + (quantity * shippingCost) - discount;
}
}
public class Store {
// Smell: Public Field
// Reason: This variable is public and can be accessed directly from outside.
// Treatment: It would be better make it private
public ArrayList<Product> theProducts = new ArrayList<Product>();
// smell: Naming
// reason: The method addAProduct() has an awkward name; it would be clearer to
// name it simply `addProduct()`. Similarly, the variable theProducts could be
// named more descriptively (e.g. products).
// Treatment: Rename method and parameter name
public void addAProduct(Product newProduct) {
theProducts.add(newProduct);
}
// Smell: Feature envy
// Reason: A method accesses the data of another object more than its own data.
// Treatment: To refactor the code from the feature envy smell, we need to move the code
// that uses Product methods from Store to Product class. One way to do this is by
// introducing a new method printCost() in the Product class, which returns a string representation
// of the product's cost details. Then, we can remove the getCostOfProducts() method from Store,
// and replace it with a simple loop that calls printCost() on each product.
public void getCostOfProducts() {
for (Product product : theProducts) {
System.out.println(
"Total cost for " + product.getQuantity() + " " + product.getName() + "s is $" + product.getTotalCost());
System.out.println("Cost per product " + product.getTotalCost() / product.getQuantity());
System.out.println("Savings per product "
+ ((product.getPrice() + product.getShippingCost()) - (product.getTotalCost() / product.getQuantity()))
+ "\n");
}
}
public static void main(String[] args) {
Store cornerStore = new Store();
cornerStore.addAProduct(new Product("Pizza", 10.00, 1.00, 52));
cornerStore.addAProduct(new Product("Pizza", 10.00, 1.00, 26));
cornerStore.addAProduct(new Product("Pizza", 10.00, 1.00, 10));
cornerStore.getCostOfProducts();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment