Глава 10: Работа с протоколами и делегатами ← Вернуться к списку глав Глава 12: Тестирование в Objective-C

Глава 11: Лучшие практики и паттерны проектирования

Добро пожаловать в одиннадцатую главу нашего увлекательного путешествия по Objective-C! В этой главе мы познакомимся с лучшими практиками и паттернами проектирования, которые помогут вам создавать структурированные и легко поддерживаемые приложения. Мы обсудим MVC (Model-View-Controller), узнаем, как создавать Singleton классы, и рассмотрим паттерн Observer с использованием NSNotificationCenter. Как всегда, мы объясним все простым и понятным языком, чтобы вы могли легко во всем разобраться.


11.1. Что такое паттерны проектирования и зачем они нужны?

Паттерны проектирования

Почему важно знать паттерны проектирования?


11.2. MVC (Model-View-Controller): разделение логики приложения

Что такое MVC?

Почему использовать MVC?

Как MVC работает в iOS-приложениях?

Пример использования MVC

Шаг 1: Создание модели

// Person.h
@interface Person : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;

@end

// Person.m
@implementation Person

@end

Шаг 2: Настройка представления (View)

Шаг 3: Реализация контроллера

// ViewController.h
@interface ViewController : UIViewController

@property (nonatomic, strong) Person *person;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UILabel *ageLabel;

@end

// ViewController.m
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Инициализация модели
    self.person = [[Person alloc] init];
    self.person.name = @"Иван";
    self.person.age = 30;
    
    // Настройка представления
    [self updateView];
}

- (void)updateView {
    self.nameLabel.text = self.person.name;
    self.ageLabel.text = [NSString stringWithFormat:@"%ld лет", (long)self.person.age];
}

@end

11.3. Singleton: создание классов-одиночек

Что такое Singleton?

Когда использовать Singleton?

Реализация Singleton в Objective-C

Пример создания Singleton-класса

// SettingsManager.h
@interface SettingsManager : NSObject

+ (instancetype)sharedManager;

@property (nonatomic, strong) NSString *appTheme;
@property (nonatomic, assign) BOOL notificationsEnabled;

@end

// SettingsManager.m
@implementation SettingsManager

+ (instancetype)sharedManager {
    static SettingsManager *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[SettingsManager alloc] init];
        // Инициализация по умолчанию
        sharedInstance.appTheme = @"Light";
        sharedInstance.notificationsEnabled = YES;
    });
    return sharedInstance;
}

@end

Использование Singleton

// Получение общего экземпляра
SettingsManager *settings = [SettingsManager sharedManager];

// Использование свойств
settings.appTheme = @"Dark";
BOOL notifications = settings.notificationsEnabled;

Предостережения при использовании Singleton


11.4. Observer: использование NSNotificationCenter для уведомления объектов о событиях

Что такое паттерн Observer?

NSNotificationCenter в Objective-C

Как работает NSNotificationCenter

Пример использования NSNotificationCenter

Шаг 1: Добавление наблюдателя

// В классе, который будет получать уведомления
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(handleNotification:)
                                             name:@"DataUpdatedNotification"
                                           object:nil];

Метод обработки уведомления

- (void)handleNotification:(NSNotification *)notification {
    NSLog(@"Получено уведомление о обновлении данных");
    // Обработка уведомления
}

Шаг 2: Публикация уведомления

// В классе, который отправляет уведомление
[[NSNotificationCenter defaultCenter] postNotificationName:@"DataUpdatedNotification" object:nil];

Шаг 3: Удаление наблюдателя

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Использование информации в уведомлениях

Публикация уведомления с информацией

NSDictionary *userInfo = @{@"data": updatedData};
[[NSNotificationCenter defaultCenter] postNotificationName:@"DataUpdatedNotification" object:nil userInfo:userInfo];

Получение информации в наблюдателе

- (void)handleNotification:(NSNotification *)notification {
    NSDictionary *userInfo = notification.userInfo;
    id data = userInfo[@"data"];
    // Использование полученных данных
}

