Exercises in Programming Style–Hollywood

NOTE : read the rest of the series, or check out the source code.

If you enjoy read­ing these exer­cises then please buy Crista’s book to sup­port her work.

exercises-prog-styles-cover

Fol­low­ing on from the last post, we will look at the Hol­ly­wood style today.

 

Style 14 – Hollywood

Constraints

  • Larg­er prob­lem is decom­posed into enti­ties using some form of abstrac­tion
  • The enti­ties are nev­er called on direct­ly for actions
  • The enti­ties pro­vide inter­faces for oth­er enti­ties to be able to reg­is­ter call­backs
  • At cer­tain points of the com­pu­ta­tion, the enti­ties call on the oth­er enti­ties that have reg­is­tered for call­backs

 

I’m not over­ly fond of Crista’s Python inter­pre­ta­tion of this style, so I decid­ed to do some­thing slight­ly dif­fer­ent using F#‘s built-in sup­port for Observ­ables. You could also use Rx via FSharp.Control.Reactive, though it seemed to be overkill for this par­tic­u­lar prob­lem.

Stick­ing with the same enti­ties Crista defined in her exam­ple:

  • DataS­tor­age
  • Stop­Words­Fil­ter
  • Word­Fre­quen­cy­Counter

in our F# ver­sion, each will sub­scribe to an upstream IOb­serv­able, does what­ev­er it needs to do and pro­vide the out­put also as an IOb­serv­able for down­stream enti­ties.

Style14_designv2

And upstream of all the enti­ties is an attempt to run a term fre­quen­cy analy­sis against a data file and a cor­re­spond­ing stop words file:

Style14_01

Our ver­sion of DataS­tor­age would depend on an IOb­serv­able<RunArgs>. It’ll in turn expose an IObservable<RunArgs * string[]> as mem­ber so down­stream enti­ties can sub­scribe to and be noti­fied when DataS­tor­age is able to load the words from the spec­i­fied data file.

Style14_02

Next, we’ll imple­ment a Stop­Words­Fil­ter type that will:

  1. sub­scribe to an IObservable<RunArgs * string[]>;
  2. on a new val­ue, load the stop words and use them to fil­ter the words from the data file;
  3. make the fil­tered words avail­able to down­stream enti­ties via an IObservable<string[]>

Style14_03

Final­ly we have the Word­Fre­quen­cy­Counter, which takes an IObservable<string[]> and print the top 25 most fre­quent words:

Style14_04

To string every­thing togeth­er, we’ll cre­ate an instance of IObservable<RunArgs> via an F# Event (Event.Publish gives us an instance of IEvent<‘T> which inher­its from IObservable<T>).

This IOserv­able will act as the upstream to DataS­tor­age and to kick things off we just have to trig­ger a new event with an instance of RunArgs:

Style14_05

 

You can find the source code for this exer­cise here.