Антишаблони, яких слід уникати у своєму коді

Кожен розробник хоче писати структурований, просто спланований та красиво коментований код. Існує навіть безліч шаблонів дизайну, які дають нам чіткі правила для дотримання та основи, про які слід пам’ятати.

Але ми все ще можемо знайти анти-шаблони в програмному забезпеченні, яке було написане через деякий час або написане занадто швидко.

Нешкідливий базовий хак для швидкого вирішення проблеми може створити прецедент у вашій кодовій базі. Його можна скопіювати в декількох місцях і перетворити на анти-шаблон, на який вам потрібно звернутися.

То що таке анти-шаблон?

У програмному забезпеченні анти-шаблон - це термін, який описує, як НЕ вирішувати повторювані проблеми у коді. Антишаблони вважаються поганим дизайном програмного забезпечення, і, як правило, це неефективні або неясні виправлення.  

Зазвичай вони також додають "технічну заборгованість" - це код, який вам доведеться повернути та правильно виправити пізніше.

Шість анти-шаблонів, які я розгляну в цій статті, - це Кодекс спагетті , Золотий молот , Якір на човні , Мертвий кодекс , Поширення кодексу та Бог-об'єкт .

Код спагетті

Код спагетті - найвідоміший анти-шаблон. Це код з малою до нульовою структурою.

Ніщо не модулізоване. У випадкових каталогах є випадкові файли. Весь потік важко простежити, і він повністю сплутаний (як спагетті).

Зазвичай це проблема, коли хтось не ретельно продумав потік своєї програми заздалегідь і просто розпочав кодування.

Що це робить?! Я не можу стежити за цим

image.png

Це не тільки кошмар технічного обслуговування, але це робить майже неможливим додавання нових функціональних можливостей.

Ви будете постійно розбивати речі, не розуміти масштабів ваших змін або давати якісь точні оцінки своєї роботи, оскільки неможливо передбачити незліченну кількість питань, які виникають при виконанні такої археології / здогадок.

Детальніше ви можете прочитати про анти-шаблон Кодексу спагетті .

Золотий молоток

"Думаю, спокусливо, якщо єдиний у вас інструмент - це молоток, поводитися з усім так, ніби це цвях". Абрахам Маслоу

Уявіть зі мною сценарій: ваша команда розробників дуже, дуже компетентна в новій архітектурі Hammer. Це спрацювало фантастично для всіх ваших минулих наборів питань. Ви є провідною архітектурною командою Hammer у світі.

Але зараз якось все завжди закінчується використанням цієї архітектури. Гвинт із плоскою головкою? Молоток. Хрестоподібний гвинт? Молоток. Вам потрібен гайковий ключ? Ні, ні, забий.

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

Вся ваша програма в кінцевому підсумку може спричинити серйозний хіт, оскільки ви намагаєтесь утрамбувати квадрат у форму кола. Ви знаєте, що кодування та виконання програми з використанням молоткової архітектури для цієї проблеми займає вдвічі більше часу, але це простіше і це те, що вам комфортно.

Це також не дуже передбачувано. Різні мови мають спільне виправлення проблем, з якими вони стикаються, та свої власні стандарти. Ви не можете застосовувати кожне правило, яке добре працювало для вас, однією мовою до іншого, без проблем.

Не нехтуйте послідовним навчанням у своїй кар’єрі. Виберіть правильну мову для своєї проблеми. Подумайте про архітектуру та витягніть зону комфорту. Досліджуйте та досліджуйте нові інструменти та нові шляхи вирішення проблем, з якими ви стикаєтесь.

Детальніше ви можете прочитати про анти-візерунок Golden Hammer .

Якір човна

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

Вони закодували щось дещо із специфікації, і це поки що не потрібно, але вони впевнені, що будуть в наступному місяці. Тому вони не хочуть його видаляти. Надішліть його на виробництво, а пізніше, коли їм це буде потрібно, вони зможуть швидко змусити його працювати.

Але це спричиняє кошмари технічного обслуговування в кодовій базі, яка містить увесь застарілий код. Величезна проблема полягає в тому, що їх колегам буде важко розібратися, який код застарів і не змінює потік, порівняно з кодом, який це робить.

Уявіть, що ви вирішили проблему і відчайдушно намагаєтесь з’ясувати, що відповідає за надсилання реквізитів карток клієнтів до API, щоб зняти кошти з їх банку. Ви можете витратити час на читання та налагодження застарілого коду, навіть не підозрюючи, що навіть не в потрібному місці в кодовій базі.

Останнє питання: застарілий код збільшує час збірки, і ви можете змішати робочий та застарілий код. Ви навіть можете ненароком почати його "вмикати" у виробництві.

