In this episode, we review the overall architecture of the game, formed so far by the following layers:
The Engine is a framework designed to be agnostic of deployment target. It does not reference any external modules, making it easy to reuse in other projects. So far, it consists of two components:
Flow, an internal class responsible for the flow of the game, coordinating the progression of the Quiz.
Router, a protocol specifying the contract for coordinating the game progress, enabling the
Flowto not depend on low level platform details. Implementations of this protocol (contract) will live outside the Engine module.
This is an example of the Dependency Inversion Principle. The application needs to implement the
Router protocol, leaving the Engine framework unaware of its implementation. By establishing this contract, we can perform changes to the iOS application without affecting the Engine.
The Routing layer, although empty for now, will consist of the concrete implementation of the Engine's
Router protocol and any other type responsible for the routing of the Quiz game.
The UI layer is formed by platform specific UI components, isolated from the rest of the application. For example, when developing iOS applications, we expect the components we use to derive from the Cocoa Touch framework.
By separating the UI layer from the rest of the system, we can have one or more implementations for each platform, meaning an implementation for macOS and a different one for tvOS, for example. In the case of iOS, we can even have different implementations for the iPhone or the iPad, if needed.
As mentioned above, the UI layer doesn't depend on the business logic for receiving any input. Instead, it references the Presentation layer, which provides all necessary values.
The Presentation layer's responsibility is to transform data models to presentable data that can be rendered by the UI. It decouples the UI layer from any business logic, by essentially being a middle man providing the values required by the UI components.
The Main layer is the root/entry point of the application. It is responsible for plugging in components for the appropriate deployment target. Essentially, we can have multiple Main modules for deploying different products or on different platforms.