Как стать автором
Обновить
75.72

Качество кода *

Как Макконнелл завещал

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

Паттерн проектирования «Цепочка обязанностей» / «Chain of Responsibility»

Время на прочтение5 мин
Количество просмотров45K
Почитать описание других паттернов.


Проблема


Эффективно и компактно реализовать механизм обработки потока событий/запросов/сообщений в системах с потенциально большим количеством обработчиков.

Описание


Модель событие/обработчик широко применяется в программных системах из различных областей. В основном, это — графический интерфейс пользователя, где события, генерируемые от действий пользователя различным образом обрабатываются элементами интерфейса. Нельзя так-же забывать про WinAPI, который сплошь и рядом реализует такую модель. В большинстве источников эта модель имеет название Event Loop.

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

280 000 строк кода — ни одной ошибки?

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


Государственная комиссия из министерства транспорта США и НАСА изучила 280 000 строчек кода в автомобилях Toyota и не нашла в них ошибок. Таким образом, названы две причины массовых случаев ДТП с участием автомобилей Toyota: это неправильное расположение коврика и залипающая педаль акселератора.

По главному пункту обвинения — сбоях в управляющей электронике и программном обеспечении — крупнейший в мире производитель автомобилей официально признан невиновным.
Читать дальше →

camelCase против under_score

Время на прочтение3 мин
Количество просмотров79K
В настоящее время существует много стандартов наименования переменных, но два из них являются наиболее популярными среди программистов: это camel case («Верблюжья» нотация) и underscore (именование переменных с использованием символа нижнего подчеркивания в качестве разделителя). Кто-то может возразить, что существуют и другие популярные стандарты, но в рамках данной статьи мы сравним эти два, и узнаем у программистов — какого стандарта придерживаются они. Конечно, некоторые программисты связаны рамками стандартов кодирования языка или фреймворка, который они используют, но мы постараемся сделать независимое сравнение.
Читать дальше →

Кристофер Александер

Время на прочтение1 мин
Количество просмотров8.7K
Во многих подкастах, затрагивающих тему шаблонов проектирования, рано или поздно всплывает это имя. Вспоминается этот человек заслуженно, но зачастую совсем не в том контексте.

imageКристофер Александер в соавторстве с пятью другими специалистами по архитектуре действительно написал книгу об архитектурных шаблонах, в которой он действительно рассмотрел свыше двухсот оных. Краткое и широко известное название это книги — «A Pattern Language». Однако же достаточно взглянуть на обложку книги, чтобы увидеть ее полное название: «A Pattern Language: Towns, Buildings, Construction». Такие длинные названия книг и широкая распространенность только названий кратких — не редкость; например, все знают «Происхождение видов» сэра Чарльза Дарвина, но редко кто сможет вспомнить ее полное наименование: «Происхождение видов путем естественного отбора, или Сохранение благоприятных рас в борьбе за жизнь».

Так вот книга Кристофера Александера к сфере разработки программного обеспечения не имеет абсолютно никакого отношения. Посвящена она исключительно вопросам градостроительного проектирования, построения пространства, городским сообществам и архитектуре в целом. Книга невероятно интересная и увлекательная — очень советую прочесть.

GRASP паттерны проектирования

Время на прочтение4 мин
Количество просмотров277K
Почитать описание других паттернов.

GRASP (General Responsibility Assignment Software Patterns) — шаблоны проектирования, используемые для решения общих задач по назначению обязанностей классам и объектам.

Известно девять GRAPS шаблонов, изначально описанных в книге Крейга Лармана «Применение UML и шаблонов проектирования». В отличие от привычных читателю паттернов из Банды Четырех, GRAPS паттерны не имеют выраженной структуры, четкой области применения и конкретной решаемой проблемы, а лишь представляют собой обобщенные подходы/рекомендации/принципы, используемые при проектировании дизайна системы.

Рассмотрим характеристики основных GRASP шаблонов.
Читать дальше →

