You have probably heard of the DRY Principle, but what you don’t know is that it has nothing to do with duplicate code. In this talk I (Steven Solomon) will teach you to re-think the DRY Principle, how to identify incorrectly “DRY” code, and how to refactor your code so that it is easy to change again.
7. # produce.rb
class Produce
def initialize(cost)
@cost = cost
end
def price
psychological_price(@cost * BigDecimal('100'))
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
PRODUCE
8. # dry_good.rb
class DryGood
def initialize(cost)
@cost = cost
end
def price
psychological_price(@cost * BigDecimal(‘200'))
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
DRY GOOD
9. # meat.rb
class Meat
def initialize(cost)
@cost = cost
end
def price
psychological_price(@cost * BigDecimal(‘300'))
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
MEAT
10. “DRY Principle is about removing
duplicate code
-Grocery App Developers
12. class Meat
def initialize(cost)
@cost = cost
end
def price
psychological_price(@cost * BigDecimal('300'))
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
class Produce
def initialize(cost)
@cost = cost
end
def price
psychological_price(@cost * BigDecimal('100'))
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
class DryGood
def initialize(cost)
@cost = cost
end
def price
psychological_price(@cost * BigDecimal('200'))
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
REMOVING CODE DUPLICATION
13. class Meat
def initialize(cost)
@cost = cost
end
def price
psychological_price(@cost * BigDecimal('300'))
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
class Produce
def initialize(cost)
@cost = cost
end
def price
psychological_price(@cost * BigDecimal('100'))
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
class DryGood
def initialize(cost)
@cost = cost
end
def price
psychological_price(@cost * BigDecimal('200'))
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
REMOVING CODE DUPLICATION
14. # priceable.rb
module Priceable
def price
psychological_price(@cost * @margin)
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
15. # priceable.rb
module Priceable
def price
psychological_price(@cost * @margin)
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
16. # produce.rb
class Produce
include Priceable
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
end
# meat.rb
class Meat
include Priceable
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
end
# dry_good.rb
class DryGood
include Priceable
def initialize(cost)
@cost = cost
@margin = BigDecimal('200')
end
end
17. # produce.rb
class Produce
include Priceable
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
end
# meat.rb
class Meat
include Priceable
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
end
# dry_good.rb
class DryGood
include Priceable
def initialize(cost)
@cost = cost
@margin = BigDecimal('200')
end
end
20. # priceable.rb
module Priceable
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
53. # produce.rb
class Produce
include Priceable
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = 100.0
end
end
# meat.rb
class Meat
include Priceable
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = 300.0
end
end
# dry_good.rb
class DryGood
include Priceable
def initialize(cost)
@cost = cost
@margin = 200.0
end
end
SHOTGUN SURGERY
54. # produce.rb
class Produce
include Priceable
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = 100.0
end
end
# meat.rb
class Meat
include Priceable
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = 300.0
end
end
# dry_good.rb
class DryGood
include Priceable
def initialize(cost)
@cost = cost
@margin = 200.0
end
end
SHOTGUN SURGERY
55. # produce.rb
class Produce
include Priceable
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
end
# meat.rb
class Meat
include Priceable
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
end
# dry_good.rb
class DryGood
include Priceable
def initialize(cost)
@cost = cost
@margin = BigDecimal('200')
end
end
SHOTGUN SURGERY
56. # produce.rb
class Produce
include Priceable
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
end
# meat.rb
class Meat
include Priceable
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
end
# dry_good.rb
class DryGood
include Priceable
def initialize(cost)
@cost = cost
@margin = BigDecimal('200')
end
end
SHOTGUN SURGERY
58. # priceable.rb
module Priceable
def price
psychological_price(@cost * @margin)
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
DIVERGENT CHANGE
59. # priceable.rb
module Priceable
def price
psychological_price(@cost * @margin)
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
DIVERGENT CHANGE
Steak prices are based on cut
60. # priceable.rb
module Priceable
def price
total += psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
DIVERGENT CHANGE
Steak prices are based on cut
61. # priceable.rb
module Priceable
def price
total += psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
DIVERGENT CHANGE
62. # priceable.rb
module Priceable
def price
total += psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
DIVERGENT CHANGE
Produce prices are based on season
63. # priceable.rb
module Priceable
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
DIVERGENT CHANGE
Produce prices are based on season
64. # priceable.rb
module Priceable
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
DIVERGENT CHANGE
69. class Produce
include Priceable
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
end
70. class Produce
include Priceable
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
end
71. class Produce
include Priceable
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
end
72. class Produce
include Priceable
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
end
73. class Produce
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
def price(season = nil)
total = psychological_price(@price * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
74. class Produce
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
75. class Produce
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
76. class Produce
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
77. class Produce
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
78. class Produce
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
season != @growing_season ? total + 1 : total
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
79. class Produce
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if season != @growing_season
total + 1
else
total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
80. class Produce
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if season != @growing_season
total + 1
else
total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
84. class DryGood
def initialize(cost)
@cost = cost
@margin = BigDecimal('200')
end
def price(season = nil)
total = psychological_price(@price * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
85. class DryGood
def initialize(cost)
@cost = cost
@margin = BigDecimal('200')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
86. class DryGood
def initialize(cost)
@cost = cost
@margin = BigDecimal('200')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
87. class DryGood
def initialize(cost)
@cost = cost
@margin = BigDecimal('200')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
88. class DryGood
def initialize(cost)
@cost = cost
@margin = BigDecimal('200')
end
def price()
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
89. class DryGood
def initialize(cost)
@cost = cost
@margin = BigDecimal('200')
end
def price()
psychological_price(@cost * @margin)
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
90. class Meat
include Priceable
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
end
91. class Meat
include Priceable
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
end
92. class Meat
include Priceable
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
end
93. class Meat
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
def price(season = nil)
total = psychological_price(@price * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
94. class Meat
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
95. class Meat
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
96. class Meat
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
97. class Meat
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
def price()
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
season != @growing_season ? total + 1 : total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
98. class Meat
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
def price()
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
99. class Meat
def initialize(cost, type, cut)
@cost = cost
@type = type
@cut = cut
@margin = BigDecimal('300')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if @type == :steak && @cut == :flatiron
total + BigDecimal('5')
else
total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
class Produce
def initialize(cost, growing_season)
@cost = cost
@growing_season = growing_season
@margin = BigDecimal('100')
end
def price(season = nil)
total = psychological_price(@cost * @margin)
if season != @growing_season
total + 1
else
total
end
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
class DryGood
def initialize(cost)
@cost = cost
@margin = BigDecimal('200')
end
def price(season = nil)
psychological_price(@cost * @margin)
end
private
def psychological_price(amount)
if amount.ceil == amount
(amount + BigDecimal('0.50')).ceil - BigDecimal('0.01')
else
(amount).ceil - BigDecimal('0.01')
end
end
end
100. “So what is the correct abstraction?
- You (Maybe)
101. ➤ DRY Principle is about duplicate knowledge
➤ Techniques to identify pre-mature abstractions
➤ Talk to product team
➤ Bits vs clumps
➤ Noticing Divergent Change
➤ Remove pre-mature abstractions
WHAT WE TALKED ABOUT