Upload
alistair-mckinnell
View
159
Download
2
Embed Size (px)
Citation preview
Don’t Settle for Poor Names
Alistair McKinnell@ amckinnell
Namingis deeply
connected to
Designing
Designingis deeply
connected to
Naming
Example fromQCloud
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, 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'] ]
# # 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'] ]
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, :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
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
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
# # 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
# # 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 andhas a timestamp
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
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
!
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
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
!
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
# # 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
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'] ]
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'] ]
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_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
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
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
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
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
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
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.build(supervisor)
class Sheet < ActiveRecord::Base include Models::AttributionEvents
attribution_event :reviewed attribution_event :submitted
...
end
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: :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 )
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 )
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 )
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
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
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
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
Example fromQCloud
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 :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
class Sheet < ActiveRecord::Base include Models::AttributionEvents attribution_event :reviewed attribution_event :submitted
sheet.capture_attribution_event( type: :submitted, user: inspector )
Namingis deeply
connected to
Designing
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.
• 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 fromQCloud
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'] ]
# # 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 )
# # 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 andhas a timestamp
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'] ]
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
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 )
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-age-old-battle-to-rest
One of the best thinkers around on effective software development: J. B. Rainsberger.