Всем привет! Хочу сразу сказать, что все выводы из этой статьи - квинтэссенция опыта моей инженерной (да и не только) деятельности. За свою трудовую деятельность я успел поработать и слесарем(по разным направлениям), и мастером на заводе, и инженером-проектировщиком в сфере ПГС, и системным-администратором, сейчас вот работаю программистом. Считаю, что многое из статьи применимо в принципе к любой трудовой деятельности и не только технической. Разница только в масштабах. По сути, хочу поделиться опытом, и возможно кто-то возьмет его на вооружение.
В любой работе должна быть система
Именно этому пункту я отвожу центральное место в работе инженера. Именно его больше всего игнорируют большинство тех инженеров, которых я знаю и это большая боль. Для начала хочу донести, что я подразумеваю под системой. Система - это самый крупный узел в проекте, который состоит из дерева более мелких узлов. Здесь важно понять суть - у каждого она может быть своя: у программиста - набор проектов и их взаимосвязи, у конструктора - сборка его 3D-моделей, у мастера на производстве - агрегаты и трубопроводы, находящиеся в его сфере обслуживания. Другими словами - архитектура.
Очень часто можно увидеть отсутствие системы в отсутствии системных решений и правил. Я очень часто наблюдал и наблюдаю точечные решения проблем без разработки системного решения. Как вариант, случай из моей практики. "На крупном заводе функционировала система теплоснабжения. Единая магистраль от которой запитывались все отопительные системы цехов (для тех, кто в теме - зависимая схема подключения). Потом заметили, что в одном из цехов прохладнее, чем нужно. Пошли слесаря, покрутили краны, вроде потеплело. Зато в другом месте на заводе стало холоднее. Разрегулировали. Поставили дроссельные шайбы - не помогло. Так слесаря и ходили из цеха в цех, краны крутили."
Другой пример из IT. Есть такое выражение, "Хороший сисадмин – ленивый сисадмин. Только лень заставит его настроить все раз и навсегда". Всякий раз, когда возникает схожая проблематика, или похожая неисправность, значит вероятно проблема не решена системно. Из IT еще неплохой пример - костыли, быстренько пишешь и задача решается, но... Не системно - локально. Все мы знаем, что происходит дальше - код начинает хромать с нашими костылями. Система сбоит.
В машиностроении та же проблематика. Например у автомобиля, поставленного на серию, постоянно ломается какой-то узел или агрегат. Это также системная ошибка и решать ее нужно переработав конструктив автомобиля, а не чинить в автоцентре каждый экземпляр. Можно было бы рассмотреть и вариант, что это программируемая поломка, но это тема отдельной статьи. При этом архитектура проектов у инженеров-машиностроителей также оставляет желать лучшего - нет четкого разделения по логике, которое в основном заключается в нарушении уровней сборки. Дерево сборок получается неровным.
Разделяй и только тогда будешь властвовать
Любая, даже самая сложная система, состоит из менее крупных узлов. В любом случае должна. Ракету не строят монолитным куском. Вместо этого в ней присутствуют блоки. Как и, к примеру, в автомобиле. Он состоит из следующих систем: кузов, трансмиссия, двигатель, электрика и т.п. То есть вышеперечисленные системы даже проектировать могут и, в большинстве случаев, должны разные люди. В итоге получается своего рода конструктор, который потом нужно просто собрать.
Система может быть очень сложной, но тут нужно определить ее составляющие узлы. Система - является большим узлом, который состоит из других, более мелких, узлов. Эти, более мелкие узлы могут быть также составными узлами или примитивными (неразборными) объектами. То есть большую систему можно и нужно декомпозировать на более мелкие. Если и более мелкие узлы могут быть декомпозированы, то их также стоит раздробить. То есть нужно проектировать иерархию системы. И чем больше эти узлы будут изолированы друг от друга, тем лучше. Например, как вариант решения вышеописанной проблемы в теплоснабжении завода, можно было бы поставить по теплообменнику в каждый цех и регулировать пришлось бы только систему теплоснабжения каждого отдельно взятого цеха, при этом другие участки теплосети не пострадали бы.
В IT - то же самое. На языке разработки ПО это называется "Сильная связность, слабое зацепление." Похоже на GRASP, не так ли? Пилишь немаленький проект и все запихиваешь физически в один файл-проект IDE-шки. Поначалу многие так делают. Зато потом тестировать подобное решение - так себе удовольствие. Разбиваешь на пакеты, где в одном - бизнес-логика, в другом - представление, в третьем - оставшийся кусок используемого паттерна MV*. И уже совершенно другая картина. Согласны? На моей практике, коллеги по цеху долго не могут выполнить подобную декомпозицию. Банально разбить на подпроекты хоть по какому-то признаку. В результате проект становится жутким Legacy. Думаю многим знакомо "Лучше с нуля все переделать".
По итогу мы получаем необходимость в построении дерева, в котором видны четкие зависимости. При этом необходимо все воспринимать именно в масштабе проблемы. Своего рода получается своеобразный механизм отлова ошибок: происходит ошибка/аварийная ситуация/поломка и мы понимаем, что поломалось в определенном узле. Иными словами данную систему легче тестировать. Узлы должны быть изолированы друг от друга и должны быть атомарными. В случае с IT - это называется инкапсуляция. И да, многие знают принципы ООП, но уж очень много специалистов, причем достаточно неплохих, пользуются ими крайне неумело.
Все гениальное просто
Чем проще агрегат, тем меньше шансов его поломать. Не раз слышал от автомобилистов - "там почти ничего нет, потому и ломаться нечему." Если разрабатывается какая-нибудь конструкция, то стоит ее сделать максимально простой. Чем проще конструкция, тем она будет дешевле в обслуживании, тем меньше внимания ей придется уделить, а лишние узлы не будут вводить в заблуждение. Рассмотренная выше система теплоснабжения - один большой сложный узел, которым было тяжело управлять и его регулярно приходилось чинить.
Для начала приведу пример из машиностроения. Открываешь конструкторскую сборку при этом ожидаешь увидеть несколько болтов и гаек, но при этом видишь гремучую смесь узлов, которые вообще должны находится в другом месте в иерархии данного узла. Один элемент соединяется болтом, сопряжения которого выставлены неверно, другой соединяется таким же болтом, но из другого места. Все это взято из разных мест - из сетевой папки, из "Моих документов", а где-то хранится в папке загрузок ибо скачано с noname-сайта.
После того, как проект будет разбит на модули, стоит сделать его максимально понятным для мозгов остальных возможных участников процесса. Лучший вариант, чтобы смог разобраться специалист вашего профиля с минимальным объемом знаний. Мы все чего-то можем не знать. Допустим, вышла какая-то фича у фреймворка или вообще у языка. Не стоит ее применять везде и всюду, если конечно это не дает каких-то неоспоримых преимуществ в виде сокращения строк кода, либо приросте производительности; а доставить коллегам неприятности это вполне может.
По работе мне приходилось сталкиваться с кодом, который был очень "навороченным". В качестве примера - в одном классе могла быть описана бизнес-логика большей части проекта + графическое представление, в другом классе один только список инициализации был из туевой хучи параметров, в третьем сущности почти все enum положены в один файл. Работать с таким кодом - сущий ад. И действительно - легче переписать с нуля, так как по сути получится как в том анекдоте - только что-то рефачишь - а оно фатально ломается и непонятно почему.
В итоге каждый узел должен быть настолько простым, чтобы его можно было переконструировать без фатальных последствий для всей системы. Отчасти здесь просматривается принцип единственной ответственности SOLID.
Чистота залог здоровья
С моей точки зрения, инженер должен действовать аккуратно и расставлять все по полочкам. Тогда и он, и тот, кто придет ему на смену, будут всегда знать, где что лежит. Например у инженера-конструктора все проекты находятся в одном месте, он всегда знает где и что у него лежит, при этом на любой вопрос в его работе он может ответить. У инженера на производстве все эксплуатационные документы хранятся в организованном виде. Если человек работает за компьютером то все его проекты разбиты по строгой иерархии папок, имена файлов осмысленные и пр.
Сколько раз обращал внимание - если бардак на рабочем столе, то значит и в голове у человека бардак. Как правило и на компьютере у него черт ногу сломит. "Системные" решения такой человек принимать, с большой долей вероятности, не может. Все время он будет делать заплатки на уже еле живой конструкции, которая того и гляди развалится при внесении очередных изменений. Все осложняется тем, что такой инженер может не только сам поломать продукт, но и утянуть за собой других, так как другим придется подстраиваться под смежные решения.
Думаю многие лиды (да и не только лиды) понимают, насколько важен чистый код. Самому же потом поддерживать, а ты не только не помнишь как работает какой-то механизм, но и не знаешь, где посмотреть, чтобы разобраться. Пример из практики, не связанной с разработкой ПО: у инженера на столе лежала кипа проектов, заявлений и пр. бумажек. Минут 10 уходило только на то, чтобы найти нужную. При этом после нахождения кипа не разбиралась. На практике в их работе не было системных решений - были только заплатки. Во время работы на заводе мне в этом плане немного повезло - многие задвижки, вентили и рабочий инструмент, когда я пришел, лежали почти что в строгом порядке. Работать было приятнее.
Без бумажки ты - бедняжка
Документация нужна любому инженеру. Составлять документацию не хочется никому. Сколько я видел закатывания глаз от необходимости переделывать документацию из-за того, что что-то в ней не так написано, что были внесены изменения в какой-то проект и да, этот вопрос действительно мучает многих инженеров. Но... Это необходимо. Если не для тебя, то для кого-то другого точно понадобится. По-дефолту человек не обладает такими качествами, как телепатия, поэтому всегда нужно писать как сделать то-то и то-то. Все должно быть прозрачно и ясно. Причем лично для меня в приоритете стоит ясность изложения, нежели соответствие стандартам.
Заодно пару слов о стандартах. Многие стандарты писались, по моему скромному мнению, именно из тех соображений, что должно быть яснопонятно всем. Делай как написано и будет тебе счастье. К примеру, винты делаем только с левой резьбой и только с таким хим.составом. Как-то спорил с одним инженером, который сказал: "Стандарты писали девочки, которые ничего не понимают в технике." Такое было слышать, как минимум, странно. Обычно стандарты рождаются между институтами, ведущими предприятиями промышленности, а потом согласуются этими предприятиями и выпускают эти согласования в бумажном виде, что и является стандартом. То есть они нужны не для того, чтобы насолить студентам инженерных ВУЗов, а для четкого взаимодействия их на практике.
Возможно, кто-то скажет что я сам себе противоречу, но я немного перефразирую высказывание из манифеста гибкой разработки: "Документ, по которому удобно и можно правильно работать, важнее исчерпывающего соответствия стандарту". Как-то слышал байку, что в одном ВУЗе висел плакат, на котором нужно было найти 3 ошибки, чтобы получить автомат по предмету. И каждый из выпусков находил что-то новое. К чему это я? Соответствие стандарту - не самоцель. К примеру есть сборочный чертеж, который дает однозначное представление о выпускаемом изделии. Это значит, что инженер свою задачу выполнил.
Были моменты в моей практике, когда я писал стандарт, по которому в дальнейшем работало предприятие. Это была не самая интересная работа. Но, в тот момент, когда я писал этот стандарт, у меня самого все разложилось по полочкам. В момент изложения мыслей на бумаге начинаешь разговаривать сам с собой видеть мысли четче и более структурированно. Я увидел недостатки, как теории, которую я описываю, так и недостатки своей инженерной работы. Она действительно была где-то сделана по принципу тяп-ляпа. Дописав очередную страницу, я решил, что будет правильнее в некоторых местах переделать свою работу по-человечески.
Используй интерфейс как связь между узлами
Вышеописанное описание стандарта напоминает описание интерфейса. Интерфейс - это своего рода также соответствие стандарту. Порой пройдет достаточно много времени, прежде чем ты понимаешь, как нужно было действительно проектировать интерфейс. С интерфейсами мы сталкиваемся постоянно в реальной жизни. Автомобилист не обязан знать устройство двигателя и уметь в нем ковыряться, если конечно это не вменено ему в обязанность. У него есть интерфейс для вождения - руль, педали, ключ зажигания и пр.
Для того, чтобы у нас узлы могли спокойно между собой взаимодействовать, необходимо тщательно продумывать именно интерфейс взаимодействия. Причем в очень многих случаях он даже важнее внутреннего устройства механизма, пускай и очень сложного. Автомобилист может ехать как на электрокаре, так и на автомобиле с ДВС. Человеку по большей части все равно, что под капотом. Шестеренкам, которые передают крутящий момент тоже. Не все равно только шестеренкам на то, как они получают этот крутящий момент. А вот это и есть очередной интерфейс. Только не для человека, а для механизма. В вышеописанной системе теплоснабжения интерфейсом мог бы стать теплообменник.
Еще одним преимуществом интерфейсов я считаю то, что по сути это как контракт на узел. Он должен быть таким-то, чтобы с ним можно было работать. И тем самым мы даем понять другому инженеру, какую ответную часть и как нужно разрабатывать другому инженеру. Я очень часто наблюдал ситуацию, когда разрабатывалась сложная конструкция, а "интерфейсам" не уделялось должного внимания, будь то программный код, продукция машиностроения или проект жилого дома. Найти общий язык с коллегами при этом достаточно сложно.
95% работы - допиливание 5% проекта или лучшее - враг хорошего
Во всех сферах, в которых успел поработать, всегда находилось "узкое горлышко" в которое непременно нужно было втиснуться. Речь о юзабельности для бизнеса. К сожалению это наш общий бич. Инженеру ПГС нужно так запроектировать, чтобы в теплоузле разместить оборудование, чтобы и доступ был, и не шумно было, и чтобы температура была допустимая, и денег минимум. Программисту - нужно вписаться в дедлайн, реализовать все хотелки заказчика, и производительность чтобы была, и денег минимум. Системному администратору нужно допилить какой-нибудь jabber-клиент, когда уже все остальное готово, подключить почту внешнего сервиса, чтобы были корректными имена сотрудников, и чтобы это ничего не стоило.
По-другому можно перефразировать все вышеописанное как впихнуть невпихуемое. И так будет всегда. Ужать захотят всегда, в первую очередь по деньгам, затем "по конструкции", поэтому теперь я всегда пытаюсь проектировать так, чтобы было недолго исправлять. Придется всегда делать лучше. Но оно того стоит. Ведь когда-то отказались в автомобилях от запуска с помощью заводной рукоятки в пользу стартера. Автомобилистам это было нужно. Можете представить, чтобы сейчас стали выпускать такие автомобили с рукояткой вместо стартера? Пускай даже автомобили будут неплохими, их вряд ли будут покупать. Почему? Просто уже неудобно будет пользоваться в сравнении с другими автомобилями.
В данном случае речь идет о том, чтобы сделать проект лучше, удобнее, так чтобы голова у конечного потребителя не болела ни о чем, касаемо Вашей работы. Но тут нужно соблюсти очень тонкую грань между хотелками потребителя - "хочу, потому что я дурачок" и "хочу, потому что действительно нужно". Тут уже нужно экспертное мнение и только оно. И да, эксперта найти нелегко.
Вместо заключения
По большей части данный момент олицетворяет мои фантазии, как инженера. На мой взгляд на данный момент инженерам не хватает инструментов "оркестрирования" их системами. Есть, правда, зачатки данных систем: у разработчиков ПО - это UML-кодогенераторы; у инженеров-проектировщиков ПГС - это BIM, у инженеров-проектировщиков в машиностроении PLM-системы. К сожалению многие из этих "продуктов" очень медленно развиваются, хотя потенциал у них больше, чем даже думают их создатели и их очень не хватает инженерам "высокого уровня".
Но это происходит по той причине, что конечные пользователи "не умеют их готовить" и, как причина следствие "продукт" не развивается из-за отсутствия фидбека. Из своих нынешних коллег кодогенератор использую только я. Остальные UML рисуют на бумажке, которую потом просто выбрасывают. Следующему разработчику, которому отдают проект, приходится вникать во многие детали и, если проект большой, общую картину он увидит не скоро. А ведь UML более нагляден, нежели банальное чтение кода. Даже для тех, кто далек от разработки. И как плюшки - часто дает возможность для самодокументирования кода.
PLM-системы дают возможность не только хранить как в файлопомойке общем хранилище инженерных изделий, они также могут вытягивать информацию для менеджмента (опять же своего рода самодокументирование). Но главное - у нас появляется возможность оркестрировать сборками "верхнего уровня" в некой виртуальной среде, повторно использовать разработанные на других проектах узлы. Наблюдая за сборками конструктора-джуна в PLM системах, могу сказать, что для него это действительно просто хранилище несвязных данных. В худшем случае на практике это касается и конструктора-сеньора.
Своего рода при присутствии недостающего определенного функционала у вышеуказанных систем можно не спускаться до узлов более низкого уровня. Тут мы абстрагируемся настолько, насколько возможно. Своего рода это проектирование "сверху вниз". Мы должны описать своего рода контракт. Инженер, который будет проектировать узел более низкого уровня, будет ограничен в своей рукожопости данными необходимыми для разработки. Хотелось бы видеть больше абстракции в подобных продуктах, где у архитектора системы нет необходимости(или возможности) вникать в детали проектируемых абстракций.
Пускай пока подобных инструментов даже не предвидится в будущем (хотя потенциал есть), хотелось бы видеть в мышлении рядового инженера больше абстракций. Ну или хотя бы, чтобы он к этому стремился - не боялся разделять сложную систему и принимать системные решения. Если в работе много технически-сложных вопросов, то стоит посидеть, пораскидать на бумажке, банально порассуждать наедине с самим собой. И не бойся ошибиться - не ошибается только тот, кто не работает.
Чуть не забыл - да начнется срач ;)
UPD.
В ЛС и комментариях указали, что вышеописанное напоминает системное мышление. Поэтому даю ссылку, автора которой мне подсказали.