不要滥用设计模式
最近在做代码剥离重构, 有一个基础库A,作为面向业务开发者的接口库,随着业务的发展,很多内容都往里面塞。虽然,中间每次添加都或多或少考虑了解耦,抽象了很多协议接口,但架不住常年累月的堆积啊。
熟悉设计模式的人,对单例模式一定不陌生吧。一次创建、处处可用。也不用担心用错。
这里讲到的是一个解析配置文件的单例, 作为配置文件的管理类, 内部会包含多个不同文件的管理对象,然后对外提供统一的接口。 但是这些管理对象呢,又存在相互依赖的关系。 然后呢, 有部分文件的管理对象就也设计成了单例, 又有一部分的文件的管理对象却是普通对象。设计成单例的文件管理对象,基本上是被其它管理对象或者其它类依赖了的。库中的其它类有的依赖管理对象,有的依赖了具体文件的管理对象。总之,就是有点乱。
初始类图关系大致如下:
现在,有一个需求,进入每个页面后,页面的配置更改不能影响全局的配置。然后,我就很崩溃了,本来呢, 快照可以是管理对象的一个实例就行了, 每次进页面创建一个快照管理对象,配置更新全部在快照管理对象上处理就行了。可是,好多单例啊, 一旦修改,全局都生效了。 好吧, 花点时间把管理理一下, 然后有如下的新类图:
图中的#
号表示这些属性对内部的类暴露, OC
实现就是用扩展,然后内部类可以包含扩展的头文件。 对外业务暴露的接口不包含扩展的接口和属性。内部其它类只依赖管理对象, 然后把具体文件的管理对象的单例干掉。在管理对象中,生成每个文件的管理对象实例。 部分文件的管理对象依赖管理对象, 不再依赖具体的文件管理对象。 这里, 我还把管理对象中属性的初始化通过懒加载实现, 为了保证线程安全, 在初始化的地方加锁, 由于存在文件管理对象依赖文件管理对象的情况, 这个锁还需要可重入的,也就是递归锁。实现代码如下:
1 |
|
好了, 进入页面,创建一个PageConfigManager
, 初始化时都是一样的。 在进入页面后,更改的也只是操作当前PageConfigManager
,不会影响到全局。
这里, 还好原先设计的逻辑比较清晰, 而且 只有内部的类使用到了具体的文件管理对象。 对外接口是统一的,改起来还可以接受吧。也许之前场景没有考虑到后续的配置独立的需求,为了方便,使用了单例模式。随着需求的演进, 需要不断的对代码进行重构,以适应新的需求。
如果之前写代码的时候,不贪图这点方便,直接一步到位, 可能会是更好的设计。 后面,只需要直接用,或者继承一下就好了。
切记,设计模式不可滥用,但是好的设计必须要用到设计模式。 重构需要捋清楚各个类的关系,对外接口清晰,类职责单一。
今天是2019.90.30, 明天就是国庆了, 中华人民共和国建国70周年, 祖国生日快乐!!
欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。