Обновить
17.8

Проектирование и рефакторинг *

Реорганизация кода

Сначала показывать
Порог рейтинга
Уровень сложности

О дизайне. Часть 2. Практические примеры

Время на прочтение8 мин
Количество просмотров3.2K
Как мы обсудили в прошлый раз, дизайн штука не простая; постоянно приходится держать в голове кучу всяких вариантов и стараться найти компромисс среди множества разных требований, раздирающих ваше элегантное решение на части. С одной стороны, хочется, чтобы решение было простым в сопровождении, хорошо расширяемым, с высокой производительностью, при этом оно должно быть понятным не только его автору, но еще как минимум одному человеку; хочется, чтобы решение ело мало памяти и не нарушало ни одного из 100 500 принципов ООП, ну и, самое главное, мы хотим его закончить хотя бы в этом году, хотя менеджер постоянно твердит, что оно должно было быть готово еще месяц назад.

Многие из названных критериев являются не очень совместимыми друг с другом, поэтому рано или поздно мы приходим к выводу, что хороший дизайн – он как уж, который старается протиснуться между десятков противоречивых требований, и найти разумный компромисс, максимально удовлетворяющий наиболее весомым требованиям, не забывая, что вес этих требований может еще и меняться с течением времени.
Читать дальше →

О дизайне

Время на прочтение5 мин
Количество просмотров3.9K
Большинство разработчиков даже с маломальским опытом сталкиваются с проблемами дизайна своего решения, когда поставленную задачу можно решить десятком разных способов и нужно выбрать определенный, более или менее адекватный вариант.

Отношение к этапу проектирования (дизайна) может быть самым разным, начиная от подхода, принятого на ранних этапах развития методологии XP, когда считалось, что дизайн и архитектура – это динозавры, которым нет места в динамично развивающемся мире agile разработки. Многие и сейчас не задумываются о дизайне решения, считая, что итеративный процесс разработки + рефакторинг сделают все за нас и хороший дизайн появится сам собой.

Есть и другая крайность, когда команда можем потратить недели в поисках идеального решения (Святого Грааля архитектора), когда дизайн будет способен «расширяться» во всех возможных направлениях, и быть настолько «гибким», что реализовать его не будет никакой возможности.
Читать дальше →

Другой взгляд на эволюцию гадкого утёнка или рефакторинг спагетти

Время на прочтение6 мин
Количество просмотров2.6K
Я с большим энтузиазмом отношусь к любым попыткам улучшить общую культуру разработки в таком неоднозначном сообществе, как сообщество PHP-разработчиков. Но видя некоторые инициативы хочется убиться об стену их немного поправить, чтобы не дай бог не пришлось работать с кодом, сильно отличающимся от моих представлений о совершенном коде.

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

Собственно мой вариант

Из гадкого утёнка в лебедя, или как исправить криворукий код

Время на прочтение4 мин
Количество просмотров1.8K
image

О чём это?


Многие начинают писать проект для работы с 1 малой задачей, не подразумевая, что данная история приведёт к многопользовательской системе управления, ну допустим, контентом или упаси, производством. И всё вроде здорово и классно, всё работает, пока не начинаешь понимать, что тот код, который написан — состоит целиком и полностью из костылей и хардкода.
Читать дальше →

Введение в CQRS + Event Sourcing: Часть 1. Основы

Время на прочтение8 мин
Количество просмотров188K
В первый раз я услышал о CQRS, когда устроился на новую работу. В компании, в которой работаю и по сей день, мне сразу сказали что на проекте, над которым я буду работать используется CQRS, Event Sourcing, и MongoDB в качестве базы данных. Из этого всего я слышал только о MongoDB. Попытавшись вникнуть в CQRS, я не сразу понял все тонкости данного подхода, но почему-то мне понравилась идея разделения модели взаимодействия с данными на две — read и write. Возможно потому что она как-то перекликалась с парадигмой программирования “разделение обязанностей”, возможно потому что была очень в духе DDD.

Вообще многие говорят о CQRS как о паттерне проектирования. На мой взгляд он слишком сильно влияет на общую архитектуру приложения, что бы называться просто “паттерном проектирования”, поэтому я предпочитаю называть его принципом или подходом. Использование CQRS проникает почти во все уголки приложения.

