context
公司最近的一个项目,在UI上有比较严格的要求: 每种屏幕下地控件的尺寸要求绝对的精确
实现方案
使用的纯代码 ,加上要适配 iOS 7 ,所以 Size-Class
就不用考虑了.
分析情况,其实控件的相对位置是固定的.开始也是用了 Masonry
,只是需要提供不同屏幕下地控件尺寸,间距等内容.
如何更优雅可拓展的实现
当然,你可以在布局的时候,写if-else
和 switch-case
来对不同屏幕的尺寸参数赋不同的值. 可是如果以后要修改呢,苹果要抽风推出了新尺寸的iPhone,而你被要求去适配呢? 你岂不是要找遍整个项目修改原来的分支判断.
就是说,以上的实现方式:
- 维护性差 人工维护成本高,也破坏了
开闭原则
- 扩展性差 如果有新的要求,需要逐个重写.
设计模式选择
对于这种情况,一开始首先是想到了策略模式
,因为我考虑每种屏幕都可以算作是一种方案.而至于策略模式
是行为模式,也当然可以通过重构技巧把属性替换为方法,完成策略的行为需求.我兴冲冲的绘制了草稿(OC没有合适的UML类图工具,所以用了普通的绘图工具,线条种类不足以完全表示UML类图中得关系)
为了规避策略模式需要让客户端(调用者)知道具体策略的缺点(我认为是缺点),我采用重构手法将逻辑下放到context
,DeviceType
能决定具体的策略,算是简单工厂
和策略模式
的结合.
但是在绘图的过程中,想到,这有点算过度设计了, 其实我只是需要一个能够保持属性的对象,然后在布局的时候,使用它 ,使用策略模式,意味着我需要把所有的属性的 getter
实现,才算符合策略
的本意.
这次是一次失败的案例:
- 对这种级别的方法使用策略,大材小用,无缘故的增加复杂度而已
- 一开始就不应该偏执的考虑将属性重构为方法,这里只是简单地赋值,不需要拦截其
get
过程
然后想到了,建造者模式: 创建型的模式,很符合我要个布局对象的需求,也给他弄上了个简单工厂,避免了在控制器中出现分支语句:
没画出具体的产品(布局),请见谅.
但是, 这里又有一个问题: 在我以前的经验中, 建造者模式是用来区分过程固定,但是有需要多样化的建造方式的. 在我的场景中,我最复杂的情况也仅仅是赋值而已, 所以,也是不适合的.
最终方案
其实最简单的,往往是最好的.最重要的是弄明白自己需要的. 我仅仅需要几个承载着不同属性的对象.最合适的方案应该是 简单工厂
,而且可以把逻辑下放到简单工厂中.这模式太简单了,就不画图了.
总结
在设计模式的选择,甚至是去除设计模式的过程中,需要开发者有足够的经验来做决定. 今天就走了一个弯路,好在及时发现了.如果用策略模式或者建造者编码,将来的维护成本肯定要上升.
下一篇中,将用代码实现.