SlideShare ist ein Scribd-Unternehmen logo
1 von 39
8	
  Lines	
  of	
  Code	
  
Greg	
  Young	
  
InfoQ.com: News & Community Site
• 750,000 unique visitors/month
• Published in 4 languages (English, Chinese, Japanese and Brazilian
Portuguese)
• Post content from our QCon conferences
• News 15-20 / week
• Articles 3-4 / week
• Presentations (videos) 12-15 / week
• Interviews 2-3 / week
• Books 1 / month
Watch the video with slide
synchronization on InfoQ.com!
http://www.infoq.com/presentations
/8-lines-code-refactoring
Presented at QCon London
www.qconlondon.com
Purpose of QCon
- to empower software development by facilitating the spread of
knowledge and innovation
Strategy
- practitioner-driven conference designed for YOU: influencers of
change and innovation in your teams
- speakers and topics driving the evolution and innovation
- connecting and catalyzing the influencers and innovators
Highlights
- attended by more than 12,000 delegates since 2007
- held in 9 cities worldwide
Simplicity	
  
I	
  am	
  stupid	
  to	
  work	
  otherwise.	
  
Fancy	
  code	
  befuddles	
  me.	
  
 public	
  class	
  DeactivateInventoryItem	
  
	
  {	
  
	
  	
  	
  	
  private	
  readonly	
  ItemRepository	
  repository;	
  
	
  
	
  	
  	
  	
  public	
  DeactivateInventoryItem(ItemRepository	
  repository)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  this.repository	
  =	
  repository;	
  
	
  	
  	
  	
  }	
  
	
  
	
  	
  	
  	
  public	
  void	
  Deactivate(Guid	
  id,	
  string	
  reason)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  item.Deactivate(reason);	
  
	
  	
  	
  	
  	
  	
  	
  	
  repository.Save(item);	
  
	
  	
  	
  	
  }	
  
	
  }	
  
 [Transactional]	
  
	
  [RequiresPermission(“admin”)]	
  
	
  [Logged]	
  
	
  [EatsExceptions]	
  
	
  [DoesBadThingsWhenYouArentWatching]	
  
	
  public	
  class	
  DeactivateInventoryItem	
  
	
  {	
  
	
  	
  	
  	
  private	
  readonly	
  ItemRepository	
  repository;	
  
	
  
	
  	
  	
  	
  public	
  DeactivateInventoryItem(ItemRepository	
  repository)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  this.repository	
  =	
  repository;	
  
	
  	
  	
  	
  }	
  
	
  
	
  	
  	
  	
  public	
  void	
  Deactivate(Guid	
  id,	
  string	
  reason)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  item.Deactivate(reason);	
  
	
  	
  	
  	
  }	
  
	
  }	
  
Simplicity?	
  
