Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.
Don’t Settle for
Poor Names
Alistair McKinnell
@amckinnell
Naming
is deeply

connected to
Designing
Designing
is deeply

connected to
Naming
Example from

QCloud
QCloud has forms,

sheets, and inspections
QCloud has forms,

sheets, and inspections
A sheet is composed of a
reviewed and a submitted
{ something or other }
class Sheet < ActiveRecord::Base
composed_of :submitted_attribution_event,
class_name: ’AttributionEvent',
allow_nil: true...
#
# Represents the information required to attribute
# an event to a user.
#
class AttributionEvent
attr_reader :name, :em...
A sheet is composed of a
reviewed and a submitted
attribution event
An attribution event
identifies a user and

has a timestamp
An attribution event
identifies a user and

has a timestamp
An attribution event
identifies a user and

has a timestamp
#
# Represents the information required to attribute
# an event to a user.
#
class AttributionEvent
attr_reader :name, :em...
sheet.submitted_attribution_event =
AttributionEvent.new(
inspector.name, inspector.email,
inspector.id, Time.zone.now
)
s...
sheet.submitted_attribution_event =
AttributionEvent.new(
inspector.name, inspector.email,
inspector.id, Time.zone.now
)
s...
#
# Represents the information required to attribute
# an event to a user.
#
class AttributionEvent
attr_reader :name, :em...
#
# Represents the information required to attribute
# an event to a user.
#
class AttributionEvent
attr_reader :name, :em...
sheet.submitted_attribution_event =
AttributionEvent.build(inspector)
sheet.submitted_by_name = inspector.name
sheet.submi...
sheet.submitted_attribution_event =
AttributionEvent.build(inspector)
sheet.submitted_by_name = inspector.name
sheet.submi...
sheet.submitted_attribution_event =
AttributionEvent.build(inspector)
sheet.submitted_by_name = inspector.name
sheet.submi...
sheet.submitted_attribution_event =
AttributionEvent.build(inspector)
sheet.submitted_by_name = inspector.name
sheet.submi...
sheet.submitted_attribution_event =
AttributionEvent.build(inspector)
sheet.submitted_by_name = inspector.name
sheet.submi...
#
# Represents the information required to attribute
# an event to a user.
#
class AttributionEvent
attr_reader :name, :em...
class Sheet < ActiveRecord::Base
composed_of :reviewed_attribution_event,
class_name: 'AttributionEvent',
allow_nil: true,...
class Sheet < ActiveRecord::Base
composed_of :reviewed_attribution_event,
class_name: ’AttributionEvent',
allow_nil: true,...
class Sheet < ActiveRecord::Base
attribution_event :reviewed
attribution_event :submitted
attribution_event :discarded
module Models
module AttributionEvents
extend ActiveSupport::Concern
module ClassMethods
def attribution_event(type, allow...
module Models
module AttributionEvents
extend ActiveSupport::Concern
module ClassMethods
def attribution_event(type, allow...
module Models
module AttributionEvents
extend ActiveSupport::Concern
module ClassMethods
def attribution_event(type, allow...
module Models
module AttributionEvents
extend ActiveSupport::Concern
module ClassMethods
def attribution_event(type, allow...
module Models
module AttributionEvents
extend ActiveSupport::Concern
module ClassMethods
def attribution_event(type, allow...
include Models::AttributionEvents
attribution_event :reviewed
composed_of :reviewed_attribution_event,
class_name :'Attrib...
An attribution event
identifies a user and

has a timestamp
And there are different 

types of attribution events
sheet.submitted_attribution_event =
AttributionEvent.build(inspector)
sheet.reviewed_attribution_event =
AttributionEvent....
How do we { log, capture,
assign, save, or record }
an attribution event ?
sheet.log_attribution_event(
type: :reviewed, user: inspector, at: reviewed_at
)
sheet.capture_attribution_event(
type: :s...
sheet.log_attribution_event(
type: :reviewed, user: inspector, at: reviewed_at
)
sheet.capture_attribution_event(
type: :s...
sheet.log_attribution_event(
type: :reviewed, user: inspector, at: reviewed_at
)
sheet.capture_attribution_event(
type: :s...
module Models
module AttributionEvents
extend ActiveSupport::Concern
included do
def capture_attribution_event(type:, user...
module Models
module AttributionEvents
extend ActiveSupport::Concern
included do
def capture_attribution_event(type:, user...
module Models
module AttributionEvents
extend ActiveSupport::Concern
included do
def capture_attribution_event(type:, user...
sheet.capture_attribution_event(
type: :submitted, user: inspector
)
Before
After
sheet.submitted_by_name = inspector.name...
Example from

QCloud
composed_of Concern
An attribution event
identifies a user and

has a timestamp
And we capture different 

types of attribution events
class Sheet < ActiveRecord::Base
include Models::AttributionEvents
attribution_event :reviewed
attribution_event :submitte...
class Sheet < ActiveRecord::Base
include Models::AttributionEvents
attribution_event :reviewed
attribution_event :submitte...
Naming
is deeply

connected to
Designing
Ubiquitous 

Language
The language used by everyone on the team
to describe the domain model when speaking,
writing user s...
• Passes the tests
• Reveals intention
Simple 

Design
• No duplication
• Fewest elements
• Passes the tests
• Reveals intention
Simple 

Design
• No duplication
• Fewest elements
• Passes the tests
• Reveals intention
Simple 

Design
• No duplication
• Fewest elements
• Passes the tests
• Improves names
Simple 

Design
• No duplication
• Fewest elements
• Improves names
Simple 

Design
• Removes duplication
• Improves names
Simple 

Design
• Removes duplication
The Simple Design Dynamo™
Example from

QCloud
class Sheet < ActiveRecord::Base
composed_of :reviewed_attribution_event,
class_name: 'AttributionEvent',
allow_nil: true,...
#
# Represents the information required to attribute
# an event to a user.
#
class AttributionEvent
attr_reader :name, :em...
#
# Represents the information required to attribute
# an event to a user.
#
class AttributionEvent
attr_reader :name, :em...
class Sheet < ActiveRecord::Base
composed_of :reviewed_attribution_event,
class_name: ’AttributionEvent',
allow_nil: true,...
module Models
module AttributionEvents
extend ActiveSupport::Concern
module ClassMethods
def attribution_event(type, allow...
class Sheet < ActiveRecord::Base
include Models::AttributionEvents
attribution_event :reviewed
attribution_event :submitte...
The Simple Design Dynamo™
Don’t Settle for
Poor Names
Don’t Settle for
Poor Names
Pretty Please
The Simple Design Dynamo™
Resources
http://blog.jbrains.ca/permalink/the-four-elements-of-simple-design
http://blog.thecodewhisperer.com/permalink/putting-an-...
Don't Settle for Poor Names
Don't Settle for Poor Names
Don't Settle for Poor Names
Don't Settle for Poor Names
Don't Settle for Poor Names
Don't Settle for Poor Names
Don't Settle for Poor Names
Don't Settle for Poor Names
Don't Settle for Poor Names
Don't Settle for Poor Names
Don't Settle for Poor Names
Don't Settle for Poor Names
Don't Settle for Poor Names
Próxima SlideShare
Cargando en…5
×

Don't Settle for Poor Names

254 visualizaciones

Publicado el

I get frustrated with code that is sprinkled with poorly named classes, methods, and variables. Whenever I work on a team or coach a team, I put a lot of energy into choosing good names and sensitizing my teammates to the power of naming. I've noticed that developers spend most of their days reading code rather than writing code. I suspect you've noticed too. Creating understandable code is a high leverage activity for any team. And naming is where I start.

Simple Design. Domain-Driven Design.

Publicado en: Tecnología
  • Sé el primero en comentar

Don't Settle for Poor Names

  1. 1. Don’t Settle for Poor Names Alistair McKinnell @amckinnell
  2. 2. Naming is deeply
 connected to Designing
  3. 3. Designing is deeply
 connected to Naming
  4. 4. Example from
 QCloud
  5. 5. QCloud has forms,
 sheets, and inspections
  6. 6. QCloud has forms,
 sheets, and inspections
  7. 7. A sheet is composed of a reviewed and a submitted { something or other }
  8. 8. class Sheet < ActiveRecord::Base composed_of :submitted_attribution_event, class_name: ’AttributionEvent', allow_nil: true, mapping: [ ['submitted_by_name', 'name'], ['submitted_by_email', 'email'], ['submitted_by_id', 'user_id'], ['submitted_at', 'event_at'] ] composed_of :reviewed_attribution_event, class_name: 'AttributionEvent', allow_nil: true, mapping: [ ['reviewed_by_name', 'name'], ['reviewed_by_email', 'email'], ['reviewed_by_id', 'user_id'], ['reviewed_at', 'event_at'] ]
  9. 9. # # Represents the information required to attribute # an event to a user. # class AttributionEvent attr_reader :name, :email, :user_id, :event_at def initialize(name, email, user_id, at) @name = name @email = email @user_id = user_id @event_at = at end end composed_of :submitted_attribution_event, class_name: ’AttributionEvent', allow_nil: true, mapping: [ ['submitted_by_name', 'name'], ['submitted_by_email', 'email'], ['submitted_by_id', 'user_id'], ['submitted_at', 'event_at'] ]
  10. 10. A sheet is composed of a reviewed and a submitted attribution event
  11. 11. An attribution event identifies a user and
 has a timestamp
  12. 12. An attribution event identifies a user and
 has a timestamp
  13. 13. An attribution event identifies a user and
 has a timestamp
  14. 14. # # Represents the information required to attribute # an event to a user. # class AttributionEvent attr_reader :name, :email, :user_id, :event_at def initialize(name, email, user_id, at) @name = name @email = email @user_id = user_id @event_at = at end end An attribution event identifies a user and
 has a timestamp
  15. 15. sheet.submitted_attribution_event = AttributionEvent.new( inspector.name, inspector.email, inspector.id, Time.zone.now ) sheet.submitted_by_name = inspector.name sheet.submitted_by_email = inspector.email sheet.submitted_by_id = inspector.id sheet.submitted_at = Time.zone.now Before After
  16. 16. sheet.submitted_attribution_event = AttributionEvent.new( inspector.name, inspector.email, inspector.id, Time.zone.now ) sheet.submitted_by_name = inspector.name sheet.submitted_by_email = inspector.email sheet.submitted_by_id = inspector.id sheet.submitted_at = Time.zone.now Before After
  17. 17. # # Represents the information required to attribute # an event to a user. # class AttributionEvent attr_reader :name, :email, :user_id, :event_at def initialize(name, email, user_id, at) @name = name @email = email @user_id = user_id @event_at = at end end An attribution event identifies a user and
 has a timestamp
  18. 18. # # Represents the information required to attribute # an event to a user. # class AttributionEvent attr_reader :name, :email, :user_id, :event_at def self.build(user, at: Time.zone.now) new(user.name, user.email, user.id, at) end def initialize(name, email, user_id, at) @name = name @email = email @user_id = user_id @event_at = at end end An attribution event identifies a user and
 has a timestamp
  19. 19. sheet.submitted_attribution_event = AttributionEvent.build(inspector) sheet.submitted_by_name = inspector.name sheet.submitted_by_email = inspector.email sheet.submitted_by_id = inspector.id sheet.submitted_at = Time.zone.now Before After
  20. 20. sheet.submitted_attribution_event = AttributionEvent.build(inspector) sheet.submitted_by_name = inspector.name sheet.submitted_by_id = inspector.id sheet.submitted_at = Time.zone.now Before After !
  21. 21. sheet.submitted_attribution_event = AttributionEvent.build(inspector) sheet.submitted_by_name = inspector.name sheet.submitted_by_email = inspector.email sheet.submitted_by_id = inspector.id sheet.submitted_at = Time.zone.now Before After
  22. 22. sheet.submitted_attribution_event = AttributionEvent.build(inspector) sheet.submitted_by_name = inspector.name sheet.submitted_by_email = reviewer.email sheet.submitted_by_id = inspector.id sheet.submitted_at = Time.zone.now Before After !
  23. 23. sheet.submitted_attribution_event = AttributionEvent.build(inspector) sheet.submitted_by_name = inspector.name sheet.submitted_by_email = reviewer.email sheet.submitted_by_id = inspector.id sheet.submitted_at = Time.zone.now Before After
  24. 24. # # Represents the information required to attribute # an event to a user. # class AttributionEvent attr_reader :name, :email, :user_id, :event_at def self.build(user, at: Time.zone.now) new(user.name, user.email, user.id, at) end def initialize(name, email, user_id, at) @name = name @email = email @user_id = user_id @event_at = at end end
  25. 25. class Sheet < ActiveRecord::Base composed_of :reviewed_attribution_event, class_name: 'AttributionEvent', allow_nil: true, mapping: [ ['reviewed_by_name', 'name'], ['reviewed_by_email', 'email'], ['reviewed_by_id', 'user_id'], ['reviewed_at', 'event_at'] ] composed_of :submitted_attribution_event, class_name: ’AttributionEvent', allow_nil: true, mapping: [ ['submitted_by_name', 'name'], ['submitted_by_email', 'email'], ['submitted_by_id', 'user_id'], ['submitted_at', 'event_at'] ]
  26. 26. class Sheet < ActiveRecord::Base composed_of :reviewed_attribution_event, class_name: ’AttributionEvent', allow_nil: true, mapping: [ [‘reviewed_by_name’, 'name'], [‘reviewed_by_email', 'email'], [‘reviewed_by_id', 'user_id'], [‘reviewed_at', 'event_at'] ] composed_of :submitted_attribution_event, class_name: ’AttributionEvent', allow_nil: true, mapping: [ [‘submitted_by_name', 'name'], [‘submitted_by_email’, 'email'], [‘submitted_by_id', 'user_id'], [‘submitted_at’, 'event_at'] ]
  27. 27. class Sheet < ActiveRecord::Base attribution_event :reviewed attribution_event :submitted attribution_event :discarded
  28. 28. module Models module AttributionEvents extend ActiveSupport::Concern module ClassMethods def attribution_event(type, allow_nil: true) attribution_event = <<-ATTRIBUTION_EVENT composed_of :#{type}_attribution_event, class_name: 'AttributionEvent', allow_nil: #{allow_nil}, mapping: [ ['#{type}_by_name', 'name'], ['#{type}_by_email', 'email'], ['#{type}_by_id', 'user_id'], ['#{type}_at', 'event_at'] ] ATTRIBUTION_EVENT class_eval(attribution_event) end end end end
  29. 29. module Models module AttributionEvents extend ActiveSupport::Concern module ClassMethods def attribution_event(type, allow_nil: true) attribution_event = <<-ATTRIBUTION_EVENT composed_of :#{type}_attribution_event, class_name: 'AttributionEvent', allow_nil: #{allow_nil}, mapping: [ ['#{type}_by_name', 'name'], ['#{type}_by_email', 'email'], ['#{type}_by_id', 'user_id'], ['#{type}_at', 'event_at'] ] ATTRIBUTION_EVENT class_eval(attribution_event) end end end end
  30. 30. module Models module AttributionEvents extend ActiveSupport::Concern module ClassMethods def attribution_event(type, allow_nil: true) attribution_event = <<-ATTRIBUTION_EVENT composed_of :#{type}_attribution_event, class_name: 'AttributionEvent', allow_nil: #{allow_nil}, mapping: [ ['#{type}_by_name', 'name'], ['#{type}_by_email', 'email'], ['#{type}_by_id', 'user_id'], ['#{type}_at', 'event_at'] ] ATTRIBUTION_EVENT class_eval(attribution_event) end end end end
  31. 31. module Models module AttributionEvents extend ActiveSupport::Concern module ClassMethods def attribution_event(type, allow_nil: true) attribution_event = <<-ATTRIBUTION_EVENT composed_of :#{type}_attribution_event, class_name: 'AttributionEvent', allow_nil: #{allow_nil}, mapping: [ ['#{type}_by_name', 'name'], ['#{type}_by_email', 'email'], ['#{type}_by_id', 'user_id'], ['#{type}_at', 'event_at'] ] ATTRIBUTION_EVENT class_eval(attribution_event) end end end end
  32. 32. module Models module AttributionEvents extend ActiveSupport::Concern module ClassMethods def attribution_event(type, allow_nil: true) attribution_event = <<-ATTRIBUTION_EVENT composed_of :#{type}_attribution_event, class_name: 'AttributionEvent', allow_nil: #{allow_nil}, mapping: [ ['#{type}_by_name', 'name'], ['#{type}_by_email', 'email'], ['#{type}_by_id', 'user_id'], ['#{type}_at', 'event_at'] ] ATTRIBUTION_EVENT class_eval(attribution_event) end end end end
  33. 33. include Models::AttributionEvents attribution_event :reviewed composed_of :reviewed_attribution_event, class_name :'AttributionEvent', allow_nil: true, mapping: [ ['reviewed_by_name', 'name'], ['reviewed_by_email', 'email'], ['reviewed_by_id', 'user_id'], ['reviewed_at', 'event_at'] ] Before After
  34. 34. An attribution event identifies a user and
 has a timestamp And there are different 
 types of attribution events
  35. 35. sheet.submitted_attribution_event = AttributionEvent.build(inspector) sheet.reviewed_attribution_event = AttributionEvent.build(supervisor) class Sheet < ActiveRecord::Base include Models::AttributionEvents attribution_event :reviewed attribution_event :submitted ... end
  36. 36. How do we { log, capture, assign, save, or record } an attribution event ?
  37. 37. sheet.log_attribution_event( type: :reviewed, user: inspector, at: reviewed_at ) sheet.capture_attribution_event( type: :submitted, user: inspector, at: submitted_at ) header.assign_attribution_event( type: :reviewed, user: inspector, at: reviewed_at ) inspection.save_attribution_event( type: :submitted, user: inspector, at: reviewed_at ) inspection.record_attribution_event( type: :reviewed, user: inspector, at: reviewed_at )
  38. 38. sheet.log_attribution_event( type: :reviewed, user: inspector, at: reviewed_at ) sheet.capture_attribution_event( type: :submitted, user: inspector, at: submitted_at ) header.assign_attribution_event( type: :reviewed, user: inspector, at: reviewed_at ) inspection.save_attribution_event( type: :submitted, user: inspector, at: reviewed_at ) inspection.record_attribution_event( type: :reviewed, user: inspector, at: reviewed_at )
  39. 39. sheet.log_attribution_event( type: :reviewed, user: inspector, at: reviewed_at ) sheet.capture_attribution_event( type: :submitted, user: inspector, at: submitted_at ) sheet.assign_attribution_event( type: :reviewed, user: inspector, at: reviewed_at ) inspection.save_attribution_event( type: :submitted, user: inspector, at: reviewed_at ) sheet.record_attribution_event( type: :reviewed, user: inspector, at: reviewed_at )
  40. 40. module Models module AttributionEvents extend ActiveSupport::Concern included do def capture_attribution_event(type:, user:, at: Time.zone.now) send("#{type}_attribution_event=", AttributionEvent.build(user, at: at)) end end module ClassMethods ... end end end
  41. 41. module Models module AttributionEvents extend ActiveSupport::Concern included do def capture_attribution_event(type:, user:, at: Time.zone.now) send("#{type}_attribution_event=", AttributionEvent.build(user, at: at)) end end module ClassMethods ... end end end
  42. 42. module Models module AttributionEvents extend ActiveSupport::Concern included do def capture_attribution_event(type:, user:, at: Time.zone.now) send("#{type}_attribution_event=", AttributionEvent.build(user, at: at)) end end module ClassMethods ... end end end
  43. 43. sheet.capture_attribution_event( type: :submitted, user: inspector ) Before After sheet.submitted_by_name = inspector.name sheet.submitted_by_email = inspector.email sheet.submitted_by_id = inspector.id sheet.submitted_at = Time.zone.now
  44. 44. Example from
 QCloud composed_of Concern
  45. 45. An attribution event identifies a user and
 has a timestamp And we capture different 
 types of attribution events
  46. 46. class Sheet < ActiveRecord::Base include Models::AttributionEvents attribution_event :reviewed attribution_event :submitted sheet.capture_attribution_event( type: :submitted, user: inspector ) An attribution event identifies a user and
 has a timestamp And we capture different 
 types of attribution events
  47. 47. class Sheet < ActiveRecord::Base include Models::AttributionEvents attribution_event :reviewed attribution_event :submitted sheet.capture_attribution_event( type: :submitted, user: inspector )
  48. 48. Naming is deeply
 connected to Designing
  49. 49. Ubiquitous 
 Language The language used by everyone on the team to describe the domain model when speaking, writing user stories, and in the source code.
  50. 50. • Passes the tests • Reveals intention Simple 
 Design • No duplication • Fewest elements
  51. 51. • Passes the tests • Reveals intention Simple 
 Design • No duplication • Fewest elements
  52. 52. • Passes the tests • Reveals intention Simple 
 Design • No duplication • Fewest elements
  53. 53. • Passes the tests • Improves names Simple 
 Design • No duplication • Fewest elements
  54. 54. • Improves names Simple 
 Design • Removes duplication
  55. 55. • Improves names Simple 
 Design • Removes duplication
  56. 56. The Simple Design Dynamo™
  57. 57. Example from
 QCloud
  58. 58. class Sheet < ActiveRecord::Base composed_of :reviewed_attribution_event, class_name: 'AttributionEvent', allow_nil: true, mapping: [ ['reviewed_by_name', 'name'], ['reviewed_by_email', 'email'], ['reviewed_by_id', 'user_id'], ['reviewed_at', 'event_at'] ] composed_of :submitted_attribution_event, class_name: ’AttributionEvent', allow_nil: true, mapping: [ ['submitted_by_name', 'name'], ['submitted_by_email', 'email'], ['submitted_by_id', 'user_id'], ['submitted_at', 'event_at'] ]
  59. 59. # # Represents the information required to attribute # an event to a user. # class AttributionEvent attr_reader :name, :email, :user_id, :event_at def initialize(name, email, user_id, at) @name = name @email = email @user_id = user_id @event_at = at end end sheet.submitted_attribution_event = AttributionEvent.new( inspector.name, inspector.email, inspector.id, Time.zone.now )
  60. 60. # # Represents the information required to attribute # an event to a user. # class AttributionEvent attr_reader :name, :email, :user_id, :event_at def self.build(user, at: Time.zone.now) new(user.name, user.email, user.id, at) end def initialize(name, email, user_id, at) @name = name @email = email @user_id = user_id @event_at = at end end An attribution event identifies a user and
 has a timestamp
  61. 61. class Sheet < ActiveRecord::Base composed_of :reviewed_attribution_event, class_name: ’AttributionEvent', allow_nil: true, mapping: [ [‘reviewed_by_name’, 'name'], [‘reviewed_by_email', 'email'], [‘reviewed_by_id', 'user_id'], [‘reviewed_at', 'event_at'] ] composed_of :submitted_attribution_event, class_name: ’AttributionEvent', allow_nil: true, mapping: [ [‘submitted_by_name', 'name'], [‘submitted_by_email’, 'email'], [‘submitted_by_id', 'user_id'], [‘submitted_at’, 'event_at'] ]
  62. 62. module Models module AttributionEvents extend ActiveSupport::Concern module ClassMethods def attribution_event(type, allow_nil: true) attribution_event = <<-ATTRIBUTION_EVENT composed_of :#{type}_attribution_event, class_name: 'AttributionEvent', allow_nil: #{allow_nil}, mapping: [ ['#{type}_by_name', 'name'], ['#{type}_by_email', 'email'], ['#{type}_by_id', 'user_id'], ['#{type}_at', 'event_at'] ] ATTRIBUTION_EVENT class_eval(attribution_event) end end end end
  63. 63. class Sheet < ActiveRecord::Base include Models::AttributionEvents attribution_event :reviewed attribution_event :submitted sheet.capture_attribution_event( type: :submitted, user: inspector ) sheet.capture_attribution_event( type: :reviewed, user: supervisor )
  64. 64. The Simple Design Dynamo™
  65. 65. Don’t Settle for Poor Names
  66. 66. Don’t Settle for Poor Names Pretty Please
  67. 67. The Simple Design Dynamo™
  68. 68. Resources
  69. 69. http://blog.jbrains.ca/permalink/the-four-elements-of-simple-design http://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest One of the best thinkers around on effective software development: J. B. Rainsberger.

×