经常看到一些第三方库有这样的写法
举个栗子
<code>protected $outType = 'html'; public function setType($type) { $this->outType = $type; }</code>
那么我在代码中调用的时候,如果要输出json
格式的数据的话就必须先调一次setType
这个方法
<code>$this->setType('json'); ... ... ... $this->display(); //这个display里判断$outType属性是`html`还是`json`</code>
我不解的是,为什么不在display()
方法里直接传递一次参数呢,比如下面这样
<code>$this->display('json');</code>
这样还省了一次方法调用。 我想知道第一种的写法的好处主要表现在什么地方。
谢谢大家了。
经常看到一些第三方库有这样的写法
举个栗子
<code>protected $outType = 'html'; public function setType($type) { $this->outType = $type; }</code>
那么我在代码中调用的时候,如果要输出json
格式的数据的话就必须先调一次setType
这个方法
<code>$this->setType('json'); ... ... ... $this->display(); //这个display里判断$outType属性是`html`还是`json`</code>
我不解的是,为什么不在display()
方法里直接传递一次参数呢,比如下面这样
<code>$this->display('json');</code>
这样还省了一次方法调用。 我想知道第一种的写法的好处主要表现在什么地方。
谢谢大家了。
第一种写法:你可以把它理解为:
<code>function demo($type = 'html'){ return $type; }</code>
只不过现在整体变成类了!因为本类在外面被继承调用时,有可能会根据调用方的不同比如:需要输出html或者json格式,但是我又不能直接修改protected $outType
的值,那必然要有一种办法去间接修改该类里面的属性,因此就出现了下面的setType($type)
方法,通过外部调用来达到修改内部属性值的效果!
面向对象的写法,在java里面特别明显。
好处当然有,封装、安全。
特别是在第三方类库中很明显,封装!
作为库函数,你只要告诉别人你有什么功能,能提供什么功能,内部使用的变量尽量不要暴露出来,使用者只关心功能就好了。
如果我要传入了一个josnd
(误操作),怎么办?
各种参数检测是不是把display撑爆了?display明明只要一个类型就好了,管这么多干什么?
分层、封装!
<code>public function display($type = 'json') { $this->type = $type; ..... }</code>
面向对象编程 和 函数式编程 的区别;
搜到知乎上这个回答:
编程说穿了就是两个方面,data和这些data上的operation,
oop, 就是让operation 围绕data, 这样的好处是,当你要添加新的data type的时候,好方便! 原来写的代码都不用改。 但是你要给已经写好的data type添加方法怎么办? 比如我要你给java自带的string 加个 python那种乘法。
functional programming采取的是另一种思路,data更多的围绕operation, 所以添加新的方法很容易。 这就是著名的the expression problem. 谁优谁劣,要看应用场景,写GUI用oop好不畅快,写interpreter我更喜欢函数式的。
在我看来这些都是idiom, 不是宗教,具体问题具体分析。 但是学习functional programming绝对大有裨益,因为国内的计算机教育太强调图灵模型(也就是C语言一脉)了,而对lambda calculus涉及太少,造成了很多偏见和误解,我不只一次在知乎上看到,学好C语言,其他高级语言都很容易理解的论调,明显就是受了这种教育的荼毒。
作者:张无忌 链接:https://www.zhihu.com/question/19732025/...
来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
莫名其妙的被人踩,只能说言尽于此。
因为display应该是不改变状态的。
其实如果这个setType仅仅是干这样的一件简单的事情,那就是过度封装了,如果这个setType还做了参数检查,错误异常处理等等,就像你说的,一个方法尽量只做一件事,结合具体的事情去看,就会发现不同之处,不这么做也不是不可以,总之最后想要的就是代码逻辑清晰,好维护,修改,后面的人看得懂,不吃力。
抛开需求谈代码,都是耍流氓
你说的那种方式,传递,肯定是可以的
但是如果在全局中用到了这个参数,你不赋值到属性中,而还是传递,那么你想想,是传参数方便,还是直接在方法中调用属性方便,面向对象编程,这个参数就是对象的属性.
当这个参数只在当前方法中用到,那你也可以不赋值到属性中.
两种都支持不是更好,setType作为默认值,display的参数优先级更高,代码改动也很小
因为输出格式不是每次调用都需要变更的,比如一次执行过程中,要多次输出,那比较常见的情况就是多次输出的格式是相同的,所以用 settype() 的方式就不需要每次 display 都传一次格式做为参数;
其实对于这种方式还有改进的空间:可以把json和html输出做为默认的类型,其他的输出格式则传递一个实现了 display() 接口的对象进来,这样就可以实现输出时无限的扩展性。
本质上来说,这种做法的目的是为了实现对象的最大化复用。
什么是对象的复用?就是一个对象被实例化之后,不需要变更它的任何属性就可以直接被多次使用。
seters/geters
缺点就是你多写了代码(开发速度降低)
优点就是加强了封装性(维护能力增强)
一两个这样的封装也就无所谓了对吧,看在更高维护性的面子上也就忍了。
如果多了,还是另外再写个load()
方法来集体装载。
你对面向对象不感冒!!
个人感觉主要是复用的问题吧,如果单单使用这一次outtype,那么直接在display中作为参数确实是更方便
但如果不止display一个方法用到outtype,我感觉作为对象的属性去设置会更方便
首先必须明白写这个类的作者觉得在某一个时刻你只需要处理一种格式,不是html就是其他,比如json,所以你实例化了一个对象,并把格式设置为json,那以后就直接使用好了,可是如果在实际的使用过程中很多人却发现需要不停地切换输出格式,那么这个类写得并不怎么样,很糟糕,还不如写成一些工具类,或者直接在display中传入输出格式。
我个人建议你不要在html和json中做任何切换,直接定义两个对对象,一个处理html一个处理json,这样反而更好,不过我不知道这两个对象是否是可变化的,如果是可变化的,还不如自己写一个有参数的display方法