<bean	
  id="moreComplexObject"	
  class="example.ComplexObject">	
  
	
  <!-­‐-­‐	
  results	
  in	
  a	
  setAdminEmails(java.uNl.ProperNes)	
  call	
  -­‐-­‐>	
  
	
  <property	
  name="adminEmails">	
  
	
  	
  	
  <props>	
  
	
  	
  	
  	
  	
  <prop	
  key="administrator">administrator@example.org</prop>	
  
	
  	
  	
  	
  	
  <prop	
  key="support">support@example.org</prop>	
  
	
  	
  	
  	
  	
  <prop	
  key="development">development@example.org</prop>	
  
	
  	
  	
  </props>	
  
	
  </property>	
  
	
  <!-­‐-­‐	
  results	
  in	
  a	
  setSomeList(java.uNl.List)	
  call	
  -­‐-­‐>	
  
	
  <property	
  name="someList">	
  
	
  	
  	
  <list>	
  
	
  	
  	
  	
  	
  <value>a	
  list	
  element	
  followed	
  by	
  a	
  reference</value>	
  
	
  	
  	
  	
  	
  <ref	
  bean="myDataSource"	
  />	
  
	
  	
  	
  </list>	
  
	
  </property>	
  
	
  <!-­‐-­‐	
  results	
  in	
  a	
  setSomeMap(java.uNl.Map)	
  call	
  -­‐-­‐>	
  
	
  <property	
  name="someMap">	
  
	
  	
  	
  <map>	
  
	
  	
  	
  	
  	
  <entry	
  key="an	
  entry"	
  value="just	
  some	
  string"/>	
  
	
  	
  	
  	
  	
  <entry	
  key	
  ="a	
  ref"	
  value-­‐ref="myDataSource"/>	
  
	
  	
  	
  </map>	
  
 [Transactional]	
  
	
  [RequiresPermission(“admin”)]	
  
	
  [Logged]	
  
	
  [EatsExceptions]	
  
	
  [DoesBadThingsWhenYouArentWatching]	
  
	
  public	
  class	
  DeactivateInventoryItem	
  
	
  {	
  
	
  	
  	
  	
  private	
  readonly	
  ItemRepository	
  repository;	
  
	
  
	
  	
  	
  	
  public	
  DeactivateInventoryItem(ItemRepository	
  repository)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  this.repository	
  =	
  repository;	
  
	
  	
  	
  	
  }	
  
	
  
	
  	
  	
  	
  public	
  void	
  Deactivate(Guid	
  id,	
  string	
  reason)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  item.Deactivate(reason);	
  
	
  	
  	
  	
  }	
  
	
  }	
  
 [Transactional]	
  
	
  [RequiresPermission(“admin”)]	
  
	
  [Logged]	
  
	
  [EatsExceptions]	
  
	
  [DoesBadThingsWhenYouArentWatching]	
  
	
  public	
  class	
  DeactivateInventoryItem	
  
	
  {	
  
	
  	
  	
  	
  private	
  readonly	
  ItemRepository	
  repository;	
  
	
  
	
  	
  	
  	
  public	
  DeactivateInventoryItem(ItemRepository	
  repository)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  this.repository	
  =	
  repository;	
  
	
  	
  	
  	
  }	
  
	
  
	
  	
  	
  	
  public	
  virtual	
  void	
  Deactivate(Guid	
  id,	
  string	
  reason)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  item.Deactivate(reason);	
  
	
  	
  	
  	
  }	
  
	
  }	
  
 public	
  object	
  Foo()	
  
	
  {	
  
	
  	
  	
  	
  	
  return	
  this;	
  
	
  }	
  
If	
  you	
  find	
  you	
  need	
  an	
  extension	
  
to	
  your	
  ide	
  to	
  understand	
  what’s	
  
going	
  on.	
  Its	
  probably	
  not	
  simple.	
  
What’s	
  the	
  root	
  of	
  the	
  problem?	
  
 
	
  	
  	
  	
  public	
  void	
  Deactivate(Guid	
  id,	
  string	
  reason)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  item.Deactivate();	
  
	
  	
  	
  	
  }	
  
	
  	
  
	
  
	
  	
  	
  	
  public	
  void	
  Reactivate(Guid	
  id,	
  DateTime	
  effective,	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  string	
  reason)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  item.Deactivate();	
  
	
  	
  	
  	
  }	
  
	
  	
  
	
  
	
  	
  	
  	
  public	
  void	
  CheckIn(Guid	
  id,	
  int	
  count)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  item.Deactivate();	
  
	
  	
  	
  	
  }	
  
	
  	
  
