This article is the first of a series about the main frontend frameworks and backend technologies, which is based on a thematic project to show how these interfaces respond using different implementations.
Get your pokémon
In few words VueJS was our first option to implement the interface because: it’s performatic, reactive, component driven and (maybe the main point, though some will argue that is subjective, it’s easy to learn and fast to implement).
Great internet tools give us a clue of how fast VueJS is, check it out. When we talk about JS frameworks, performance is often associated to ReactJS, but VueJS can be even faster, check this comparison between them.
Object.defineProperty. The getters/setters are invisible, but under the hood they enable Vue to perform dependency-tracking and change-notification when properties are accessed or modified. So with that we achieve in a easy way reactivity and data separation from the DOM.
It’s easy and fast to implement because is component based. There is no need to understand in-depth design patterns and related stuffs (of course that is even better if you understand them, but is not a requirement to develop great applications with Vue). Every component is compounded by an HTML file, a CSS file and a JS file (or theirs’ pre-processors/transpilers) and just that.
We decided to go for Lumen (Laravel’s micro framework) as we had a previous experience with Laravel. So, we could get the benefits of Laravel’s core without increasing it’s bootstrap with structures that we would not use (in a restful API context).
Basically, 3 routes are provided:
- Get all Pokémons
- Select player’s Pokémon
- Hit your opponent
The “heavy” part is when we do the calculations to determine how much damage your Pokémon will cause/receive. It considers the traditional Pokémon types advantages/disadvantages. Besides that, we’ve added the miss/critical situations, where a random value can make your Pokémon fail to cause damage into its opponent or do almost twice of its normal damage.
The Pokémons and their attacks were stored in a separate JSON file and were implemented repositories to retrieve them by name and randomly. The Pokemon class encapsulates the data retrieved by the PokemonRepository as well as providing the behavior of hitting another Pokémon. The type modifier and damage computation of inflicted attacks were implemented by specific classes. TypeModifierCalculator uses a type chart - multipliers that consider the inflicted attack type and the opponent Pokémon type to modify the caused damage. DamageCalculator implements the official formula, which uses the TypeModifier returned by the TypeModifierCalculator. Tests were implemented for all significant classes in order to ensure their expected behavior, achieving 84% of test coverage.
We tried to follow as strict as possible the SOLID principles - the classes have only one responsibility, their behavior can be easily extended without modifying their code, they don’t need to implement unnecessary methods because they implement an interface and they are easily replaceable by their subtypes. This way we could ship a reliable and maintainable piece of software, with a score of 4.0 on Codeclimate.
The project was developed around the SCRUM concepts, so we step-by-step delivered a plenty functional software. In each cycle new functionalities were added and existing ones improved. On that scenario code refactoring was a common practice.
As we mentioned before, this is just the beginning, in the next days we’re going to rebuild this interface using different tools and then create a real experience of what can we get with each one. Be ready for the next episodes!
Watch and stars us on Github!!