Created
March 26, 2023 16:36
-
-
Save arisupriatna14/d6ca3eeff746a46333d34d7e9362e8bc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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