No	
  common	
  interface!	
  
 
	
  	
  	
  	
  public	
  void	
  Log(PointCut	
  calledOn)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  logger.Log(calledOn.Name	
  +	
  “:”	
  +	
  calledOn.Parameters);	
  	
  	
  	
  
	
  	
  	
  	
  }	
  
	
  	
  	
  
	
  
 
	
  	
  	
  	
  public	
  void	
  Handle(DeactivateCommand	
  c)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(c.id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  item.Deactivate();	
  
	
  	
  	
  	
  }	
  
	
  	
  
	
  
	
  	
  	
  	
  public	
  void	
  Handle(ReactivateCommand	
  c)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(c.id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  item.Reactivate();	
  
	
  	
  	
  	
  }	
  
	
  	
  
	
  
	
  	
  	
  	
  public	
  void	
  Handle(CheckInCommand	
  c)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(c.id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  item.CheckIn(c.quantity);	
  
	
  	
  	
  	
  }	
  
	
  	
  
	
  
 
	
  interface	
  Handles<T>	
  where	
  T:Command	
  
	
  {	
  
	
  	
  	
  	
  	
  void	
  Handle(T	
  command);	
  	
  	
  	
  	
  	
  	
  	
  
	
  }	
  
	
  	
  
	
  
 class	
  LoggingHandler<T>	
  	
  :	
  Handles<T>	
  where	
  T:Command	
  
	
  {	
  
	
  	
  	
  	
  	
  private	
  readonly	
  Handles<T>	
  next;	
  
	
  
	
  	
  	
  	
  	
  public	
  LoggingHandler(Handles<T>	
  next)	
  
	
  	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  this.next	
  =	
  next;	
  
	
  	
  	
  	
  	
  }	
  
	
  
	
  	
  	
  	
  	
  public	
  void	
  Handle(T	
  command)	
  
	
  	
  	
  	
  	
  {	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  myLoggingFramework.Log(command);	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  next.Handle(command);	
  
	
  	
  	
  	
  	
  }	
  
	
  }	
  
	
  
	
  	
  
	
  	
  var	
  handler	
  =	
  new	
  LoggingHandler<DeactivateCommand>(	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  new	
  DeactivateCommandHandler(...)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  );	
  
	
  
 public	
  class	
  DeactivateInventoryItem	
  :Handles<DeactivateCommand>	
  
	
  {	
  
	
  	
  	
  	
  	
  private	
  readonly	
  ItemRepository	
  repository;	
  
	
  
	
  	
  	
  	
  	
  public	
  DeactivateInventoryItem(ItemRepository	
  repository)	
  
	
  	
  	
  	
  	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  this.repository	
  =	
  repository;	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  
	
  	
  	
  	
  	
  	
  	
  	
  public	
  void	
  Handle(DeactivateCommand	
  command)	
  
	
  	
  	
  	
  	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(command.id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  item.Deactivate(cmd.Reason);	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  
 public	
  class	
  DeactivateInventoryItem	
  :Handles<DeactivateCommand>	
  
	
  {	
  
	
  	
  	
  	
  	
  private	
  readonly	
  ItemRepository	
  repository;	
  
	
  
	
  	
  	
  	
  	
  public	
  DeactivateInventoryItem(ItemRepository	
  repository)	
  
	
  	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  this.repository	
  =	
  repository;	
  
	
  	
  	
  	
  	
  }	
  
	
  
	
  	
  	
  	
  	
  public	
  void	
  Handle(DeactivateCommand	
  command)	
  
	
  	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(command.id);	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  item.Deactivate(cmd.Reason);	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  }	
  
	
  }	
  
 class	
  Handlers	
  
	
  {	
  
	
  	
  	
  public	
  static	
  void	
  Handle(ItemRepository	
  repository,	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  DeactivateCommand	
  c)	
  
	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(c.id);	
  
	
  	
  	
  	
  	
  	
  	
  item.Deactivate();	
  
	
  	
  	
  }	
  
	
  
	
  	
  	
  public	
  static	
  void	
  Handle(ItemRepository	
  repository,	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ReactivateCommand	
  c)	
  
	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(c.id);	
  
	
  	
  	
  	
  	
  	
  	
  item.Deactivate();	
  
	
  	
  	
  }	
  
	
  
	
  	
  	
  public	
  static	
  void	
  Handle(ItemRepository	
  repository,	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  CheckInCommand	
  c)	
  
	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(c.id);	
  
	
  	
  	
  	
  	
  	
  	
  item.Deactivate();	
  
	
  	
  	
  }	
  
