Cocoa Design Patterns

1,116 views

Published on

Cocoa Design Patterns Talk on 2010 China Mobile Development Conference

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,116
On SlideShare
0
From Embeds
0
Number of Embeds
12
Actions
Shares
0
Downloads
10
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • 什么是设计模式\n说白了就是经验的积累。在软件开发中,慢慢形成了一些设计方法,这些方法是一些经过实践证明的有效的解决方案。\n\nCocoa\n苹果公司推出的应用程序框架,基于Objective-C,主要用于Mac桌面应用和iOS移动应用中。\nObjective-C,动态语言,\n\n
  • \n
  • 如果你不理解为什么要把模块按照MVC的方式分开,不妨把所有的代码先写在一起,有时候,这样做没什么问题,而且,如果你从没有把它们写在一起过,你可能很难真正了解把它们分开到底有什么好处。如果有一天,你发现,每次为了增加或者修改一个数据属性就要修改五六个地方,也许你自己就意识到需要把一部分独立出来集中在一起。又有一天,老板让你把同一组内容用不同的方式展示,或者同一个界面需要显式几组不同的数据,你也许就会发现有总有某些部分的代码是一起变化。\n理想状态下,Model是不需要考虑数据是如何被展示的,View也不需要考虑和限制所展示的数据类型。两部分没有任何依赖关系,只由controller来产生交互。\n多Model的情况:\n数据源不同。来自本地,来自网络。或者不同的数据格式,有的是json,有的是rss,有的是xml。或者数据来自不同的帐号\n数据分类不同,采用不同的过滤、分类和排序方式\n多视图的情况:\n列表,详细,\n\n
  • Cocoa框架本身大量使用了MVC模式,或者说就是按照MVC量身定做的。例如tableview,就以delegate的方式将控制器部份的代码和数据源部份的代码代理给用户实现而不是全部实现在tableview中,展示方式则可以通过不同的cell有各种变化,非常灵活的支持各种数据和各种展示方式。\n\n
  • \n
  • 单体,全局只有一个实例,通过统一的接口获得实例,实例的创建过程通常被封装起来,不能被直接调用。\n通常用于下面的场合:访问独立的系统资源,每次访问都创建新的实例会造成内存浪费或者影响效率;或者对全局变量的封装,减少全局变量带来的副作用。\n\n
  • \n
  • 静态方法? 还是singleton?\n在实现单体时,通常会重载创建接口,防止单体被反复创建。另外,要考虑对单体访问的线程安全问题。\n单体的生命周期常常是整个程序的运行周期,如果不是这样,需要考虑是否有必要采用单体模式。在设计单体时,还要考虑单体实例占用的内存。\n\n
  • Objective-C的语言特性,可以不用创建子类,直接为已有的类增加方法。其原意是将方法分类实现。可以很方便的扩展类,甚至扩展cocoa frameworks中的类型。同时,实现一些模式也更方便。\n\n
  • Adapter模式。模块A通过interface A来访问对象,而Class B只提供以Interface B的形式来访问,这时我们会加入一个Adapter Class C,它或者包含了Class B的对象,是has-a的关系,或者是Class B的一个子类,完成从interface A到interface B的转换,就好象把一个三相插头变成两相插头。\n\n
  • 而借助Category,我们不需要产生一个新的Adapter Class,而可以直接在Class B上做扩展,为Class B实现interface A,完成转换。\n\n
  • \n
  • 在使用category时,需要注意方法名冲突的问题,如果两个category中都使用了相同的方法名,互相会替换,结果可能无法预期。慎重替换已有实现。\n\n
  • 模版方法模式。算法框建或者处理流程相对固定的情况下,仍然保留定制其中某些步骤的灵活性。通常,对这些步骤的重新定义是通过子类重载来完成的。\n\n
  • Cocoa frameworks中大量使用了模版方法模式。比如UIViewController中的这些方法,controller加载视图的流程是固定的,但允许我们通过重载这些方法来干预视图的加载过程。UIView的drawRect也是一个模版方法,通过重载这个方法来定制自己的视图。\n\n
  • 在查阅文档时,要注意哪些方法是模版方法,是可以重载的,哪些方法不是模版方法,不适于重载。还要注意缺省的模版方法做了什么,是否需要在重载后调用。很多缺省的模版方法什么也没有做,在重载时可以为了考虑向后兼容而调用,也可以干脆不调用。有的缺省模版方法明确说明不要调用,比如loadView。有的则必须调用,比如dealloc。\n\n
  • \n
  • 委托模式。一个对象,在完成某个通用功能的过程中,某些技术特性代理给一个委托对象来实现。这个被委托的对象只需要实现约定的接口,无需继承关系,源对象无需知道被委托的对象是什么类,对被委托对象的约束很小,两者是弱引用关系,耦合程度比Template Method模式更低。\n\n
  • Cocoa中最典型的例子是UITableView,这个视图类把和数据有关的细节委托给一个数据源对象,这样,无论什么样的数据源,只要实现了UITableViewDataSouce协议,就可以作为tableview的数据源;同时,将管理、修改tableview的细节委托给另一个对象,通常是一个控制器。试想,如果用Template Method模式来设计,必须创建父类是UITableView的子类,一旦此视图中的内容和其它类中的内容有关联,则各种视图子类之间需要建立联系,产生复杂的关联。\n\n
  • 在使用delegate模式时,需要注意delegate关系的生存期。在委托关系建立之前,委托方法是不会被调用的。objective-c,对空对象调用方法不会出错,所以当预期的功能不工作时,检查委托关系是否被建立。当被委托对象被析构的时候,需要解除委托关系,否则会出现非法内存访问。\n\n
  • Delegate模式实现简便,无需继承,使用灵活,被广泛使用。但需要注意,委托关系是一对一的关系,同一时间被委托的对象只能有一个,如果需要一对多的关系,可以考虑observer模式。协议接口定义时,objective-c 2.0开始支持可选方法,在调用此类方法的时候,需要检查被委托对象是否实现了该方法。委托关系需要是弱连接关系,不retain,否则很容易因为循环引用而产生内存泄露。\n\n
  • 观察者模式。有些对象之间存在这样的关系,当一个对象状态发生变化时,其它对象需要根据其状态的改变做响应的操作,但这些对象又相对独立,彼此不希望建立依赖关系。\n\n
  • cocoa的Notification机制采用了Observer模式,实现了一对多的广播通知。观察者可以向Notification Center注册它所关注的消息,每当这个消息产生,所有关注此消息的观察者都会被通知到。被观察者无需知道谁会关注这个消息。消息的订阅和分发完全由Notification Center管理。需要注意的是,当观察者被dealloc时,需要退订阅,否则有可能发生非法地址访问的错误。Notification可以有同步和异步两种方式,可以通过通知队列来发送异步通知。Mac SDK还支持进程间的消息通知。\n\n
  • 通过key-value observing,视图对象可以通过控制器对象监测数据对象属性的变更,这一技术被用户binding的实现。思考题,Key-value observing是否可以通过template method模式或者delegate模式来实现?\n\n
  • \n
  • \n
  • Cocoa Design Patterns

    1. 1. 10/20/10
    2. 2. • – – –10/20/10
    3. 3. • • • •10/20/10
    4. 4. • – • – • – •10/20/10
    5. 5. •10/20/10
    6. 6. • NavigationController ViewController TableController ViewController View TableView View SubView1 HeadView SubView1 SubView2 FootView SubView2 ModelController Model 1 Model 210/20/10
    7. 7. • – – – –10/20/10
    8. 8. • – Cocoa • [UIApplica,on
sharedApplica,on] • [NSBundle
mainBundle] • [NSNo,fica,onCenter
defaultCenter] • ....10/20/10
    9. 9. •10/20/10
    10. 10. • – Objec,ve‐C – – –10/20/10
    11. 11. •10/20/10
    12. 12. •10/20/10
    13. 13. • Category – hEp://code.google.com/p/google‐toolbox‐for‐mac/ – hEp://code.google.com/p/iphone‐classes – hEp://code.google.com/p/iphonebits – hEp://regexkit.sourceforge.net/ – ....10/20/10
    14. 14. • Category – –10/20/10
    15. 15. • – –10/20/10
    16. 16. • – – loadView – viewDidLoad – viewDidUnload10/20/10
    17. 17. • – –10/20/10
    18. 18. • – – – – –10/20/10
    19. 19. • – – –10/20/10
    20. 20. • – – – –10/20/10
    21. 21. • – • •10/20/10
    22. 22. • – – –10/20/10
    23. 23. • – – – –10/20/10
    24. 24. • Cocoa Observer – Post Object Notification Center Observer Observer Observer10/20/10
    25. 25. • Cocoa Observer – - (void)setOpeningBalance:(double)theBalance { [self willChangeValueForKey:@"openingBalance"]; openingBalance=theBalance; [self didChangeValueForKey:@"openingBalance"]; }10/20/10
    26. 26. •10/20/10
    27. 27. •10/20/10

    ×