MP - рефакторинг обработки дефолтного товара

This commit is contained in:
poskrobkaA 2024-04-08 16:13:51 +03:00
parent e4946ea50e
commit 50b98c1b98
12 changed files with 306 additions and 65 deletions

5
php/description.txt Normal file
View File

@ -0,0 +1,5 @@
на мой взгляд задача описана не полностью и на реальном проекте я бы такую задачу не брал в работу.
по-моему мнению ее следовало бы дополнительно обсудить с бизнес аналитиком.
как минимум вопросы
- поэтому у него нет срока хранения - что значит нет срока? ноль? если уже какой-то был указан обнулить или просто не учитывать?
- качество увеличивается пропорционально возрасту - тут по идее нужен какой-то коэффицинт пропорционалности

View File

@ -4,6 +4,12 @@ declare(strict_types=1);
namespace GildedRose;
use GildedRose\Handlers\AgedBrieItemHandler;
use GildedRose\Handlers\BackStageItemHandler;
use GildedRose\Handlers\ConjuredItemHandler;
use GildedRose\Handlers\DefaultItemHandler;
use GildedRose\Handlers\SulfarusItemHandler;
final class GildedRose
{
/**
@ -14,7 +20,7 @@ final class GildedRose
) {
}
public function updateQuality(): void
public function updateQuality(): array
{
foreach ($this->items as $item) {
if ($item->name != 'Aged Brie' and $item->name != 'Backstage passes to a TAFKAL80ETC concert') {
@ -63,5 +69,26 @@ final class GildedRose
}
}
}
return $this->items;
}
public function updateQuality1(): array
{
foreach ($this->items as $item) {
$handler = match ($item->name) {
'Aged Brie' => new AgedBrieItemHandler(),
'Sulfuras, Hand of Ragnaros' => new SulfarusItemHandler(),
'Backstage passes to a TAFKAL80ETC concert' => new BackStageItemHandler(),
'Conjured Mana Cake' => new ConjuredItemHandler(),
default => new DefaultItemHandler(),
};
$handler->handle($item);
unset($handler);
}
return $this->items;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace GildedRose\Handlers;
use GildedRose\Item;
class AgedBrieItemHandler implements ItemHandlerInterface
{
public function handle(Item $item): Item
{
$item->sellIn = $this->changeSallIn($item->sellIn);
$item->quality = $this->changeQuality($item->quality, $item->sellIn);
return $item;
}
private function changeQuality(int $quality, int $sallIn): int
{
//Todo добавить реализацию метода
return $quality;
}
private function changeSallIn(int $sallIn): int
{
//Todo добавить реализацию метода
return $sallIn;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace GildedRose\Handlers;
use GildedRose\Item;
class BackStageItemHandler implements ItemHandlerInterface
{
public function handle(Item $item): Item
{
$item->sellIn = $this->changeSallIn($item->sellIn);
$item->quality = $this->changeQuality($item->quality, $item->sellIn);
return $item;
}
private function changeQuality(int $quality, int $sallIn): int
{
//Todo добавить реализацию метода
return $quality;
}
private function changeSallIn(int $sallIn): int
{
//Todo добавить реализацию метода
return $sallIn;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace GildedRose\Handlers;
use GildedRose\Item;
class ConjuredItemHandler implements ItemHandlerInterface
{
public function handle(Item $item): Item
{
$item->sellIn = $this->changeSallIn($item->sellIn);
$item->quality = $this->changeQuality($item->quality, $item->sellIn);
return $item;
}
private function changeQuality(int $quality, int $sallIn): int
{
//Todo добавить реализацию метода
return $quality;
}
private function changeSallIn(int $sallIn): int
{
//Todo добавить реализацию метода
return $sallIn;
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace GildedRose\Handlers;
use GildedRose\Item;
class DefaultItemHandler implements ItemHandlerInterface
{
private const KOEF_DECREASE = 2;
public function handle(Item $item): Item
{
$item->sellIn = $this->changeSallIn($item->sellIn);
$item->quality = $this->changeQuality($item->quality, $item->sellIn);
return $item;
}
private function changeQuality(int $quality, int $sallIn): int
{
if ($quality === 0) {
return 0;
}
if ($sallIn === 0) {
return $quality - self::KOEF_DECREASE;
}
return $quality - 1;
}
private function changeSallIn(int $sallIn): int
{
if ($sallIn === 0) {
return 0;
}
return $sallIn - 1;
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace GildedRose\Handlers;
use GildedRose\Item;
interface ItemHandlerInterface
{
public function handle(Item $item): Item;
}

View File

@ -0,0 +1,28 @@
<?php
namespace GildedRose\Handlers;
use GildedRose\Item;
class SulfarusItemHandler implements ItemHandlerInterface
{
public function handle(Item $item): Item
{
$item->sellIn = $this->changeSallIn($item->sellIn);
$item->quality = $this->changeQuality($item->quality, $item->sellIn);
return $item;
}
private function changeQuality(int $quality, int $sallIn): int
{
//Todo добавить реализацию метода
return $quality;
}
private function changeSallIn(int $sallIn): int
{
//Todo добавить реализацию метода
return $sallIn;
}
}

View File

@ -1,44 +0,0 @@
<?php
declare(strict_types=1);
namespace Tests;
use GildedRose\GildedRose;
use GildedRose\Item;
use PHPUnit\Framework\TestCase;
use ApprovalTests\Approvals;
/**
* This unit test uses [Approvals](https://github.com/approvals/ApprovalTests.php).
*
* There are two test cases here with different styles:
* <li>"foo" is more similar to the unit test from the 'Java' version
* <li>"thirtyDays" is more similar to the TextTest from the 'Java' version
*
* I suggest choosing one style to develop and deleting the other.
*/
class ApprovalTest extends TestCase
{
public function testFoo(): void
{
$items = [new Item('foo', 0, 0)];
$app = new GildedRose($items);
$app->updateQuality();
Approvals::verifyList($items);
}
public function testThirtyDays(): void
{
ob_start();
$argv = ["", "30"];
include(__DIR__.'/../fixtures/texttest_fixture.php');
$output = ob_get_clean();
Approvals::approveString($output);
}
}

View File

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace Tests;
use GildedRose\GildedRose;
use GildedRose\Item;
use PHPUnit\Framework\Assert;
use PHPUnit\Framework\TestCase;
/**
* This unit test uses [Approvals](https://github.com/approvals/ApprovalTests.php).
*
* There are two test cases here with different styles:
* <li>"foo" is more similar to the unit test from the 'Java' version
* <li>"thirtyDays" is more similar to the TextTest from the 'Java' version
*
* I suggest choosing one style to develop and deleting the other.
*/
class DefaultItemTest extends TestCase
{
public function testDefaultChange(): void
{
$items = [new Item('default', 1, 1)];
$app = new GildedRose($items);
$actualAItems = $app->updateQuality();
$itemsExpected = [new Item('default', 0, 0)];
Assert::assertEquals($itemsExpected, $actualAItems);
}
public function testDefaultAfterSallInChange(): void
{
$items = [new Item('default', -1, 6)];
$app = new GildedRose($items);
$actualAItems = $app->updateQuality();
$itemsExpected = [new Item('default', -2, 4)];
Assert::assertEquals($itemsExpected, $actualAItems);
}
public function testDefaulWithZeroSallInChange(): void
{
$items = [new Item('default', 0, 10)];
$app = new GildedRose($items);
$actualAItems = $app->updateQuality();
$itemsExpected = [new Item('default', -1, 8)];
Assert::assertEquals($itemsExpected, $actualAItems);
}
}

View File

@ -1,20 +0,0 @@
<?php
declare(strict_types=1);
namespace Tests;
use GildedRose\GildedRose;
use GildedRose\Item;
use PHPUnit\Framework\TestCase;
class GildedRoseTest extends TestCase
{
public function testFoo(): void
{
$items = [new Item('foo', 0, 0)];
$gildedRose = new GildedRose($items);
$gildedRose->updateQuality();
$this->assertSame('fixme', $items[0]->name);
}
}

View File

@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace Tests\beforeRefactoring;
use GildedRose\GildedRose;
use GildedRose\Item;
use PHPUnit\Framework\Assert;
use PHPUnit\Framework\TestCase;
use ApprovalTests\Approvals;
/**
* This unit test uses [Approvals](https://github.com/approvals/ApprovalTests.php).
*
* There are two test cases here with different styles:
* <li>"foo" is more similar to the unit test from the 'Java' version
* <li>"thirtyDays" is more similar to the TextTest from the 'Java' version
*
* I suggest choosing one style to develop and deleting the other.
*/
class DefaultItemTest extends TestCase
{
public function testDefaultChange(): void
{
$items = [new Item('default', 1, 1)];
$app = new GildedRose($items);
$actualAItems = $app->updateQuality();
$itemsExpected = [new Item('default', 0, 0)];
Assert::assertEquals($itemsExpected, $actualAItems);
}
public function testDefaultAfterSallInChange(): void
{
$items = [new Item('default', -1, 6)];
$app = new GildedRose($items);
$actualAItems = $app->updateQuality();
$itemsExpected = [new Item('default', -2, 4)];
Assert::assertEquals($itemsExpected, $actualAItems);
}
public function testDefaulWithZeroSallInChange(): void
{
$items = [new Item('default', 0, 10)];
$app = new GildedRose($items);
$actualAItems = $app->updateQuality();
$itemsExpected = [new Item('default', -1, 8)];
Assert::assertEquals($itemsExpected, $actualAItems);
}
}