Практический пример

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

Шаг 1: Когда данные обновлены, публикуйте уведомление

- (void)dataDidUpdate {
    NSDictionary *userInfo = @{@"data": self.data};
    [[NSNotificationCenter defaultCenter] postNotificationName:@"DataUpdatedNotification" object:nil userInfo:userInfo];
}

Шаг 2: В классах, которым нужно знать об обновлении данных, добавьте наблюдателей

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleDataUpdate:)
                                                 name:@"DataUpdatedNotification"
                                               object:nil];
}

- (void)handleDataUpdate:(NSNotification *)notification {
    NSDictionary *userInfo = notification.userInfo;
    id data = userInfo[@"data"];
    // Обновите интерфейс или выполните необходимые действия с данными
}

Шаг 3: Не забудьте удалить наблюдателя

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

11.5. Практические задания

Задание 1: Реализация MVC

  1. Создайте приложение, которое отображает список задач (To-Do List).
  2. Model: создайте класс Task с свойствами title и completed.
  3. View: используйте UITableView для отображения списка задач.
  4. Controller: контроллер должен управлять данными модели и обновлять представление при изменении задач.

Решение:

Задание 2: Создание Singleton-класса

  1. Создайте класс DataManager, который будет Singleton.
  2. Класс должен содержать массив dataArray для хранения данных.
  3. Добавьте методы для добавления и получения данных.
  4. Используйте DataManager в разных частях приложения для доступа к общим данным.

Решение:

// DataManager.h
@interface DataManager : NSObject

+ (instancetype)sharedManager;

@property (nonatomic, strong) NSMutableArray *dataArray;

- (void)addData:(id)data;
- (NSArray *)getAllData;

@end

// DataManager.m
@implementation DataManager

+ (instancetype)sharedManager {
    static DataManager *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[DataManager alloc] init];
        sharedInstance.dataArray = [NSMutableArray array];
    });
    return sharedInstance;
}

- (void)addData:(id)data {
    [self.dataArray addObject:data];
}

- (NSArray *)getAllData {
    return [self.dataArray copy];
}

@end

// Использование в разных местах приложения
[[DataManager sharedManager] addData:@"Новые данные"];
NSArray *allData = [[DataManager sharedManager] getAllData];

Задание 3: Использование NSNotificationCenter

  1. В одном классе публикуйте уведомление @"UserLoggedInNotification" при входе пользователя в систему.
  2. В другом классе добавьте наблюдателя на это уведомление.
  3. При получении уведомления выводите сообщение "Пользователь вошел в систему".

Решение:

В классе авторизации:

- (void)loginUser {
    // Логика входа пользователя
    [[NSNotificationCenter defaultCenter] postNotificationName:@"UserLoggedInNotification" object:nil];
}

В классе, который должен реагировать на вход пользователя:

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(userDidLogin:)
                                                 name:@"UserLoggedInNotification"
                                               object:nil];
}

- (void)userDidLogin:(NSNotification *)notification {
    NSLog(@"Пользователь вошел в систему");
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

11.6. Заключение

Поздравляем! Вы познакомились с некоторыми из самых важных паттернов проектирования в Objective-C — MVC, Singleton и Observer. Эти паттерны помогают создавать структурированные, гибкие и легко поддерживаемые приложения. Понимание и использование этих паттернов является ключом к профессиональной разработке и позволит вам создавать качественные и масштабируемые проекты.


Что дальше?

В следующей (и завершающей) главе мы подведем итоги нашего путешествия по Objective-C, обсудим, как продолжать развиваться как разработчик, и предложим дополнительные ресурсы для углубления знаний.

Не забывайте практиковаться! Применение паттернов проектирования в ваших проектах поможет закрепить знания и повысить качество вашего кода.

Удачи и до встречи в следующей главе!

Глава 10: Работа с протоколами и делегатами ← Вернуться к списку глав Глава 12: Тестирование в Objective-C

Просмотров: 39