Оператор switch снижает адаптируемость функции

Ниже вы можете увидеть класс и функцию. Класс – это просто фиктивная сущность. У функции есть оператор switch. Этот оператор switch вычисляет налог по заранее определенной жестко заданной строке, и мне это не нравится.

Сущность класса:

class Product {
    private int $id;
    private string $name;
    private int $price;
    private string $category;
    
    public function __construct(int $id, string $name, int $price, string $category) {
        $this->id = $id;
        $this->name = $name;
        $this->price = $price;
        $this->category = $category;
    }
    public function getId(): int
    {
        return $this->id;
    }
    public function getName(): string
    {
        return $this->name;
    }
    public function getPrice(): int
    {
        return $this->price;
    }
    public function getCategory(): string
    {
        return $this->category;
    }
}

Клиентский код:

//$product = new Product(200, 'Bread', 200, 'Food'); // A different product category
$product = new Product(100, 'Chair', 5000, 'Furniture');

$taxForChair = calculateTax($product);
var_dump($taxForChair); // float 1050
exit;

function calculateTax(Product $product): float {
    // The switch statement below decreases adaptablity.
    // At this point, it has 2 cases. 
    // When the Business Rule change by create a new product category, then this function needs to change too.
    switch($product->getCategory()) {
        case 'Furniture':
            $tax = $product->getPrice() / 100 * 21; 
            break;
        case 'Food':
            $tax = $product->getPrice() / 100 * 9; 
            break;
        default:
            $tax = 0;
            break;
    }
    
    return (float)$tax;
}

Будьте добры и лучше напишите calculateTax функция?

1 ответ
1

Я исправил это сам, представив абстрактные классы, см. Ниже:

class Product {
    private int $id;
    private string $name;
    private int $price;
    private Category $category;
    
    public function __construct(int $id, string $name, int $price, Category $category) {
        $this->id = $id;
        $this->name = $name;
        $this->price = $price;
        $this->category = $category;
    }
    public function getId(): int
    {
        return $this->id;
    }
    public function getName(): string
    {
        return $this->name;
    }
    public function getPrice(): int
    {
        return $this->price;
    }
    public function getCategory(): Category
    {
        return $this->category;
    }
}

вот оно

abstract class Category { 
    abstract public function calculateTax(int $price): float;
}
class CategoryFurniture extends Category {
    public function calculateTax(int $price): float {
        return (float)($price / 100 * 21);
    }
}
class CategoryFood extends Category {
    public function calculateTax(int $price): float {
        return (float)($price / 100 * 9);
    }
}

//$product = new Product(200, 'Bread', 200, new CategoryFood); 
$product = new Product(100, 'Chair', 5000, new CategoryFurniture);

$taxForChair = calculateTax($product);
var_dump($taxForChair); // float 1050
exit;

function calculateTax(Product $product): float {
    
    $price = $product->getPrice();
    
    $category = $product->getCategory();
    return $category->calculateTax($price);
}

  • Поскольку налог рассчитывается по той же формуле, я бы предпочел хранить фактические значения в база данных. Таким образом, вам вообще не придется редактировать код.

    – Ваш здравый смысл

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *