bikalbasnet / GildedRose-Refactoring-php

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

GildedRose Kata - PHP Version (Solution)

This is a solution to the GildedRose Kata in PHP.

Installation

Clone the repository:

git clone git@github.com:bikalbasnet/GildedRose-Refactoring-php.git

Install all the dependencies using composer

cd ./GildedRose-Refactoring-php
composer install

Dependencies

The project uses composer to install:

commands

componser tests
composer phpstan
composer check-cs
composer fix-cs

Solution Explanation

You can check the commits at https://github.com/bikalbasnet/GildedRose-Refactoring-php/commits/main, which are the steps I took to refactor the code.

  1. The first commit is the original code from the GildedRose repository.
  2. After that, I added the tests for the existing code and fixed coding standard and phpstan issues. These are the commits: Add phpunit tests and Fix phpcs, phpstan issue.
  3. This is the step where the actual refactoring began (Check the commits Make code slightly simple by reducing nested if statements and Remove more nested if statements). I have tried to make the code more readable and simple by removing nested if statements without breaking any existing tests.
  4. With this, I am left with simple functions like $this->incrementItemQuality($item); and $this->decrementItemQuality($item); which can be easily refactored to a single function. This is what I exactly did in these commits: Combine all increment quality in one function and [combine multiple decrement item quality into one function] (https://github.com/bikalbasnet/GildedRose-Refactoring-php/commit/3e3699058ada6c3ea0f1a8def6eb831a94cb10cb)
  5. Up until this point the code is much simpler, however there were still lot of if else condition which were handling different cases for different types of item. So I decided to use strategy pattern to make the code more readable and maintainable. This is the commit where I started implementing it Implement strategy pattern to make code more readable and maintainable and Add object for all item type.
  6. I created an Item class for each item type, example AgedBrie, BackstagePasses, etc. I realized that I was repeating some code and this can be further refactored. So I created a parent class Item that contains the common code for all the items. This is the commit Reduce code by having each item object implement parent class.
  7. I was still repeating some code in parent class like maximum quality that is allowed, so I decided to create an abstract class, which will be implemented by all Item classes. Each item would then have to implement an abstract function getNewQuality because every item has its own logic on quality. The value which is obtained from this function is passed to updateInventory, which makes sure that the quality is not higher than allowed 50. But Sulfurus is the only item that can have quality 80, So I created a function getHighestQuality, which is overridden by Sulfurus Item to be 80, whereas it defaults to 50. This is the commit Use Abstract class to reuse common logic like max quality values
  8. I furthered refactored the code by removing interface methods that are not needed and kept only one method updateInventory in the interface. This is the commit Remove interfaces methods that are not needed.
  9. After refactoring upto this stage , adding a new Item was very easy. Whenever a new item was added we only have to extend it from AbstractItem class and implement its own getNewQuality function. This is the commit Add Conjured Item.

About


Languages

Language:PHP 99.5%Language:Batchfile 0.5%