Про єнотів та IT


Channel's geo and language: Ukraine, Ukrainian
Category: Technologies


Привіт, мене звати Біпа. Я самостійно вивчаю веб-розробку і ділитимусь тут своїми how-to та цікавинками зі сфери IT та програмування.
Я: @Kurusa

Related channels

Channel's geo and language
Ukraine, Ukrainian
Statistics
Posts filter


💡 Dependency Injection vs Service Locatorстаття від пана Мартіна Фаулера.

- DI — це про передавання залежностей через конструктор, сеттери або інтерфейс. Це дозволяє коду не залежати від конкретної реалізації компонентів.
- Service Locator — інший варіант: спеціальний об’єкт знаходить потрібні сервіси. Але це створює залежність від самого локатора.

DI краще підходить для багаторазового використання компонентів, а локатор простіший для внутрішніх проектів.

Приклад DI через конструктор:
class MovieLister {
private MovieFinder finder;

public MovieLister(MovieFinder finder) {
this.finder = finder;
}
}

А ось Service Locator:
class MovieLister {
MovieFinder finder = ServiceLocator.movieFinder();
}

Фаулер також каже, що DI краще показує залежності класу, оскільки вони явно передаються через конструктор або сеттери, а в Service Locator доводиться шукати ці залежності по всьому коду.


Вебсайт пана Фабіана — то є скарб. Це про розвиток Symfony та розробку загалом. Дуже цікаво спостерігати, як у 2007 році розробники підходили до створення модулів і як тоді виглядав процес дебагінгу.

Натрапила на статтю, де порівнюється продуктивність print та echo за допомогою VLD. Він показує, як вони виконуються на рівні opcodes і розбирає різницю між ними. Виявляється, echo трохи швидший за print, бо останній викликає на один opcode більше (через те, що повертає значення).

Де би ви зараз почули про таке? Про zval-контейнери, opcode'и та подібні дрібні оптимізації. Сьогодні ж просто поставимо Xdebug чи Clockwork і не паримось 😅


💡Стаття нульових від пана Фабіана, засновника Symfony, про використання private/protected: http://fabien.potencier.org/pragmatism-over-theory-protected-vs-private.html

Цікаво, що у Symfony 1 взагалі не використовували private, а у Symfony2 на початку це навіть було заборонено (на рівні код стилю), але з часом, коли почали долучатись нові розробники і кількість думок збільшилась, все ж переважили прихильники private


Привіт привіт, ти часом на ларавелі не пишеш? Натрапила на доку, яка точно стане в нагоді:
https://github.com/alexeymezenin/laravel-best-practices/blob/master/ukrainian.md

Особливо подобається пункт "Використовуйте, де можливо, короткий та читабельний синтаксис"

І у ту ж копілку:
https://github.com/piotrplenik/clean-code-php

#code_style










Общие принципы разработки хорошего кода, а именно про DRY, KISS, YAGNI и почему нельзя возвращать NULL. По-сути, первые 3 говорят говорят про очевидные вещи, но иногда разработчики про них забывают.

DRY
don't repeat yourself
— нарушения принципа DRY называют WET — "Write Everything Twice" или "We enjoy typing"
— не допускай повторяющихся участков кода, на уровне функций, также не допускай классов с повторяющимся функционалом

KISS
keep it simple, stupid или keep it short and simple
— нет смысла реализовать дополнительный функционал, который возможно когда-нибудь пригодится
— бессмысленно делать реализацию сложной бизнес-логики, которая учитывает в себе все возможные варианты
— нет смысла подключать огромную библиотеку, если вам от нее нужна только пара функций
— нужно держать компоненты своей системы (классы, методы) в максимально простом, не осложнённом, не перегруженном состоянии
— перекликается с Single responsibility, Interface Segregation принципами из SOLID

YAGNI
you aren't gonna need it
— прежде чем писать новый компонент/функцию подумай: а нужен/на ли она тебе вообще? Может это можно не делать вообще? Или по крайней мере сделать это изящнее, проще, умнее, в рамках уже существующего/ей компонента/функции, не добавляя лишнего
— заказчик не должен оплачивать то, что он не заказывал
— бесплатных функций в продуктах не бывает
— ненужные новые функции могут впоследствии помешать добавить новые нужные
— новые функции должны быть отлажены, документированы и сопровождаться
— добавление новой функциональности может привести к желанию ещё более новой функциональности, приводя к эффекту "снежного кома"

почему нельзя возвращать NULL
— накладывается неявное ограничение на код, который должен проверять значение на NULL
— обработка ошибок вручную

