Подтвердить что ты не робот

Должны ли взгляды содержать ссылки на модели?

Скажем, мы имеем следующие классы:

Просмотр

@interface ArticleView : UIView
@property IBOutlet UILabel *titleLabel;
@property IBOutlet UILabel *bodyLabel;
@end

Model

@interface Article : NSObject
@property NSString *title;
@property NSString *body;
@end

контроллер

@interface ArticleViewController : UIViewController
@property Article *myArticle;
@property ArticleView *myArticleView;
- (void)displayArticle;
@end

@implementation
- (void)displayArticle {
    // OPTION 1
    myArticleView.titleLabel.text = myArticle.title;
    myArticleView.bodyLabel.text = myArticle.body;    

    // ... or ...

    // OPTION 2
    myArticleView.article = myArticle;
}
@end

ВАРИАНТ 1

  • PRO: Оба представления и модели не связаны друг с другом.
  • CON: Контроллер должен знать детали как модели, так и вида.

ВАРИАНТ 2

  • PRO: Код контроллера является легким и гибким (если вид или модель меняются, код контроллера остается прежним.
  • CON: Вид и модель связаны и, следовательно, менее пригодны для повторного использования.

В OPTION 2, ArticleView должен быть изменен для хранения ссылки на модель:

@interface ArticleView : UIView
@property IBOutlet UILabel *titleLabel;
@property IBOutlet UILabel *bodyLabel;
@property Article *article;
@end

Редактор статьи затем может быть перезаписан, чтобы обновить представление соответственно:

- (void)setArticle:(Article *)newArticle {
    _article = newArticle;
    self.titleLabel.text = _article.title;
    self.bodyLabel.text = _article.body;
}

Итак, мой вопрос: какой из этих двух вариантов лучше всего подходит с точки зрения лучших практик OO и iOS/MVC?

Я, конечно, видел, как оба используются. Я видел OPTION 2, обычно используемый в подклассах UITableViewCell.

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

Чувство моей кишки состоит в том, чтобы использовать OPTION 1 просто потому, что я предпочел бы, чтобы диспетчер представлений выполнял грязную работу по привязке модели к представлению, и пусть модель и вид остаются независимыми и не знают друг о друге. Но так как некоторые взгляды предназначены для того, чтобы делать только одно, то, возможно, не так уж плохо, если бы они были привязаны к конкретной модели напрямую.

Я хотел бы услышать ваше мнение по этому поводу.

4b9b3361

Ответ 1

Это не всегда либо/или решение. Ваш первый вариант более типичен для Apple версии MVC; в iOS обычно верно, что модель и представление не говорят друг с другом напрямую, а контроллер выполняет большую часть координации между ними. Однако неразумно иметь пользовательский вид, который знает о конкретных классах в более крупной модели. У вас вполне может быть ArticleView, который знает, что делать со статьей, но ArticleView все равно должен получать любую статью, которую он отображает из контроллера, вместо того, чтобы получать ее непосредственно из более крупной модели.

Одна из целей MVC - сделать классы моделей и классов более многоразовыми. Если вы сохраните свой ArticleView очень просто, так что контроллер должен выполнять всю работу по интерпретации статьи, тогда вы можете потерять возможность повторного использования - каждый раз, когда вы хотите повторно использовать ArticleView с новым контроллером представления, вам нужно воспроизвести весь код, который интерпретирует статью для ArticleView. Кроме того, вы всегда используете один и тот же класс контроллера представления для управления ArticleView. Ни один из них не является действительно "многоразовым".

В то же время вы должны признать, что существует некоторая естественная связь между статьей и ArticleView просто в силу того факта, что ArticleView предназначен для отображения всех соответствующих деталей статьи, независимо от того, получает ли она их непосредственно из статьи или устанавливает их с помощью контроллера вида. Если статья изменяется, существует большая вероятность того, что ArticleView придется изменить, знает ли она о статье или нет.

Итак, даже если статья может быть модельным классом, может быть хорошо иметь представление, которое знает об этом. То, что вы не хотите, - это ArticleView, который знает о более крупной модели и пытается извлечь статьи из самой модели. Это ограничивает статьи, которые вы можете отображать в ArticleView, только те, которые можно найти там, где выглядит ArticleView - это мешает вам отображать статьи из других источников.

Ответ 2

Да, вы продемонстрировали понимание предмета.

ВАРИАНТ 1 - классическая структура MVC, и я рекомендую его в качестве маршрута по умолчанию для двух представленных.

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

Наиболее частое отклонение, которое я делаю, заключается в том, что реализация настолько специфична и не используется повторно, что введение специального типа контроллера приводит к получению большего количества кода для написания и поддержки, когда реализации крошечные, очень специализированные, не могут повторно использоваться и не будут расти по существу. Если программа хорошо сгибает V и C в единую реализацию и вписывается в что-то маленькое (например, десятки строк кода), я не беспокоюсь об использовании OPTION 2.

Реальность более сложная, чем та, но суть такова: не чувствуйте, что вам нужно придерживаться № 1, хотя вы, вероятно, не поймете, как использование # 2 может привести к проблемам обслуживания, пока вы не написали и не сохранили некоторые программы среднего размера в течение нескольких лет. Переход от одного к другому может внести множество изменений в отгруженную программу - чего можно было бы избежать.

Использование ВАРИАНТА 2 должно быть меньшим. Если есть сомнения, используйте опцию 1.

В любом случае, я считаю, что модель не должна знать о представлении или контроллере.

Для меня важнее строгое соблюдение при написании многоразовых компонентов.

Ответ 3

Честно говоря, иногда я сам делаю Option 2. Но вариант 1 - "из книги".

Ответ 4

С точки зрения официального руководства Apple по этой теме, MVC в качестве составного шаблона проектирования в разделе "Концепции" в Objective-C Обсуждается программный документ оба подхода, но четко формулирует предпочтение Apple вашего варианта 1 над вашим вариантом 2. Фактически Cocoa Основные компетенции перечисляет только вариант 1.

Я никогда не сожалел о реализации подхода 1-го варианта, но когда я срезал углы и пытался напрямую взаимодействовать с моделями и представлениями, я часто сожалел об этом, когда мне приходилось возвращаться и модифицировать систему на более поздняя дата.

Ответ 5

Вариант 1 - MVC. Вариант 2 - нет.

OO на самом деле на другом уровне, у вас есть объекты для Model, View и Controller, поэтому вы не можете сделать намного больше, чем OO.

Оба варианта, конечно, будут работать, но MVC существует по какой-то причине (я уверен, что вы уже сделали какое-то общее чтение как это), и вы обнаружите, что ваш код легче читать, понимать и повторно использовать, если вы следуете принципам MVC.

Ответ 6

Как говорили другие, Вариант 1 - более чистый подход. Контроллер должен быть "соединительной коробкой" между представлением и моделью.

Однако ряд реализаций этого типа подхода (например, структура, которую Microsoft вызывает MVC) пухлый для Варианта 2. Конечно, в случае Microsoft, тот факт, что View и Model знают друг о друге, позволяют IDE создавать партии кода шаблона и избавить вас от "проблем". Преимущество этого заключается в том, что вы тратите свое время на создание кода "функции", а не на код "проводки". Итак, чистый или нет, вы можете оценить, откуда они.

Как часто в разработке программного обеспечения выбор между Вариантом 1 и Вариантом 2 сводится к чистоте и прагматизму.