首页 » Cisco » 正文

严肃文学:通过Factory减少参数传递

作者: 邢政

移动APP的开发中,GUI的设计有时会遇到如下场景:
假设当前界面为
A,内包含自定义控件B,通过点击B来弹出窗体C。实例创建的顺序是由AB,再由B创建C

由类图可以推出,构建C用到的parameter1InCparameter2InC需要由B给出。 

同理,在构建B时,需要A给出parameterInB。可以看到A为了构建BC,包含了自身完全无用的3个参数。代码极其丑陋。 

这就好比三顾茅庐第一次报名号的刘备,包含的参数有:汉左将军,宜城亭侯,领豫州牧,皇叔。 

书童 直接告诉他,我记不得许多名字,你去重构下。 

皇叔作为一个要招CTO的CEO,不得不展示了一下自己的代码功底,做了一层封装,将要传递的参数封装到AppContext中。再次调用书童的接口(可能同时还塞了一个红包)。 

AppContext的代码大概长成这样,包含了构建B和C所用到的所有参数,差不多相当于皇叔的名片,包含了所有的头衔。 

然后在构建B时,将整个AppContext丢进去。 

在构建C时像这样: 

放到我们的剧情里,是这样一副画面:

这样的好处在于不用将一长串的参数暴露给并不感兴趣的书童。 

而是将信息封装在AppContext里,由最终感兴趣的对象自己去拿。 

缺点也很明显,仅仅是将大量的参数做了一层包装,犹如开了美图的网红,卸了妆长啥样自己心里清楚…… 

再激进一点,我们可以将构建A,B,C实例的逻辑放倒工厂类里面。再将AppContext做成单例,由工厂类创建实例时自行获取需要的参数。 

可以看到B的构造函数参数仅包含它关心的ParameterInB 

CFactory根据Parameter1InC和Parameter2InC创建了C的实例 

用过Factory之后,基本就相当于皇叔与书童相视一笑,书童默契叫醒午睡的诸葛先生,孔明掐指一算,就知道来的是谁,想干什么。

到这里有同学会问了,折腾了半天,代码没减少,还多出来三个工厂类,会不会有点累呢? 

说实话写这个东西是挺累的,本篇我们到目前为止,都在说减少不必要的参数传递。 

而我们最终的目的是通过抽象,来解决A,B,C三个类耦合过紧的问题。 

依赖抽象,不要依赖具体,是什么意思呢? 

假设存在一个抽象的“诸葛亮接口”,不同的“诸葛亮工厂”可以生产符合“诸葛亮接口”的各种诸葛亮。 

那我们既可以生产唐国强那个诸葛亮,同时UnitTest工程的“Fake诸葛亮工厂”也可以生产下图这种符合接口的诸葛亮,然后搭建一个测试用例…… 

更进一步,是给工厂类也实现接口,业务类ABC不再依赖具体的Factory实现,仅包含对Factory接口的引用。将具体的依赖都放倒可以替换的Factory中。这样的话Factory就有点像是配置文件。

 

本篇的代码放在全球最大的同性交友平台Github上,欢迎查阅 

https://github.com/manupstairs/FactoryTest

样例代码使用跨平台的Visual Studio Code + 跨平台的.NET Core编写,Mac上也能跑,考虑再写篇攻略安利你哟。