Сразу хочу уточнить что я работал только со связкой CQRS + Event Sourcing, и никогда не пробовал просто CQRS, так как мне кажется что без Event Sourcing он теряет очень много бенефитов. В качестве CQRS фреймворка я буду использовать наш корпоративный Paralect.Domain. Он чем-то лучше других, чем то хуже. В любом случае советую вам ознакомиться и с остальными. Я здесь упомяну только несколько фреймворков для .NET. Наиболее популярные это NCQRS, Lokad CQRS, SimpleCQRS. Так же можете посмотреть на Event Store Джонатана Оливера с поддержкой огромного количества различных баз данных.

Начнем с CQRS


Что же такое CQRS?
CQRS расшифровывается как Command Query Responsibility Segregation (разделение ответственности на команды и запросы). Это паттерн проектирования, о котором я впервые услышал от Грега Янга (Greg Young). В его основе лежит простое понятие, что вы можете использовать разные модели для обновления и чтения информации. Однако это простое понятие ведет к серьёзным последствиям в проектировании информационных систем. (с) Мартин Фаулер
Читать дальше →

FuckItJS: принудительное исполнение JavaScript-кода

Время на прочтение1 мин
Количество просмотров2.2K
Американский веб-разработчик Мэтт Даймонд (Matt Diamond) написал библиотеку JavaScript под названием FuckItJS. Если вставить в код метод FuckIt, то он заставит исполняться самый плохой скрипт, «нравится это компилятору или нет».

В общем, FuckItJS работает так: из скрипта вырезаются все строчки, на которые выскочили ошибки. Процесс повторяется, пока скрипт (или что там от него осталось) не проходит компиляцию без ошибок. Чтобы выжить в этом жестоком мире, FuckItJS перезагружается после каждой итерации.
Читать дальше →

Контракты vs Юнит тесты

Время на прочтение5 мин
Количество просмотров7.9K
DISCLAIMER: Эта заметка подразумевает наличие у читателя базовых знаний о юнит тестах, в чем автор этих строк не сомневается, а также базовых знаний о проектирование по контракту, которые можно пополнить начиная отсюда.

На одном из выступлений, посвященных проектированию по контракту, один из моих коллег задал вполне резонный вопрос о связи контрактов и юнит тестов. Постусловия в контракте класса, как и юнит тесты говорят о гарантиях класса перед его клиентами, а поскольку юнит тесты являются в этом вопросе более мощным механизмом (сложные постусловия выразить в виде контрактов не всегда просто, а иногда и невозможно), то возникает вопрос о необходимости постусловий.

Итак, давайте вкратце рассмотрим, в каком именно месте находится пересечение контрактов и юнит тестов, и постараемся ответить на вопрос: являются ли постусловия избыточными при наличии юнит тестов?

Читать дальше →

Как реанимировать ваш PHP-проект с помощью Symfony2 компонентов

Время на прочтение7 мин
Количество просмотров10K
Данный пост является переводом не статьи, как принято, а доклада+презентации, поэтому текст поста достаточно вольный.

Думаю, всем хорошо известно и очевидно, что PHP — один из самых популярных языков программирования, на котором написано множество веб-проектов, начиная с персональных homepage-страниц и заканчивая мастодонтами типа Facebook, Vimeo, WordPress и даже YouPorn.

PHP появился в 1995 году, при этом полноценная поддержка ООП была реализована только в PHP5, который вышел в 2005 году. За это время было написано большое количество кода, как хорошего, так и плохого, а точнее сказать сильно устаревшего и тяжело сопровождаемого.

Многие проекты, как и экосистема PHP в целом, к настоящему моменту стали представлять подобие оживленного городского квартала.

Читать дальше →

Три ключевых принципа ПО, которые вы должны понимать

Время на прочтение13 мин
Количество просмотров243K

Разрабатывая приложения, мы постоянно сталкиваемся с новыми подходами, языками и концептами. И постоянно мы мечемся в сомнениях «смогу ли я быть на волне, оставаться конкурентоспособным, учитывая все изменения и тренды?». Давайте задумаемся на мгновение, вспомнив фразу из моего любимого фильма «Касабланка» — в любви законов новых нет — так создан свет.

Все, что касается любви, применимо и к коду. Новых законов в коде нет. Если вы четко понимаете основные идеи разработки, вы способны максимально быстро адаптироваться к новым подходам. В этой статье я расскажу вам о трех основных принципах, которые, наряду с другими, позволяют регулировать сложность разработки. Я поделюсь своим видением вопроса, которое, надеюсь, поможет вам в повседневной работе.
Читать дальше →

Жизнь без объектов

Время на прочтение5 мин
Количество просмотров21K
(Перевод)

Последние несколько лет я провел в изучении и экспериментах со многими языками программирования. В частности, я начал использовать Scala как основной язык, стараюсь использовать функциональный стиль везде где это возможно. Меня также весьма заинтересовал Haskell (чистый функциональный язык) и Clojure (современный диалект Лиспа).

