Анти-модели, които трябва да избягвате в кода си

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

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

Безобиден основен хак за бързо разрешаване на проблем може да създаде прецедент във вашата кодова база. Той може да бъде копиран на множество места и да се превърне в анти-шаблон, към който трябва да се обърнете.

И така, какво е анти-модел?

В софтуера анти-шаблонът е термин, който описва как да НЕ се решават повтарящи се проблеми във вашия код. Анти-шаблоните се считат за лош софтуерен дизайн и обикновено са неефективни или неясни поправки.  

Те обикновено добавят и „технически дълг“ - това е код, който трябва да се върнете и поправите правилно по-късно.

Шестте анти-модела, които ще обсъдя в тази статия, са Спагети код , Златен чук , Котва за лодка , Мъртъв код , Разпространение на кода и Бог Обект .

Код за спагети

Кодът за спагети е най-известният анти-модел. Това е код с малка до нулева структура.

Нищо не е модулирано. Има произволни файлове, разпръснати в произволни директории. Целият поток е труден за проследяване и е напълно заплетен (като спагети).

Обикновено това е проблем, при който някой не е обмислил внимателно потока на програмата си предварително и просто е започнал да кодира.

Какво прави?! Не мога да следя това

image.png

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

Постоянно ще разбивате нещата, няма да разберете обхвата на вашите промени или ще дадете точни оценки за работата си, тъй като е невъзможно да се предвидят безбройните проблеми, които се появяват, когато правите такава археология / предположения.

Можете да прочетете повече тук за анти-модела на Спагети код .

Златен чук

„Предполагам, че е изкушаващо, ако единственият инструмент, който имате, е чук, да се отнасяте към всичко, сякаш е пирон.“ Ейбрахам Маслоу

Представете си сценарий с мен: вашият екип за разработчици е много, много компетентен в чисто новата архитектура на Hammer. Работи фантастично за всичките ви минали въпроси. Вие сте водещият световен архитектурен екип на Hammer.

Но сега по някакъв начин всичко винаги завършва с помощта на тази архитектура. Винт с плоска глава? Чук. Винт с глава на Phillips? Чук. Имате нужда от гаечен ключ? Не, не го чукай.

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

Цялата ви програма може в крайна сметка да вземе сериозен хит за изпълнение, защото се опитвате да набиете квадрат в кръгла форма. Знаете, че отнема два пъти повече време за кодиране и за изпълнение на програма, използваща архитектурата на чука за този проблем, но е по- лесно и е това, с което се чувствате добре.

Също така не е много предсказуемо. Различните езици имат общи корекции на проблемите, с които се сблъскват, и собствените си стандарти. Не можете да прилагате всяко правило, което е работило добре за вас на един език, към следващия, без проблеми.

Не пренебрегвайте последователното учене в кариерата си. Изберете правилния език за вашия проблем. Помислете за архитектурата и изтласкайте зоната си на комфорт. Проучете и проучете нови инструменти и нови начини за подход към проблемите, с които се сблъсквате.

Тук можете да прочетете повече за анти-модела Golden Hammer .

Котва за лодка

The Boat Anchor анти-модел е мястото, където програмисти напускат код в програмния код, тъй като те може да се нуждаят от нея по-късно.

Те кодираха нещо малко извън спецификацията и все още не е необходимо, но са сигурни, че ще го направят следващия месец. Така те не искат да го изтрият. Изпратете го до производството и по-късно, когато се нуждаят, те могат бързо да го накарат да работи.

Но това причинява кошмари за поддръжка в кодовата база, която съдържа целия този остарял код. Огромният проблем е, че колегите им трудно ще разберат кой код е остарял и не променя потока, в сравнение с кода, който го прави.

Представете си, че имате актуална корекция и отчаяно се опитвате да разберете какво е отговорно за изпращането на данните за картите на клиентите до API, за да изтеглите средства от тяхната банка. Можете да губите време за четене и отстраняване на грешки на остарял код, без да осъзнавате, че дори не сте на правилното място в кодовата база.

Последният проблем е, че остарелият код удължава времето ви за изграждане и можете да смесвате работещ и остарял код. Можете дори да започнете неволно да го „включите“ в производството.

Вероятно вече можете да разберете защо се нарича анти-шаблон за котва на лодката - той е тежък за носене (добавя технически дълг), но не прави нищо (буквално кодът няма никаква цел, не работи).

Тук можете да прочетете повече за анти-шарката на котвата на лодка .

Мъртъв код

Случвало ли ви се е да разглеждате код, написан от някой, който вече не работи във вашата компания? Има функция, която не изглежда така, сякаш прави нещо. Но се вика отвсякъде! Питате наоколо и никой друг не е съвсем сигурен какво прави, но всички са твърде притеснени да го изтрият.

Понякога можете да видите какво прави, но контекстът липсва. Вие сте в състояние да четете и разбирате потока, но защо? Не изглежда, че вече трябва да ударим тази крайна точка. Отговорът винаги е един и същ отговор за всеки различен потребител.

This is commonly described as the Dead code anti-pattern. When you can't see what is "actual" code necessary to the flow and successful execution of your program, versus what was only needed 3 years ago, and not now.

This particular anti-pattern is more common in proof on concept or research code that ended up in production.

One time at a tech meet up I met a guy who had this exact problem. He had tons of dead code, which he knew was dead, and lots he suspected was dead. But he could not get permission from management to ever remove all the dead code.

He referred to his approach as Monkey testing, where he started to comment out and turn off things to see what blew up in production. Maybe a little too risky!

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, ако сте харесали тази статия и искате да видите повече.