From 640fc0de633e297085582dd50d8b28362dcdd8f1 Mon Sep 17 00:00:00 2001 From: Fbenas Date: Mon, 7 May 2018 15:55:10 +0100 Subject: Remove long opts and add design decisions to readme --- README.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Script/Input.php | 36 ++++----------------------------- 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 70dd44e..c1da941 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,61 @@ # Installation +Create autoloader and pull in any libiraries for testing (PHPUnit) +``` +composer install +``` + +Create an input file in the format discussed in `homework.txt` + # Running +``` +php scripts/run.php [options] +``` + +Available CLI options +- -f - input file with the vendors data +- -d - delivery day (dd/mm/yy) +- -t - delivery time in 24h format (hh:mm) +- -l - delivery location (postcode without spaces, e.g. NW43QB) +- -c - number of people to feed + # Design Decisions + +## Coding style and standards +Where possible I have tried to implement a consistent standard of code, namely using PSR2. I've also added doc blocks to each class, function and class variable. + +In general I am happy to work with many different coding standards, but here I have tried to show that my focus is on a clear and consistent code style. + +I have added a constraint to the composer json for this test so that php7 is a hard requirement. I decided that it's useful to show that I understand the differences in major and minor versions of PHP and can therefore write relevant and runnable code that runs, regardless of the system constraints. + +# Structure +Set-up of classes using composer and PSR4 autoloading standard + +## Input handling + +Usually I'd avoid doing any of this input handling manually and I would much prefer using a well supported OO library such as `symfony/console`. In this case I have created my own `App\Script\Input` class that uses PHP's `getopt` function to load the required options and do some basic exception handling when options are missing or formatted incorrectly. + +## Output handling + +Again, I would prefer to use something like `symfony/console` here to easily produce well formatted CLI output, including progress bars etc. Here I have kept things very simple by just using `echo` to output the results from a search, keeping the format consistent with the input file. + +## Storage/Persistence + +Here I decided against of any long-term persistence and instead I have created a `App\Model\Collection` class that acts as the storage for the input data and the filtered data that will be returned to the user. + +## File Handling + +I have also kept this part as simple as possible. The class `App\Handler\File` simply loads a file into a string for proper parsing later + +## Model + +I decided to create a couple of models for `App\Model\Vendor` and `App\Model\Menu`. These items, along with the collection mean we have all the data required accessible easily from memory in a structured format. The Vendor class then handles loading instances of itself, and returning itself as a string for output. If this task was more complex I'd consider removing this content to some input/output adapters that would mean a change in the specific formats would simply require adjustments to the adapter or creation of new adapters. + +## Filtering + +The filtering is tightly coupled with both the `App\Model\Collection` and the `App\Model\Vendor` classes. I choose to do this because the vendor and the collection have the closest access to the data that we are filtering on. If I had chosen some data persistence such as a database like MySQL, or a search engine like Elastic Search then the logic for filtering would probably be removed from the collection and perhaps placed in some form of loading/saving adapter or handlers. + +# Testing +I have not attempted to get full coverage of the code, and I have not attempted to cover all the possible use cases for input. +I have added these unit tests, using PHPUnit to show that I am capable of writing testable code and writing unit tests to cover that code. diff --git a/src/Script/Input.php b/src/Script/Input.php index 6a91a72..eb9d2da 100644 --- a/src/Script/Input.php +++ b/src/Script/Input.php @@ -21,25 +21,7 @@ class Input * * @var string */ - protected $shortOpts = 'f:d::t::l::c::'; - - /** - * Available CLI options - * f filename - input file with the vendors data - * d day - delivery day (dd/mm/yy) - * t time - delivery time in 24h format (hh:mm) - * l location - delivery location (postcode without spaces, e.g. NW43QB) - * c covers - number of people to feed - * - * @var string - */ - protected $longOpts = [ - 'filename:', - 'day::', - 'time::', - 'location::', - 'covers::' - ]; + protected $availableOptions = 'f:d::t::l::c::'; /** * The loaded CLI options @@ -66,7 +48,7 @@ class Input */ protected function loadOptions() { - $this->options = getopt($this->getShortOptionString(), $this->getLongOptionString()); + $this->options = getopt($this->getOptionString()); if (!array_key_exists('f', $this->options)) { throw new Exception('Filename Option `-f` is required'); @@ -92,21 +74,11 @@ class Input * @author Phil Burton * @return string */ - public function getShortOptionString(): string + public function getOptionString(): string { - return $this->shortOpts; + return $this->availableOptions; } - /** - * Return the option string for the options we want to load - * - * @author Phil Burton - * @return string - */ - public function getLongOptionString(): array - { - return $this->longOpts; - } /** * Return an option value -- cgit v1.2.3