portaldacalheta.pt
  • Основен
  • Управление На Проекти
  • Дизайн На Марката
  • Процес На Проектиране
  • Начин На Живот
Управление На Проекти

Създаване на наистина модулен код без зависимости



Разработката на софтуер е страхотна, но ... Мисля, че всички можем да се съгласим, че това може да бъде емоционално влакче. В началото всичко е страхотно. Добавяйте нови функции една след друга за броени дни, ако не и часове. Вие сте в щастие!

Бързо напред няколко месеца и скоростта на вашето развитие се забавя. Дали защото не работите толкова усилено, колкото преди? Не точно. Превъртете напред още няколко месеца и скоростта на вашето развитие ще се забави още повече. Работата по този проект вече не е забавна и се превърна в плъзгане.



Абстрактно представяне на модулен кодов дизайн



Но става по-лошо. Започвате да откривате множество грешки във вашето приложение. Често решаването на една грешка създава две нови. На този етап можете да започнете да пеете:



99 малки грешки в кода. 99 малки грешки. Вземете един, поставете лепенка върху него,

... 127 малки грешки в кода.



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

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



Причини, поради които разработването на софтуер се забавя с времето

И така, каква е причината за този проблем?

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



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

Голямата кална топка и как да я намалим

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



И така, какъв точно е този антипатерн? Просто казано, получавате голяма топка глина, когато всеки елемент има зависимост от други предмети. По-долу можете да видите графика на зависимостите на популярния проект с отворен код Apache Hadoop. За да визуализирате голямата топка глина (или по-скоро голямата топка прежда), нарисувайте кръг и поставете класовете по проекта равномерно в него. Просто начертайте линия между всяка двойка класове, които зависят един от друг. Сега можете да видите източника на проблемите си.

javascript преобразува низ във време

Визуализация на



'Голямата топка кал' на Apache Hadoop

Модулно кодово решение

Затова си зададох въпрос: би ли било възможно да се намали сложността и все пак да се забавлявам като в началото на проекта? Честно казано, не можете да изтриете всички сложността. Ако искате да добавите нови функции, винаги ще трябва да увеличавате сложността на кода си. Сложността обаче може да се движи и разпространява.

Как други отрасли решават този проблем

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

Техническа схема на механизъм и как частите му се напасват

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

Можем ли да повторим това в софтуерната индустрия?

Ние със сигурност можем! Чрез използване на интерфейси и обръщане на принципа на управление; най-добрата част е фактът, че този подход може да се използва във всеки обектно-ориентиран език: Java, C #, Swift, TypeScript, JavaScript, PHP - списъкът продължава и продължава. За да приложите този метод, не ви е необходима изискана рамка. Просто трябва да се придържате към няколко прости правила и да останете дисциплинирани.

Инверсията на контрола е вашият приятел

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

Нека да видим в прост пример как можем да отделим нашата система, за да създадем модулен код. Следните диаграми са внедрени като прости Java приложения. Можете да ги намерите в това Хранилище на GitHub .

проблем

Да предположим, че имаме много просто приложение, състоящо се само от един клас Main, три услуги и един клас Util. Тези елементи зависят един от друг по множество начини. По-долу можете да видите изпълнение, използващо подхода „голяма топка кал“. Класовете просто се обаждат един на друг. Те са тясно свързани и не можете просто да извадите един елемент, без да докоснете останалите. Приложенията, създадени в този стил, ви позволяват първоначално да растете бързо. Мисля, че този стил е подходящ за проекти с доказателство за концепция, тъй като можете да играете с лекота. Той обаче не е подходящ за готови за производство решения, защото дори поддръжката може да бъде опасна и всяка промяна може да създаде непредсказуеми грешки. Диаграмата по-долу показва тази голяма топка глинена архитектура.

Една проста диаграма на стилова архитектура

Защо инжекцията на зависимостта направи всичко погрешно?

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

Диаграма за инжектиране на зависимост, добавена към голямото топче кал

Единствената разлика между текущата ситуация и голяма топка кал е фактът, че сега, вместо да извикваме класове директно, ние ги извикваме през техните интерфейси. Подобрява леко разделящите елементи един от друг. Ако например искате да използвате повторно Servicio A В различен проект можете да направите това, като извадите Servicio A, заедно с Interfaz A, както и Interfaz B и Interface Útil. Както можете да видите, Servicio A все още зависи от други елементи. В резултат на това все още имаме проблеми с промяната на кода на едно място и объркване на поведението на друго. Все още създава проблема, че ако модифицирате Servicio B e Interfaz B, ще трябва да промените всички елементи, които зависят от него. Този подход не решава нищо; по мое мнение той просто добавя интерфейсен слой върху елементите. Никога не трябва да инжектирате зависимости, а по-скоро да се отървете от тях веднъж завинаги. Ура за независимост!

Решението за модулен код

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

Диаграма на приложението, модифицирана да използва архитектурата на елемента

Имайте предвид, че в тази архитектура само класът Main има множество зависимости. Свържете всички елементи и капсулирайте бизнес логиката на приложението.

Услугите, от друга страна, са напълно независими елементи. Сега можете да извадите всяка услуга от това приложение и да я използвате другаде. Те не зависят от нищо друго. Но изчакайте, става по-добре: вече не е необходимо да променяте тези услуги, стига да не променяте поведението им. Докато тези услуги правят това, което трябва да правят, те могат да останат непокътнати до края на времето. Те могат да бъдат създадени от a професионален софтуерен инженер , или кодер за първи път, ангажиран с най-лошия код за спагети, който някой някога е приготвял с изявления на goto смесени. Няма значение, защото вашата логика е капсулирана. Колкото и да е ужасно, никога няма да се разпространи в други класове. Това ви дава също така силата да разделите работата по даден проект между множество разработчици, където всеки разработчик може да работи самостоятелно върху своя компонент, без да е необходимо да прекъсва друг или дори да знае за други разработчици.

