作为我模特的一部分,我有一个名为“幻灯片”的课程,它有两个孩子:“QuizzSlide”和“ImageSlide”。我还有另一个名为“SlideView”的类(这是我的观点的一部分),它有两个孩子“QuizzSlideView”和“ImageSlideView”。
现在我要做的是浏览幻灯片的集合并创建正确的SlideView来显示它们。问题是,要实例化SlideView,我需要知道Slide的类型。 QuizzSlide应该创建一个QuizzSlideView,而ImageSlide应该创建一个ImageSlideView。我看到两个选择:
反思。我不喜欢内省,因为它意味着构建对象的类必须详尽地列出它可以处理的对象类型。如果我在行下添加另一种类型的幻灯片,我必须修改构建器类。
使幻灯片创建其关联的视图。所以我有一个函数getView被Slide的每个子项覆盖,为该幻灯片创建正确的View。这可以工作,它会使维护更容易,但它会使程序混乱,因为模型不应包含对它所代表的视图的引用。
这就是它。我还有其他选择吗?关于如何从我的视图中解开我的模型,根据模型类型构建正确的视图并避免内省的任何想法?
由于
答案 0 :(得分:1)
我认为内省方法是最好的,但如果您担心如果引入新类(合法的问题)必须修改代码,那么我会将其设为表驱动,这将限制所需的新代码量。
(注意我还没有测试过这段代码):
static struct {
Class slideClass;
Class viewClass;
} _slideMap[] = {
{ [QuizzSlide class], [QuizzView class] },
{ [ImageSlide class], [ImageView class] }
};
#define NUM_SLIDE_MAPS (sizeof(_slideMap) / sizeof(_slideMap[0]))
然后使用:
for (id slide in _slides) {
UIView *view = nil;
CGRect frame = ...;
for (unsigned i = 0; i < NUM_SLIDE_MAPS && !view; i++)
if ([slide isKindofClass:_slideMap[i].slideClass])
view = [[_slideMap[i].viewClass alloc] initWithFrame:frame];
NSAssert(view, @"Missing slide/view map entry for class %@", NSStringFromClass([slide class]));
}
注意:由于表达式[QuizzSlide class]
不是常量表达式,因此该代码可能无法编译,在这种情况下,您将被迫使用{在运行时创建数组{1}}声明或其他一些。
您也可以使用dispatch_once()
来保存幻灯片和视图类之间的映射,从而获得更快的查找性能。
答案 1 :(得分:1)
为什么createView()
上的Factory method Slide
QuizzSlide
类在QuizzSlideView
中实现时返回ImageSlide
并在ImageSlideView
中返回CreateIterator()
指向正确的模型。
这让我想起了Iterator模式,其中{{1}}是工厂方法。
Iterator pattern in UML http://www.silversoft.net/docs/dp/hires/Pictures/itera040.gif