IS MISUNDERSTOOD Steven Solomon Senior Software Engineer @ Pivotal - - PowerPoint PPT Presentation

is misunderstood steven solomon
SMART_READER_LITE
LIVE PREVIEW

IS MISUNDERSTOOD Steven Solomon Senior Software Engineer @ Pivotal - - PowerPoint PPT Presentation

THE DRY PRINCIPLE IS MISUNDERSTOOD Steven Solomon Senior Software Engineer @ Pivotal Labs Twitter: @ssolo112 Medium: @ssolomon DRY PRINCIPLE GROCERY APPLICATION By Annie Spratt on Unsplash WHAT IS IN THE APPLICATION? Dry Goods Produce


slide-1
SLIDE 1

THE DRY PRINCIPLE IS MISUNDERSTOOD

slide-2
SLIDE 2

Steven Solomon

Senior Software Engineer @ Pivotal Labs Twitter: @ssolo112 Medium: @ssolomon

slide-3
SLIDE 3

DRY PRINCIPLE

slide-4
SLIDE 4 By Annie Spratt on Unsplash

GROCERY APPLICATION

slide-5
SLIDE 5

Dry Goods Produce Meats

WHAT IS IN THE APPLICATION?

slide-6
SLIDE 6

Dry Goods Produce Meats

Margin: 300% Margin: 200% Margin: 100%

PRICING GROCERIES

slide-7
SLIDE 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

slide-8
SLIDE 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

slide-9
SLIDE 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

slide-10
SLIDE 10

DRY Principle is about removing duplicate code

  • Grocery App Developers
slide-11
SLIDE 11 By Annie Spratt on Unsplash

GROCERY APPLICATION

slide-12
SLIDE 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

slide-13
SLIDE 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

slide-14
SLIDE 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

slide-15
SLIDE 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

slide-16
SLIDE 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
slide-17
SLIDE 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
slide-18
SLIDE 18 Djim Loic on Unsplash
slide-19
SLIDE 19 Ricardo Viana on Unsplash
slide-20
SLIDE 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

slide-21
SLIDE 21

WHY DID THIS HAPPEN?

slide-22
SLIDE 22

THE DRY PRINCIPLE IS NOT ABOUT DUPLICATE CODE

slide-23
SLIDE 23

WHAT IS THE DRY PRINCIPLE REALLY ABOUT?

slide-24
SLIDE 24

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system

  • Dave Thomas & Andy Hunt
slide-25
SLIDE 25

TECHNIQUES

slide-26
SLIDE 26

TALKING TO THE PRODUCT TEAM

slide-27
SLIDE 27

BALANCED TEAM

Product Design Software

slide-28
SLIDE 28

BALANCED TEAM LANGUAGE

Business User Technical

Balanced Language

slide-29
SLIDE 29

BALANCED TEAM LANGUAGE

Business User Technical

Balanced Language

slide-30
SLIDE 30 Mark Rabe - Unsplash
slide-31
SLIDE 31

Meat Produce Priceable

:price

DryGood

slide-32
SLIDE 32

Meat Produce Priceable

:price

DryGood

slide-33
SLIDE 33

Meat Produce Priceable

:price

DryGood

slide-34
SLIDE 34

Meat Produce Priceable

:price

DryGood

slide-35
SLIDE 35

Meat Produce

:price

DryGood

:price :price

slide-36
SLIDE 36

Business User Technical

BALANCED TEAM LANGUAGE

slide-37
SLIDE 37

Business User Technical

DryGood Produce Meat

BALANCED TEAM LANGUAGE

Priceable

slide-38
SLIDE 38

Business User Technical

Priceable

BALANCED TEAM LANGUAGE

DryGood Produce Meat

slide-39
SLIDE 39

Business User Technical

BALANCED TEAM LANGUAGE

DryGood Produce Meat

slide-40
SLIDE 40

Business User Technical

BALANCED TEAM LANGUAGE

DryGood Produce Meat

slide-41
SLIDE 41

TALKING TO THE PRODUCT TEAM

slide-42
SLIDE 42

BITS VS CLUMPS

https://www.facebook.com/notes/kent- beck/bits-clumps-and-just- right/792597974106402

slide-43
SLIDE 43

DryGood Produce

CAN I REASON ABOUT THESE SEPARATELY?

:price :price

slide-44
SLIDE 44

DryGood Produce

CAN I REASON ABOUT THESE SEPARATELY?

:price :price

slide-45
SLIDE 45