И накрая, можете да започнете да пишете независим код още веднъж, точно както в началото на последния си проект.

Модел на елемента

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

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

Диаграма с един елемент и неговия слушател в приложение

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

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

Проста диаграма на по-сложен елемент

Нека да разгледаме един прост пример за „Hello World“, създаден в Java.

public class Main { interface ElementListener { void printOutput(String message); } static class Element { private ElementListener listener; public Element(ElementListener listener) { this.listener = listener; } public void sayHello() { String message = 'Hello World of Elements!'; this.listener.printOutput(message); } } static class App { public App() { } public void start() { // Build listener ElementListener elementListener = message -> System.out.println(message); // Assemble element Element element = new Element(elementListener); element.sayHello(); } } public static void main(String[] args) { App app = new App(); app.start(); } }

Първоначално дефинираме ElementListener за да зададете метода, който отпечатва изхода. Самият елемент е дефиниран по-долу. Обажда се sayHello върху елемента, просто отпечатайте съобщение, използвайки ElementListener. Имайте предвид, че елементът е напълно независим от изпълнението на метода printOutput Той може да бъде отпечатан на конзолата, физически принтер или изискан потребителски интерфейс. Елементът не зависи от това изпълнение. Поради тази абстракция този елемент може лесно да бъде използван повторно в различни приложения.

Сега погледнете основния клас на App. Внедрете слушателя и съберете елемента заедно с конкретното изпълнение. Сега можем да започнем да го използваме.

Можете също да стартирате този пример в JavaScript тук

Архитектура на елементите

Нека да разгледаме използването на модела на елемента в мащабни приложения. Едно е да го покажете в малък проект; друго е да го приложите в реалния свят.

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

src ├── client │ ├── app │ └── elements │ └── server ├── app └── elements

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

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

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

Практически примери

Ако вярваме, че практиката винаги надделява над теорията, нека разгледаме пример от реалния живот, създаден в Node.js и TypeScript.

Примери от реалния живот

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

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

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

Развивайте се по-бързо, използвайте по-често!

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

  • Много проблеми възникват в софтуера поради зависимости между различни компоненти.

  • Като направите промяна на едно място, можете да въведете непредсказуемо поведение на друго място.

Трите общи архитектурни подхода са:

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

  • Инжектиране на зависимост. Това е половин решение, което трябва да избягвате.

  • Архитектура на елементите. Това решение ви позволява да създавате независими компоненти и да ги използвате повторно в други проекти. Поддържа се и е брилянтен за стабилни производствени версии.

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

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

Сега можете да започнете да създавате и споделяте свои собствени елементи. В дългосрочен план това ще ви помогне да създадете продукти, които са лесни за поддръжка. Успех и ме уведомете какво сте създали!

Също така, ако откриете, че преждевременно оптимизирате кода си, прочетете _ Как да избегнем проклятието на преждевременната оптимизация_ от моя партньор от ApeeScape, Кевин Блок.

Започнете с разработката на IoT: Урок за ESP8266 Arduino

Технология

Започнете с разработката на IoT: Урок за ESP8266 Arduino
AI Investment Primer: Полагане на основите (Част I)

AI Investment Primer: Полагане на основите (Част I)

Финансови Процеси

Популярни Публикации
Изцеление на скъсани вериги за доставки: производство извън Китай
Изцеление на скъсани вериги за доставки: производство извън Китай
Включете Angular 2: Надстройка от 1.5
Включете Angular 2: Надстройка от 1.5
Урок за работен поток за проектиране за разработчици: Осигурете по-добър UI / UX навреме
Урок за работен поток за проектиране за разработчици: Осигурете по-добър UI / UX навреме
PHP Frameworks: Избор между Symfony и Laravel
PHP Frameworks: Избор между Symfony и Laravel
Шевморфизъм, плосък дизайн и възходът на типографския дизайн
Шевморфизъм, плосък дизайн и възходът на типографския дизайн
 
.NET Core - да станем диви и с отворен код. Microsoft, какво ти отне толкова време ?!
.NET Core - да станем диви и с отворен код. Microsoft, какво ти отне толкова време ?!
Крайно ръководство за езика за обработка, част I: Основите
Крайно ръководство за езика за обработка, част I: Основите
Ractive.js - Уеб приложения, направени лесно
Ractive.js - Уеб приложения, направени лесно
Защо има толкова много Pythons?
Защо има толкова много Pythons?
Съвети и инструменти за оптимизиране на приложения за Android
Съвети и инструменти за оптимизиране на приложения за Android
Популярни Публикации
  • бъдещо използване на виртуалната реалност
  • когато обектът е предназначен да задава и управлява свойства, къде трябва да се съхраняват тези свойства?
  • какво прави node js
  • един от принципите на дизайна, следван от художника по оформление, е, че:
  • как да компилирам c++ код
  • Статистика за членство във фитнес залата по месеци
Категории
  • Управление На Проекти
  • Дизайн На Марката
  • Процес На Проектиране
  • Начин На Живот
  • © 2022 | Всички Права Запазени

    portaldacalheta.pt