2. Программирование – это как секс
• DDD
• CQRS
• Event Sourcing
• Эволюционный рефакторинг
• Горизонтальное масштабирование и облачная архитектура
• Эффективное взаимодействие между командами
Один раз ошибешься, а
потом поддерживать
всю жизнь
5. Проблемы
• Специфическая терминология
• Сложная предметная область, не
очевидные бизнес-правила
• Бизнес-логика может часто меняться
• Высокая и/или неравномерная нагрузка
6. Цели разработчика
• Сохранять темпы разработки
• Повысить bus factor
• Обеспечить горизонтальное
масштабирование системы
10. Metal Gear
• S – Single responsibility principle
• O – Open/closed principle
• L – Liskov substitution principle
• I – Interface segregation principle
• D – Dependency inversion principle
12. Как структурировать бизнес-логику?
• 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
13. Единый язык (Ubiquitous language)
ticket.State = TicketState.Sold;
ticketRepository.Update(ticket);
var ticket = cashdesk.Sale (seat);
14. DDD vs OOP
• Гвоздь суше воды
• DDD про отделение мух от котлет домена от
инфраструктуры
• DDD про взаимодействие с бизнесом
15. Entity
• Есть Id
• У вас есть, у гвоздя – нет
• Наличие или отсутствие Id может зависеть
от контекста
17. Что не так с Repository?
public interface IRepository<T>
{
T GetById(int id);
IEnumerable<T> GetAll();
bool Add(T entity);
bool Remove(T entity);
}
18. Что не так с 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);
}
19. Что не так с Repository?
• 100500 методов, в т.ч. в интерфейсе
IAccountRepository
• Не удобно тестировать
• Многа-букаф, чтобы написать новый метод
• Приходится прокидывать сигнатуры в
сервисный слой
• Рефакторинг затруднен
20. Ок, я понял
public interface IRepository<T>
{
T GetById(int id);
//во имя луны
IQueryable<T> GetAll();
bool Add(T entity);
bool Remove(T entity);
}
21. Что не так с 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());
32. Монада 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");
33. 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;
}
}
34. Иногда лучше по-быстрому, чем SRP, если
знаешь как будешь рефакторить
public class ProductCategoryController :
AdminControllerBase<ProductCategory>
{
public ProductCategoryController(DbContext dbContext) :
base(dbContext)
{
}
}
Например, INotifyPropertyChanged
35. Дай разработчику дефолтное поведение и он будет
штамповать формочки весь день. Научи как
переопределить его…
• Во FreeBSD ты можешь настроить все, и ты
%$@ть будешь настраивать все
• ASP.NET MVC
• WCF
42. Оптимизация БД
• Убираем ORM для лучшей оптимизации
• Оптимизируем индексы
• Убираем весь код выборки в хранимые
процедуры
• Строим/оптимизируем индексы
• Денормализуем данные (когда ничего не
помогает)
43. Стратегии денормализации
• Убрать JOIN’ы, добавить
денормализованные колонки
• Создаем отдельные таблицы/view
• Хранилище с «плоскими» данными
44. Теорема CAP
• Consistency (согласованность данных)
• Availability (доступность)
• Partition tolerance (устойчивость к
разделению)
60. Взаимодействие между командами,
границы применимости
• И снова Bounded Context
• UI-команда – клиент для Backend-команды
• Сначала интерфейс, потом реализация
• CQRS и ES могут жить в подсистеме
• Code Review – не блажь, а необходимость
• Парное программирование для сложных
задач