前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式之结构型模式(下)

设计模式之结构型模式(下)

作者头像
Sheepy
发布2018-09-10 12:19:10
3930
发布2018-09-10 12:19:10
举报
文章被收录于专栏:我杨某人的青春满是悔恨

上篇已经介绍了适配器模式、桥接模式和组合模式,这篇将介绍装饰者模式、外观模式、享元模式和代理模式。

装饰者(Decorator)

装饰者模式可以动态地给一个对象添加一些额外的职责。

举个例子,我们要给UIView及其子类创建一个装饰者,在调用addSubview方法的时候打印一条调试信息:

代码语言:javascript
复制
class LogDecorator: UIView {
    var view: UIView
    
    init(frame: CGRect, view: UIView) {
        self.view = view
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func addSubview(view: UIView) {
        self.view.addSubview(view)
        log()
    }
    
    func log() {
        // ...
        print("Add a subview.")
    }
}

LogDecorator继承自UIView,在能够使用UIView的地方也同样可以使用LogDecorator。这个装饰者可以用来装饰UIView及其所有子类,譬如装饰一个 Button:

代码语言:javascript
复制
let button = LogDecorator(frame: frame, view: UIButton())
button.addSubview(UIView())

//打印信息
Add a subview.

装饰者模式跟对象适配器模式很像,但是装饰者跟被装饰者必须是继承自同一个抽象类的,对外提供一致的接口;而适配器跟被适配者却没有这个限制。虽然适配器也可以给被适配者增加新的职责,扩展它的功能,但是它们的目的是不同的,前者是为了动态地给某个对象增添新功能,而后者则是为了包装已有对象,对外提供符合需求的接口。

外观(Facade)

外观模式为子系统中的一组接口提供一个一致的界面。

这个呢其实没什么可多说的,无非是新建一个类用作用户界面,将一个复杂子系统中的类组合起来,对外提供一个易用的高层接口,隐藏内部细节。这里蕴含分层的思想,可以让系统模块化程度更高,便于复用,也便于使用。

享元(Flyweight)

享元模式运用共享技术有效地支持大量细粒度的对象。

Flyweight 是一个共享对象,它包含内部状态和外部状态,内部状态是那些可以用来共享的状态,而外部状态则是需要根据不同场景进行计算得到的状态。

有些做 iOS 开发的同学可能对享元模式这个名字比较陌生,但其实我们几乎天天都要跟它打交道。比如 TableView 和 CollectionView 中 Cell 的重用机制,就是运用享元模式的一大典范。Cell 对象就是一个 Flyweight,Cell 包含的那些 Subview(以及Subview 的位置大小颜色等信息)都是内部状态,而 Cell 的高度、要显示的内容等等,这些都是外部状态,是需要在 Cell 显示之前计算得到的。说到这里想必大家也明白享元模式的作用了,对的,就是为了节约内存。

代理(Proxy)

代理模式为其他对象提供一种代理以控制对这个对象的访问

代理模式在形式上其实跟装饰者模式是差不多的,代理者跟实际对象都继承自同一个抽象类,代理者持有一个指向实际对象的指针。使用时可以用代理对象代替实际对象,代理对象控制对实际对象的存取,并可能负责创建和删除它,其他附加功能根据代理的类型而有所不同。

代理一般分为以下几种类型:

  • 远程代理(Remote Proxy):负责对请求及其参数进行编码,并向不同地址空间的实体对象发送已编码的请求。
  • 虚代理(Virtual Proxy):缓存实体的附加信息,实现延迟加载(Lazy Load)等功能。
  • 保护代理(Protection Proxy):检查调用者是否拥有对实体的访问权限,并分情况进行处理。
  • 智能指引(Smart Reference):取代简单的指针,在访问对象时执行一些附加操作(控制引用计数、首次加载持久对象、加锁保证线程安全等)。

由此可见,iOS 开发中无处不在的 Delegate(委托)其实跟代理模式是有区别的,委托对象跟实际对象并没有一致的接口,只是在某些特定的时间节点调用委托对象中的方法(一般以对应实际对象为参数),从而对实际对象进行操作。

小结

到此为止结构型模式就介绍完了,想必大家也发现了,其实绕来绕去就是类继承跟对象组合罢了,只是因为设计目的不同以及一些实现上的细微差别,才分出了这么多模式。

设计模式就像公式定理,你可以把它背下来,这样在跟人交流或者阅读别人的系统的时候,会少很多障碍。但比公式更重要的是推导过程,对应到日常开发中就是系统设计能力。套用公式并不能解决所有问题,所以大家在学习设计模式的时候还是要多学习它的设计思路,知道每个模式是针对什么场景设计的,这样设计的好处与弊端,它具体是怎么实现的,场景变化的时候可以做怎样的变通,等等。只有这样,你才能真正从设计模式中受益。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016.02.24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 装饰者(Decorator)
  • 外观(Facade)
  • 享元(Flyweight)
  • 代理(Proxy)
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档