Extending a Base Product for Multiple Customers

Extending a Base Product for Multiple Customers

Details how MediaGeniX builds customised, made-to-measure software for its customers.

Be732ee41fd3038aa98a0a7e7b7be081?s=128

Denis Defreyne

August 27, 2012
Tweet

Transcript

  1. ESUG 2012 Extending a Base Product for Multiple Customers Denis

    Defreyne MediaGeniX NG 1
  2. 2

  3. “ Your product is cool, but it’s missing feature X!

    3 — CUSTOMER
  4. “ Yes, feature X would be nice… for you, but

    nobody else! 4 — YOU
  5. “Why did you not implement feature X? :( 5 —

    CUSTOMER
  6. “Ugh, this product is getting bloated! :( 6 — OTHER

    CUSTOMER
  7. Contents 1. Customisations 2. Techniques 3. Modules 7

  8. 1. Customisations 8

  9. Customisation = extra bits of code for a single customer

    9
  10. Customisations 10 ‣ New functionality e.g. new issue checks (no

    porn at noon) ‣ Extended functionality e.g. extra metadata on films, contracts, … ‣ Changed functionality e.g. parental rating management in UK, Finland
  11. Integrations 11 ‣ Playout server ‣ Commercial scheduling system ‣

    Music scheduling system ‣ … unique for every customer!
  12. Customisations are only possible if you have FEW customers 12

  13. Requirements ‣ Be customer-specific ‣ Be fine-grained ‣ Allow merging

    bugfixes ‣ Be decoupled 13
  14. Why? 14 ‣ Talk to other devices You’ll have static

    on your TV otherwise ‣ Cater to a diverse market No two broadcasters have the same workflow ‣ Resolve conflicting requirements Don’t compromise, let them both have it their way ‣ Make customers happy! But don’t over-do it :)
  15. 15

  16. 2. Techniques 16

  17. Techniques 17 1. Site classes 2. Behaviors 3. Convenience methods

  18. Techniques 18 1. Site classes 2. Behaviors 3. Convenience methods

  19. Site classes – example 19

  20. Site classes – example 20

  21. Site class = subclass for one specific customer 21

  22. Site = customer 22

  23. Site classes 23 Film

  24. Site classes 24 Film FilmMTV

  25. MTV Site classes 25 Film  class  >>  siteClassForMTV ^FilmMTV

  26. BASE Site classes 26 newAustinPowersFilm ^Film  siteClass  new title:  'Adventures

     at  ESUG'; duration:  (Duration  fromMinutes:  93); yourself
  27. WHATS’On code for MTV only Packages 27 MTV BASE FRAMEWORK

    WHATS’On code shared between customers MediaGeniX framework code
  28. Packages 28 MTV VTM VRT TV2 NRK SBS FI NPO

    VPRO PRO7 FOX FTO …
  29. Extensions in packages 29 PACKAGE A MusicClip MusicClip>>title MusicClip>>videoFile MusicClip>>audioFile

    MusicClip>>is16Plus PACKAGE B MusicClip>>contract MusicClip>>agency Contract Agreement
  30. MTV Site classes 30 Film  class  >>  siteClassForMTV ^FilmMTV

  31. Site classes 31 BASE Film MusicClip Commercial MTV FilmMTV Film>>siteClassForMTV

  32. Film  >>  siteClassForMTV Film  siteClass  new 32

  33. FRAMEWORK Site classes 33 Class  >>  siteClass ^Site  current  siteClassOf:

     self  
  34. MTV Site classes 34 SiteMTV  >>  siteClassOf:  aClass ^aClass  siteClassForMTV

       
  35. BASE Site classes 35 Site  >>  siteClassOf:  aClass ^aClass

  36. BASE Site classes – example 36 Film  class  >>  buildSuperModelWith:

     aBuilder super  buildSuperModelWith:  aBuilder. aBuilder addString:  #title  name:  'Title'; addDuration:  #duration  name:  'Duration'
  37. 37

  38. BASE Site classes – example 38 Film  class  >>  buildSuperModelWith:

     aBuilder super  buildSuperModelWith:  aBuilder. aBuilder addString:  #title  name:  'Title'; addDuration:  #duration  name:  'Duration'
  39. MTV Site classes – example 39 FilmMTV  class  >>  buildSuperModelWith:

     aBuilder super  buildSuperModelWith:  aBuilder. aBuilder addString:  #idForMTV  name:  'ID  for  MTV'
  40. Site classes – example 40

  41. Site classes – example 41

  42. BASE Site classes – example 42 FilmEditor  class  >>  form

    ^self  newForm addFormField:  #title; addFormField:  #duration; yourself
  43. MTV Site classes – example 43 FilmEditor  >>  siteClassForMTV ^FilmEditorMTV

    FilmEditorMTV  class  >>  form ^super  form addFormField:  #idForMTV; yourself
  44. Site classes – example 44

  45. Site classes – example 45

  46. BASE Site classes – example 46 FilmEditor  class  >>  form

    ^self  newForm addFormField:  #title; addFormField:  #duration; addFormField:  #imdbRating; yourself
  47. Site classes – example 47

  48. Site classes – example 48

  49. BASE Site classes – example 49 Film  >>  openInEditor ^FilmEditor

     siteClass openWithEditee:  self
  50. Call #siteClass everywhere? 50 YES! It’s not as bad as

    you may think…
  51. PRO TIP Avoid long methods 51

  52. Techniques 52 1. Site classes 2. Behaviors 3. Convenience methods

  53. Behaviors 53 Product Film Commercial MusicClip

  54. Product ProductMTV Behaviors 54

  55. Behaviors 55 Product Film Commercial MusicClip

  56. Behaviors 56 Product Film Commercial MusicClip ProductBehavior ProductBehaviorMTV

  57. Behavior class = siteclassable class with behavior from original class

    57
  58. FRAMEWORK Behaviors 58 BehaviorObject  class  >>  newOn:  anObject ^self  new

    orig:  anObject; yourself
  59. BASE Behaviors – example 59 Product  >>  hasValidCertForTx:  aTx ^self

     certification  isOkayForTx:  aTx
  60. BASE Behaviors – example 60 ProductBehavior  >>  hasValidCertForTx:  aTx ^self

     orig  certification  isOkayForTx:  aTx
  61. MTV Behaviors – example 61 ProductBehaviorMTV  >>  hasValidCertForTx:  aTx ^self

     orig  videoFiles  allSatisfy: [:f  |  f  certification  isOkayForTx:  aTx]
  62. BASE Behaviors – example 62 Product  >>  hasValidCertForTx:  aTx ^self

     behavior  hasValidCertForTx:  aTx
  63. BASE Behaviors – example 63 Product  >>  behavior behavior  ifNil:

       [behavior  :=  ProductBehavior  siteClass        newOn:  self]. ^behavior
  64. PRO TIP 64 Prefer composition over inheritance

  65. Techniques 65 1. Site classes 2. Behaviors 3. Convenience methods

  66. Convenience method = commonly implemented or overridden method 66

  67. Convenience methods 67 buildSuperModelWith:  aBuilder addToolsMenuItemsTo:  aMenu addCommandsToToolBar:  aToolBar

  68. Convenience methods 68 buildSuperModelWith:  aBuilder buildSuperModelForMTVWith:  aBuilder addToolsMenuItemsTo:  aMenu addToolsMenuItemsForMTVTo:

     aMenu addCommandsToToolBar:  aToolBar addCommandsToToolBarForMTV:  aToolBar
  69. MTV Convenience methods 69 FilmMTV  class  >>  buildSuperModelWith:  aBuilder super

     buildSuperModelWith:  aBuilder. aBuilder addString:  #idForMTV  name:  'ID  for  MTV'
  70. MTV Convenience methods 70 Film  class  >>  buildSuperModelForMTVWith:  aBuilder super

     buildSuperModelForMTVWith:  aBuilder. aBuilder addString:  #idForMTV  name:  'ID  for  MTV'
  71. FRAMEWORK Convenience methods 71 Site  >>  buildSuperModelWith:  aBuilder    

               for:  aClass aClass  buildSuperModelWith:  aBuilder
  72. MTV Convenience methods 72 SiteMTV  >>  buildSuperModelWith:  aBuilder    

                     for:  aClass super  buildSuperModelWith:  aBuilder  for:  aClass. aClass  buildSuperModelForMTVWith:  aBuilder.
  73. PRO TIP 73 Use convenience methods for common methods only

  74. Techniques to avoid ‣ Branches Use them, but not for

    customer-specific code ‣ VisualWorks “overrides” They prevent access to original code 74
  75. Techniques 75 1. Site classes 2. Behaviors 3. Convenience methods

  76. 3. Modules 76

  77. Module = pluggable component that provides a set of related

    functionalities 77
  78. Example modules ‣ Contract management ‣ Secondary events (logos) ‣

    Video on demand 78
  79. BASE Super models in modules 79 Film  class  >>  buildSuperModelWith:

     aBuilder super buildSuperModelWith:  aBuilder. aBuilder "  …  other  attributes  here  …  " addReference:  #contract to:  Contract  name:  'Contract' W R O N G
  80. MTV Activating modules SiteMTV  >>  moduleClasses ^OrderedCollection  new add:  ContractModule;

    add:  SecondaryEventsModule; yourself 80
  81. Super models in modules 81

  82. BASE Super models in modules 82 Film  class  >> buildSuperModelForContractModuleWith:

     aBuilder super buildSuperModelForContractModuleWith:  aBuilder. aBuilder addReference:  #contract to:  Contract  name:  'Contract'
  83. FRAMEWORK Super models in modules 83 Site  >>  buildSuperModelWith:  aBuilder

                   for:  aClass aClass  buildSuperModelWith:  aBuilder.
  84. FRAMEWORK Super models in modules 84 Site  >>  buildSuperModelWith:  aBuilder

                   for:  aClass aClass  buildSuperModelWith:  aBuilder. self  modules  do: [:m  | m  buildSuperModelWith:  aBuilder  for:  aClass].
  85. FRAMEWORK Super models in modules 85 Module  >>  buildSuperModelWith:  aBuilder

                       for:  aClass "nothing  by  default"
  86. BASE Super models in modules 86 ContractPresentModule  >>  buildSuperModelWith:  aBuilder

                                                     for:  aClass aClass  buildSuperModelForContractModuleWith: aBuilder.
  87. Extensions in modules 87

  88. BASE Extensions in modules 88 FilmEditor  class  >>  form form

     :=  self  newForm. form  addFormField:  #title. form  addFormField:  #duration. ^form
  89. BASE Extensions in modules 89 FilmEditor  class  >>  form form

     :=  self  newForm. form  addFormField:  #title. form  addFormField:  #duration. form  addFormField:  #contract. ^form W R O N G
  90. BASE Extensions in modules 90 FilmEditor  class  >>  form form

     :=  self  newForm. form  addFormField:  #title. form  addFormField:  #duration. ContractModule  current addFieldsTo:  form  for:  self. ^form
  91. BASE Extensions in modules 91 ContractPresentModule  >>    addFieldsTo:  aForm

       for:  anEditor anEditor  addContractFieldsTo:  aForm
  92. BASE Extensions in modules 92 FilmEditor  >>    addContractFieldsTo:  aForm

       aForm  addFormField:  #contract.
  93. BASE Extensions in modules 93 ContractAbsentModule  >>    addFieldsTo:  aForm

       for:  aSender    "nothing  by  default"
  94. Extensions in modules 94 CONTRACT

  95. Extensions in modules 95 CONTRACT

  96. Site classes vs. modules 96 ‣ Modules can be shared

    across sites ‣ Modules require hooks
  97. Recap 97

  98. Techniques 98 ‣ Use site classes whenever possible ‣ Use

    behaviors when site classes fail (inheritance trees) ‣ Use modules when you need more separation
  99. Requirements ‣ Be customer-specific (with packages) ‣ Be fine-grained (with

    site classes) ‣ Allow merging bugfixes (with packages) ‣ Be decoupled (with site classes and modules) 99
  100. 100 “ Your product is cool, but it’s missing feature

    X! — CUSTOMER Do not worry. We’ll implement it for you! — YOU
  101. 101 ? MAIL denis.defreyne@mediagenix.tv TWITTER @ddfreyne GITHUB github.com/ddfreyne

  102. Extra Slides 102

  103. FRAMEWORK Site classing modules 103 Site  >>  modules ^self  moduleClasses

     collect: [:c  |  c  siteClass  new]
  104. FRAMEWORK Site classing modules 104 SuperModellary  >>  buildSuperModelFor:  aClass  

     builder  :=  SuperModelBuilder  new.    Site  current  buildSuperModelWith:  builder        for:  aClass.    supermodels  at:  aClass  put:  builder  superModel.
  105. BASE Extensions in modules 105 FilmEditor  class  >>  form form

     :=  self  newForm. form  addFormField:  #title. form  addFormField:  #duration. ContractModule  current addFieldsTo:  form  for:  self. ^form
  106. BASE Extensions in modules 106 FilmEditor  class  >>  form form

     :=  self  newForm. form  addFormField:  #title. form  addFormField:  #duration. ContractModule  current  isAvailable  ifTrue: [form  addFormField:  #contract]. ^form
  107. BASE Extensions in modules 107 Film  >>  isLegallyBroadcastable ^ContractModule  current

     isAvailable ifFalse:  [true] ifTrue:  [self  contract  isSigned].
  108. BASE Extensions in modules 108 Film  >>  isLegallyBroadcastable ^ContractModule  current

     isAvailable ifFalse:  [true] ifTrue:  [self  contract  isSigned].
  109. BASE Extensions in modules 109 Film  >>  isLegallyBroadcastable ^ContractModule  current

    isFilmLegallyBroadcastable:  self
  110. BASE Extensions in modules 110 ContractPresentModule  >>    isFilmLegallyBroadcastable:  aFilm

    ^aFilm  contract  isSigned
  111. BASE Extensions in modules 111 ContractAbsentModule  >>    isFilmLegallyBroadcastable:  aFilm

    ^true