SlideShare a Scribd company logo
1 of 62
Download to read offline
Кто подставил
Барбару Лисков?
или Кто кого SOLID?
Сергей Крапивенский, Rambler&Co
как сказал наш великий полководец Суворов
“Do Not Learn Frameworks”
Фундаментальные знания
Фундаментальные знания
Язык
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
Язык
Фреймворки
RayWenderlich - driven development
Senior ReactiveCocoa Developer
Рамблер - секта VIPER
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
Язык
Фреймворки
Фундаментальные знания
• Структуры данных
• Алгоритмы
• Паттерны
• DRY, KISS, YAGNI
• SOLID
• И многое другое
Single responsibility principle
Open-closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
Single Responsibility Principle
“A class should have only one
reason to change”
MassiveViewController
1.Ответственности сильно связаны
2.Класс перестает помещаться в голове
3.Тяжело поддерживать и тестировать
UITableViewController
1.Изменение логики работы с таблицей
2.Поменять иерархию вьюшек
UITableViewController
Решение проблемы: не использовать его
Запуск приложения
Push Notifications
Quick Actions
Уведомления о
состояниях приложения
Открытие по URL
Фоновая
загрузка данных
AppDelegate
AppDelegate
Запуск приложения Quick Actions
ПоискPush Notifications
Открытие URL
Состояния
приложения
Загрузка в фоне
Handoff
Extensions
AppDelegate
Запуск приложения Quick Actions
ПоискPush Notifications
Открытие URL
Состояния
приложения
Загрузка в фоне
Handoff
Extensions
https://github.com/rambler-digital-solutions/RamblerAppDelegateProxy
SRP о снижении сложности
Single responsibility principle
Open-closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
Open-Closed Principle
“Software entities (classes,
modules, functions, etc.) should
be open for extension, but closed
for modification”
Простой и устойчивый
дизайн
Новость
Новость
Новость
Новость
Новость
Новость
Новость
Новость
Новость с фото
Новость с фото
Новость
Новость
Новость
Новость
Новость с фото
Новость с фото
Реклама
Реклама
} else ...
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeue...];
id model = [self modelAtIndex:indexPath.row];
if ([model isKindOfClass:[News class]]) {
NewsCell *newsCell = (NewsCell *)cell;
[newsCell setupWithNews:model];
} else if ([model isKindOfClass:[Advertisement class]]) {
AdvertisementCell *adCell = (AdvertisementCell *)cell;
[adCell setupWithAd:model];
} else ...
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeue...];
id model = [self modelAtIndex:indexPath.row];
if ([model isKindOfClass:[News class]]) {
NewsCell *newsCell = (NewsCell *)cell;
[newsCell setupWithNews:model];
} else if ([model isKindOfClass:[Advertisement class]]) {
AdvertisementCell *adCell = (AdvertisementCell *)cell;
[adCell setupWithAd:model];
} else ...
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeue...];
id model = [self modelAtIndex:indexPath.row];
if ([model isKindOfClass:[News class]]) {
NewsCell *newsCell = (NewsCell *)cell;
[newsCell setupWithNews:model];
} else if ([model isKindOfClass:[Advertisement class]]) {
AdvertisementCell *adCell = (AdvertisementCell *)cell;
[adCell setupWithAd:model];
} else ...
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeue...];
id model = [self modelAtIndex:indexPath.row];
if ([model isKindOfClass:[News class]]) {
NewsCell *newsCell = (NewsCell *)cell;
[newsCell setupWithNews:model];
} else if ([model isKindOfClass:[Advertisement class]]) {
AdvertisementCell *adCell = (AdvertisementCell *)cell;
[adCell setupWithAd:model];
} else ...
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeue...];
id model = [self modelAtIndex:indexPath.row];
if ([model isKindOfClass:[News class]]) {
NewsCell *newsCell = (NewsCell *)cell;
[newsCell setupWithNews:model];
} else if ([model isKindOfClass:[Advertisement class]]) {
AdvertisementCell *adCell = (AdvertisementCell *)cell;
[adCell setupWithAd:model];
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
id model = [self modelAtIndex:indexPath.row];
UITableViewCell<ConfigurableCell> *cell = ...;
[cell configureWithObject:model];
return cell;
}
NewsCell PhotoCell AdCell
<ConfigurableCell>
- (void)configure:(<CellObject>)object;
News Photo Advert
<CellObject>
- (Class)cellClass;
Когда применять?
Single responsibility principle
Open-closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
Liskov Substitution Principle
“Subtypes must be substitutable
for their base types”
Нужен для проверки
корректности наследования
- (void)hideViews {
[UIView animateWithDuration:1.0
animations:^
{
for (UIView *view in self.animatableViews) {
view.alpha = 0.5f;
}
}];
}
UIView
UIVisualEffectView
Всё ок !
<UIVisualEffectView> is being asked to animate its
opacity. This will cause the effect to appear broken until
opacity returns to 1
¯_( )_/¯
Single responsibility principle
Open-closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
Interface Segregation Principle
“Clients should not be forced to
depend on methods that they
do not use”
MailAPIClient
- auth
- findContact
- getMailboxes
- createMailbox
- sendMail
Auth Contacts Mailboxes Messages
- auth
- findContact
- getMailboxes
- createMailbox
- sendMail
- auth
- findContact
- getMailboxes
- createMailbox
- sendMail
- auth
- findContact
- getMailboxes
- createMailbox
- sendMail
- auth
- findContact
- getMailboxes
- createMailbox
- sendMail
AuthServiceMailboxServiceContactServiceMessageService
Auth Contacts Mailboxes Messages
- auth
- findContact
- getMailboxes
- createMailbox
- sendMail
- auth
- findContact
- getMailboxes
- createMailbox
- sendMail
- auth
- findContact
- getMailboxes
- createMailbox
- sendMail
- auth
- findContact
- getMailboxes
- createMailbox
- sendMail
MailAPIClient
ISP - это не SRP
- sendSelfDestructMessage
- deleteBothMessages
ChatChannel
- loadMessages
- sendMessage
- replyToMessage
- forwardMessage
ChannelSecretChat Supergroup
- banUser
Group
- loadMessages
- sendMessage
- replyToMessage
- forwardMessage
- sendSelfDestruct
- deleteBoth
- pinMessage
- banUser
- pinMessage - loadMessages
- sendMessage
- replyToMessage
- forwardMessage
- sendSelfDestruct
- deleteBoth
- pinMessage
- banUser
- loadMessages
- sendMessage
- replyToMessage
- forwardMessage
- sendSelfDestruct
- deleteBoth
- pinMessage
- banUser
- loadMessages
- sendMessage
- replyToMessage
- forwardMessage
- sendSelfDestruct
- deleteBoth
- pinMessage
- banUser
Single responsibility principle
Open-closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
Dependency Inversion Principle
“A. High-level modules should not
depend on low-level modules.
Both should depend on
abstractions”
Dependency Inversion Principle
“B. Abstractions should not
depend on details. Details should
depend on abstractions”
- (void)displayNews {
NSPredicate *newsPredicate = ...;
NSArray *news = [News MR_findAllWithPredicate:newsPredicate];
// Отображаем новости
}
Зависимость от Core Data
NewsViewController MagicalRecord
Realm😓
@protocol NewsProvider <NSObject>
- (NSArray *)obtainNewsForDate:(NSDate *)date;
@end
Зависимость от Core Data
- (void)displayNews {
NSDate *todayDate = ...;
NSArray *news = [self.newsProvider obtainNewsForDate:todayDate];
// Отображаем новости
}
@protocol NewsProvider <NSObject>
- (NSArray *)obtainNewsForDate:(NSDate *)date;
@end
Зависимость от Core Data
- (void)displayNews {
NSDate *todayDate = ...;
NSArray *news = [self.newsProvider obtainNewsForDate:todayDate];
// Отображаем новости
}
@interface NewsViewController : UIViewController
- (instancetype)initWithNewsProvider:(id<NewsProvider>)newsProvider;
@end
Зависимость от Core Data
NewsViewController <NewsProvider>
MagicalRecord
NewsProvider
Зависимости инвертированы #
Серебряной пули нет 😢
- Оноре де Бальзак
“Обстоятельства переменчивы,
принципы - никогда”

