Hi and welcome to a SOLID example of implementing inversion of control (IOC) in TypeScript when working in distributed teams. Spoiler alert! It’s all about plugins! Photo by rawpixel on Unsplash The inspiration We performed this by Emily Bache yesterday at work. tennis refactoring Kata Your task is to write a “TennisGame” class containing the logic which outputs the correct score as a string for display on the scoreboard. When a player scores a point, it triggers a method to be called on your class letting you know who scored the point. Later, you will get a call “score()” from the scoreboard asking what it should display. This method should return a string with the current score. [1] Six developers trying to untangle code, wonderful! Having the game’s nitty-gritty details inside the , I’m just going to highlight its gameplay. Kata starts strong and gets to “Thirty-Fifteen” in his favor, but p summons his inner strength and wins! Player one layer two We refactored the class which exposed the and methods to the caller, keeping its green. During the refactoring, I felt concepts like and trying to emerge. TennisGame wonPoint getScore tests player score Later that evening I was drinking a beer, maybe more, with a friend, discussing Robert C. Martin’s SOLID principle, . dependency inversion Two things struck me: I have no life, talking about IOC in a pub; I have just found the subject for my next article! What is the inversion of control? The Dependency Inversion Principle (DIP) tells us that the most flexible systems are those in which source code dependencies refer only to abstractions, not to concretions [2] Building on Robert C. Martin’s explanation quoted above let’s highlight this design principle through a hopefully exciting journey. The task Let’s implement the same tennis game described in the Kata, but with a distributed team working on it. Meet Frank Gamelord Working on the 25th floor in a New York City office building, Frank is in charge of the overall game and its integration in the company’s systems. He knows the importance of separating concerns in distributed projects. The contracts Frank takes a cup of coffee, thinks about the tennis game and writes its interface. The state of the game will consist of two player objects. Each player will have a and a total number of . With this information, Frank writes the interface. name points Player Find out more about the concept of state and how it applies to modern single page applications in . my article Next, Mr. Gamelord reads the requirements and realizes that he will need a way to manage players, ergo the interface. ManagePlayers Looking out the window, sipping more coffee, the last piece of the puzzle unveils, the ! score Frank puts down his cup of coffee and rushes to the printer. He comes back with five , each representing one of the interfaces he just modeled. contracts Frank’s job is to fulfill the contract. Due to his busy schedule, he’ll have to delegate the rest. TennisGame The rest of the team In the left corner, from London, database enthusiast Bill Playwell! In the right corner, from Reykjavik, Haskell enthusiast Andy Scoreson! The talk Bill Playwell, do you take the and contracts in code marriage and vow to implement them well? Player ManagePlayers Andy Scoreson, do you take the contract in code marriage and vow to implement them well? CalculateScore Frank creates the project’s structure in a way that allows everybody to work independently. He will work in the folder, Bill in the folder and Andy in the one. gameplay player score Notice how the folder holds all the interfaces while the and folders contain only implementations? gameplay player score Frank’s implementation Mr. Gamelord creates the . It expects a object and a function as arguments and returns another function. The later takes the names of the players as parameters, returning the game. curried createGameFactory factory function ManagePlayers calculateScore The does not import any concrete implementations. Its source code dependencies are the and interfaces. createGameFactory CalculateScore MangePlayers Not depending on actual implementations, allows Frank to finish his work even before Bill and Any start theirs. Bill’s implementation It’s a chilly British morning when Mr. Playwell starts working. He implements the five methods required by the interface with pure functions and exports them as a whole. ManagePlayers Bill’s module has two abstract source code dependencies, the and interfaces, exporting the laters implementation. Player ManagePlayers Andy’s work It’s a beautiful Icelandic morning when Mr. Scoreson thinks of a descriptive algorithm composed of pure functions. It allows him to achieve temporal decoupling. The order in which functions inside the get called doesn’t matter. calculateScore closure Andy’s module has a single dependency, the interface and it exports its implementation. abstract CalculateScore Almost done All the concrete implementations , , and depend only on abstract interfaces, the mighty contracts. createGameFactory PlayerManager calculateScore Frank thinks proudly about his team and puts everything together in the . createGame higher-order function The source code dependency graph looks like this: Notice how the blue source code dependencies arrows of the point in the opposite direction of the red dependencies of the and implementations? createGameFactory calculateScore PlayerManager That’s inversion of control! IOC allows developers to work together without stepping on each other’s toes. It enables temporal decoupling for the engineers. Frank finished his work before Bill and Andy. Andy could have started long after Bill without problems and source control conflicts. It enables modules similar to and to become plugins of the application. PlayerManager calculateScore If Andy thinks he can improve the scoring algorithm he can change it without affecting the rest of the app. The end If you feel like sharing your thoughts with me, please do! Learning together is the reason I write! Feel like wanting more? Watch ’s video on . Mattias Petter Johansson inversion of control For an academic presentation, you can purchase Robert C. Martin’s (I am not an affiliate). video You can find the with the presented code . repo here [1] https://github.com/emilybache/Tennis-Refactoring-Kata/blob/master/javascript/TennisTest.js [2] Robert C. Martin, 2017, Clean Architecture: A Craftsman’s Guide to Software Structure and Design