Паттерн проектирования «Заместитель» / «Proxy»

Время на прочтение7 мин
Количество просмотров55K
Почитать описание других паттернов.

Проблема


Необходимо контролировать доступ к объекту, не изменяя при этом поведение клиента.

Описание


При проектировании сложных систем, достаточно часто возникает необходимость обеспечить контролируемый доступ к определенным объектам системы. Мотивацией для этого служит ряд приобретаемых преимуществ. Таких как, ленивая инициализация по требованию для «громоздких» объектов, подсчет количества ссылок на объект и т.д. и т.п. Однако, не всегда потребность в контролируемом доступе к объекту базируется только на преимуществах. Как правило, сложность процессов реального мира, ограничения вычислительных ресурсов просто не оставляют проектировщику выбора, нежели как воспользоваться паттерном «Заместитель» («Сурогат»).
Читать дальше →

Паттерн проектирования «Приспособленец» / «Flyweight»

Время на прочтение6 мин
Количество просмотров33K
Почитать описание других паттернов.

Проблема


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

Описание


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

Паттерн проектирования «Фасад» / «Facade»

Время на прочтение5 мин
Количество просмотров86K
Почитать описание других паттернов.

Проблема


Минимизировать зависимость подсистем некоторой сложной системы и обмен информацией между ними.

Описание


При проектировании сложных систем, зачастую применяется т.н. принцип декомпозиции, при котором сложная система разбивается на более мелкие и простые подсистемы. Причем, уровень декомпозиции (ее глубину) определяет исключительно проектировщик. Благодаря такому подходу, отдельные компоненты системы могу быть разработаны изолированно, затем интегрированы вместе. Однако возникает, очевидная на первый взгляд, проблема — высокая связность модулей системы. Это проявляется, в первую очередь, в большом объеме информации, которой модули обмениваются друг с другом. К тому же, для подобной коммуникации одни модули должны обладать достаточной информацией о природе других модулей.

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

Один из способов решения данной задачи — использование паттерна «Фасад».
Читать дальше →

Паттерн проектирования «Декоратор» / «Decorator»

Время на прочтение4 мин
Количество просмотров94K
Почитать описание других паттернов.

Проблема


Возложить дополнительные обязанности (прозрачные для клиентов) на отдельный объект, а не на класс в целом.

Описание


Для более детального понимания проблемы, рассмотрим конкретную ситуацию. Пусть имеется некоторый объект — «кнопка», принадлежащий классу объектов «Кнопка», на который понадобилось возложить дополнительные обязанности. Под обязанностями, в данном контексте, понимаются какие-либо особенности поведения объекта. В случае с кнопкой, можно рассмотреть поведение объекта при его отображении на экране. При этом, будем считать, дополнительными обязанностями — отображение рамки кнопки, надписи, иконки. Важно понимать, что все эти обязанности должны иметь возможность быть наложенными как одновременно, так и по отдельности. Очевидно, первое, что приходит на ум — порождение классов (механизм наследования). Для данной задачи возможно это и выход — расширить класс «Кнопка» семью (23-1 = 7) различными классами, сочетающими в себе всевозможные комбинации обязанностей. Это классы: «Кнопка_С_Надписью», «Кнопка_С_Рамкой», «Кнопка_С_Иконкой», «Кнопка_С_Надписью_И_Иконкой», «Кнопка_С Рамкой_И_Иконкой», «Кнопка_С_Надписью_И_Рамкой», «Кнопка_С_Надписью_И_Рамкой_И_Иконкой». А если таких обязанностей будет не три, а хотя бы десять, не говоря уже про неудобство работы с подобной структурой. Безусловно, порождение классов в таком случае — заведомо проигрышный вариант. Однако, из этой ситуации есть выход — паттерн «Декоратор».
Читать дальше →

Паттерн проектирования «Компоновщик» / «Composite»

Время на прочтение5 мин
Количество просмотров44K
Почитать описание других паттернов.

Проблема