More Related Content

Similar to Being SOLID

Пластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать житьПластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать житьMoscow.pm
 
automation is iOS development
automation is iOS developmentautomation is iOS development
automation is iOS developmentIvan Trifonov
 
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NETASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NETDev2Dev
 
Регрессионное тестирование верстки
Регрессионное тестирование версткиРегрессионное тестирование верстки
Регрессионное тестирование версткиTalks&Works
 
C# Web. Занятие 11.
C# Web. Занятие 11.C# Web. Занятие 11.
C# Web. Занятие 11.Igor Shkulipa
 
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVCАрхитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVCDevDay
 
Take more from Jquery
Take more from JqueryTake more from Jquery
Take more from JqueryMagento Dev
 
Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?buranLcme
 
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...lshevtsov
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.Igor Shkulipa
 
Контроль качества верстки или как начать делать Makeup
Контроль качества верстки или как начать делать MakeupКонтроль качества верстки или как начать делать Makeup
Контроль качества верстки или как начать делать MakeupTimophy Chaptykov
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорьdrupalconf
 
"Адаптивный дизайн интерфейса JS API Яндекс.Карт и особенности его реализации...
"Адаптивный дизайн интерфейса JS API Яндекс.Карт и особенности его реализации..."Адаптивный дизайн интерфейса JS API Яндекс.Карт и особенности его реализации...
"Адаптивный дизайн интерфейса JS API Яндекс.Карт и особенности его реализации...Yandex
 
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлениюCodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлениюCodeFest
 
