This section introduces the design of the mobile application. Generally speaking, this architecture adopts the classic Model-View-Controller (MVC) pattern (Reenskaug and Coplien, 2009).
WikiModel and many others,
each holding information and buffered data from X5GON Backend.
Data updates are made from
User interactions are captured through
Actions in various
ViewControllers and then delegate to the
With the main logic implemented in the
MainController, it dispatch changes to relevant
Models, which will then be reflected in
Refresher workers keep track of the
Model changes and update them with the X5Learn backend when suitable.
Our team adopted the MVC architecture mainly because of its high cohesion and low coupling. We can group sections of similar actions on
DataModels together in the
MainController, and ensure there is little to no coupling among these three parts. In other words, modifications to views would in no way break our API, and similarly otherwise. This gives us confidence when working on our code and helps us to work together as a team with multiple development branches on the same code base.
We have made substantial effort to separate responsibility among multiple modules in our application. As an example, we abstracted the reloading and refreshing logic out of all
ViewControllers and put them into an
Refreshing can be done easily with passing lambda or
Closures to the extension without any other code needed.
We find this principle particularly useful as we can maintain a same set of multi-threading strategy and
Queue throughout the code base. For a deeper dive into our multi-threading strategy, see implementation section for more details.
We strictly follow the Open Closed Principle and its extension Liskov's Substitution Principle throughout our
DataModels. For instance, models like
PDFs are subtypes of
Content and can be substituted seamlessly in the code. This allows us to share multiple properties among the
DataModels and eliminate redundancy.
Prototype Design Pattern is used in the project on
PlayerViewController to ensure single responsibility principle and make different
ViewControllers replicas for various Video sessions cleaner. For more information on our
playerView implementation, see here for details.
Whilst we are developing our application, the backend from our client is transforming from
X5Learn, such that we are supporting two back-ends at the same time. Therefore, we utilised the Adapter Design Pattern to make sure our
MainController have access to the same set of API at the same time.
To ensure that there is only one hefty
MainController available globally, we utilised the singleton design pattern. The controller is available globally and statically, and is forbidden be constructed twice throughout the application's lifecycle.
As a typical client side application, we are only storing limited amount of user and cache data.
User token, name and ID information are stored with
NSUserDefaults (Apple Developer, 2020b) to ensure data persistence after quitting the application.
Videos, audios and PDF contents are only cached and can be retrieved with the
iOS (Apple Developer, 2020a).
See below, an entity diagram, on relations of user and cache data stored.
We tried to make our application as intuitive as possible so as the user would be easy to navigate around. All views can be divided into
NavigationViews are used to navigate users around and incorporating supporting views such as
MainViews are the core content presenting views and the user profile console.