代码之家  ›  专栏  ›  技术社区  ›  zoul

如何防止可可控制器变得太大?

  •  6
  • zoul  · 技术社区  · 16 年前

    那个 不好,但我还是想把代码重构成几个独立的部分。

    3 回复  |  直到 16 年前
        1
  •  4
  •   Peter Hosey    16 年前

    问题不在于规模,而在于责任。你的控制器戴的帽子不止一顶吗?如果是这样,就把它炸成多个,每个类一个作业控制器。

    分类有助于扩大规模,但不影响责任。如果你仍然在一个(合并的)类中做多件事情,那么你仍然有一个问题;把它们放到不同的文件中并不能解决这个问题。

    在一个类上有多个类别会带来方法冲突的风险:在多个类别中实现同一个方法,可能是在类别B中实现它,而忘记类别a已经有一个类别。当对象向自己发送一条消息时,这将导致一个问题,期望一个类别对该消息做出响应,而得到另一个类别的响应。

    声明 全部的

    如果你的控制器戴着不止一顶帽子,把它炸成多个等级。

    我推荐martinfowler的《重构》一书。重构代码就是清理代码,而清理过大的类(以及方法和函数)就是清理的一个子集。

    当然,曾经是一个类的多个类需要一个替换来替换以前在类内部的通信。Cocoa提供了多种解决方案:

    你不需要只选一个,也不需要全部使用。哪些解决方案是合适的将取决于新类之间的通信需求。

        2
  •  3
  •   obijohn    16 年前

    分类才是出路。诀窍(对于“不那么独立”的东西)是在主controller.h文件(不是单独的controller+category.h文件,没有)中声明category方法,然后在controller+category.m文件中实现它们。这样地:

    //******************
    // MyController.h
    //******************
    #import <Cocoa/Cocoa.h>
    
    @interface MyContoller : NSObject 
    {
        NSWindow   *window;
    
        // stuff to implement in the category
        NSComboBox *someCombo;
        NSButton       *someButton; 
    }
    
    @property IBOutlet NSWindow   *window;
    
    @property IBOutlet NSComboBox *someCombo;
    @property IBOutlet NSButton   *someButton;
    
    @end
    
    @interface  MyController (MyCategory)
    
    - (IBAction)someComboSelected:(id)sender;
    - (IBAction)someButtonPressed:(id)sender;
    
    @end
    
    //**************************
    // MyController+MyCategory.m
    //**************************
    #import <Cocoa/Cocoa.h>
    #import "MyController.h"
    
    @implementation MyContoller (MyCategory)
    
    - (IBAction)someComboSelected:(id)sender
    {
        ....
    }
    
    - (IBAction)someButtonPressed:(id)sender
    {
        ....
    }
    

    显然,我没有包括“MyController.m”,在这里你可以放置“@synthetic”以及主控制器/从nib唤醒/任何其他需要的东西。无论如何,这样做可以让控制器方法访问category方法,反之亦然,category方法可以访问所有属性。

        3
  •  2
  •   Chris Hanson    15 年前

    在常规Cocoa中,NSViewController可以通过允许窗口中的“组件”拥有自己的总体控制器来管理控制器的复杂性。