context
今天一同学问我封装时候的基本依据. 然后要详细一点 . 所以写了这篇文章.
封装的场景
- 最舒服的方式应该是基于需求的封装 , 比如知道自己想怎么用了, 然后写出用法 , 编写方法的实现.
- 可能是为了日后的拓展而进行的封装
对于第二种方式, 个人是不太建议的. 我们不应该去臆测将来的需求. 如果真的需要了, 通过重构去实现即可.
但是还是借着今天的机会, 说说我封装的时候的思考方式吧.
- 阅读方法, 明白方法的目的 ,例如以下的代码,一个关键帧动画.
1 | - (CAKeyframeAnimation *)createAnimation:(CGRect)frame { |
- 提取可能的变量 ,方法要灵活性, 那么就需要把需要变化的参数开放给方法使用者(以下简称开发者). 通常,方法中的局部变量都可以作为方法的参数.或者根据实际需要,添加其他参数.
1 | int waveWidth = 50; |
特别的, 能根据参数计算的局部变量,不应该作为参数,否则就冗余了.比如下面的两个
1 | int xOffset = frame.origin.x; |
包含复杂计算过程的变量,也应该把计算过程封装到方法中.只暴露出索引,比如下面,我们将 -100抽出来,供使用者自定义,当然,可以根据需要把 40 和20 暴露
1 | int height = -100 + arc4random() % 40 - 20; |
所以,应该添加两个额外的参数(加上原来的frame,一共三个参数)
1 | waveWidth |
方法的安排
类方法 or 实例方法
- 看返回值的类型(CAKeyframeAnimation *)是否和容器(NSObject)有依赖关系(比如依赖属性) ,如果没有, 直接使用类方法,因为可以省去实例化类的步骤.
- 如果有关系,可以采取先实例,然后封装到类方法的方式.
- 方法安排
- 首先应该提供一个全参数方法,保证开发者能够更改所有值. 例如本例中,可以根据到现在的原则设计出一个这个方法:
1 | + (CAKeyframeAnimation*)createAnimationWithFrame:(CGRect)frame waveWidth:(int)waveWidth heightFactor:(int)heightFactor |
- 便捷调用
并不是所有开发者都想一次次的写所有参数,所以应该提供便捷的调用方法.
+(CAKeyframeAnimation*)curveAnimationWithFrame:(CGRect)frame{
return [GUIFrameAnimation createAnimationWithFrame:frame waveWidth:50 heightFactor:100];
}
结语
这只是封装, 远远不够一份可读性高代码的要求. 应该继续进行重构. 但是不在现在讨论的范畴 .所以暂不讨论了.