SlideShare a Scribd company logo
1 of 61
Максим Аршинов
IT–гуру, μISV
Обрел просветление в разработке ПО
Программирование – это как секс
• DDD
• CQRS
• Event Sourcing
• Эволюционный рефакторинг
• Горизонтальное масштабирование и облачная архитектура
• Эффективное взаимодействие между командами
Один раз ошибешься, а
потом поддерживать
всю жизнь
Программирование – это как секс
А проектирование – это как петтинг
Распределенные и/или
нагруженные бизнес-приложения
• Система продажи билетов
• Трейдинговая площадка
• Баннерная сеть для порно-сайтов
Проблемы
• Специфическая терминология
• Сложная предметная область, не
очевидные бизнес-правила
• Бизнес-логика может часто меняться
• Высокая и/или неравномерная нагрузка
Цели разработчика
• Сохранять темпы разработки
• Повысить bus factor
• Обеспечить горизонтальное
масштабирование системы
«Архитектура»
• Что это такое?
• Чем отличается от «инфраструктуры»?
Всему свое время
Трёхуровневая архитектура
UI
Business Rules
Data Access Layer
Metal Gear
• S – Single responsibility principle
• O – Open/closed principle
• L – Liskov substitution principle
• I – Interface segregation principle
• D – Dependency inversion principle
Как структурировать бизнес-логику?
Как структурировать бизнес-логику?
• DDD (Domain Driven Design)
• Инфраструктура – не домен!
• Persistence ignorance
• Aggregation Roots
• Anemic Domain Model Rich Models
• Active Record Unit of Work
• Controller Service Layer
• using(var uow = new UoW()), Singleton, Registry
IOC
Единый язык (Ubiquitous language)
ticket.State = TicketState.Sold;
ticketRepository.Update(ticket);
var ticket = cashdesk.Sale (seat);
DDD vs OOP
• Гвоздь суше воды
• DDD про отделение мух от котлет домена от
инфраструктуры
• DDD про взаимодействие с бизнесом
Entity
• Есть Id
• У вас есть, у гвоздя – нет
• Наличие или отсутствие Id может зависеть
от контекста
CRUD
Что не так с Repository?
public interface IRepository<T>
{
T GetById(int id);
IEnumerable<T> GetAll();
bool Add(T entity);
bool Remove(T entity);
}
Что не так с Repository?
class AccountRepository : IRepository<Account>
{
public Account GetByName(string name);
public Account GetByEmail(string email);
public Account GetByAge(int age);
// ...
public Account GetByAreYouFuckingKiddingMe(SomeCriteria c);
}
Что не так с Repository?
• 100500 методов, в т.ч. в интерфейсе
IAccountRepository
• Не удобно тестировать
• Многа-букаф, чтобы написать новый метод
• Приходится прокидывать сигнатуры в
сервисный слой
• Рефакторинг затруднен
Ок, я понял
public interface IRepository<T>
{
T GetById(int id);
//во имя луны
IQueryable<T> GetAll();
bool Add(T entity);
bool Remove(T entity);
}
Что не так с Repository?
repo.GetAll()
.Where(a => a.IsDeleted = false);
repo.GetAll()
.Where(a => a.IsDeleted = false &&
a.Balance > 0);
repo.GetAll()
.Where(a => a.CreationDate <
getCurrentDate());
Specification Pattern
public interface ISpecification<T>
{
bool IsSatisfiedBy(T candidate);
}
Expression Specification
public interface ISpecification<T>
{
Expression<Func<T, bool>> IsSatisfiedBy();
}
Стало лучше
IEnumerable<T> GetBySpecifications(
IEnumerable<ISpecification<T>> specifications,
params IFetchStrategy<T>[] fetchStrategies);
FilterPolicy (Value Object)
public class FilterPolicy<T>
{
public IEnumerable<ISpecification<T>> Specifications { get; private set; }
public IEnumerable<IFetchStrategy<T>> FetchStrategies { get; private set; }
public FilterPolicy(
IEnumerable<ISpecification<T>> specifications,
IEnumerable<IFetchStrategy<T>> fetchStrategies)
{
Specifications = specifications;
FetchStrategies = fetchStrategies;
}
}
Более подробно о Value Object
• Не Entity
• Immutable
• Value - не Reference
Защитное программирование на
страже инварианта
public class FilterPolicy(
IEnumerable<ISpecification<T>> specifications,
IEnumerable<IFetchStrategy<T>> fetchStrategies)
{
if(specifications == null) throw new ArgumentException(
"specifications can't be null", "specifications");
if(fetchStrategies == null) throw new ArgumentException(
"fetchStrategies can't be null", "fetchStrategies");
Specifications = specifications;
FetchStrategies = fetchStrategies;
}
Composite
• OrSpecification
• AndSpecification
• ActiveAccountSpecification …
Composite
public class OrSpecification<T> : ISpecification<T>
{
private readonly ISpecification<T>[] _specs;
public OrSpecification(params ISpecification<T>[] specs)
{
if(specs.Length == 0) throw new ArgumentException(
"specs length must be > 0", "specs");
_specs = specs;
}
public Expression<Func<T, bool>> IsSatisfiedBy()
{
throw new NotImplementedException();
}
}
Декларативный стиль >
императивного
• DSL
• Функциональное программирование,
монады
• Мета-программирование и AOP, Code
Contracts
• Кодогенерация
• Динамическая компиляция
Монада Maybe
string postCode;
if (person != null)
{
if (HasMedicalRecord(person) && person.Address != null)
{
CheckAddress(person.Address);
if (person.Address.PostCode != null)
postCode = person.Address.PostCode.ToString();
else
postCode = "UNKNOWN";
}
}
public static TResult With<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator)
where TResult : class where TInput : class
{
if (o == null) return null;
return evaluator(o);
}
string postCode = this.With(x => person)
.With(x => x.Address)
.With(x => x.PostCode)
.Return(x => "UNKNOWN");
Conventions > configuration
[DisplayName("Категории продуктов")]
[DataContract]
public class ProductCategory : EntityBase
{
[Display(Name = "Название")]
[Column(TypeName = "VARCHAR"), StringLength(255), Required]
[DataMember(IsRequired = true)]
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
Иногда лучше по-быстрому, чем SRP, если
знаешь как будешь рефакторить
public class ProductCategoryController :
AdminControllerBase<ProductCategory>
{
public ProductCategoryController(DbContext dbContext) :
base(dbContext)
{
}
}
Например, INotifyPropertyChanged
Дай разработчику дефолтное поведение и он будет
штамповать формочки весь день. Научи как
переопределить его…
• Во FreeBSD ты можешь настроить все, и ты
%$@ть будешь настраивать все
• ASP.NET MVC
• WCF
Разделяй и властвуй
• Module aka Package
• Onion - архитектура
• SOA
Bounded Context
• Anti-Corruption Layer
• Контекстов может быть много
Anti-Corruption Layer. How To?
class Messy
{
String concat(String param, String str) { /* ... */ }
bool contains(String param, String s) { /* ... */ }
bool isEmpty(String param) { /* ... */ }
bool matches(String param, String regex) { /* ... */ }
bool startsWith(String param, String prefix) { /* ... */ }
}
class Reasonable // anti-corruption layer
{
String param;
Messy messy = new Messy();
Reasonable(String param)
{
this.param = param;
}
String concat(String str) { return messy.concat(param, str); }
bool contains(String s) { return messy.contains(param, s); }
bool isEmpty() { return messy.isEmpty(param); }
bool matches(String regex) { return messy.matches(param, regex); }
bool startsWith(String prefix) { return messy.startsWith(param, prefix); }
}
Разгрузочный слайд
Shared DB
Реляционная база данных – узкое
место
Оптимизация БД
• Убираем ORM для лучшей оптимизации
• Оптимизируем индексы
• Убираем весь код выборки в хранимые
процедуры
• Строим/оптимизируем индексы
• Денормализуем данные (когда ничего не
помогает)
Стратегии денормализации
• Убрать JOIN’ы, добавить
денормализованные колонки
• Создаем отдельные таблицы/view
• Хранилище с «плоскими» данными
Теорема CAP
• Consistency (согласованность данных)
• Availability (доступность)
• Partition tolerance (устойчивость к
разделению)
2 из 3
• Consistency + Availability (традиционные СУБД)
• Consistency + Partition tolerance
(пессимистические блокировки)
• Availability + Partition tolerance (NOSQL-решения)
CQS
• Command–query separation
• Commands – update state (C, U, D)
• Queries – fetch results (R)
CQS – зачем?
• Отсутствие сайд-эффектов
• Поддержка декларативного стиля (WCF)
• Горизонтальное масштабирование
Query Object как альтернатива
Repository
• Абстракция от ORM (но велосипед)
• Не надо городить кучу IEntityRepository
• Просто тестировать
• SRP
QueryObject и QueryBuilder
public interface IQueryFor<out T>
{
T With(ISpecification<T> specification)
T ById(int id);
IEnumerable<T> All();
}
public interface IQueryBuilder
{
IQueryFor<TResult> For<TResult>();
}
var account = queryBuilder.For<Account>()
.With(new LoginSpecification("Вася"))
.All();
Command Pattern
public interface ICommand
{
void Execute();
}
Не все CQS by design
• Например Стек
• Помним про Bounded Context
Синхронизация хранилищ
• Синхронно (C,U,D)
Синхронизация хранилищ
• Асинхронно
Команды и шина
• bus.Send(command);
• Диспетчеризация
• Логирование
Минусы
• Eventually consistent
• Архитектура гораздо сложнее, чем Shared
DB
• Обработка ошибок
• UX Issues
Горизонтальное масштабирование
записи данных
• Очередь сообщений (Producer-Consumer
pattern)
• RabbitMQ
• IronMQ
• NServiceBus
Разгрузочный слайд
Event Sourcing – вспомнить все
Проблемы
• Рефакторинг
• Сложность системы, Bus factor
• Сторонние сервисы
• Выбор Aggregation Root
• Tool Support
Взаимодействие между командами,
границы применимости
• И снова Bounded Context
• UI-команда – клиент для Backend-команды
• Сначала интерфейс, потом реализация
• CQRS и ES могут жить в подсистеме
• Code Review – не блажь, а необходимость
• Парное программирование для сложных
задач
Вопросы?

More Related Content

What's hot

Как мы данные готовили ORM и все-все-все в приложении Почта Mail.Ru / Кирилл ...
Как мы данные готовили ORM и все-все-все в приложении Почта Mail.Ru / Кирилл ...Как мы данные готовили ORM и все-все-все в приложении Почта Mail.Ru / Кирилл ...
Как мы данные готовили ORM и все-все-все в приложении Почта Mail.Ru / Кирилл ...
Ontico
 
Система обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на GroovyСистема обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на Groovy
Regn
 
Архитектура А/Б тестирования: сделай сам
Архитектура А/Б тестирования: сделай самАрхитектура А/Б тестирования: сделай сам
Архитектура А/Б тестирования: сделай сам
Sergey Xek
 
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...
Badoo Development
 
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
Ontico
 
Java c человеческим (и даже богатым) лицом / Филипп Дельгядо
Java c человеческим (и даже богатым) лицом / Филипп ДельгядоJava c человеческим (и даже богатым) лицом / Филипп Дельгядо
Java c человеческим (и даже богатым) лицом / Филипп Дельгядо
Ontico
 

What's hot (19)

Денис Трифонов
Денис ТрифоновДенис Трифонов
Денис Трифонов
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
 
Андрей Лузин
Андрей ЛузинАндрей Лузин
Андрей Лузин
 
Как жить в согласии с SOLID?
Как жить в согласии с SOLID?Как жить в согласии с SOLID?
Как жить в согласии с SOLID?
 
Как мы данные готовили ORM и все-все-все в приложении Почта Mail.Ru / Кирилл ...
Как мы данные готовили ORM и все-все-все в приложении Почта Mail.Ru / Кирилл ...Как мы данные готовили ORM и все-все-все в приложении Почта Mail.Ru / Кирилл ...
Как мы данные готовили ORM и все-все-все в приложении Почта Mail.Ru / Кирилл ...
 
"Производительность MySQL: что нового?"
"Производительность MySQL: что нового?""Производительность MySQL: что нового?"
"Производительность MySQL: что нового?"
 
Модульная архитектура Сбербанк Онлайн, Владимир Озеров и Александр Черушнико...
Модульная архитектура Сбербанк Онлайн, Владимир Озеров и Александр Черушнико...Модульная архитектура Сбербанк Онлайн, Владимир Озеров и Александр Черушнико...
Модульная архитектура Сбербанк Онлайн, Владимир Озеров и Александр Черушнико...
 
Игорь Кашкута
Игорь КашкутаИгорь Кашкута
Игорь Кашкута
 
Система обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на GroovyСистема обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на Groovy
 
Архитектура программных систем на Node.js
Архитектура программных систем на Node.jsАрхитектура программных систем на Node.js
Архитектура программных систем на Node.js
 
Артем Титаренко
Артем ТитаренкоАртем Титаренко
Артем Титаренко
 
презентация.1
презентация.1презентация.1
презентация.1
 
Архитектура А/Б тестирования: сделай сам
Архитектура А/Б тестирования: сделай самАрхитектура А/Б тестирования: сделай сам
Архитектура А/Б тестирования: сделай сам
 
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...
 
"Новые возможности MySQL 5.7"
"Новые возможности MySQL 5.7""Новые возможности MySQL 5.7"
"Новые возможности MySQL 5.7"
 
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
 
Порядок для скорости. Система структурирования фронтендовой части веб-приложе...
Порядок для скорости. Система структурирования фронтендовой части веб-приложе...Порядок для скорости. Система структурирования фронтендовой части веб-приложе...
Порядок для скорости. Система структурирования фронтендовой части веб-приложе...
 
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
 
Java c человеческим (и даже богатым) лицом / Филипп Дельгядо
Java c человеческим (и даже богатым) лицом / Филипп ДельгядоJava c человеческим (и даже богатым) лицом / Филипп Дельгядо
Java c человеческим (и даже богатым) лицом / Филипп Дельгядо
 

Viewers also liked

Viewers also liked (10)

CQRS на практике. В поиске точки масштабирования и новых метафор
CQRS на практике. В поиске точки масштабирования и новых метафорCQRS на практике. В поиске точки масштабирования и новых метафор
CQRS на практике. В поиске точки масштабирования и новых метафор
 
Гедонизм и выбор повседневных занятий
Гедонизм и выбор повседневных занятийГедонизм и выбор повседневных занятий
Гедонизм и выбор повседневных занятий
 
Rambler.iOS #5: Переходы и передача данных между VIPER модулями
Rambler.iOS #5: Переходы и передача данных между VIPER модулямиRambler.iOS #5: Переходы и передача данных между VIPER модулями
Rambler.iOS #5: Переходы и передача данных между VIPER модулями
 
RDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на Swift
 
Design & Process Models
Design & Process ModelsDesign & Process Models
Design & Process Models
 
Магия в Python: Дескрипторы. Что это?
Магия в Python: Дескрипторы. Что это?Магия в Python: Дескрипторы. Что это?
Магия в Python: Дескрипторы. Что это?
 
Rambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и SwiftRambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и Swift
 
Dapper + QueryObject
Dapper + QueryObjectDapper + QueryObject
Dapper + QueryObject
 
Node.JS error handling best practices
Node.JS error handling best practicesNode.JS error handling best practices
Node.JS error handling best practices
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
 

Similar to Coding like a sex

High Load 2009 Dimaa Rus Ready
High Load 2009 Dimaa Rus ReadyHigh Load 2009 Dimaa Rus Ready
High Load 2009 Dimaa Rus Ready
HighLoad2009
 
2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels
Nikolay Samokhvalov
 
IOP202 DevCon 2012 Apache Lucene in Windows Azure
IOP202 DevCon 2012 Apache Lucene in Windows AzureIOP202 DevCon 2012 Apache Lucene in Windows Azure
IOP202 DevCon 2012 Apache Lucene in Windows Azure
Vadim Novitskiy
 
JS Fest 2019. Игорь Березин и Николай Крещенко. Эволюция архитектуры многогра...
JS Fest 2019. Игорь Березин и Николай Крещенко. Эволюция архитектуры многогра...JS Fest 2019. Игорь Березин и Николай Крещенко. Эволюция архитектуры многогра...
JS Fest 2019. Игорь Березин и Николай Крещенко. Эволюция архитектуры многогра...
JSFestUA
 

Similar to Coding like a sex (20)

Есть ли жизнь с ORM или типовая архитектура CRUD приложения
Есть ли жизнь с ORM или типовая архитектура CRUD приложенияЕсть ли жизнь с ORM или типовая архитектура CRUD приложения
Есть ли жизнь с ORM или типовая архитектура CRUD приложения
 
RESTful API: Best practices, versioning, design documentation
RESTful API: Best practices, versioning, design documentationRESTful API: Best practices, versioning, design documentation
RESTful API: Best practices, versioning, design documentation
 
Реляционные базы данных
Реляционные базы данныхРеляционные базы данных
Реляционные базы данных
 
High Load 2009 Dimaa Rus Ready
High Load 2009 Dimaa Rus ReadyHigh Load 2009 Dimaa Rus Ready
High Load 2009 Dimaa Rus Ready
 
Всеволод Поляков "История одного мониторинга"
Всеволод Поляков "История одного мониторинга"Всеволод Поляков "История одного мониторинга"
Всеволод Поляков "История одного мониторинга"
 
разработка бизнес приложений (8)
разработка бизнес приложений (8)разработка бизнес приложений (8)
разработка бизнес приложений (8)
 
Артемий Гарин "Выбор лучшего хранилища в Android (cпойлер: Realm)"
Артемий Гарин "Выбор лучшего хранилища в Android (cпойлер: Realm)"Артемий Гарин "Выбор лучшего хранилища в Android (cпойлер: Realm)"
Артемий Гарин "Выбор лучшего хранилища в Android (cпойлер: Realm)"
 
Clickhouse
ClickhouseClickhouse
Clickhouse
 
Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)
Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)
Alasql.js - SQL база данных на JavaScript / Андрей Гершун (МАГ КОНСАЛТИНГ)
 