Back	
  to	
  the	
  same	
  problem!	
  
 public	
  static	
  int	
  Add(int	
  a,	
  int	
  b)	
  
	
  {	
  
	
  	
  	
  	
  	
  return	
  a	
  +	
  b;	
  
	
  }	
  
	
  
 public	
  static	
  int	
  Add(int	
  a,	
  int	
  b)	
  
	
  {	
  
	
  	
  	
  	
  	
  return	
  a	
  +	
  b;	
  
	
  }	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  var	
  add5	
  =	
  x	
  =>	
  Add(5,	
  x);	
  
	
  
 public	
  static	
  void	
  Deactivate(ItemRepository	
  repository,	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  DeactivateCommand	
  c)	
  
	
  {	
  
	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(c.id);	
  
	
  	
  	
  	
  	
  item.Deactivate();	
  
	
  }	
  	
  
	
  
	
  
	
  	
  
	
  	
  	
  
	
  
 public	
  static	
  void	
  Deactivate(ItemRepository	
  repository,	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  DeactivateCommand	
  c)	
  
	
  {	
  
	
  	
  	
  	
  	
  var	
  item	
  =	
  repository.GetById(c.id);	
  
	
  	
  	
  	
  	
  item.Deactivate();	
  
	
  }	
  	
  
	
  
	
  
	
  	
  
	
  	
  	
  
	
  	
  	
  	
  	
  var	
  nodepends	
  =	
  x	
  =>	
  Deactivate(new	
  ItemRepository(),	
  x);	
  
	
  
 	
  
	
  
	
  
	
  
	
  
	
  
	
  void	
  BootStrap()	
  
	
  {	
  
	
  	
  	
  	
  handlers.Add(x	
  =>	
  Deactivate(new	
  ItemRepository(),	
  x));	
  
	
  	
  	
  	
  handlers.Add(x	
  =>	
  Reactivate(new	
  ItemRepository(),	
  x));	
  
	
  	
  	
  	
  handlers.Add(x	
  =>	
  CheckIn(new	
  ItemRepository(),	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  new	
  BarService(),	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  x));	
  
	
  }	
  
 	
  
	
  
	
  
	
  
	
  
	
  
	
  void	
  BootStrap()	
  
	
  {	
  
	
  	
  	
  	
  handlers.Add(x	
  =>	
  Deactivate(()	
  =>	
  new	
  ItemRepository(),	
  x));	
  
	
  	
  	
  	
  handlers.Add(x	
  =>	
  Reactivate(()	
  =>	
  new	
  ItemRepository(),	
  x));	
  
	
  	
  	
  	
  handlers.Add(x	
  =>	
  CheckIn(()	
  =>	
  new	
  ItemRepository(),	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  new	
  BarService(),	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  x));	
  
	
  }	
  
 	
  
	
  
	
  
	
  
	
  
	
  
	
  public	
  static	
  void	
  Log<T>(T	
  command,	
  Action<T>	
  next)	
  	
  
	
  	
  	
  where	
  T:Command	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  myLoggingFramework.Log(command);	
  
	
  	
  	
  	
  	
  	
  	
  	
  next(command);	
  
	
  	
  	
  	
  }	
  
 class	
  LoggingHandler<T>	
  	
  :	
  Handles<T>	
  where	
  T:Command	
  
	
  {	
  
	
  	
  	
  	
  	
  private	
  readonly	
  Handles<T>	
  next;	
  
	
  
	
  	
  	
  	
  	
  public	
  LoggingHandler(Handles<T>	
  next)	
  
	
  	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  this.next	
  =	
  next;	
  
	
  	
  	
  	
  	
  }	
  
	
  
	
  	
  	
  	
  	
  public	
  void	
  Handle(T	
  command)	
  
	
  	
  	
  	
  	
  {	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  myLoggingFramework.Log(command);	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  next.Handle(command);	
  
	
  	
  	
  	
  	
  }	
  
	
  }	
  
	
  
	
  	
  
	
  	
  var	
  handler	
  =	
  new	
  LoggingHandler<DeactivateCommand>(	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  new	
  DeactivateCommandHandler(...)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  );	
  
	
  
