Paulo Monteiro
The submited version passes in all tests.
In order to keep the code clean and "free of repeated ifs", I took an approach that instead of verifying if a given variable is set and then executing something, we apply a operation directly on a pool of objects. This objects has the structure:
(
[searchTypes:protected] => Array
(
[simple] => Uniplaces\STest\Search\SimpleSearch\SimpleSearch Object
(
[search] => Array
()
)
[advanced] => Uniplaces\STest\Search\AdvancedSearch\AdvancedSearch Object
(
[search] => Array
(
[address] => Uniplaces\STest\Search\AdvancedSearch\AddressSearch Object
()
[price] => Uniplaces\STest\Search\AdvancedSearch\PriceSearch Object
()
)
)
)
)
To do this, there are two main steps:
- Abstract the search type and create an array 'search type' => object (object implementing a given interface and being generated by a factory)
- Each object in the search type has a constructor that generates all the objects necessary for the purpose of the Search. All this methods have to extend a SearchOperation to have a common method between them.
To add a new Search Type is as simple as:
- Create a class that extends SearchOperations (to have a common function filterType)
- Each Search operation in each Type must implement SearchInterface (to implement function execute)
This functions are essencial as they create a protocol that allows us to largerly refactor the code. This approach allowed me to reduce the reduce function to less than 20 lines, as instead of doing ifs to validate we can simply do:
$searchMethod = $this->searchMethods->type($this->searchType);
foreach ($searchMethod->filterType($search) as $k => $v) {
if (!$v->execute($listing, $search)) {
continue 2;
}
}