我写得 OOP 今天被喷了

2014-11-07 10:57:22 +08:00
 johnsneakers
事情是这样的,原来的代码是这样:

$login = new ILogin();
$uid = $login->getLoginUid();
if ($uid < 10000) {
return json_encode(array('ret'=>-1));
}

我改成了这样:

$login = new ILogin();
$uid = $login->getLoginUid();
if ($login->hasError()) {
return json_encode($login->getErrorl());
}


说我没事瞎JB调用这么多函数干啥,明明可以一步到位的。
我解释:这样方便维护,而且语义强。
他说:你这个太多调用方法,速度慢。
我:.....

我就是喜欢OOP, 但不知道这种情况改怎么反驳
7245 次点击
所在节点    程序员
51 条回复
jox
2014-11-07 12:16:43 +08:00
OOP是啥谁来告诉我
RemRain
2014-11-07 12:41:19 +08:00
hasError 不是面向过程的方法么,OOP 的话,抛个异常吧
johnsneakers
2014-11-07 12:47:26 +08:00
@tedeyang 可能我这里给的例子不对,总之原来项目的代码全是如下这种:
contronller:
$obj = new Model();
$userinfo = array();
$ret = $obj->getUserInfo(&$userinfo); //这里引用传递,只是直观,语法错误请无视。
if($ret < 0)
{
return json_encode(array('ret'=>$ret));
}


另外我model里面没有写error方法哦, 所有model都有父类, error方法都是在父类里面, 这里不详细帖了。。。。 请大神指教
loryyang
2014-11-07 12:57:34 +08:00
过早的性能优化是罪恶的源泉,特别是为了性能而去牺牲系统架构优雅性,增加模块耦合,降低代码可读性、易维护性等。当然,如果没有后面这些损失,你当然应该写更高效的代码。

很多时候你根本不会知道最影响性能的是哪部分代码。你过早的优化,也许只是优化了占总耗时1%的那部分代码。

关于你这个代码,我觉得原来的代码也还可以,oop不是解决问题的唯一方式,不用oop也一样可以写出好代码。你们两位支撑自己观点的原因都不太合适。最重要的还是代码的合理性,这部分错误code处理的逻辑本该属于谁,后续很可能出现的扩展是否方便支持,代码是否可以简洁易懂,是否会带来冗余代码。
tabris17
2014-11-07 12:59:27 +08:00
I打头的不应该都是interface么
tabris17
2014-11-07 13:01:53 +08:00
另外回答呵呵就好了
eric_zyh
2014-11-07 13:04:21 +08:00
看场景
1.如果 $uid < 10000 是一个常用的判断,实现成一个函数是很方便维护的。
2.如果只是在一两处地方有这个判断,就没有必要了。把只出现一、两次的都弄成函数,那维护起来反而不知道每个函数的含义。

如@tedeyang 所说的,这种代码考虑效率问题,那就太矫情了。。
kmvan
2014-11-07 13:04:58 +08:00
lz 这段代码是干啥的呢?是要判断用户是否登录?还是要验证登录信息是否正确?如果是判断登录,不就一个函数可以搞定吗?如果是验证登录信息,我觉得 wp 那种比这个更好理解。
zhouzm
2014-11-07 13:37:51 +08:00
抛开性能问题不谈,第二种写法,明显是对对象理解有问题,只是对第一段代码的形式上改写。

既然对象方法可能会有异常结果,那就不应该直接取值,应该是首先执行方法,由方法返回状态,如果成功,取值,不成功,则返回错误信息:

$login = new ILogin();
if !($login->doLogin()) {
return json_encode($login->getErrorl());
}
$uid = $login->getLoginUid();

反观第一段代码没有任何问题,由返回值来代表状态,改进的话只要把“array('ret'=>-1)”改为$login->getErrorl()就解决了错误信息封装的问题。

根本不是什么 OOP 的问题,是逻辑问题,楼主你好好思考一下。
dbfox
2014-11-07 13:47:29 +08:00
我觉得只要能发挥出OOP的好处,就可以用OOP
raincious
2014-11-07 13:58:06 +08:00
@chemzqm

这不是过渡封装。
https://gist.github.com/raincious/037f56d050ae92f01aa6

我觉得楼主唯一的问题是

if ($login->hasError()) {

这句定义的不明确,什么都是hasError。如果非要这样不如throw一个异常然后一个一个catch。

另外关于性能,那东西不是交给编译器优化的么?不要尝试过渡优化你的程序(微优化大部分情况下只是在浪费时间),应该尽量写出易于(让别人乐于)阅读的代码。
bombless
2014-11-07 14:52:27 +08:00
看什么产品什么公司吧,改动的比较猛的自己就会改一种写法,没有动力改其实也说明对可维护性的要求也不那么急迫
feinux
2014-11-07 15:27:24 +08:00
要我说,代码写出来是要用程序实现的。程序是给用户用的。用户是人。所以归根到底,他妈的你返回一句人看不懂的提示,老子用你的程序干蛋啊?除非是国企这种的,花大价钱搞来非用不可。

最讨厌一类程序员就是图自己省事儿,为难用户。还自己觉得自己很牛逼,用户是傻逼不懂。用户是不懂,用户可以不用啊?放着那么多好的程序不用,老子干吗委屈自己?

你把这段话复制过去,就说是我说的。
rwx
2014-11-07 15:55:36 +08:00
这是技术问题吗?这明明是人的问题
不是所有人都喜欢被别人无故改掉自己的代码,那是很直白的在告诉他:你写的真烂

不喷你喷谁。。
princecauchy
2014-11-07 16:06:01 +08:00
@jox object-oriented programming 面向对象编程。
latyas
2014-11-07 16:13:20 +08:00
原来的代码运行的好好的何必修改。
ren2881971
2014-11-07 16:18:33 +08:00
也不是oop啊 就是封装了下函数而已。
但是我觉得LZ这种做法是对的!
告诉那个人 万一 $uid < 10000 这个条件变了 且不是应用中所有的代码都挨个检查下更改了?
封装成方法 直接改方法内部就可以啦啊。
palxex
2014-11-07 16:52:52 +08:00
@jemyzhang 这个。。。招行信用卡的查询密码原来可以不设的么?我记得办卡时就设好了啊。(不是说交易密码啊,那个确实可以不设,而且我从来不设,绑定微信也没发现问题。)
pljhonglu
2014-11-07 16:54:38 +08:00
如果多处靠判断 uid 来判断正确性,那可以单独封装。否则还是觉得第一种比较直观。大项目为了可维护性必须要多封装。小工程本来模块间的耦合度就低,没必要过度封装。

另外,同意上面的说法,OOP的写法应该是抛异常
dreampuf
2014-11-07 17:02:24 +08:00
- 除了正确执行,代码就是用来维护的。谈维护有个标准,就是谁都能执行,大家品味一致
- 你能兼容他的hard code,他未必能兼容你的OOP
- 除非没人愿意接手维护了,或者有强力Leader牵头,不要干重构这类吃力不讨好的事儿。Martin 的书有点像心灵鸡汤,描绘了该是什么什么样。问题是design一旦脱离实际执行的人就变了味道,执行不好,培训不够,监督不全都会慢慢变坏。
- 没有数据,“可维护性”很有可能不可度量。比起明眼就能看出来的调用效率,自然被攻击。你需要想办法证明“这样写”的代码不可维护。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/144612

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX