Skip to content

A weather app ☀️ ☔ ☁️ for an object oriented architecture and design university assignment.

License

Notifications You must be signed in to change notification settings

PatrickShaw/weather-app

Repository files navigation

FIT3077 Full Lambda Assignment 2

Please mark Assignment 2 stage 2 from the last commit of Thursday 25th May

🚢💯✔️

Student details

Patrick Shaw

David Lei

Prerequisites

  • Node.js ~v6.9.1: A JavaScript runtime. The code base should be relatively independant of the Node.js version being run.
  • Yarn (Optional but highly recommended): Depedency management software that typically outperforms npm at installation speed.

Tested envionments

  • Windows 10 Home (OS Build 14393.1066)
  • OS X El Captain 10.11.6

Browser support

We used the assignment to try out new features of JavaScript and CSS such as promises and CSS Grid. This limits the compatibility of the app to modern browsers only. Our Webpack transpiler loaders should provide extended compatibility, however, for the sake of marking, the app works correctly on the following browsers:

  • Google Chrome +58.0.3029.110 (64-bit)
  • Firefox +53.0.3

Installation instructions

  1. Make sure Node.js is installed.
  2. Open up a terminal.
  3. cd to desired folder.
  4. git clone https://github.com/Monash-University-FIT3077/fulllambda-Assignments.git
  5. cd fulllambda-Assignments/Assignment_2
  6. Run npm install. If you have yarn installed you can use yarn install. Wait for all the node packages to finish downloading.
  7. Run npm run backend-start. Wait for the the 'Webpack configuration complete' message to be printed to the console.
  8. Open up another terminal.
  9. Run npm run frontend-start. Wait for Webpack to finish again.
  10. Open a browser.
  11. Type into the URL bar: 'localhost:3000'.

Note: You MUST wait for the backend's compilation to finish before running npm run frontend-start. This is an issue with having two Webpack builds running at the same time in the same folder with similar configurations. It is assumed that a solution to this problem is out of scope for this assignment.

Assignment 2

The report resides in the repository with the file name: FIT3077_Assignment2_Stage2_Report_26029391_26898187_FullLambda.

UML Diagrams

Why do we have a backend server

We use Node.js to provide our own API to frontend applications, as opposed to the frontend application communicating with the SOAP client directly. Despite the added latency, there are a plethora of reasons for doing this:

  • Removes frontend polling all-together: Polling is inefficient and poorly scales with high frequency polling (a potential change to the requirements in stage 2). By rolling our own API, we are able to leverage WebSocket which removes the need for frontend clients to poll all together. This is far more efficient compared to high frequency polling.
  • Minimizes traffic directed at the SOAP service: One of the objectives of assignment was to "minimize the network traffic generated by your system: don't access the web service more than is absolutely necessary". Our server acts as a cache for the SOAP service's data, allowing users of frontend clients to retrieve data witout the need to retrieve data from the SOAP service at all. This means that the amount of traffic directed at the SOAP service is independent of the number of frontend cleints. Real world APIs also often have a limit on the number of requests that can be made to their service per hour. Our implementation circumnavigates this issue.
  • Changes are invisible to the client: Changes in the WeatherClient are transparent to frontend clients. This is particularly useful when constantly switching between MelbourneWeatherClient and TestWeatherClient.
  • Potentially less computationally intensive for poor-performing devices: Less logic on the frontend means that simpler devices can use the application without lag.

Engineering philosophies and patterns used

  • The observer pattern: The observer pattern was used for on click events and in the LocationMonitoringManager & SessionMonitoringManager. Our observer pattern mimics the Android SDK's implementation of the observer pattern.
  • Factory pattern: We use the factory pattern to allow the FullLambdaWeatherService to create a WeatherClient from a WeatherClientFactory so that the service does not need to know the underlying steps to create the client. Retry-client-creation functionality will be written into the FullLambdaWeatherService as an example of using the pre-existing factory code to potentially build multiple Promise<WeatherClient>s.
  • Seperate GUI and logic: We almost totally avoid any logic on the frontend of our project. This allows us to provide functionality that is independant of the user's interface. In fact, the only frontend class that performs limited controller functionality is the WeatherPageContainer which links the view to the socket.io API. All other frontend classes concern themselves with rendering the DOM in a particular way.
  • MVC (Model, view, controller): The model, view and controller (as previously discussed) are seperated. The WeatherPageContainer determines how inputs are interpreted, all other React.Components serve as view type classes. All business type logic is handled by the backend server.
  • Use dependency injection: Gregory Kick's Java Dagger 2 video explains dependency injection quite well. As an example of the benefits of dependency injection in our own code; WeatherClient is passed into the FullLambdaWeatherService's constructor. This allows us to swap out the MelbourneWeatherClient with a TestWeatherClient which allows for easier debugging.
  • Composition over inheritance: Self explanatory. This mentality is typically considered to enable more flexibility in code. An example of this was our choice to compose the LocationItem of a GenericListItem rather than inheriting from it.

Guidelines

Current loggin guidelines

  • Green text: successful
  • Red text: error information
  • Cyan text: important information
  • Purple text: parameterized information
  • White text: General/other

Git patterns

The development-master pattern is used in conjuction with feature branches. Code is merged (usually) via pull requests.

master: The development branch should be merged into this branch whenever a new version/set of features, ideally bug free, have been completed.

development: Features should be merged into this branch once implemented. This branch should maintain transpilability and compilability. Known bugs are allowed to be merged into this branch. Developers can work on the development branch for minor changes to the codebase.

Feature branches: Feature branches contain major refactored code or implementations of new functionality. Code from feature branches should be merged into the development via pull requests.

Other cool things our product does

Our product can handle multiple sessions from different browsers/tabs. Each will have it's own set of clickable buttons to add and remove rainfall and temperature data. We also cache the weather data so new sessions can be served ASAP.

It also has a google map which can be used to toggle location pins for a weather service.

Location pins represent the intensity of rainfall, with greater rainfall resulting in a deep blue and less rainfall in a light blue pin. If rainfall is not selected it defaults to red. If rainfall in not a valid number it defaults to grey.

Around each marker is a circle representing the intensity of temperature, the hotter it is the more red the circle. Likewise if temperature is not selected it defaults to a greyish-blue and if temperature is not a valid number it defaults to grey.

Hovering over the pins displays more information about the area.

Gif

Alt Text

Screen shot

Technology stack

Languages & syntax choices

TypeScript

A superset of JavaScript that allows the use of static typing, interfaces and classes. Developed by Microsoft.
Differences to Java
  • Interfaces can have variables. These variables are passed onto the implementer of the interface.
  • Variables do not necessarily have to be typed. This allows compatibility with JavaScript packages that do not provide types.
  • Optional parameters are supported in TypeScript. This renders the Builder pattern somewhat redundent and is thus not used in our code base.
  • readonly is supported in TypeScript. We use this public readonly over accessor methods, in all 'model data' type objects.

ECMAScript 2015

The 6th major release of ECMAScript. A standardized JavaScript language. Provides us with classes and the core features of OO langages (E.g. classes).

JSX Harmony

JSX harmony is a language primarily built for React. The language was primarily used to make React components easier to read and faster to write.

SASS & CSS Modules

SASS is effectively an extension of CSS3. We used SASS over plain CSS3 simply for SASS's variable constants feature.

Frameworks & libraries we use

React

Facebook's JavaScript library for rendering view type objects for use in graphical user interfaces for a set of state.

Node.js

Node.js is a server framework built from Chrome's JavaScript V8 engine. It was chosen for a number of reasons.

Babel

Babel essentially allows developers to transpile newer and alternative versions of JavaScript into older, more widely supported versions of JavaScript. We were unsure of whether the markers' used modern browsers so Babel ensured application compatiblity with their browsers.

Webpack

Webpack was used to tie all the languages and frameworks used in our product together and bundle the backend and frontend applications, each into single JavaScript files. In addition, Webpack was used as a means of hot module replacement which was handy for frontend development and rapid prototyping of features and functionality.

Frameworks & libraries we decided against

Redux

Redux is an exellent framework for managing state in an application and works well with React. However, Redux has a functional programming based nature which didn't fit in with the assignment (object oriented assignment).

React Router

React Router allows easy management of routes/url navigation. The assignment only really required a single page and browser history management was out of scope.