<bean	
  id="moreComplexObject"	
  class="example.ComplexObject">	
  
	
  <!-­‐-­‐	
  results	
  in	
  a	
  setAdminEmails(java.uNl.ProperNes)	
  call	
  -­‐-­‐>	
  
	
  <property	
  name="adminEmails">	
  
	
  	
  	
  <props>	
  
	
  	
  	
  	
  	
  <prop	
  key="administrator">administrator@example.org</prop>	
  
	
  	
  	
  	
  	
  <prop	
  key="support">support@example.org</prop>	
  
	
  	
  	
  	
  	
  <prop	
  key="development">development@example.org</prop>	
  
	
  	
  	
  </props>	
  
	
  </property>	
  
	
  <!-­‐-­‐	
  results	
  in	
  a	
  setSomeList(java.uNl.List)	
  call	
  -­‐-­‐>	
  
	
  <property	
  name="someList">	
  
	
  	
  	
  <list>	
  
	
  	
  	
  	
  	
  <value>a	
  list	
  element	
  followed	
  by	
  a	
  reference</value>	
  
	
  	
  	
  	
  	
  <ref	
  bean="myDataSource"	
  />	
  
	
  	
  	
  </list>	
  
	
  </property>	
  
	
  <!-­‐-­‐	
  results	
  in	
  a	
  setSomeMap(java.uNl.Map)	
  call	
  -­‐-­‐>	
  
	
  <property	
  name="someMap">	
  
	
  	
  	
  <map>	
  
	
  	
  	
  	
  	
  <entry	
  key="an	
  entry"	
  value="just	
  some	
  string"/>	
  
	
  	
  	
  	
  	
  <entry	
  key	
  ="a	
  ref"	
  value-­‐ref="myDataSource"/>	
  
	
  	
  	
  </map>	
  
 	
  
	
  
	
  
	
  
	
  
	
  
	
  public	
  static	
  void	
  Log<T>(T	
  command,	
  Action<T>	
  next)	
  	
  
	
  	
  	
  where	
  T:Command	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  myLoggingFramework.Log(command);	
  
	
  	
  	
  	
  	
  	
  	
  	
  next(command);	
  
	
  	
  	
  	
  }	
  
Understand	
  the	
  problem	
  a	
  tool	
  
or	
  idea	
  solves	
  well	
  
If	
  you	
  need	
  to	
  add	
  stuff	
  to	
  your	
  
IDE	
  you	
  are	
  probably	
  on	
  the	
  wrong	
  
path.	
  
You	
  own	
  all	
  code	
  in	
  your	
  project.	
  
	
  
	
  
	
  
	
  
Your	
  boss	
  doesn’t	
  care	
  if	
  the	
  bug	
  
happened	
  in	
  someone	
  else’s	
  library!	
  

Weitere ähnliche Inhalte

Mehr von C4Media

Understand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsUnderstand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsC4Media
 
Kafka Needs No Keeper
Kafka Needs No KeeperKafka Needs No Keeper
Kafka Needs No KeeperC4Media
 
High Performing Teams Act Like Owners
High Performing Teams Act Like OwnersHigh Performing Teams Act Like Owners
High Performing Teams Act Like OwnersC4Media
 
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaDoes Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaC4Media
 
Service Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideService Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideC4Media
 
Shifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDShifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDC4Media
 
CI/CD for Machine Learning
CI/CD for Machine LearningCI/CD for Machine Learning
CI/CD for Machine LearningC4Media
 
Fault Tolerance at Speed
Fault Tolerance at SpeedFault Tolerance at Speed
Fault Tolerance at SpeedC4Media
 
Architectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsArchitectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsC4Media
 
ML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsC4Media
 
Build Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerBuild Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerC4Media
 
User & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleUser & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleC4Media
 
Scaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeScaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeC4Media
 
Make Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereMake Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereC4Media
 
The Talk You've Been Await-ing For
The Talk You've Been Await-ing ForThe Talk You've Been Await-ing For
The Talk You've Been Await-ing ForC4Media
 
Future of Data Engineering
Future of Data EngineeringFuture of Data Engineering
Future of Data EngineeringC4Media
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreC4Media
 
Navigating Complexity: High-performance Delivery and Discovery Teams
Navigating Complexity: High-performance Delivery and Discovery TeamsNavigating Complexity: High-performance Delivery and Discovery Teams
Navigating Complexity: High-performance Delivery and Discovery TeamsC4Media
 
High Performance Cooperative Distributed Systems in Adtech
High Performance Cooperative Distributed Systems in AdtechHigh Performance Cooperative Distributed Systems in Adtech
High Performance Cooperative Distributed Systems in AdtechC4Media
 
Rust's Journey to Async/await
Rust's Journey to Async/awaitRust's Journey to Async/await
Rust's Journey to Async/awaitC4Media
 

Mehr von C4Media (20)

Understand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsUnderstand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java Applications
 
Kafka Needs No Keeper
Kafka Needs No KeeperKafka Needs No Keeper
Kafka Needs No Keeper
 