PostgreSQL performance recipes
PostgreSQL performance recipesPostgreSQL performance recipes
PostgreSQL performance recipes
 
разработка бизнес приложений (7)
разработка бизнес приложений (7)разработка бизнес приложений (7)
разработка бизнес приложений (7)
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
 
2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels
 
AlaSQL библиотека для обработки JavaScript данных (презентация для ForntEnd 2...
AlaSQL библиотека для обработки JavaScript данных (презентация для ForntEnd 2...AlaSQL библиотека для обработки JavaScript данных (презентация для ForntEnd 2...
AlaSQL библиотека для обработки JavaScript данных (презентация для ForntEnd 2...
 
Reactive Extensions
Reactive ExtensionsReactive Extensions
Reactive Extensions
 
Agile Instrumentation
Agile InstrumentationAgile Instrumentation
Agile Instrumentation
 
Мастер класс по алгоритмам. Часть 1
Мастер класс по алгоритмам. Часть 1Мастер класс по алгоритмам. Часть 1
Мастер класс по алгоритмам. Часть 1
 
IOP202 DevCon 2012 Apache Lucene in Windows Azure
IOP202 DevCon 2012 Apache Lucene in Windows AzureIOP202 DevCon 2012 Apache Lucene in Windows Azure
IOP202 DevCon 2012 Apache Lucene in Windows Azure
 
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
 
JS Fest 2019. Игорь Березин и Николай Крещенко. Эволюция архитектуры многогра...
JS Fest 2019. Игорь Березин и Николай Крещенко. Эволюция архитектуры многогра...JS Fest 2019. Игорь Березин и Николай Крещенко. Эволюция архитектуры многогра...
JS Fest 2019. Игорь Березин и Николай Крещенко. Эволюция архитектуры многогра...
 

Coding like a sex