Objective c 实例化一个对象';s类型取决于另一个对象';s型

Objective c 实例化一个对象';s类型取决于另一个对象';s型,objective-c,oop,design-patterns,Objective C,Oop,Design Patterns,作为我模型的一部分,我有一个名为“幻灯片”的班级,它有两个孩子:“测验幻灯片”和“图像幻灯片”。我还有另一个叫做“SlideView”的类(这是我观点的一部分),它有两个孩子“QuizzSlideView”和“ImageSlideView” 现在我要做的是浏览一组幻灯片,并创建正确的幻灯片视图来显示它们。问题是,要实例化SlideView,我需要知道幻灯片的类型。QuizzSlide应创建QuizzSlideView,ImageSlide应创建ImageSlideView。我看到两种选择: 内省

作为我模型的一部分,我有一个名为“幻灯片”的班级,它有两个孩子:“测验幻灯片”和“图像幻灯片”。我还有另一个叫做“SlideView”的类(这是我观点的一部分),它有两个孩子“QuizzSlideView”和“ImageSlideView”

现在我要做的是浏览一组幻灯片,并创建正确的幻灯片视图来显示它们。问题是,要实例化SlideView,我需要知道幻灯片的类型。QuizzSlide应创建QuizzSlideView,ImageSlide应创建ImageSlideView。我看到两种选择:

  • 内省。我不喜欢内省,因为它意味着构建对象的类必须详尽地列出它可以处理的对象类型。如果我添加另一种类型的幻灯片,我必须修改生成器类

  • 使幻灯片创建其关联视图。所以我有一个函数getView,它被幻灯片的每个子级覆盖,为该幻灯片创建正确的视图。这将起作用,并使维护更容易,但它会使程序变得一团糟,因为模型不应该包含对它所表示的视图的引用

  • 差不多就是这样。我还有其他选择吗?关于如何将我的模型与我的视图分离、根据模型类型构建正确的视图以及避免内省,有什么想法吗


    谢谢

    我认为内省方法是最好的,但是如果您担心在引入新类时必须修改代码(这是一个合理的考虑),那么我会将其设置为表驱动,这将限制所需的新代码量

    (注意,我没有测试此代码):

    然后使用:

    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]));
    }        
    
    for(id幻灯片中的幻灯片){
    UIView*view=nil;
    CGRect帧=。。。;
    对于(无符号i=0;i
    注意:此代码可能无法编译,因为表达式
    [QuizzSlide class]
    不是常量表达式,在这种情况下,您将被迫在运行时使用
    dispatch\u once()
    语句或类似语句创建数组

    您还可以使用
    NSDictionary
    来保存幻灯片类和视图类之间的映射,并获得更快的查找性能。

    为什么不在
    幻灯片
    类中使用
    createView(),当在
    QuizzSlide
    中实现时,返回一个
    QuizzSlideView
    并在
    ImageSlide
    中返回一个指向正确模型的
    ImageSlideView

    这让我想起了模式,
    CreateIterator()
    是工厂方法


    我不明白这一复杂情况(也许我遗漏了什么)。在控制器中,如果([slideInstance isKindOfClass:[QuizzSlide class]]){view=[[QuizzView alloc]initWithFrame…];}如果(…){…}
    ,如果我想使用内省,这不是一个
    的例子吗?是的。但这意味着,对于我稍后添加的每种幻灯片类型,我都必须返回到该控制器并添加另一个“isKindOfClass”,此外,我想对这些幻灯片类集体执行的任何操作都需要一个“isKindOfClass”。我想避免那样,谢谢。这是内省问题的合理解决方案,我可能会同意。我在研究解决方案时偶然发现了访问者模式,但我仍在尝试它是否以优雅的方式解决了我的问题。是的,这是我提到的第二个选择,这个解决方案的唯一问题是我将模型与我的视图绑定在一起。这通常是不好的,但在我的例子中尤其糟糕,因为模型和视图有不同的生命周期。等等,除非你是说幻灯片应该只创建对象而不保存引用?六羟甲基三聚氰胺六甲醚。。。这可能真的有用!我试试看。谢谢。为什么模型元素不知道他们的观点?这是因为假设视图相对于其模型不太稳定,并且您希望避免不必要地将更改传播到模型中。你提到的“可怕的混乱”。如果您认为视图变化太大,可以在实例化视图时将视图插入幻灯片中。但这似乎又是一场混乱,就像自省。每张幻灯片一个视图的关系可能是稳定的,很像迭代器示例。您可以选择您的战斗(混乱),并接受模型了解其视图的风险。
    
    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]));
    }