High Performing Teams Act Like Owners
High Performing Teams Act Like OwnersHigh Performing Teams Act Like Owners
High Performing Teams Act Like Owners
 
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaDoes Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
 
Service Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideService Meshes- The Ultimate Guide
Service Meshes- The Ultimate Guide
 
Shifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDShifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CD
 
CI/CD for Machine Learning
CI/CD for Machine LearningCI/CD for Machine Learning
CI/CD for Machine Learning
 
Fault Tolerance at Speed
Fault Tolerance at SpeedFault Tolerance at Speed
Fault Tolerance at Speed
 
Architectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsArchitectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep Systems
 
ML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.js
 
Build Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerBuild Your Own WebAssembly Compiler
Build Your Own WebAssembly Compiler
 
User & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleUser & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix Scale
 
Scaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeScaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's Edge
 
Make Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereMake Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home Everywhere
 
The Talk You've Been Await-ing For
The Talk You've Been Await-ing ForThe Talk You've Been Await-ing For
The Talk You've Been Await-ing For
 
Future of Data Engineering
Future of Data EngineeringFuture of Data Engineering
Future of Data Engineering
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
 
Navigating Complexity: High-performance Delivery and Discovery Teams
Navigating Complexity: High-performance Delivery and Discovery TeamsNavigating Complexity: High-performance Delivery and Discovery Teams
Navigating Complexity: High-performance Delivery and Discovery Teams
 
High Performance Cooperative Distributed Systems in Adtech
High Performance Cooperative Distributed Systems in AdtechHigh Performance Cooperative Distributed Systems in Adtech
High Performance Cooperative Distributed Systems in Adtech
 
Rust's Journey to Async/await
Rust's Journey to Async/awaitRust's Journey to Async/await
Rust's Journey to Async/await
 

Kürzlich hochgeladen

How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 

Kürzlich hochgeladen (20)

How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 

