#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
@interface Spreadsheet : NSObject
- (void)loadFromURL:(NSURL *)url;
- (void)saveToURL:(NSURL *)url;
- (void)drawTo:(CGRect*)targetArea withContext:(CGContextRef *)context;
@end
Я бы сказал, что приведенный выше пример нарушает SRP.
На первый взгляд ясно, что класс отвечает за одну вещь: электронные таблицы. Он отличается от других объектов в проблемной области управления документами, таких как обработка текстов.
Однако рассмотрите причины, по которым объект электронной таблицы может измениться.
Возможно изменение модели, лежащей в основе электронной таблицы. Это влияет на загрузку и сохранение кода, но не влияет на отображение таблицы. Поэтому обязанности по загрузке / сохранению отделены от обязанностей по рисованию. Наш класс имеет две обязанности.
Так что, если мы подумаем обо всех разумно предсказуемых причинах изменения класса и увидим, что это повлияет только на конкретные методы класса, мы увидим возможность выделить ответственность за получение более сфокусированного класса.
Пересмотренный класс будет:
@interface SpreadsheetEncoder
- (NSData *)encodedSpreadsheet:(Spreadsheet *)spreadsheet;
- (Spreadsheet *)spreadsheetFromEncodedData:(NSData *)data;
@end
@interface Spreadsheet2 : NSObject
- (NSData *)data;
- (instancetype)initSpreadsheetFromData:(NSData *)data;
- (void)drawTo:(CGRect*)targetArea withContext:(CGContextRef *)context;
@end
По мере развития продукта мы снова можем спросить себя: «Что может измениться», а затем провести рефакторинг классов, чтобы они отвечали только за одну проблему. SRP относится только к проблемной области и нашему пониманию ее в данный момент времени.
СРП, на мой взгляд, сводится к вопросу "что может измениться?" и «что будет затронуто». Когда «что может изменить» отображает только одну вещь, на которую влияют, у вас есть классы, реализующие принцип SRP.