React со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендерингReact со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендерингTimophy Chaptykov
 
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетью
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетьюИнтуит. Разработка приложений для iOS. Лекция 7. Работа с сетью
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетьюГлеб Тарасов
 
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложениеASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложениеAlexander Byndyu
 

Similar to Being SOLID (20)

Grails & Groovy
Grails & GroovyGrails & Groovy
Grails & Groovy
 
Zend Framework и Doctrine
Zend Framework и DoctrineZend Framework и Doctrine
Zend Framework и Doctrine
 
Пластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать житьПластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать жить
 
automation is iOS development
automation is iOS developmentautomation is iOS development
automation is iOS development
 
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NETASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NET
 
Регрессионное тестирование верстки
Регрессионное тестирование версткиРегрессионное тестирование верстки
Регрессионное тестирование верстки
 
C# Web. Занятие 11.
C# Web. Занятие 11.C# Web. Занятие 11.
C# Web. Занятие 11.
 
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVCАрхитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
 
Take more from Jquery
Take more from JqueryTake more from Jquery
Take more from Jquery
 
Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?
 
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.
 
Контроль качества верстки или как начать делать Makeup
Контроль качества верстки или как начать делать MakeupКонтроль качества верстки или как начать делать Makeup
Контроль качества верстки или как начать делать Makeup
 
UWDC 2013, Yii2
UWDC 2013, Yii2UWDC 2013, Yii2
UWDC 2013, Yii2
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
 
"Адаптивный дизайн интерфейса JS API Яндекс.Карт и особенности его реализации...
"Адаптивный дизайн интерфейса JS API Яндекс.Карт и особенности его реализации..."Адаптивный дизайн интерфейса JS API Яндекс.Карт и особенности его реализации...
"Адаптивный дизайн интерфейса JS API Яндекс.Карт и особенности его реализации...
 
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлениюCodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
 
React со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендерингReact со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендеринг
 
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетью
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетьюИнтуит. Разработка приложений для iOS. Лекция 7. Работа с сетью
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетью
 
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложениеASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
 

Being SOLID