Таким образом, я постепенно отказываюсь от объектно-ориентированной парадигмы, несмотря на то, что использовал в основном её последние 17 лет моей профессиональной деятельности. У меня появляется чувство, что объекты это то, что мешает нам писать лапидарный, структурированный и повторно используемый код.
Читать дальше →

А как выглядит ваш прикладной код?

Время на прочтение3 мин
Количество просмотров3.1K
При разработке платформы я считаю крайне важным уделять особое внимание простоте, понятности и удобстве работы с прикладным кодом. Испробовав разные подходы, я хочу поделиться удобными рецептами из своего опыта.

Под прикладным кодом имеется в виду код, относящийся непосредственно к бизнес-логике конкретного приложения, при этом, в отличии от ядра (framework-а, платформы) такой код максимально подвержен изменениям и в крупных проектах может составлять львиную долю проекта. От удобства прикладного разработчика зависит скорость и качество разработки самым существенным образом.

Например на языке Brainfuck Hello world выглядит так:
image
А вот наши критерии удобства:
  • Строгая статическая типизация
  • Документированность
  • Отсутствие “мусора”
  • Однотипность
  • Лаконичность

И вот как мы их достигаем: код на C#

Правила разработки сложных систем. История одного проекта

Время на прочтение8 мин
Количество просмотров18K
Привет, Хабр. Меня зовут Александр. И я хочу поделится своей историей работы над одним крупным и сложным проектом.

В этой статье не будет кода и схем, в ней будет только история создания «от и до» самого проекта. Думаю, многим будет интересна данная статья. Итак, поехали!

Начало


Все началось летом 2011. На тот момент я был 3 года чистокровным фрилансером. То есть моя работа — это фриланс. Работал и работаю до сих пор только с западными заказчиками. Основная специализация — разработка проектов связанных с распознаванием образов, текста и т.д.

Все началось с того, что я, как всегда, с утра проверял почту, чистил спам, занимался рутинной работой. Обычно я не смотрю, что у меня в спаме, но тут я увидел письмо, с вполне реального адреса. Я открыл письмо, в котором одна компания искала программиста для допиливания крупного западного проекта. Причем эта компания требовала программиста именно из моего города и обязательно с опытом работы в области распознавания. Я ради любопытства ответил на это письмо. Буквально через час мне пришел ответ. А через два мы уже созвонились с менеджером проекта. Поначалу мне показалось, что ничего сложного в доработке нет, обычный набор функционала. После непродолжительного разговора с менеджером я огласил свой прайс, то есть ставку в час. И на этом мы попрощались. На следующий день мне сказали, что согласны на мой ценник и дали тестовое задание. Я его успешно выполнил в течении часа, и мы двинулись дальше. А здесь начинается самое интересное. Во-первых, меня пригласили в офис для того, чтобы подписать договор о неразглашении (Non-Disclosure Agreement). Во-вторых, и это логично, исходники проекта мне обещали отдать только после подписания договора. Если честно, меня это смутило, не знаю даже почему. И интуиция меня не подвела. Я потребовал хотя бы часть исходного кода, чтобы оценить сложность работы и попросил рассказать подробнее о проекте. Как оказалось проект на тот момент велся уже три года и я был 4 (!) исполнителем. До меня работала американская компания, потом индусы, потом компания, которая наняла меня, пыталась реализовать проект силами одной девочки-программиста, а потом это все чудо предложили разгребать мне. Меня это не просто удивило, а очень насторожило. Потом я узнал множество удивительных вещей, например о том, что заказчик 2 года не видел программу, а видел только скриншоты, а индусы кормили обещаниями этого заказчика. У меня не укладывалось в голове, как такое можно реализовать. Менеджеру индусов надо дать медаль «За находчивость».

После того как я выслушал удивительную историю, мы договорились с менеджером о том, что он мне отдаст исходный код и я оценю масштаб трагедии. Чтобы было более понятно, я расскажу более подробно о проекте. Этот проект — это инструмент для инженеров, архитекторов, электриков и других людей, которые занимаются строительством домов, небоскребов, одним словом зданий. Он служит для подсчета различных элементов на строительных планах, расчета площадей, измерения длин и составления смет. Грубо говоря есть строительный план и на нем есть розетки. Нам надо распознать и посчитать сколько этих розеток. Для распознавания использовалась библиотека написанная другим программистом. Сам проект написан на C#. Моя задача была собрать все воедино и доработать дополнительный функционал, а также привести программу к более менее стабильному состоянию. Кажется все просто и элементарно. Я тоже так подумал. Но не тут-то было.

