Venmo
Course Description
When we think of enterprise-grade applications, we think of complexity. The trick to managing complexity is to apply first-principles thinking to programming. This course will demonstrate these essential programming principles by working through a series of tightly controlled examples in JavaScript and TypeScript. We will build up a mental framework that you can use to approach non-trivial application development at any size.
This course and others like it are available as part of our Frontend Masters video subscription.
Preview
CloseWhat They're Saying
In the course Enterprise Architecture Patterns, it focuses on eliminate complexity. Great instructor!

Ibrahim Cesar
ibrahimcesar
Course Details
Published: February 2, 2021
Learning Paths
Learn Straight from the Experts Who Shape the Modern Web
Your Path to Senior Developer and Beyond
- 200+ In-depth courses
- 18 Learning Paths
- Industry Leading Experts
- Live Interactive Workshops
Table of Contents
Introduction
Section Duration: 17 minutes
- Lukas Ruebbelke discusses the outline and scope of the course. Exercises can be completed using the GitHub repository or through code examples on stackblitz.com.
- Lukas opens the Github repository and explains where to find the solutions to each exercise.
- Lukas explains how the scope of the course relates to enterprise development. Reducing the complexity of code makes large-scale applications easier to build and maintain.
Complexity
Section Duration: 55 minutes
- Lukas explains that managing complexity includes the proper handling of state, code volume, and flow of control. Any application with a shared mutable state can be difficult to test or share code across multiple components.
- Lukas explains that local, or micro, complexity is addressed at the component level. In order for component code to be testable, it should avoid hidden state and adhere to the single responsibility principle. The first step to fixing issues with hidden state is utilizing dependency injection.
- Lukas uses the extract-to-method technique to address issues with flow control. When a method's logic becomes too complex or breaks the single responsibility principle, the code can be split into separate, reusable functions.
- Lukas answers a student question about how far a developer should go when splitting up logic and how to determine which methods to test.
- Students are instructed to refactor the home service until all unit tests pass.
- Lukas live codes the solution to the Reducing Complexity exercise.
Object Oriented Programming
Section Duration: 1 hour, 20 minutes
- Lukas demonstrates why TypeScript makes it easier for developers to communicate the intention of code. Prior to ECMAScript 6, class-like objects could only be created through prototypes. ECMAScript 6 introduced native classes in JavaScript and TypeScript adds strict typing to those classes.
- Lukas describes the process of writing code as the continuous use of nouns, verbs, conditions, and iterators. Any programmatic task can be summarized in terms of these four concepts.
- Lukas explains the programming concepts around the object models within an application. Classes are the blueprint for models. Interfaces define a contract that classes must follow.
- Lukas creates two custom types and uses them to strongly type an Object. When an Object is strongly typed, IDEs are able to offer type-checking and code hinting.
- Lukas demonstrates that modeling data objects in an application makes it easier to define and maintain state. Composing the state objects from existing data types makes the functionality in the component or application more clear.
- Lukas answers questions about why it was necessary to create a BaseEntity class, why the string type was used for for the id, and strategies for abstracting the data modeling outside the home component.
- Students are instructed to create an object to represent a client project and implements an interface. An initialState object should also be created and implement a ProjectState interface.
- Lukas live codes the solution to the Object Modeling exercise.
- Lukas creates a ClientStore object. The methods within the ClientStore are the actions for that store.
- Lukas refactors the ClientStore object to include the ClientsState object rather than the individual clients array and currentClient properties. The use of array notation is also explained in this segment.
- Students are instructed to create a ProjectStore class with a constructor, state property, and the methods getState and select. The class should be instantiated with the initialState object and the select method should be called to retrieve the projects collection.
- Lukas live codes the solution to the Adding Methods exercise.
Decisions & Conditionals
Section Duration: 26 minutes
- Lukas explains that flow control in an application is managed through conditions. When a certain condition is true, the corresponding action is fired.
- Lukas demonstrates how reducers are used to manage state changes. A series of conditions are checked with a case statement to determine which action's method should be called. String-based action names should be replaced with constant variables to reduce code duplication.
- Students are instructed to create a reducer function that accepts a state and an action parameter. A switch statement should evaluate the action type and call the appropriate method.
- Lukas live codes the solution to the Reducer exercise.
Collections & Iterators
Section Duration: 43 minutes
- Lukas demonstrates why higher order functions like forEach more succinctly iterate over collections of data. Other useful higher order functions are filter, map, and reduce.
- Lukas explains how to use immutable methods to create new items, update existing items, or delete an item within an array. Each of these immutable operations returns a new array and avoids a shared mutable state. This segment also discusses how to use the Object.freeze method.
- Lukas demonstrates how to refactor the reducer methods using immutable operations. The concat method is be used for creating a new project. The map and assign methods are be used for updating projects. The filter method is used for deleting a project.
- Lukas answers questions about the Object.assign method and how to extract common CRUD operations for better reusability.
- Lukas implements an immutable store by adding a dispatch method that accepts an action and calls the reducer method with the state and the action.
- Lukas reviews how the four elements of programming have been used to build a light-weight state management module. The code is using the same architecture patterns as other state management libraries like Redux or NgRx.
Time Management in Applications
Section Duration: 1 hour, 18 minutes
- Lukas explains how to manage time, or asynchronicity, in applications. Observable streams encapsulate functionality, transport data asynchronously, and transform the data reliably.
- Lukas compares observables and streaming values with promises. A promise is effective when managing a single asynchronous event. Observables coordinate multiple asynchronous events since streaming values are emitted over time.
- Lukas demonstrates a basic observable example from the macro application. Data outputted from the stream is passed directly into the subscribe method. The data can be transformed before reaching the subscribe method by using the pipe method.
- Students are instructed to capture the searchControl output into a queryString. The data should also be mapped to uppercase letters and reversed.
- Lukas live codes the solution to the Observables exercise.
- Lukas answers questions about IDE theme configurations, promises vs. observables, and if data should be transformed on the server or client in an asynchronous call.
- Lukas discusses how to preserve state within a stream. The scan method behaves like the reduce method by continually updating an initial value. The scan method can also receive a partially applied function for cases when multiple streams are being merged.
- Lukas explains in more detail how partially applied functions are passed into the stream and called at a later time. The mapTo method passes the property and value that should be applied to the position property once it enters the stream.
- Lukas demonstrates how the switchMap method is used to switch to another stream. The takeUntil method allows the stream to receive data until a desired observable is emitted.
- Lukas explains how communication messages are sent and received between subjects in an application. A subject's asObservable method returns a stream and any observer subscribed to the stream will receive updates when an event is emitted.
- Lukas answers questions about currying, partially applied functions, and Redux vs. Observables.
Distributed Complexity
Section Duration: 30 minutes
- Lukas discusses how user interactions can be simulated by manually dispatching actions. A properly decoupled system is not dependent on what triggers an action. It subscribes to a stream and waits for an action to be emitted.
- Lukas demonstrates some real world examples of distributed complexity. Abstracting the state from an application allows two distinct instances of the application to share a synchronous stream of data through the use of web sockets.
Wrapping Up
Section Duration: 7 minutes
- Lukas wraps up the course by answering questions about storing state on the server and pushing data to client applications from the server.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops