Рубрика «Проектирование и рефакторинг» - 65

Интро

Я хочу рассказать об опыте разработки iOS-клиента для социальной сети и бэкенда реализованного с помощью BaaS Parse.com Нижe приведена архитектура, которая у нас получилась, некоторые tips&tricks и размышления по поводу работы с parse.com.
Изначально клиент думал о сервере на RoR, но, видимо, они не рискнули вкладывать сразу много денег. Мы подписали строгое NDA, поэтому ссылку на Appstore я дать не могу.
Читать полностью »

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

Ущербный — имеющий изъян, неполноценный. Вредный, недостаточный.

Наследование

Наследование — это способ получить возможности старого кода в новом коде. Программист наследуется от существующей функции или блока кода, копируя этот кусок к себе и внося правки. Унаследованный код, как правило, конкретизируется под новые нужды с помощью возможностей, которые не поддерживал старый код. В таком смысле, старый код остается нетронутым, но новый наследуется от него.

Читать полностью »

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

Я специализируюсь на отладке, исправлении, поддержке и расширении функциональности старого программного обеспечения. Мой типичный клиент имеет веб-сайт или приложение, которое более-менее работает, но автор которого недоступен. Бизнес-требования изменились, и ПО перестало им удовлетворять. Или у моего клиента есть что-то, что «уже закончено», но он расстался с разработчиком после исчерпания бюджета и сроков. Обычно такая ситуация сопровождается списком пропущенных фич и багов.
Мой типичный клиент обычно разговаривал с другими программистами, которые рекомендовали выбросить имеющееся и начать разработку с нуля. Большинство программистов не любит поддержку кода, и особенно, они не любят поддержку чужого кода.Читать полностью »

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

Картинка для привлечения внимания:

Паттерн «VIP слушатель»

Читать полностью »

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

Изначально, задача показалась весьма линейной — посмотреть тут, потом там, взять что-то по приоритету и передать дальше. Но в процессе выяснилось, что некоторые метки могут появляться асинхронно, и, следовательно, их нужно уметь «ждать».

Усложнение задачи привело к желанию упростить код, участвующий в ее решении.

На примере решения такой задачи, данный пост пытается показать, как проектирование и over engineering может помочь вам в разработке гибких и легко изменяемых приложений.
Читать полностью »

Итератор в шаблонизаторе doT.js по объектам с фильтрациейКомпактный (3.5 Кб) и быстрый шаблонизатор doT.js для браузеров и nodeJS до сих пор (v.1.0.1) имеет итерацию только по массивам. Это не всегда удобно — подгонять управляющий объект под наличие в нём массивов. Лучше подогнать шаблонизатор под наличие в нём итератора по объектам c проверкой условия. Проверять условия в циклах по объектам приходится часто — это и hasOwnProperty(), и проверка на DOM-объект, и взятие части хеша по фильтрации индексов.

Как пишут в шаблоне итерацию по массиву? Примерно так:

{{~it.elemsArray:property:i}} ... {{~}}

Читать полностью »

Большинство интернет-магазинов, новостные порталы, да и многие информационные сайты содержат большой объем элементов контента в одной категории. Одним структурированием каталога здесь не обойтись. Придется либо строить иерархию меню уровней в 5-7 (хотя и это может не решить проблемы), либо вываливать на пользователя десятки страниц выдачи в надежде, что он сам разберется, что ему нужно.
Выглядит это обычно как на картинке (плюс еще 10 экранов вниз). Деление на страницы (пейджинация), естественно, никак не улучшает опыт взаимодействия, это лишь способ снизить нагрузку на систему.
Борьба с изобилием: usability форм фильтрации

Читать полностью »

Разделения на MVC недостаточно

С каждым днем iOS приложения становятся все более громоздкими, в следствие чего одного MVC становится мало.

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

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

[[RequestManager sharedInstance] loadResourcesAtPath:@"http://example.com/resources" withDelegate:self];
// или
[[DatabaseManager sharedManager] saveResource:resource];

Этот подход используется во множестве проектов, но он имеет некоторые недостатки:

  • тяжело застабать синглтон который используется внутри тестируемого класса
  • синглтон, по сути, глобальная переменная
  • с точки зрения SRP объект не должен контролировать свое Singleton'овское поведение

Первую проблему решить довольно просто — нужно использовать свойства:

@interface ViewController : UIViewController

@property (nonatomic, strong) RequestManager *requestManager;

@end

Но этот подход имеет другие минусы — теперь кто-то должен «заполнить» это свойство.
Магия Крови способствует решению этой проблемы.
Читать полностью »

Код с одной и той же структурой в двух и более местах — верный признак необходимости рефакторинга. Если вам нужно будет что-нибудь изменить в одном месте, то, скорее всего, нужно также сделать то же самое и в других местах. Но есть близкая к 100% вероятность не найти эти места или попросту забыть за них.

Большинство понимает, что многократное повторение кода (или copy-paste) в примере ниже — зло:
Читать полностью »

Модель у нас отвечает за доступ к данным. Модель может быть реализована как в самом QML, так и на C++. Выбор тут больше всего зависит от того, где находится источник данных. Если в качестве источника данных используется код на C++, то там удобнее сделать и модель. Если же данные поступают напрямую в QML (например получаются из сети при помощи XMLHttpRequest), то лучше и модель реализовать на QML. Иначе придется передавать данные в C++, чтобы затем обратно их получать для отображения, что только усложнит код.

По тому, как модели реализуются, я разделю их на три категории:

  • модели на C++;
  • модели на QML;
  • модели на JavaScript.

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

Model-View в QML:

  1. Model-View в QML. Часть нулевая, вводная
  2. Model-View в QML. Часть первая: Представления на основе готовых компонентов
  3. Model-View в QML. Часть вторая: Кастомные представления
  4. Model-View в QML. Часть третья: Модели в QML и JavaScript

Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js