Предоставить клиенту единообразный доступ к листовым и составным элементам древовидной структуры.

Описание


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

Паттерн проектирования «Мост» / «Bridge»

Время на прочтение5 мин
Количество просмотров52K
upd: Изменил диаграмму и код. Расширил пример и описание.

Почитать описание других паттернов.

Предыстория


Вернувшись домой, после непродолжительных посиделок у старого друга, я обнаружил, что оставил у него свой мобильный телефон, а вместе с тем и единственный в квартире будильник. Ситуация осложнялась тем, что завтра в 8:00 надо было быть на работе. Вариант вернуться за мобильником в 11 часов вечера я даже не рассматривал. И первое, что пришло мне на ум — написать свой будильник, причем с применением паттерна «Мост», который мне и без того надо было реализовать в рамках спецкурса. Как говорится, двух зайцев… Я думаю, не стоит пояснять что лег спать я под утро, но довольный собой. А утром, ровно в 7:00 меня победоносно разбудил мой bridge-будильник, весело наигрывая мотив из TBBT.

Как я до такого докатился, читайте под хаброкатом.
Читать дальше →

Паттерн проектирования «Адаптер» / «Adapter»

Время на прочтение6 мин
Количество просмотров102K
Почитать описание других паттернов.

Пожалуй, начнем.
Для начала, поясню несколько организационных вопросов.
  • Описание того или иного паттерна, является моей сугубо личной интерпретацией теоретического и практического материала, собранного из книг и интернет-статей;
  • При построении UML-диаграмм, я буду использовать свободный редактор от компании astah, ввиду его простоты и независимости от конкретного языка или среды. При этом, диаграммы не будут отличатся изобилием картинок и цветов, но будут ясно отображать суть паттерна;
  • При реализации практических примеров, язык программирования будет выбираться совершенно случайно. Однако, я буду стараться подбирать те языковые средства, на которых данный паттерн реализуется не тривиально;
  • Каждый мой пост, будет содержать как минимум 5 секций — Проблема, Описание патерна, Практическая задача, Диаграмма классов и Реализация;
  • Если Вы, с чем-то не согласны или у Вас есть дополнения к материалу, изложенному мной — я буду рад их почитать в комментариях. Однако, помните — я тоже изучаю паттерны вместе с Вами :)

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

Как влияет кеш на многопоточные приложения

Время на прочтение6 мин
Количество просмотров5.8K
Теоретическая составляющая.

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

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

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

У меня возник вопрос насколько все может быть плохо. Кроме того, интересно было посмотреть как влияет длина данных.
Читать дальше →

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

Совершенный код

Время на прочтение4 мин
Количество просмотров19K
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
Damian Conway, co-designer of Perl 6

Хороший программный код определяется как минимум тремя признаками: однозначность, эффективность и сопровождаемость.

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

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

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

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

Время на прочтение3 мин
Количество просмотров16K
Читая Хабрахабр или просматривая чужие исходные коды, мне довольно часто приходится замечать примерно следующий кусок кода, который совершенно одинаково «звучит» на любом языке, на каком бы не был написан:
function(single_document)
{  
  if (single_document.getElementById("comments") != null)
    return;
    …
    …
    …
    …
}
* This source code was highlighted with Source Code Highlighter.

Здесь приведён кусочек кода на Javascript, но то же самое можно написать на нескольких десятках других языков. Что здесь не так? Только то, что у функции (метода, свойства, процедуры) несколько точек выхода. Если вам интересно почему это плохо, прочитай то что написано под катом.
Читать дальше →

Atomically thread-safe Meyers singleton implementation

Время на прочтение1 мин
Количество просмотров3.6K
Прочел последний топик про Singleton в этой группе «Совершенный код» и вспомнилось мне недавнее сообщение в группе Google comp.lang.c++.moderated про совершенную реализацию thread safe Singleton.
Советую всем любителям C++ прочитать это сообщение и вникнуть в код в нем.

По-моему это своего рода шедевр про то, как можно стремлением к совершенству убить красоту и понятность кода и превратить его в совершенный и нечитаемый фарш.
Мое мнение, что thread safe для Singleton не нужен, т.к. проблему одновременной инициализации static переменной в Meyers Singleton можно решить более простыми способами.

Например, вызывать метод instance для этого Singleton до создания первого потока, который будет его использовать, например, вначале main() или в функции, создающей эти потоки.

Есть возражения или мысли на этот счет?

Реализация Singleton в JAVA

Время на прочтение4 мин
Количество просмотров283K
В этой статье я хочу затронуть тему одного из наиболее распространенных паттернов объектно-ориентированного программирования – Singleton. Но в данном случае я не буду описывать преимущества/недостатки и области применения этого паттерна, а попытаюсь изложить свой взгляд на его имплементацию в JAVA.

Общие сведения
Паттерн Singleton гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа.
Читать дальше →

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

Время на прочтение2 мин
Количество просмотров861
Нашествие многоядерных процессоров и повсеместный параллелизм наступили как-то неожиданно для софтверной индустрии (компания Intel довольно резко переметнулась на многоядерные проекты в 2004 году). В результате, современные средства разработки программного обеспечения оказались совершенно не приспособлены к параллельной архитектуре ПК. А ведь практически все современные процессоры являются многоядерными, и количество этих ядер растёт у них в геометрической прогрессии: 4, 8, 16 и т.д. Если программы не научатся в самое ближайшее время эффективно использовать параллелизм, то весь технический прогресс в процессоростроении пойдёт насмарку.

Фактически, это новая чаша Грааля для компаний-разработчиков: кто первым сможет разработать компиляторы для эффективного распараллеливания программ? Здесь начинается настоящая золотая лихорадка, пишет NY Times.

Месяц назад Intel и Microsoft объявили о программе исследований в этом направлении. Они финансируют работу группы в Университете Калифорнии в Беркли. Над той же проблемой бьются исследователи из Университета Иллинойса. Сейчас стало известно, что ещё один — третий — альянс «золотоискателей» при Стенфорде (Pervasive Parallelism Lab) сформировали корпорации Sun Microsystems, AMD, Nvidia, IBM, HP и та же Intel.
Читать дальше →

Основы мастерства

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

Боритесь со сложностью


Как известно, мозг человека может одновременно рассматривать 7±2 элемента. Поэтому очень важно стремиться к снижению сложности ПО. Вот некоторые конкретные рекомендации:
  • Разделите систему на подсистемы на уровне архитектуры, чтобы концентрироваться в каждый конкретный момент времени на меньшей части системы.
  • Тщательно определяйте интерфейсы классов, чтобы можно было игнорировать
    внутреннее устройство классов.
  • Поддерживайте абстракцию, формируемую интерфейсом класса, чтобы не
    запоминать ненужных деталей.
  • Избегайте глобальных данных, потому что их использование значительно увеличивает процент кода, который нужно удерживать в уме в любой момент
    времени.
  • Избегайте глубоких иерархий наследования, потому что они предъявляют
    высокие требования к интеллекту.

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

Личность программиста

Время на прочтение5 мин
Количество просмотров37K
«Чтобы стать экспертом в практической или научной области, нужны огромный труд и долгое время. Если человек добросовестно трудится каждый час рабочего дня, когда-нибудь он проснется одним из самых компетенткых специалистов своего поколения.»
Ульям Джеймс


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

Но ведь программы пишут люди, такие же, как мы с вами. Одни становятся выдающимися программистами и достигают больших успехов, другие же забрасывают профессию. Перефразируя классика, можно сказать: «покажи мне свой код, и я скажу, кто ты». Исследования показывают, что лучшие программисты создают программы в 10 раз быстрее, чем их менее квалифицированные коллеги. Время, уходящее на отладку кода, а также объем и быстродействие итоговой программы, уровень ошибок и число обнаруженных ошибок также различаются примерно в 10 раз.

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