Тепер ви, мабуть, можете зрозуміти, чому його називають анкерною схемою для човна - його важко переносити (додає технічний борг), але нічого не робить (буквально, код не має жодної мети, він не працює).

Детальніше ви можете прочитати про антимодель анкера човна .

Мертвий код

Вам коли-небудь доводилося розглядати код, написаний кимось, хто більше не працює у вашій компанії? Існує функція, яка, здається, нічого не робить. Але його кличуть звідусіль! Ви запитуєте, і ніхто інший не впевнений, що робить, але всі надто переживають, щоб видалити це.

Іноді ви бачите, що це робить, але контекст відсутній. Ви вмієте читати і розуміти потік, але чому? Схоже, нам більше не потрібно досягати цієї кінцевої точки. Відповідь - це завжди однакова відповідь для кожного різного користувача.

Це зазвичай називають анти-шаблоном Мертвого коду . Коли ви не можете зрозуміти, який "фактичний" код необхідний для потоку та успішного виконання вашої програми, порівняно з тим, що було потрібно лише 3 роки тому, а не зараз.

Цей конкретний шаблон найчастіше зустрічається в якості підтвердження концепції чи коду дослідження, який закінчився виробництвом.

Одного разу на технічній зустрічі я зустрів хлопця, який мав саме цю проблему. У нього було безліч мертвих кодів, які, як він знав, були мертві, і багато, як він підозрював, були мертві. Але він не зміг отримати дозвіл керівництва на те, щоб коли-небудь видалити весь мертвий код.

Він назвав свій підхід тестуванням на мавпах, де він почав коментувати та відключати речі, щоб побачити, що підірвалось у виробництві. Можливо, трохи занадто ризиковано!

If you don't fancy Monkey testing your production app, try to frame technical debt to management as "technical risk" to better explain why you think it's so important to tidy up.

Or even write down everything your particular module/section does you want to re-write, and take an iterative approach to remove piece by piece the dead code. Checking every time you haven't broken anything.

You don't have to drop a huge rewrite with thousands of changes. But you will either understand why it's so crucial and document why it's needed, or delete the dead code as you desired.

You can read more here about the Dead code anti-pattern.

Proliferation of Code

Objects or modules regularly communicate with others. If you have a clean, modularised codebase you often will need to call into other separate modules and call new functions.

The Proliferation of Code anti-pattern is when you have objects in your codebase that only exist to invoke another more important object. Its purpose is only as a middleman.

This adds an unnecessary level of abstraction (adds something that you have to remember) and serves no purpose, other than to confuse people who need to understand the flow and execution of your codebase.

A simple fix here is to just remove it. Move the responsibility of invoking the object you really want to the calling object.

You can read more here about the Proliferation of Code anti-pattern.

God Object

If everywhere in your codebase needs access to one object, it might be a God object.

God objects do too much. They are responsible for the user id, the transaction id, the customer's first and last name, the total sum of the transaction, the item/s the user is purchasing...you get the picture.

It is sometimes called the Swiss Army Knife anti-pattern because you only really need it to cut some twine, but it also can be a nail file, saw, pair of tweezers, scissors, bottle opener and a cork screw too.

In this instance you need to separate out and modularise your code better.

Programmers often compare this problem to asking for a banana, but receiving a gorilla holding a banana. You got what you asked for, but more than what you need.

The SOLID principles explicitly discuss this in object orientated languages, to help us model our software better (if you don't know what the SOLID principles are, you can read this article).

The S in the acronym stands for Single Responsibility - every class/module/function should have responsibility over one part of the system, not multiple.

You can see this problem over and over again, how about the below interface?

interface Animal { numOfLegs: string; weight: number; engine: string; model: string; sound: string; claws: boolean; wingspan: string; customerId: string; } 

Can you see by even just briefly scanning this interface that the responsibility of this is far too broad, and needs refactoring? Whatever implements this has the potential to be a God object.

How about this?

 interface Animal { numOfLegs: string; weight: number; sound: string; claws: boolean; } interface Car { engine: string; model: string; } interface Bird { wingspan: string; } interface Transaction { customerId: string; } 

Interface segregation will keep your code clear about where the responsibilities lie, and stop forcing classes that only need wingspan to also implement the engine, customerId and model  and so on.

Ви можете прочитати тут більше про анти-шаблон Бога .

Висновок

У будь-якій великій кодовій базі існує постійний баланс між управлінням технічним боргом, початком нової розробки та керуванням чергою помилок для вашого продукту.

Сподіваюся, ця стаття дала вам око для виявлення випадків, коли ви, можливо, спускаєтесь по кролячій норі анти-шаблону, а також деяких інструментів для його чистого вирішення.

Я ділюсь своїми роботами в Twitter, якщо вам сподобалась ця стаття і ви хочете побачити більше.