Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Denis Defreyne

August 27, 2012
Tweet

More Decks by Denis Defreyne

Other Decks in Technology

Transcript

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

    View Slide

  2. 2

    View Slide

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

    View Slide


  4. Yes, feature X would be nice…
    for you, but nobody else!
    4
    — YOU

    View Slide

  5. “Why did you not
    implement feature X? :(
    5
    — CUSTOMER

    View Slide

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

    View Slide

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

    View Slide

  8. 1. Customisations
    8

    View Slide

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

    View Slide

  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

    View Slide

  11. Integrations
    11
    ‣ Playout server
    ‣ Commercial scheduling system
    ‣ Music scheduling system
    ‣ …
    unique for every customer!

    View Slide

  12. Customisations are
    only possible if you
    have FEW customers
    12

    View Slide

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

    View Slide

  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 :)

    View Slide

  15. 15

    View Slide

  16. 2. Techniques
    16

    View Slide

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

    View Slide

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

    View Slide

  19. Site classes – example
    19

    View Slide

  20. Site classes – example
    20

    View Slide

  21. Site class =
    subclass for one
    specific customer
    21

    View Slide

  22. Site = customer
    22

    View Slide

  23. Site classes
    23
    Film

    View Slide

  24. Site classes
    24
    Film
    FilmMTV

    View Slide

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

    View Slide

  26. BASE
    Site classes
    26
    newAustinPowersFilm
    ^Film  siteClass  new
    title:  'Adventures  at  ESUG';
    duration:  (Duration  fromMinutes:  93);
    yourself

    View Slide

  27. WHATS’On code for MTV only
    Packages
    27
    MTV
    BASE
    FRAMEWORK
    WHATS’On code shared between customers
    MediaGeniX framework code

    View Slide

  28. Packages
    28
    MTV
    VTM
    VRT
    TV2
    NRK
    SBS FI NPO
    VPRO
    PRO7
    FOX FTO …

    View Slide

  29. Extensions in packages
    29
    PACKAGE A
    MusicClip
    MusicClip>>title
    MusicClip>>videoFile
    MusicClip>>audioFile
    MusicClip>>is16Plus
    PACKAGE B
    MusicClip>>contract
    MusicClip>>agency
    Contract
    Agreement

    View Slide

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

    View Slide

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

    View Slide

  32. Film  >>  siteClassForMTV
    Film  siteClass  new
    32

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  36. BASE
    Site classes – example
    36
    Film  class  >>  buildSuperModelWith:  aBuilder
    super  buildSuperModelWith:  aBuilder.
    aBuilder
    addString:  #title  name:  'Title';
    addDuration:  #duration  name:  'Duration'

    View Slide

  37. 37

    View Slide

  38. BASE
    Site classes – example
    38
    Film  class  >>  buildSuperModelWith:  aBuilder
    super  buildSuperModelWith:  aBuilder.
    aBuilder
    addString:  #title  name:  'Title';
    addDuration:  #duration  name:  'Duration'

    View Slide

  39. MTV
    Site classes – example
    39
    FilmMTV  class  >>  buildSuperModelWith:  aBuilder
    super  buildSuperModelWith:  aBuilder.
    aBuilder
    addString:  #idForMTV  name:  'ID  for  MTV'

    View Slide

  40. Site classes – example
    40

    View Slide

  41. Site classes – example
    41

    View Slide

  42. BASE
    Site classes – example
    42
    FilmEditor  class  >>  form
    ^self  newForm
    addFormField:  #title;
    addFormField:  #duration;
    yourself

    View Slide

  43. MTV
    Site classes – example
    43
    FilmEditor  >>  siteClassForMTV
    ^FilmEditorMTV
    FilmEditorMTV  class  >>  form
    ^super  form
    addFormField:  #idForMTV;
    yourself

    View Slide

  44. Site classes – example
    44

    View Slide

  45. Site classes – example
    45

    View Slide

  46. BASE
    Site classes – example
    46
    FilmEditor  class  >>  form
    ^self  newForm
    addFormField:  #title;
    addFormField:  #duration;
    addFormField:  #imdbRating;
    yourself

    View Slide

  47. Site classes – example
    47

    View Slide

  48. Site classes – example
    48

    View Slide

  49. BASE
    Site classes – example
    49
    Film  >>  openInEditor
    ^FilmEditor  siteClass
    openWithEditee:  self

    View Slide

  50. Call #siteClass everywhere?
    50
    YES!
    It’s not as bad as you may think…

    View Slide

  51. PRO TIP
    Avoid long methods
    51

    View Slide

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

    View Slide

  53. Behaviors
    53
    Product
    Film Commercial MusicClip

    View Slide

  54. Product
    ProductMTV
    Behaviors
    54

    View Slide

  55. Behaviors
    55
    Product
    Film Commercial MusicClip

    View Slide

  56. Behaviors
    56
    Product
    Film Commercial MusicClip
    ProductBehavior
    ProductBehaviorMTV

    View Slide

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

    View Slide

  58. FRAMEWORK
    Behaviors
    58
    BehaviorObject  class  >>  newOn:  anObject
    ^self  new
    orig:  anObject;
    yourself

    View Slide

  59. BASE
    Behaviors – example
    59
    Product  >>  hasValidCertForTx:  aTx
    ^self  certification  isOkayForTx:  aTx

    View Slide

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

    View Slide

  61. MTV
    Behaviors – example
    61
    ProductBehaviorMTV  >>  hasValidCertForTx:  aTx
    ^self  orig  videoFiles  allSatisfy:
    [:f  |  f  certification  isOkayForTx:  aTx]

    View Slide

  62. BASE
    Behaviors – example
    62
    Product  >>  hasValidCertForTx:  aTx
    ^self  behavior  hasValidCertForTx:  aTx

    View Slide

  63. BASE
    Behaviors – example
    63
    Product  >>  behavior
    behavior  ifNil:
       [behavior  :=  ProductBehavior  siteClass
           newOn:  self].
    ^behavior

    View Slide

  64. PRO TIP
    64
    Prefer composition
    over inheritance

    View Slide

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

    View Slide

  66. Convenience method =
    commonly implemented
    or overridden method
    66

    View Slide

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

    View Slide

  68. Convenience methods
    68
    buildSuperModelWith:  aBuilder
    buildSuperModelForMTVWith:  aBuilder
    addToolsMenuItemsTo:  aMenu
    addToolsMenuItemsForMTVTo:  aMenu
    addCommandsToToolBar:  aToolBar
    addCommandsToToolBarForMTV:  aToolBar

    View Slide

  69. MTV
    Convenience methods
    69
    FilmMTV  class  >>  buildSuperModelWith:  aBuilder
    super  buildSuperModelWith:  aBuilder.
    aBuilder
    addString:  #idForMTV  name:  'ID  for  MTV'

    View Slide

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

    View Slide

  71. FRAMEWORK
    Convenience methods
    71
    Site  >>  buildSuperModelWith:  aBuilder
                   for:  aClass
    aClass  buildSuperModelWith:  aBuilder

    View Slide

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

    View Slide

  73. PRO TIP
    73
    Use convenience methods
    for common methods only

    View Slide

  74. Techniques to avoid
    ‣ Branches
    Use them, but not for customer-specific code
    ‣ VisualWorks “overrides”
    They prevent access to original code
    74

    View Slide

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

    View Slide

  76. 3. Modules
    76

    View Slide

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

    View Slide

  78. Example modules
    ‣ Contract management
    ‣ Secondary events (logos)
    ‣ Video on demand
    78

    View Slide

  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

    View Slide

  80. MTV
    Activating modules
    SiteMTV  >>  moduleClasses
    ^OrderedCollection  new
    add:  ContractModule;
    add:  SecondaryEventsModule;
    yourself
    80

    View Slide

  81. Super models in modules
    81

    View Slide

  82. BASE
    Super models in modules
    82
    Film  class  >>
    buildSuperModelForContractModuleWith:  aBuilder
    super
    buildSuperModelForContractModuleWith:  aBuilder.
    aBuilder
    addReference:  #contract
    to:  Contract  name:  'Contract'

    View Slide

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

    View Slide

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

    View Slide

  85. FRAMEWORK
    Super models in modules
    85
    Module  >>  buildSuperModelWith:  aBuilder
                       for:  aClass
    "nothing  by  default"

    View Slide

  86. BASE
    Super models in modules
    86
    ContractPresentModule  >>  buildSuperModelWith:  aBuilder
                                                     for:  aClass
    aClass  buildSuperModelForContractModuleWith:
    aBuilder.

    View Slide

  87. Extensions in modules
    87

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  91. BASE
    Extensions in modules
    91
    ContractPresentModule  >>
       addFieldsTo:  aForm
       for:  anEditor
    anEditor  addContractFieldsTo:  aForm

    View Slide

  92. BASE
    Extensions in modules
    92
    FilmEditor  >>
       addContractFieldsTo:  aForm
       aForm  addFormField:  #contract.

    View Slide

  93. BASE
    Extensions in modules
    93
    ContractAbsentModule  >>
       addFieldsTo:  aForm
       for:  aSender
       "nothing  by  default"

    View Slide

  94. Extensions in modules
    94
    CONTRACT

    View Slide

  95. Extensions in modules
    95
    CONTRACT

    View Slide

  96. Site classes vs. modules
    96
    ‣ Modules can be shared across sites
    ‣ Modules require hooks

    View Slide

  97. Recap
    97

    View Slide

  98. Techniques
    98
    ‣ Use site classes
    whenever possible
    ‣ Use behaviors
    when site classes fail (inheritance trees)
    ‣ Use modules
    when you need more separation

    View Slide

  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

    View Slide

  100. 100
    “ Your product is cool,
    but it’s missing feature X!
    — CUSTOMER
    Do not worry.
    We’ll implement it for you!
    — YOU

    View Slide

  101. 101
    ?
    MAIL [email protected]
    TWITTER @ddfreyne
    GITHUB github.com/ddfreyne

    View Slide

  102. Extra Slides
    102

    View Slide

  103. FRAMEWORK
    Site classing modules
    103
    Site  >>  modules
    ^self  moduleClasses  collect:
    [:c  |  c  siteClass  new]

    View Slide

  104. FRAMEWORK
    Site classing modules
    104
    SuperModellary  >>  buildSuperModelFor:  aClass
       builder  :=  SuperModelBuilder  new.
       Site  current  buildSuperModelWith:  builder
           for:  aClass.
       supermodels  at:  aClass  put:  builder  superModel.

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  109. BASE
    Extensions in modules
    109
    Film  >>  isLegallyBroadcastable
    ^ContractModule  current
    isFilmLegallyBroadcastable:  self

    View Slide

  110. BASE
    Extensions in modules
    110
    ContractPresentModule  >>
       isFilmLegallyBroadcastable:  aFilm
    ^aFilm  contract  isSigned

    View Slide

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

    View Slide