今年刚开始的时候就想了很多,但是拖拖拉拉的到了五月才进行设想的第一步(嗯,没错…是今年目标的第一阶段…)
入职新公司一年多了,在需求的包围下业务代码咔咔的写了很多,写着写着..发现不对啊,这个还有那个我好想在哪见过一样的…这种搭讪的桥段让我决定先总结总结当前的的一些问题,然后学习如何重构。
问题归纳
所有人在尝试重构前都会遇到的几个大boss:
① 重复代码过多
举个简单的例子: 我们光一个轮播图样式就已经出现了3、4个以banner为后缀的文件。
② 结构定义不够规范
从整个页面结构这么大的角度而言就已经出现了好几套,改bug看别人写的结构还得想一想...
③ 新旧兼容问题
在业务发展一定阶段的时候,一定会遇到兼容的问题,新的结构摆在这里,但是为了兼容旧结构居然…无视新的结构,不采用一层抽象替换,而是直接使用旧的结构
总而言之,即便是业务代码也随着岁月积累了越来越多的问题,而且现在还在继续...所以一边学习一边决定走上重构的道路。
重构第一阶段
以拥有3、4个以banner为后缀文件的轮播图为例:
旧结构
当前业务同时在使用BannerView和BannerCell两种轮播图控件类型,而不同的业务在添加新功能时并不是在现有代码的基础上进行修改,反而是在不断的复制新的控件以满足新需求。
第一步: 创建抽象层
新结构将通用部分进行抽象,每一个业务都只需要考虑不同的部分,减少了代码的重复性,也让整体的结构变得更加的清晰。
第二步:对象的多态性
以banner的size进行考虑,目前是直接使用判断语句来调整layout布局:
如果是A,就采用A关联的size,
如果是B,就采用B关联的size
.....
判断条件是最简单直接表达出类多态的效果,但是这里面涉及到我一直以来的困惑:
什么时候用判断条件?什么时候用对象的多态性?
就目前可以给的建议:
如果对象间差异性很大,也就是非通用性的部分已经到了新写一个对象的程度,就直接用多态性来做。
因为业务不只是在对size有差异,所以将判断语句移除替换成各个业务对象自己进行处理。
第三步:细节把控
① 提炼函数
如果在定义一个函数名时,左看看右看看无法完全覆盖当前函数的内容,那么就说明是时候提炼多个函数了
② 命名格式
首先,对于类中的私有函数可以在函数名前加一些标识符,如“_”或”p”
- (void)initializeView {
[super initializeView];
self.clipsToBounds = YES;
[self __initialWithScrollImageView];
[self __initialWithNotification];
}
其次,对于一些参数或函数的命名不是越长越好,而是能明确的说明该参数在使用范围内是干啥的就行。
举个例子:
- (NSArray<NSString *> *)imageArray{}
乍看之下,这个方法…应该是想要得到所有的图片信息,返回值的数组中又是字符串..一番脑部小活动
- (NSArray <NSString *> *)imageUrls{}
但是,改成这样就很直接...拿的就是图片的Url,猜都不用猜。
③ Delegate和block
在一些小的控件中都会同时存在Delegate和block,是Delegate不能满足你还是block不够强大?
如果只是类中只会需要处理少量的外传以及参数很少的话,会优先考虑block;相反情况下则会以delegate为主,而delegate内部的方法命名也常是我很焦虑的一点:
@protocol MallIndexBannerScrollDelegate <NSObject>
@optional
- (void)bannerView:(MallBaseBannerView *)bannerView willDisplayCell:(UICollectionViewCell *)cell indexPath:(NSIndexPath *)indexPath;
- (void)bannerView:(MallBaseBannerView *)bannerView didSelectItemAtIndex:(NSInteger)index;
@end
大部分人会觉得应该去模仿官方的代理回调方法格式,道理是没有错,但是首先还是以自己的风格为主,其次减少无用参数的外传
④ 方法的迭代
功能的重构是不应该影响业务的使用,但经常会发生删除或者调整了某个方法,在检查没有完全覆盖的情况下可能导致崩溃或者无法点击等问题。
对于通用控件而言,可以使用deprecated声明
+ (NSArray *)allHUDsForView:(UIView *)view __attribute__((deprecated("Store references when using more than one HUD per view.")));
但是对于业务线内部使用的控件,除了及时检查,各个业务线中共享控件使用文档之外,好像也无法要求再多。
总结
刚开始看关于重构的一些资料和书,先拿轮播图小小的试水,还有一些类似灵活性、新旧逻辑兼容问题等慢慢来,动手前考虑好架构大方向。
网友评论