ARE THEY SEPARATE?

Produce Priceable

:price

DryGood

slide-46
SLIDE 46

ARE THEY SEPARATE?

Produce Priceable

:price

DryGood

slide-47
SLIDE 47

ARE THEY SEPARATE?

Produce Priceable

:price

DryGood

slide-48
SLIDE 48

ARE THEY SEPARATE?

Produce Priceable

:price

DryGood Priceable

:price

slide-49
SLIDE 49

ARE THEY SEPARATE?

Produce

:price

DryGood

:price

slide-50
SLIDE 50

BITS VS CLUMPS

https://www.facebook.com/notes/kent- beck/bits-clumps-and-just- right/792597974106402

slide-51
SLIDE 51

NOTICING DIVERGENT CHANGE

slide-52
SLIDE 52

SHOTGUN SURGERY

slide-53
SLIDE 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

slide-54
SLIDE 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

slide-55
SLIDE 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

slide-56
SLIDE 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

slide-57
SLIDE 57

DIVERGENT CHANGE

slide-58
SLIDE 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

slide-59
SLIDE 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

slide-60
SLIDE 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

slide-61
SLIDE 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

slide-62
SLIDE 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

slide-63
SLIDE 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

slide-64
SLIDE 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

slide-65
SLIDE 65
slide-66
SLIDE 66

Shotgun Surgery Divergent Change

slide-67
SLIDE 67

NOTICING DIVERGENT CHANGE

slide-68
SLIDE 68

TECHNIQUES

slide-69
SLIDE 69

GETTING BACK TO SAFETY

slide-70
SLIDE 70

class Produce include Priceable def initialize(cost, growing_season) @cost = cost @growing_season = growing_season @margin = BigDecimal('100') end end

slide-71
SLIDE 71

class Produce include Priceable def initialize(cost, growing_season) @cost = cost @growing_season = growing_season @margin = BigDecimal('100') end end

slide-72
SLIDE 72

class Produce include Priceable def initialize(cost, growing_season) @cost = cost @growing_season = growing_season @margin = BigDecimal('100') end end

slide-73
SLIDE 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

slide-74
SLIDE 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

slide-75
SLIDE 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

slide-76
SLIDE 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

slide-77
SLIDE 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

slide-78
SLIDE 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

slide-79
SLIDE 79

class DryGood include Priceable def initialize(cost) @cost = cost @margin = BigDecimal('200') end end

slide-80
SLIDE 80

class DryGood include Priceable def initialize(cost) @cost = cost @margin = BigDecimal('200') end end

slide-81
SLIDE 81

class DryGood include Priceable def initialize(cost) @cost = cost @margin = BigDecimal('200') end end

slide-82
SLIDE 82

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

slide-83
SLIDE 83

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

slide-84
SLIDE 84

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

slide-85
SLIDE 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

slide-86
SLIDE 86

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

slide-87
SLIDE 87

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

slide-88
SLIDE 88

class Meat include Priceable def initialize(cost, type, cut) @cost = cost @type = type @cut = cut @margin = BigDecimal('300') end end

slide-89
SLIDE 89

class Meat include Priceable def initialize(cost, type, cut) @cost = cost @type = type @cut = cut @margin = BigDecimal('300') end end

slide-90
SLIDE 90

class Meat include Priceable def initialize(cost, type, cut) @cost = cost @type = type @cut = cut @margin = BigDecimal('300') end end

slide-91
SLIDE 91

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

slide-92
SLIDE 92

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

slide-93
SLIDE 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(@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

slide-94
SLIDE 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

slide-95
SLIDE 95

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

slide-96
SLIDE 96

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

slide-97
SLIDE 97

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

slide-98
SLIDE 98

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

slide-99
SLIDE 99
slide-100
SLIDE 100
slide-101
SLIDE 101 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
slide-102
SLIDE 102

So what is the correct abstraction?

  • You (Maybe)
slide-103
SLIDE 103 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
slide-104
SLIDE 104

There isn’t one. We don’t have enough information.

  • Me
slide-105
SLIDE 105

SUMMARY

slide-106
SLIDE 106

➤ 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

slide-107
SLIDE 107

THANKS

slide-108
SLIDE 108

QUESTIONS

Steven Solomon Senior Software Engineer Twitter: @ssolo112 Medium: @ssolomon

leanpub.com/agilesoftware

slide-109
SLIDE 109

I’m writing a book. It is a software book with a story leanpub.com/agilesoftware