После того как я получил исходники, я попытался скомпилировать проект. Это мне не удалось. После краткого анализа, я исправил ошибки и все же запустил проект. Но, к сожалению, он не заработал так как нужно. После нескольких часов анализа кода я пришел к выводу, что вся проблема в библиотеке распознавания. На тот момент у меня стояла 64-битная «семерка», а у менеджера 32-битная. У него все работало, у меня нет. Я попросил, что бы мне скомпилировали библиотеку под 64-битную платформу. Но разработчик библиотеки с пеной у рта доказывал, что не в разрядности дело. Я не мог ему ничего доказать, так как он дал очень немного информации о своей библиотеке и вообще берег ее как зеницу ока. Время шло и мне надо было хотя бы полностью провести процесс поиска. Я плюнул на все и поставил себе 32-х битную версию ОС. И о чудо! Все заработало. Отвлекаясь, хочу сказать о библиотеке, в будущем дело все же оказалось в ее разрядности.

Я начал анализировать код. Первое впечатление было просто отвратным. Я был в шоке. Я приведу список того, что меня возмутило в проекте.

1. Компоненты и контролы.

Проект очень сильно связан с графикой, но для ее вывода и обработки использовался обычный PictureBox. Самый маленький размер плана — 5400x3600 пикселей. Знающие люди поймут, что для PictureBox -это достаточно проблематичная тема с выводом больших картинок и их обработкой. Не стоит забывать, что помимо самих планов выводится еще много информации (площади, текст, найденные символы и т.д.). При запуске проекта с 5 маленькими планами, программа непременно падала с ошибкой «Out of memory». Что было очень большой проблемой, так как основной задумкой было то, что инструмент должен был работать по принципу «запустил и забыл».

2. Логика архитектуры исходного кода программы.
Читать дальше →

О повторном использовании кода

Время на прочтение6 мин
Количество просмотров7.3K
Сегодня существуют разные мнения по поводу успешности объектной технологии. С одной стороны, большинство современных mainstream языков программирования являются объектно-ориентированными, с другой стороны, нередко можно услышать критику ООП, дескать, объектно-ориентированное программирование «провалилось» и не оправдало тех надежд, которые были возложены на нее индустрией разработки ПО. Все, мол, ожидали наступления вселенского счастья в виде увеличения повторного использования, упрощения сопровождения, да и вообще, обещали, что думать придется кому-то другому, а я за это буду деньги получать.
Читать дальше →

Ближайшие события

Басни на ночь — Хорошие имена как залог успеха

Время на прочтение3 мин
Количество просмотров1.5K
image
Доброго времени суток всем.

«Как лодку назовешь, так она и поплывет» — довольная известная фраза, которая вполне подходит к функциям, переменным, классам.

Сколько раз вам приходилось читать чужой (а бывает и свой код, каюсь, бывало подобное с моим же кодом) и разбираться с написанным месивом. Назначение переменных, функций, а то и вовсе классов не являются интуитивно понятным.
Казалось бы, есть переменная, есть ее имя, но ее назначение не понятно.

Например
enum Dates{
  GET_FIRST,
  GET_SECOND,
  GET_BOTH,
  None
}



Вот и думай, что этот енам делает эдакого в вашем коде. Вроде из названия перечисления понятно, что дело связано с датами. Может методу передаются две даты, и нужно выбрать какую то из них. А может в расчет нужно брать только определенные даты, первую и вторую из списка. А может что еще, может быть много мнений.
Читать дальше →

Что значат для вас юнит-тесты?

Время на прочтение5 мин
Количество просмотров8K
С технической точки зрения юнит-тесты – это очень простой инструмент, основанный на паре несложных концепций: (1) тестируемый класс, (2) набор тестовых методов, завернутых в некоторый класс и (3) набор методов, с помощью которых можно удостовериться в том, что состояние тестового класса соответствует (или не соответствует) некоторому значению.

