锁定老帖子 主题:今天老板的一个问题让我很无语
精华帖 (0) :: 良好帖 (0) :: 灌水帖 (6) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-12-16
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-12-16
就是咯,如果你那些参数都是一样的,而且都同类。那你以后改动你要把所有的都改一次。
用一个类,你就改一个地方。你说哪个安全呢? |
|
返回顶楼 | |
发表时间:2011-12-16
追求全对象会导致类太多。
|
|
返回顶楼 | |
发表时间:2011-12-16
完全瞎扯淡。一个接口的定义应该这个接口所要表达的语义相吻合。
public boolean login(String name, String password); public boolean login(User user); 这两端代码到底谁能够表达更好的语义?非常显然是前者。 User这个对象把一个login动作的实际需求屏蔽了!这在一个复杂的系统中是一个非常危险的事情。比如说,你这个系统中的login方法,未来要被其他的上层接口或者其他系统调用。当别人拿到login(User user)的时候就傻眼了,因为User这个对象中一定包含有其他的字段,对方在调用的时候怎么知道如何去populate这个user对象,你这个系统才能正确处理呢?如果没有注释的帮助,估计接口调用者会骂死你。 所以我认为你们老板的面向对象学真该好好补补课了。 |
|
返回顶楼 | |
发表时间:2011-12-16
downpour 写道 完全瞎扯淡。一个接口的定义应该这个接口所要表达的语义相吻合。
public boolean login(String name, String password); public boolean login(User user); 这两端代码到底谁能够表达更好的语义?非常显然是前者。 User这个对象把一个login动作的实际需求屏蔽了!这在一个复杂的系统中是一个非常危险的事情。比如说,你这个系统中的login方法,未来要被其他的上层接口或者其他系统调用。当别人拿到login(User user)的时候就傻眼了,因为User这个对象中一定包含有其他的字段,对方在调用的时候怎么知道如何去populate这个user对象,你这个系统才能正确处理呢?如果没有注释的帮助,估计接口调用者会骂死你。 所以我认为你们老板的面向对象学真该好好补补课了。 明显他们老板的意思是 public boolean login(LoginableUser user); 然后LoginableUser里只有String name, String password |
|
返回顶楼 | |
发表时间:2011-12-16
gtssgtss 写道 明显他们老板的意思是 public boolean login(LoginableUser user); 然后LoginableUser里只有String name, String password 要是他们老板连DTO是一个反模式都不能理解,那就没什么好说的了。 |
|
返回顶楼 | |
发表时间:2011-12-16
downpour 写道 gtssgtss 写道 明显他们老板的意思是 public boolean login(LoginableUser user); 然后LoginableUser里只有String name, String password 要是他们老板连DTO是一个反模式都不能理解,那就没什么好说的了。 要我说javabean就已经是反模式了 |
|
返回顶楼 | |
发表时间:2011-12-16
downpour 写道 完全瞎扯淡。一个接口的定义应该这个接口所要表达的语义相吻合。
public boolean login(String name, String password); public boolean login(User user); 这两端代码到底谁能够表达更好的语义?非常显然是前者。 User这个对象把一个login动作的实际需求屏蔽了!这在一个复杂的系统中是一个非常危险的事情。比如说,你这个系统中的login方法,未来要被其他的上层接口或者其他系统调用。当别人拿到login(User user)的时候就傻眼了,因为User这个对象中一定包含有其他的字段,对方在调用的时候怎么知道如何去populate这个user对象,你这个系统才能正确处理呢?如果没有注释的帮助,估计接口调用者会骂死你。 所以我认为你们老板的面向对象学真该好好补补课了。 同意downpour的说法。函数定义接口应该暴露所有需要的参数上下文。 如果一定要用User复合结构,应该引入类似于这样的表达样式。login(user = { name, password} )。 关于这个问题,我恰好有些想法。函数定义时,参数应该清晰地展开。不过,在函数调用时,有些情况下(如参数个数较多,并且需要分在不同的过程中获取的时候),复合结构就有优势了。比如,这样的场景。 user = getUser(); // 获取所需要参数。user包含name和password两个字段。 login( user) 和 login( user.name, user.password) 这两种调用方式,那种更加方便呢?在我看来,login(user)比较方便。那么,能否两全呢?我恰好写了点东西。 《编程机制探析》第六章 面向对象 http://www.iteye.com/topic/1114088 这个帖子中的一个回复。 buaawhl 写道 说到了继承,借机再谈一下一些不成熟的想法。 继承虽然有一些弊端,但不可否认,继承有一个切实的好处——直接引入另一个类的上下文,即,子类可以直接使用父类的成员属性和方法。这实际上是通过方法表(我只关注虚方法表,这里指的也只是虚方法表)复制来实现的,子类直接获得了父类的公共接口。不过,这不是什么了不得的特性。一个类完全可以通过暴露内部类接口的方式直接提供其他类的接口。 继承值得一提的好处就是,子类调用父类方法,如同调用本类方法一样方便。比如,getName()。但是,调用内部对象的方法,就不那么方便了,必须每次都带上内部对象的引用。比如,o.getName()。 这种功能虽然很方便,但是,可能会引入各种问题。比如,我们熟知的override、overload、covariance问题、多重继承问题。Python和Ruby引入的mixin语法,更加轻便的实现了多重继承(引入多个方法表)的效果,但是,并没有避免多重继承的问题,比如,同名方法问题(同名后来者覆盖前者)。 以上是在类级别直接引入上下文(context)的功能。另外,在模块级别也存在类似功能。 一个模块引入另一个模块的功能,通常需要import之类的关键字。这方面,C++、C#的using namespace做得很好,比import做得好。Import进来的功能,必须带着外部模块的引用。比如,o.getName()。Using space既可以达到import的效果,也可以进一步达到直接引入的效果。可以直接调用getName。 Pascal有一个with语法,可以展开任何复合结构,在本作用域内直接调用复合结构中的成员,就好像调用本作用域内定义的局部变量一样。这种语法是我所知道的最为灵活的直接引入上下文的语法。值得借鉴。 我设想的faramita语法是这样:函数参数即上下文。 这种语法和curry语法结合在一起,就可以实现非常灵活强大的直接引入上下文功能。 假设一个函数:f (x, y, z) = x + y + z 那么,f(x = 1) (y = 2) (z = 3, x = 4),这个函数调用看起来只是一种curry形式,但是,实际上确是参数上下文的叠加复制。最终结果相当于f (x = 4, y = 2, z = 4) 的调用结果。这和curry的形式是一样的。 如果有一个tuple。t = (x = 2, y = 4, z = 6) 那么,f(t)的结果就是f(x = 2, y = 4, z = 6)的结果。 如果t1 = (z = 10) 。那么,f(t)(t1)的结果就是f(x = 2, y = 4, z = 10)的结果。 这种参数上下文的叠加复制,其实就相当于多层继承、多重继承中的方法表的叠加复制,因此,也完全能够达到同样的效果,而且,语义上更加清晰。 如果有了这样的语法,在函数定义的时候,可以清晰地声明所有参数,在函数调用的时候,可以直接使用复合结构。 |
|
返回顶楼 | |
发表时间:2011-12-16
最后修改:2011-12-16
buaawhl 写道 downpour 写道 完全瞎扯淡。一个接口的定义应该这个接口所要表达的语义相吻合。
public boolean login(String name, String password); public boolean login(User user); 这两端代码到底谁能够表达更好的语义?非常显然是前者。 User这个对象把一个login动作的实际需求屏蔽了!这在一个复杂的系统中是一个非常危险的事情。比如说,你这个系统中的login方法,未来要被其他的上层接口或者其他系统调用。当别人拿到login(User user)的时候就傻眼了,因为User这个对象中一定包含有其他的字段,对方在调用的时候怎么知道如何去populate这个user对象,你这个系统才能正确处理呢?如果没有注释的帮助,估计接口调用者会骂死你。 所以我认为你们老板的面向对象学真该好好补补课了。 同意downpour的说法。函数定义接口应该暴露所有需要的参数上下文。 如果一定要用User复合结构,应该引入类似于这样的表达样式。login(user = { name, password} )。 关于这个问题,我恰好有些想法。函数定义时,参数应该清晰地展开。不过,在函数调用时,有些情况下(如参数个数较多,并且需要分在不同的过程中获取的时候),复合结构就有优势了。比如,这样的场景。 user = getUser(); // 获取所需要参数。user包含name和password两个字段。 login( user) 和 login( user.name, user.password) 这两种调用方式,那种更加方便呢?在我看来,login(user)比较方便。那么,能否两全呢?我恰好写了点东西。 《编程机制探析》第六章 面向对象 http://www.iteye.com/topic/1114088 这个帖子中的一个回复。 buaawhl 写道 说到了继承,借机再谈一下一些不成熟的想法。 继承虽然有一些弊端,但不可否认,继承有一个切实的好处——直接引入另一个类的上下文,即,子类可以直接使用父类的成员属性和方法。这实际上是通过方法表(我只关注虚方法表,这里指的也只是虚方法表)复制来实现的,子类直接获得了父类的公共接口。不过,这不是什么了不得的特性。一个类完全可以通过暴露内部类接口的方式直接提供其他类的接口。 继承值得一提的好处就是,子类调用父类方法,如同调用本类方法一样方便。比如,getName()。但是,调用内部对象的方法,就不那么方便了,必须每次都带上内部对象的引用。比如,o.getName()。 这种功能虽然很方便,但是,可能会引入各种问题。比如,我们熟知的override、overload、covariance问题、多重继承问题。Python和Ruby引入的mixin语法,更加轻便的实现了多重继承(引入多个方法表)的效果,但是,并没有避免多重继承的问题,比如,同名方法问题(同名后来者覆盖前者)。 以上是在类级别直接引入上下文(context)的功能。另外,在模块级别也存在类似功能。 一个模块引入另一个模块的功能,通常需要import之类的关键字。这方面,C++、C#的using namespace做得很好,比import做得好。Import进来的功能,必须带着外部模块的引用。比如,o.getName()。Using space既可以达到import的效果,也可以进一步达到直接引入的效果。可以直接调用getName。 Pascal有一个with语法,可以展开任何复合结构,在本作用域内直接调用复合结构中的成员,就好像调用本作用域内定义的局部变量一样。这种语法是我所知道的最为灵活的直接引入上下文的语法。值得借鉴。 我设想的faramita语法是这样:函数参数即上下文。 这种语法和curry语法结合在一起,就可以实现非常灵活强大的直接引入上下文功能。 假设一个函数:f (x, y, z) = x + y + z 那么,f(x = 1) (y = 2) (z = 3, x = 4),这个函数调用看起来只是一种curry形式,但是,实际上确是参数上下文的叠加复制。最终结果相当于f (x = 4, y = 2, z = 4) 的调用结果。这和curry的形式是一样的。 如果有一个tuple。t = (x = 2, y = 4, z = 6) 那么,f(t)的结果就是f(x = 2, y = 4, z = 6)的结果。 如果t1 = (z = 10) 。那么,f(t)(t1)的结果就是f(x = 2, y = 4, z = 10)的结果。 这种参数上下文的叠加复制,其实就相当于多层继承、多重继承中的方法表的叠加复制,因此,也完全能够达到同样的效果,而且,语义上更加清晰。 如果有了这样的语法,在函数定义的时候,可以清晰地声明所有参数,在函数调用的时候,可以直接使用复合结构。 user.login才是面向对象啊 我觉得数据库和业务是典型的桥接关系 |
|
返回顶楼 | |
发表时间:2011-12-17
downpour 写道 gtssgtss 写道 明显他们老板的意思是 public boolean login(LoginableUser user); 然后LoginableUser里只有String name, String password 要是他们老板连DTO是一个反模式都不能理解,那就没什么好说的了。 如果从OO的角度上说,LoginableUser这样的接口肯定是对的方案,但是老实说,我从来没这么写过。因为这个LoginableUser看不到被复用的场景,或者复用的场景太少了(即使被复用,一般只能在重构时体现,除非是在写一个security框架,否则很难预见) DTO不是反模式,问题是创建很多只用一次的interface。 |
|
返回顶楼 | |