DRY absolutely can get this ugly and messy (I've seen it many times), but I believe that this is largely an experience problem. You have many tiers of DRY knowledge:
- Have heard of it and it sounds like a good idea
- Let's DRY everywhere!
- OK, maybe don't DRY everywhere...
- There are multiple ways to implement DRY, and it all depends on circumstance
Taking the article example, a better approach would be to DRY the data first (after discovering that in your organization the most common pizza is thin crust with tomato sauce and regular cheese):
val STANDARD_PIZZA = {
crust: "thin",
sauce: "tomato",
cheese: "regular",
}
val TOPPINGS_PEPPERONI = ["pepperoni"]
val TOPPINGS_HAWAIIAN = ["pepperoni", "pineapple"]
def make_pizza(design):
requests.post(PIZZA_URL, design)
def make_standard_pizza(toppings):
make_pizza(STANDARD_PIZZA + {toppings: toppings})
This gives you both low level and high level (convenience) interfaces to pizza generation, with none of the silly class complexity or function explosion.
- Have heard of it and it sounds like a good idea
- Let's DRY everywhere!
- OK, maybe don't DRY everywhere...
- There are multiple ways to implement DRY, and it all depends on circumstance
Taking the article example, a better approach would be to DRY the data first (after discovering that in your organization the most common pizza is thin crust with tomato sauce and regular cheese):
Now it's easy to use with no repetition: You can easily add to it: Then when you need to expand for half-and-half: This gives you both low level and high level (convenience) interfaces to pizza generation, with none of the silly class complexity or function explosion.