Design patterns currently used in projects I’ve worked on

Factory Method

  • Used in Protocol0 backend to generate notification / prompt / select windows

Abstract Factory

  • Used textbook in Protocol0 to generate a track recorder
  • The abstract factory generates for a track and record type :
    • A track recorder
    • A scene index for the recording
    • A bar length for the recording

Singleton

  • Used in basile ats client generation tests
  • The test ats client returned is always the same to be able to push fake http responses into the tests (pattern not used anymore)

Facade

  • Used in protocol0 SongFacade to expose readonly access to song objects
  • Also in Scheduler to expose simplified facade to scheduling methods from 2 scheduler classes

Composite

  • Used to abstract composite tracks in protocol0 e.g. in arming tracks or soloing them.
  • Implemented using classical inheritance with AbstractTrack
  • Leaves are SimpleTracks, containers are AbstractGroupTracks
  • We could remove the AbstractTrack.base_track as it breaks the encapsulation principle.

Decorator

Used in its simple form but could be improved to implements the real pattern semantics.

  • Used in protocol0, to augment behavior of notification classes.
  • Used somewhat in basile to catch exceptions. Respects the pattern semantics but replaces the interface step by just using callables.
  • Could improve the generation of missing ATS responses in basile. The ATSServiceFactory could return a ATSServiceResponseGeneratorDecorator implementing the interface without handling these kind of cases explicitly.
  • Could also work for the ErrorHandlerService instead of catching the exceptions in the client code.
  • Could also be used for offer synchronization by applying decorators at service instantiation time for company custom code instead of using inheritance. Might be overkill though.

Template method

  • Used in basile ats synchonize offers
  • Used in protocol0 recording system ()

Observer

  • Used in protocol0 system notification system
  • The inner notification window notifies values when buttons are clicked
  • A decorator applied at instantiation (in the notification factory) observes the inner window and sends values to the script over midi.

Pub / sub

in a simple, synchronous way

  • Used in Basile status synchronization
  • The status code emits events on a event bus
  • The event bus dispatches to observers subscribed to specific events

Design patterns partially used

Builder

  • Used in basile admin crud. ressemble because we don’t use a bloated constructor.
  • Not using a specific builder class but by passing directly an instantiated object
  • Could be improved by creating an AdminCrudConfigBuilderInterface subclassed by AdminCrudConfigBuilder and AdminFormConfigBuilder. Not really the builder pattern because we would pass a specific builder class and not interface but close.

Prototype

  • Used in basile to clone newsletters
  • Not respecting the prototype pattern semantics but using __clone magic method

State

  • Used in Protocol0 Sequence code
  • A Sequence can be in different states (unstarted, started, paused, cancelled, errored)
  • Transitions are defined accordingly
  • Implemented using the transitions package
  • NB : states are not defined in specific classes which doesn’t respect the pattern

Design patterns that could improve existing projects

Abstract Factory

  • In basile ATSServiceFactory
  • Instead of using a single class per ATS we could instead create one feature class per abstract ATS feature
  • The current ats class could be replaced by a factory returning a feature class instance respecting the single responsibility principle.
  • That would be beneficial for the status synchronization as we could have a single synchronizeStatusesInteface (with method synchronizeStatuses) instead of using a match in ATSSynchronizeStatusesService.
  • Downside : would need a lot more classes and would complicate the subclassing of the ats code by a specific company’s ats implementations.

Command

  • Replace the encoder action code with commands
  • create a command class per feature
  • logging by command (using command class name)
  • add an undo button doing multiple undo.
  • undo can be used for undoing recordings as well
  • define macro commands using commands arm track, show plugins ..

In basile

  • NB : in basile we use messages as commands but it’s message handlers that connect to a specific receiver and not client code
  • We could use commands to wire up some frontend and backoffice features but how do we serialize the command in the front ?

Adapter

  • Maybe on ATS system to abstract the different protocols used (if one day we use more that are not rest ..?)
  • For ATS V1