Чистый PHP код. Переменные.

Принципы разработки программного обеспечения, из книги Роберта К. Мартина «Чистый код», адаптированной для PHP. Это не руководство по стилю. Это руководство по созданию читаемого, многоразового и рефакторируемого программного обеспечения на PHP.

Не каждый принцип должен строго соблюдаться, и еще меньше будет универсальными. Это руководящие принципы и не более того, но они кодифицированы многолетним коллективным опытом авторов Clean Code.

Хотя многие разработчики все еще используют PHP 5, большинство примеров в этой статье работают только с PHP 7.1+.

Используйте значащие и легко читаемые имена переменных

Плохо:

$ymdstr = $moment->format('y-m-d');

Хорошо:

$currentDate = $moment->format('y-m-d');

Используйте тот же словарь для  переменных одного типа

Плохо:

getUserInfo();
getUserData();
getUserRecord();
getUserProfile();

Хорошо:

getUser();

Используйте имена, доступные для поиска (часть 1)

Мы читаем больше кода, чем мы когда-либо напишем. Важно, чтобы код, который мы пишем, был читаем и доступен для поиска. Не указав название для переменных, которые в конечном итоге имеют смысл для понимания нашей программы, мы навредим нашим читателям. Сделайте свои имена доступными для поиска.

Плохо:

// Что означает 448 ?
$result = $serializer->serialize($data, 448);

Хорошо:

$json = $serializer->serialize($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

Используйте имена, доступные для поиска (часть 2)

Плохо:

// Что означает 4 ?
if ($user->access & 4) {
    // ...
}

Хорошо:

class User
{
    const ACCESS_READ = 1;
    const ACCESS_CREATE = 2;
    const ACCESS_UPDATE = 4;
    const ACCESS_DELETE = 8;
}

if ($user->access & User::ACCESS_UPDATE) {
    // ...
}

Используйте поясняющие переменные

Плохо:

$address = 'One Infinite Loop, Cupertino 95014';
$cityZipCodeRegex = '/^[^,]+,\s*(.+?)\s*(\d{5})$/';
preg_match($cityZipCodeRegex, $address, $matches);

saveCityZipCode($matches[1], $matches[2]);

Уже лучше:

Это лучше, но мы все еще сильно зависим от регулярного выражения.

$address = 'One Infinite Loop, Cupertino 95014';
$cityZipCodeRegex = '/^[^,]+,\s*(.+?)\s*(\d{5})$/';
preg_match($cityZipCodeRegex, $address, $matches);

[, $city, $zipCode] = $matches;
saveCityZipCode($city, $zipCode);

Хорошо:

Уменьшите зависимость от регулярного выражения, указав подшаблоны.

$address = 'One Infinite Loop, Cupertino 95014';
$cityZipCodeRegex = '/^[^,]+,\s*(?<city>.+?)\s*(?<zipCode>\d{5})$/';
preg_match($cityZipCodeRegex, $address, $matches);

saveCityZipCode($matches['city'], $matches['zipCode']);

Избегайте большой вложенности и возвращайте как можно раньше (часть 1)

Слишком много if/else  конструкций могут сделать ваш код сложным для понимания. Явное лучше, чем неявное.

Плохо:

function isShopOpen($day): bool
{
    if ($day) {
        if (is_string($day)) {
            $day = strtolower($day);
            if ($day === 'friday') {
                return true;
            } elseif ($day === 'saturday') {
                return true;
            } elseif ($day === 'sunday') {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    } else {
        return false;
    }
}

Хорошо:

function isShopOpen(string $day): bool
{
    if (empty($day)) {
        return false;
    }

    $openingDays = [
        'friday', 'saturday', 'sunday'
    ];

    return in_array(strtolower($day), $openingDays, true);
}

Избегайте большой вложенности и возвращайте как можно раньше (часть 2)

Плохо:

function fibonacci(int $n)
{
    if ($n < 50) {
        if ($n !== 0) {
            if ($n !== 1) {
                return fibonacci($n - 1) + fibonacci($n - 2);
            } else {
                return 1;
            }
        } else {
            return 0;
        }
    } else {
        return 'Not supported';
    }
}

Хорошо:

function fibonacci(int $n): int
{
    if ($n === 0 || $n === 1) {
        return $n;
    }

    if ($n > 50) {
        throw new \Exception('Not supported');
    }

    return fibonacci($n - 1) + fibonacci($n - 2);
}

Избегайте неявного сопоставления

Не заставляйте читателя вашего кода переводить то, что означает переменная. Явное лучше, чем неявное.

Плохо:

$l = ['Austin', 'New York', 'San Francisco'];

for ($i = 0; $i < count($l); $i++) {
    $li = $l[$i];
    doStuff();
    doSomeOtherStuff();
    // ...
    // ...
    // ...
    // Wait, what is `$li` for again?
    dispatch($li);
}

Хорошо:

$locations = ['Austin', 'New York', 'San Francisco'];

foreach ($locations as $location) {
    doStuff();
    doSomeOtherStuff();
    // ...
    // ...
    // ...
    dispatch($location);
}

Не добавляйте ненужный контекст

Если ваше имя класса / объекта что-то означает, не повторяйте это имя в имени переменной.

Плохо:

class Car
{
    public $carMake;
    public $carModel;
    public $carColor;

    //...
}

Хорошо:

class Car
{
    public $make;
    public $model;
    public $color;

    //...
}

Используйте аргументы по умолчанию вместо короткого замыкания или условных обозначений

Не хорошо:

Это не хорошо, потому что $breweryName может быть NULL.

function createMicrobrewery($breweryName = 'Hipster Brew Co.'): void
{
    // ...
}

Не плохо:

Это более понятно, чем предыдущая версия, лучше контролируется значение переменной.

function createMicrobrewery($name = null): void
{
    $breweryName = $name ?: 'Hipster Brew Co.';
    // ...
}

Хорошо:

Если вы поддерживаете только PHP 7+, вы можете использовать подсказку типа и быть уверенным, что $ breweryName не будет NULL.

function createMicrobrewery(string $breweryName = 'Hipster Brew Co.'): void
{
    // ...
}

 

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

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

девятнадцать + двадцать =