Parallel Keynote: 8 Lines of Code

  • 1. 8  Lines  of  Code   Greg  Young  
  • 2. InfoQ.com: News & Community Site • 750,000 unique visitors/month • Published in 4 languages (English, Chinese, Japanese and Brazilian Portuguese) • Post content from our QCon conferences • News 15-20 / week • Articles 3-4 / week • Presentations (videos) 12-15 / week • Interviews 2-3 / week • Books 1 / month Watch the video with slide synchronization on InfoQ.com! http://www.infoq.com/presentations /8-lines-code-refactoring
  • 3. Presented at QCon London www.qconlondon.com Purpose of QCon - to empower software development by facilitating the spread of knowledge and innovation Strategy - practitioner-driven conference designed for YOU: influencers of change and innovation in your teams - speakers and topics driving the evolution and innovation - connecting and catalyzing the influencers and innovators Highlights - attended by more than 12,000 delegates since 2007 - held in 9 cities worldwide
  • 5. I  am  stupid  to  work  otherwise.   Fancy  code  befuddles  me.  
  • 6.  public  class  DeactivateInventoryItem    {          private  readonly  ItemRepository  repository;            public  DeactivateInventoryItem(ItemRepository  repository)          {                  this.repository  =  repository;          }            public  void  Deactivate(Guid  id,  string  reason)          {                  var  item  =  repository.GetById(id);                  item.Deactivate(reason);                  repository.Save(item);          }    }  
  • 7.  [Transactional]    [RequiresPermission(“admin”)]    [Logged]    [EatsExceptions]    [DoesBadThingsWhenYouArentWatching]    public  class  DeactivateInventoryItem    {          private  readonly  ItemRepository  repository;            public  DeactivateInventoryItem(ItemRepository  repository)          {                  this.repository  =  repository;          }            public  void  Deactivate(Guid  id,  string  reason)          {                  var  item  =  repository.GetById(id);                  item.Deactivate(reason);          }    }  
  • 9. <bean  id="moreComplexObject"  class="example.ComplexObject">    <!-­‐-­‐  results  in  a  setAdminEmails(java.uNl.ProperNes)  call  -­‐-­‐>    <property  name="adminEmails">        <props>            <prop  key="administrator">administrator@example.org</prop>            <prop  key="support">support@example.org</prop>            <prop  key="development">development@example.org</prop>        </props>    </property>    <!-­‐-­‐  results  in  a  setSomeList(java.uNl.List)  call  -­‐-­‐>    <property  name="someList">        <list>            <value>a  list  element  followed  by  a  reference</value>            <ref  bean="myDataSource"  />        </list>    </property>    <!-­‐-­‐  results  in  a  setSomeMap(java.uNl.Map)  call  -­‐-­‐>    <property  name="someMap">        <map>            <entry  key="an  entry"  value="just  some  string"/>            <entry  key  ="a  ref"  value-­‐ref="myDataSource"/>        </map>  
  • 10.  [Transactional]    [RequiresPermission(“admin”)]    [Logged]    [EatsExceptions]    [DoesBadThingsWhenYouArentWatching]    public  class  DeactivateInventoryItem    {          private  readonly  ItemRepository  repository;            public  DeactivateInventoryItem(ItemRepository  repository)          {                  this.repository  =  repository;          }            public  void  Deactivate(Guid  id,  string  reason)          {                  var  item  =  repository.GetById(id);                  item.Deactivate(reason);          }    }  
  • 11.  [Transactional]    [RequiresPermission(“admin”)]    [Logged]    [EatsExceptions]    [DoesBadThingsWhenYouArentWatching]    public  class  DeactivateInventoryItem    {          private  readonly  ItemRepository  repository;            public  DeactivateInventoryItem(ItemRepository  repository)          {                  this.repository  =  repository;          }            public  virtual  void  Deactivate(Guid  id,  string  reason)          {                  var  item  =  repository.GetById(id);                  item.Deactivate(reason);          }    }  
  • 12.  public  object  Foo()    {            return  this;    }  
  • 13.
  • 14. If  you  find  you  need  an  extension   to  your  ide  to  understand  what’s   going  on.  Its  probably  not  simple.  
  • 15. What’s  the  root  of  the  problem?  
  • 16.          public  void  Deactivate(Guid  id,  string  reason)          {                  var  item  =  repository.GetById(id);                  item.Deactivate();          }                public  void  Reactivate(Guid  id,  DateTime  effective,                                                          string  reason)          {                  var  item  =  repository.GetById(id);                  item.Deactivate();          }                public  void  CheckIn(Guid  id,  int  count)          {                  var  item  =  repository.GetById(id);                  item.Deactivate();          }      
  • 18.          public  void  Log(PointCut  calledOn)          {                  logger.Log(calledOn.Name  +  “:”  +  calledOn.Parameters);                }          
  • 19.          public  void  Handle(DeactivateCommand  c)          {                  var  item  =  repository.GetById(c.id);                  item.Deactivate();          }                public  void  Handle(ReactivateCommand  c)          {                  var  item  =  repository.GetById(c.id);                  item.Reactivate();          }                public  void  Handle(CheckInCommand  c)          {                  var  item  =  repository.GetById(c.id);                  item.CheckIn(c.quantity);          }        
  • 20.    interface  Handles<T>  where  T:Command    {            void  Handle(T  command);                  }        
  • 21.  class  LoggingHandler<T>    :  Handles<T>  where  T:Command    {            private  readonly  Handles<T>  next;              public  LoggingHandler(Handles<T>  next)            {                    this.next  =  next;            }              public  void  Handle(T  command)            {                      myLoggingFramework.Log(command);                    next.Handle(command);            }    }            var  handler  =  new  LoggingHandler<DeactivateCommand>(                                              new  DeactivateCommandHandler(...)                                      );    
  • 22.
  • 23.  public  class  DeactivateInventoryItem  :Handles<DeactivateCommand>    {            private  readonly  ItemRepository  repository;              public  DeactivateInventoryItem(ItemRepository  repository)                  {                          this.repository  =  repository;                  }                    public  void  Handle(DeactivateCommand  command)                  {                          var  item  =  repository.GetById(command.id);                          item.Deactivate(cmd.Reason);                          }          }  
  • 24.  public  class  DeactivateInventoryItem  :Handles<DeactivateCommand>    {            private  readonly  ItemRepository  repository;              public  DeactivateInventoryItem(ItemRepository  repository)            {                          this.repository  =  repository;            }              public  void  Handle(DeactivateCommand  command)            {                          var  item  =  repository.GetById(command.id);                          item.Deactivate(cmd.Reason);                    }    }  
  • 25.  class  Handlers    {        public  static  void  Handle(ItemRepository  repository,                                                            DeactivateCommand  c)        {                var  item  =  repository.GetById(c.id);                item.Deactivate();        }          public  static  void  Handle(ItemRepository  repository,                                                              ReactivateCommand  c)        {                var  item  =  repository.GetById(c.id);                item.Deactivate();        }          public  static  void  Handle(ItemRepository  repository,                                                              CheckInCommand  c)        {                var  item  =  repository.GetById(c.id);                item.Deactivate();        }  
  • 26. Back  to  the  same  problem!  
  • 27.  public  static  int  Add(int  a,  int  b)    {            return  a  +  b;    }    
  • 28.  public  static  int  Add(int  a,  int  b)    {            return  a  +  b;    }                                                var  add5  =  x  =>  Add(5,  x);    
  • 29.  public  static  void  Deactivate(ItemRepository  repository,                                                        DeactivateCommand  c)    {            var  item  =  repository.GetById(c.id);            item.Deactivate();    }                    
  • 30.  public  static  void  Deactivate(ItemRepository  repository,                                                        DeactivateCommand  c)    {            var  item  =  repository.GetById(c.id);            item.Deactivate();    }                            var  nodepends  =  x  =>  Deactivate(new  ItemRepository(),  x);    
  • 31.                void  BootStrap()    {          handlers.Add(x  =>  Deactivate(new  ItemRepository(),  x));          handlers.Add(x  =>  Reactivate(new  ItemRepository(),  x));          handlers.Add(x  =>  CheckIn(new  ItemRepository(),                                                                new  BarService(),                                                                x));    }  
  • 32.                void  BootStrap()    {          handlers.Add(x  =>  Deactivate(()  =>  new  ItemRepository(),  x));          handlers.Add(x  =>  Reactivate(()  =>  new  ItemRepository(),  x));          handlers.Add(x  =>  CheckIn(()  =>  new  ItemRepository(),                                                                new  BarService(),                                                                x));    }  
  • 33.                public  static  void  Log<T>(T  command,  Action<T>  next)          where  T:Command          {                  myLoggingFramework.Log(command);                  next(command);          }  
  • 34.  class  LoggingHandler<T>    :  Handles<T>  where  T:Command    {            private  readonly  Handles<T>  next;              public  LoggingHandler(Handles<T>  next)            {                    this.next  =  next;            }              public  void  Handle(T  command)            {                      myLoggingFramework.Log(command);                    next.Handle(command);            }    }            var  handler  =  new  LoggingHandler<DeactivateCommand>(                                              new  DeactivateCommandHandler(...)                                      );    
  • 35. <bean  id="moreComplexObject"  class="example.ComplexObject">    <!-­‐-­‐  results  in  a  setAdminEmails(java.uNl.ProperNes)  call  -­‐-­‐>    <property  name="adminEmails">        <props>            <prop  key="administrator">administrator@example.org</prop>            <prop  key="support">support@example.org</prop>            <prop  key="development">development@example.org</prop>        </props>    </property>    <!-­‐-­‐  results  in  a  setSomeList(java.uNl.List)  call  -­‐-­‐>    <property  name="someList">        <list>            <value>a  list  element  followed  by  a  reference</value>            <ref  bean="myDataSource"  />        </list>    </property>    <!-­‐-­‐  results  in  a  setSomeMap(java.uNl.Map)  call  -­‐-­‐>    <property  name="someMap">        <map>            <entry  key="an  entry"  value="just  some  string"/>            <entry  key  ="a  ref"  value-­‐ref="myDataSource"/>        </map>  
  • 36.                public  static  void  Log<T>(T  command,  Action<T>  next)          where  T:Command          {                  myLoggingFramework.Log(command);                  next(command);          }  
  • 37. Understand  the  problem  a  tool   or  idea  solves  well  
  • 38. If  you  need  to  add  stuff  to  your   IDE  you  are  probably  on  the  wrong   path.  
  • 39. You  own  all  code  in  your  project.           Your  boss  doesn’t  care  if  the  bug   happened  in  someone  else’s  library!