Przejdź do treści

Zad. 8 - Branch By Abstraction - sprzątanie

Uznaliśmy, że wdrożenie wyświetlania rekomendacji przebiegło prawidłowo i możemy pozbyć się flagi show_recommendations_on_product_lookup.

1. Usunięcie flagi

1.1. Usuń definicję flagi w main/src/Flags.php

1.2. Usuń flagę z docker-compose.yml

1.3. Zmodyfikuj pipeline.sh, tak by już nie uruchamiał dodatkowych testów z tą flagą.

1.4. Usuń test ProductLookupControllerTest::testControllerReturnsValidResponseWithRecommendationsDisabled

1.5. Zmodyfikuj test ProductLookupControllerTest::testControllerReturnsValidResponseWithRecommendationsEnabled usuwając warunek pomijający test w zależności od flagi.

1.6. Usuń test ProductImpressionMiddlewareTest::testControllerReturnsValidResponseWithRecommendationsDisabled

1.7. Zmodyfikuj test ProductImpressionMiddlewareTest::testControllerReturnsValidResponseWithRecommendationsEnabled usuwając warunek pomijający test w zależności od flagi.

1.8. Zmodyfikuj main/src/Products/ProductLookupController.php, by zamiast warstwy abstrakcji używać ProductLookupWithRecommendationsDataProvider.

1.9. Usuń warstwę abstracji main/src/Products/ProductLookupDataProviderAbstraction.php.

1.10. Usuń starą implementację main/src/Products/ProductLookupStandardDataProvider.php.

1.11. Uruchom pipeline.sh, by mieć pewność, że wszystko jest ok.

1.12. Commit.

2. Refactoring zależności

2.1. Zmodyfikuj testy używające ProductLookupController, by zależność od serwisu rekomendacji była przekazana do konstruktora.

2.2. Zmodyfikuj ProductLookupController, by zależność od serwisu rekomendacji pochodziła z konstruktora.

2.3. Dostosuj main/src/Application.php, by przekazać zależność do ProductLookupController

2.4. Uruchom pipeline.sh, by mieć pewność, że wszystko jest ok.

2.5. Commit.

Rozwiązanie
<?php

namespace Tbd\Main\Products;

use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;
use Tbd\Main\Recommendations\RecommendationsServiceInterface;

class ProductLookupController
{
    private $repository;
    private ProductLookupDataProviderInterface $dataProvider;

    public function __construct(ProductRepositoryInterface $repository, RecommendationsServiceInterface $recommendationsService)
    {
        $this->repository = $repository;
        $this->dataProvider = new ProductLookupWithRecommendationsDataProvider($recommendationsService);
    }

    public function __invoke(ServerRequestInterface $request)
    {
        $id = $request->getAttribute('id');
        $product = $this->repository->findProduct($id);

        if ($product === null) {
            return Response::plaintext(
                "Product not found\n"
            )->withStatus(Response::STATUS_NOT_FOUND);
        }

        $data = $this->getDataProvider()->getData($product);

        return Response::json($data);
    }

    public function getDataProvider(): ProductLookupDataProviderInterface
    {
       return $this->dataProvider;
    }
}
<?php

namespace Tbd\Main;

use FrameworkX\App;
use FrameworkX\Container;
use React\Http\Message\Response;
use Tbd\Main\FeatureFlags\FeatureFlag;
use Tbd\Main\Products\ProductRepository;
use Tbd\Main\Recommendations\RecommendationsService;

class Application
{
protected App $app;

    public function __construct()
    {
        $diArray = [
            RecommendationsService::class => function(){
                $address = getenv('RECOMMENDATIONS_SERVICE_URL');
                return new RecommendationsService($address);
            },
            Products\ProductsListController::class => function (ProductRepository $repository) {
                return new Products\ProductsListController($repository);
            },
            Products\ProductLookupController::class => function (ProductRepository $repository, RecommendationsService $service) {
                return new Products\ProductLookupController($repository, $service);
            }
        ];

        if(FeatureFlag::isEnabled('create_impression_on_product_lookup')) {
            $diArray[Products\ProductImpressionMiddleware::class] = function (RecommendationsService $service) {
                return new Products\ProductImpressionMiddleware($service);
            };
        }

        $container = new Container($diArray);

        $this->app = new App($container);
        $this->app->get('/products',  Products\ProductsListController::class);
        if(FeatureFlag::isEnabled('create_impression_on_product_lookup')) {
            $this->app->get('/products/{id}', Products\ProductImpressionMiddleware::class, Products\ProductLookupController::class);
        }else{
            $this->app->get('/products/{id}', Products\ProductLookupController::class);
        }

        $this->app->get('/', function () {
            return Response::plaintext(
                "Hello trunk!\n"
            );
        });
    }

    public function run(){
        $this->app->run();
    }

}