Это очень простая штуковина, которая может кардинальным образом повлиять на процесс разработки в целом. С одной стороны существует TDD (“test-first approach"), при котором тесты «драйвят» не только процессом кодирования, но и процессом проектирования (т.е. дизайном системы). С другой стороны существуют разработчики с противоположной точкой зрения, которые считают юнит-тесты пустой тратой времени, потому что они не приносят никакой ценности пользователю.

Читать дальше →

Организация рабочих потоков: синхронизационный канал

Время на прочтение7 мин
Количество просмотров9.4K
Представьте себе архитектуру типичного приложения:

Есть рабочий поток движка, выполняющий какую-то функциональность, допустим копирование файлов (архивирование, поиск простых чисел). В общем что-то длительное.
Данный поток должен периодически сообщать информацию о текущем копируемом файле, а также уметь обрабатывать ошибки, допустим ошибка нехватки места на диске.

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

Казалось бы, как можно допустить ошибку в такой простой ситуации?
Читать дальше →

Проектирование веб-приложений с применением Data Management System (на основе технологии скаффолдинга)

Время на прочтение4 мин
Количество просмотров8.1K


В предыдущей статье я рассказал о том, почему считаю неэффективной разработку с применением Content Management System. В этой статье, я расскажу о том, какой подход использую в построении веб-приложений.
Читать дальше →

Асинхронный конечный автомат: идеология и технология

Время на прочтение8 мин
Количество просмотров14K

Вступление


Хорошо, когда твои подчиненные никогда не болеют, не умирают, всегда присутствуют на работе и выполняют твои распоряжения без предварительных приготовлений: «Вызвали — встань». Таковы, например, веб-сервисы, соблюдающие модель REST (которая, если отбросить специальную HTTP-терминологию, сводится к тому, что интерфейс сервиса фактически является интерфейсом контейнера данных).

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

Асинхронный конечный автомат — это удобная абстракция верхнего уровня для управления сущностями с богатым и не всегда предсказуемым внутренним миром. Такой сущностью может быть аппаратное устройство, сессия сетевого протокола или просто параллельно запущенный процесс, код которого вы не контролируете.

Описываемая ниже архитектура асинхронного конечного автомата решает ряд стандартных проблем, возникающих при «лобовой» интеграции подсистем с учетом их внутреннего состояния. Самая заметная из таких проблем — это недостаточная разнесенность (я бы даже сказал — недостаточная «гальваническая развязка») сущностей сигнала и перехода между состояниями, из-за чего автомат становится неустойчивым к DoS-атакам. Есть и другие, менее очевидные — например, «недостаточно атомарная» замена узла подсистемы или используемого ей ресурса.

Анатомия (объектная декомпозиция)


Модель конечного автомата включает следующие базовые сущности:
  1. Состояние — это режим функционирования управляемой системы, отличный от других по предоставляемым возможностям. Таким образом, снапшоты кешей и буферов, варианты циклов «от забора и до обеда» и другие акциденции управляемой системы в понятие «состояния» не входят. В норме состояний должны быть считанные единицы; если счет пошел на второй десяток — скорее всего, управляемую систему следует раздробить или иерархизировать.
  2. Условие — это логическое значение (true или false) на одном из «входов» системы. Суперпозиция состояний всех входов автомата однозначно определяет целевое состояние автомата. Таким образом, любой входной сигнал, значимый для состояния автомата, в конечном счете сводится к установке значения одного или нескольких условий.
  3. Реакция — это отклик автомата на отличие текущего состояния от целевого. Принципиально различных видов реакции мы насчитали два с половиной: прямой переход между состояниями, маршрут и стоп-маршрут («кирпич»). Прямой переход может быть и пустой операцией (NOP) — например, в случае, если изменение входов вызвано уведомлением о завершении асинхронной операции.
Читать дальше →

Коллекция паттернов и антипаттернов JavaScript

Время на прочтение1 мин
Количество просмотров5.5K
Несколько месяцев назад на Гитхабе появилась очень неплохая коллекция паттернов и антипаттернов JavaScript и jQuery на все случаи жизни. Автор проекта Shi Chuan проделал отличную работу, собрав десятки примеров кода из книг и других источников. Репозиторий уже набрал почти полторы тысячи подписчиков и активно пополняется. Всё очень удобно разложено по категориям и откомментировано. Наслаждайтесь!

Перестаньте писать классы

Время на прочтение9 мин
Количество просмотров187K
Фото Джэка Дидриха из профиля на G+ Признак того, что объект не должен быть классом — если в нём всего 2 метода, и один из них — инициализация, __init__. Каждый раз видя это, подумайте: «наверное, мне нужна просто одна функция».

Каждый раз когда из написанного класса вы создаёте всего один экземпляр, используете только раз и тут же выбрасываете, следует думать: «ой, надо бы это отрефакторить! Можно сделать проще, намного проще!»

Перевод доклада Джэка Дидриха, одного из ключевых разработчиков языка Питон. Доклад прозвучал 9 марта 2012 на конференции PyCon US.
Читать дальше →