SOLID principles in php

SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 4 Принцип за разделяне на интерфейсите – ISP

Част 1 – SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 1 Принцип на единна отговорност

Част 2 – SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 2 Принцип отворено-затворен

Част 3 – SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 3 Принцип на заместване на Лисков

Част 4 – SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 4 Принцип за разделяне на интерфейсите – ISP

Част 5 – SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 5 Принцип на обръщане на зависимостите – DIP

Принципът на разделяне на интерфейса гласи:

Всеки интерфейс трябва да бъде разбит на много на брой малки интерфейси. Тези интерфейси трябва да отговарят за едно-единствено нещо. Нито един клас не трябва да бъде принуждаван да имплементира методи, които няма да ползва никога.

Все още изграждайки от предишния ShapeInterface пример, ще трябва да поддържате новите триизмерни форми на Cuboidи Spheroid, като тези форми също ще трябва да изчислят volume.

Нека помислим какво би се случило, ако промените, за ShapeInterface да добавите друг договор:

interface ShapeInterface
{
    public function area();

    public function volume();
}

Сега всяка форма, която създавате, трябва да приложи volume метода, но знаете, че квадратите са плоски форми и че нямат обеми, така че този интерфейс ще принуди Square класа да приложи метод, който не използва.

Това би нарушило принципа на разделяне на интерфейса. Вместо това можете да създадете друг интерфейс, наречен, ThreeDimensionalShapeInterfaceкойто има volume договора и триизмерните форми могат да реализират този интерфейс:

interface ShapeInterface
{
    public function area();
}

interface ThreeDimensionalShapeInterface
{
    public function volume();
}

class Cuboid implements ShapeInterface, ThreeDimensionalShapeInterface
{
    public function area()
    {
        // calculate the surface area of the cuboid
    }

    public function volume()
    {
        // calculate the volume of the cuboid
    }
}

Това е много по-добър подход, но нещото, за което трябва да внимавате, е когато намеквате тези интерфейси. Вместо да използвате a ShapeInterfaceили a ThreeDimensionalShapeInterface, можете да създадете друг интерфейс, може би ManageShapeInterface, и да го приложите както върху плоски, така и върху триизмерни форми.

По този начин можете да имате един API за управление на формите:

interface ManageShapeInterface
{
    public function calculate();
}

class Square implements ShapeInterface, ManageShapeInterface
{
    public function area()
    {
        // calculate the area of the square
    }

    public function calculate()
    {
        return $this->area();
    }
}

class Cuboid implements ShapeInterface, ThreeDimensionalShapeInterface, ManageShapeInterface
{
    public function area()
    {
        // calculate the surface area of the cuboid
    }

    public function volume()
    {
        // calculate the volume of the cuboid
    }

    public function calculate()
    {
        return $this->area();
    }
}

Сега в AreaCalculatorклас можете да замените извикването на areaметода с calculateи също да проверите дали обектът е екземпляр на, ManageShapeInterfaceа не на ShapeInterface.

Това отговаря на принципа на разделяне на интерфейса.

Вашият коментар