Мне нравится описание Filip Hanik всех этих принципов:
Разбивайте задачи на подзадачи которые не должны по вашему мнению длиться более 4-12 часов написания кода
Разбивайте задачу на множество более маленьких задач, каждая задача должна решаться одним или парой классов
Сохраняйте ваши методы маленькими. Каждый метод должен состоять не более чем из 30-40 строк. Каждый метод должен решать одну маленькую задачу, а не множество случаев. Если в вашем методе множество условий, разбейте его на несколько. Это повысит читаемость, позволит легче поддерживать код и быстрее находить ошибки в нём. Вы полюбите улучшать код.
Придумайте решение задачи сначала, потом напишите код. Никогда не поступайте иначе. Многие разработчики придумывают решение задачи во время написания кода и в этом нет ничего плохого. Вы можете делать так и при этом придерживаться выше обозначенного правила. Если вы можете в уме разбивать задачу на более мелкие части, когда вы пишете код, делайте это любыми способами. И не бойтесь переписывать код ещё и ещё и ещё… В счёт не идёт число строк, до тех пор пока вы считаете что можно ещё меньше/ещё лучше.
Не бойтесь избавляться от кода. Изменение старого кода и написание нового решения два очень важных момента. Если вы столкнулись с новыми требованиями, или не были оповещены о них ранее, тогда порой лучше придумать новое более изящное решение решающее и старые и новые задачи.


Прочитала про одну кумедну багу (хоча для розробників вона не така вже й кумедна) — якось в Ізраїлі проходили випробування нового процесора для автопілота від фірми Моторолла для винищувачів (так, вони робили не тільки телефони) і все було добре, поки раптово в польоті відбувається загальне скидання процесора, автопілот вимикається на повному ходу, пілоти переходять на ручне керування та садять винищувач. Усі ламають голову, проганяють тест за тестом – на тестовому стенді все добре, у польоті за межами Ізраїлю – все добре, на випробуваннях в Ізраїлі – знову та сама проблема, що була. Нарешті, проаналізувавши кожен рядок коду знайшли у чому була проблема. У обчисленнях автопілота використовувався такий параметр, як висота над рівнем моря. При цьому розробники логічно припустили, що він не може в польоті дорівнювати нулю або менше нуля — автопілот для літака, а не підводного човна. Але є таке унікальне місце на Землі і знаходиться воно в Ізраїлі, де земля знаходиться нижче рівня моря - це Мертве море. Підлітаючи до нього змінна отримувала значення спочатку 0, а потім негативне. Вже при значенні 0 відбувалось ділення на нуль і програмне скидання процесора.




SOLID

Single responsibility
— клас відповідає за одну функцію
— код позбавляється копіпасти (дублікатів)
— при дебагу простіше виправляти помилки, бо немає шматків коду, що повторюються

Нехай у вас є якийсь клас Date, який віддає інформацію про температуру та час. Якщо якийсь Вася хоче отримати інформацію про час, йому доведеться продублювати обидва методи цього класу. Те саме стосується й якогось Андрія, який захоче отримати інформацію про температуру.
————— ————— —————
|DateTemp| копія |Date | копія |DateTime |
—————— ——————
|- temp() | |- time() | |- time() |
—————— |- temp() | ——————
—————
Правильніше буде створити 2 окремі класи, які повертатимуть температуру та час відповідно.

Opened-closed
— клас має бути відкритий для розширення, і закритий для змін
— чому добре дотримуватися цього принципу? якщо у вас був уже протестований шматок коду і ви додаєте новий, не змінюючи поточний, вам не потрібно тестувати старий. швидше за все, у ньому не буде багів

Liskov Substitution
— поведінка спадкових класів не повинна суперечити роботі базових
— підклас не повинен вимагати від коду, що викликає, більше, ніж базовий клас, і не повинен надавати коду, що викликає, менше, ніж базовий клас.
— Там де використовується Child клас, повинен підходити і його Parent

Наприклад, у вас є класи Child та Parent. Неправильною буде наступна реалізація:
— використовуючи Parent, можна викликати будь-який метод, а використовуючи Child потрібні додаткові дії для виклику того ж методу. Наприклад, виклик якогось init()
— якщо метод getMessages() класу Parent повертає колекцію з бази даних, Child не повинен повертати порожній масив або null

Допустимо, у вас є класи Rectangle та Square, який успадковується від першого. Якщо написати тест на Rectangle, який вважатиме площу функцією a*b, виникне помилка, так як у дочірньому класі Square не реалізована сторона b.
——— ————
|Rect | extends | Square |
———








​​Nano в терміналі сказав мені мр-бр-бр)









20 last posts shown.

92

subscribers
Channel statistics