锁定老帖子 主题:面向行为编程!继面向对象的新的软件开发模式
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2011-02-24
面向行为跟面向过程有什么区别?
楼主面向行为是跟面向对象同等级的互斥的概念吗? spring的面向切片(或方面)编程,并不是排斥或否决,而是共存和补充。 任何过程和行为都是对输入数据的处理,楼主目前的设计,只是对输入数据的一种非声明式隐藏,这样带来什么好处? 试想随便一个第三方或非自己写的api和service,提供给你的一些无参数的方法,你要怎么调用?或者说为调用它,你要怎么输入或输入哪些数据?是不是只能看着必须的详细的文档,一个一个的拼写正确set进去? service.setParameter("username",username); serivce.setParameter("password",password); service.login(); 哪怕 service.setUsername(username); serivce.setPassword(password); service.login(); 跟 service.login(username, password); 那个跟简介明了 上一种情况service还是固定为有状态的。 logger.setOut("test1"); logger.debug(); logger.setOut("test2"); logger.warn(); |
|
返回顶楼 | |
发表时间:2011-02-24
zijan 写道 add2ws 写道 zijan 写道 一般软件开发都有3个角色,接口(方法或行为)的定义者,接口的实现者,接口的调用者,有的是时候3个角色是同一人。楼主的方法可以简化接口定义者的工作量,但并不能减少其他两个角色的工作量,调用者和实现者也没有减少耦合。就拿用户登录的例子来说,假如以后增加管理员登录,要多传一个参数-验证码。行为调用和实现的代码都要修改做相应的判断。本来应该是接口定义者的工作(应该在设计阶段考虑好的事情),分给了调用者和实现者,让他们俩自己商量着办吧。
这种方式肯定会增加调试和维护的困难。以后换了一拨新程序员,不仔细读代码很难调试程序。yangm1203已经给出了他的答案,如果他们项目中的那个老人是个架构师(接口定义者)的话,真是够懒够聪明! 另外判断一个架构,一种编程思想好坏的一个重要标准就是成本。成本包括使用技术的难易程度(招个高级程序员还是初级程序员成本肯定不一样),代码量(10月和2个月也不一样),调试和维护的工作量。 我的意思正是把接口(参数和返回值)在代码里隐藏起来,这样程序员在实现他的功能模块的时候就不会因为接口设计不当(缺少参数或返回值)而停滞任务。正如你刚才所说,假设多了一个验证码,按照传统的接口编程的话,不只是要改你自己的实现和接口了,因为别人可能已经在自己的模块里调用你的接口了,大家的代码都要改。但如果用行为来封装自己的模块,传入参数的更改根本不会影响到别人对你模块的调用,大家不需要改代码,只要在设计文档里把行为的所需参数做相应的修改即可了 我基本同意你说的,改变接口可以不影响原有模块的调用。但是会对设计文档过分依赖,实际开发中很难做到文档和代码的一致,尤其是上百人的大项目。必须设专人管理检查文档,只要有一点文档没及时更新,扯皮的事情就在所难免了。这种开发模式也许更适合小项目。你是否已经在项目中用到了这种开发模式?项目有多大?怎么协调行为的调用和实现的?调试程序是不是方便?另外对开发成本的影响有没有考虑,毕竟培训一个新人用一种新的开发模式需要一定时间。 奇怪了,怎么会都不需要改代码? 如果加了个管理员登录,要多验证个变量,只要改文档就能实现了? 太牛了吧? 如果是说有10个登录入口,只为其中一个提供管理员登录,那就多加个方法不就行了?要管理员登录的,调用新方法。 |
|
返回顶楼 | |
发表时间:2011-02-24
最后修改:2011-02-24
看了一下楼主的代码,是不是要实现这样的功能:
function login() { return arguments[0] == 'sulong'; } login('http://www.sulong.info') //重新定义方法,不用改变形参,就可以改变实参 function login() { return arguments[0] == 'http://www.sulong.info' && arguments[1] == 'sulong'; } login('sulong', 'sulong') //重新定义方法,方法定义,就可能改变返回值了 function login() { if (arguments.length < 2) {return "返回值变成字符串了";} return arguments[0] == 'http://www.sulong.info' && arguments[1] == 'sulong'; } login() 就是同样的function login() 却可以适用很多种不同的调用方式,是不是?这个功能很多动态语言都有了,上面的代码就是用js写的。如果只是这样的话,这个“面向行为"也不是很给力。 |
|
返回顶楼 | |
发表时间:2011-02-28
最后修改:2011-03-01
它的特色是将有关现实世界的一切“名词”封装成一个代码块(类)
仅此一句便证明了楼主OO理解不够,动词不能抽象成类?
public interface Run{ public void move(Runner runner,double time); }
public class DefaultRun{ private double speed;
public DefaultRun(double speed){ this.speed=speed; } public void move(Runner runner,double time){ return runner.setPosition(runner.getPosition()+(speed*time)); } }
另外,如果在设计上模糊的地方,反倒是可以把层次分的更清晰一些,之前开会我们有讨论过一个议题,是说的领域建模的,也说到其实某些设计在特定的项目组是合适的,但是放到其他项目组重用就可能要删减或者修改一部分的代码,但是整个模块大部分的代码是一致的,这里其实就牵扯到一个我们可以确定的和不确定的代码两部分 如何重构程序,以及今后如何设计就围绕这个问题讨论了很久,确定的东西可以设计为接口,不确定的设计个抽象类,至于楼主说的以后代码确实需要发生改变的时候,IDE吧。。。
|
|
返回顶楼 | |
发表时间:2011-03-03
面向行为,其实也一种对变化的泛化。
但是,往往行为模型设计导致的问题也多,比如一个对象有N个行为,还是一个行为中涉及N个对象。 |
|
返回顶楼 | |
发表时间:2011-03-03
我觉得这样做的话复用性就没有。。。。
|
|
返回顶楼 | |
发表时间:2011-03-08
拔错,滚去研究代码。。。
|
|
返回顶楼 | |
发表时间:2011-03-21
最后修改:2011-03-21
嗯,看了看lz的贴,你基本上是把一个函数的函数体当做一个东西(就是你说的行为),然后参数和返回值都用类似HashMap这样的东西代替了。其实按照你说的,非常简单,只要实现两条:
1.所有的函数都是类似这样的: HashMap func(HashMap param) throws ParameterNotFoundException, ResultNotFoundException, ehaviorNotFoundException{ //do something return HashMap result; } 2.所有的函数本身可以直接作为对象来参与操作,比如作为参数传递(就是作为值出现在HashMap里,作为结果返回,等等。(你之所以写Login类,仅仅是因为java不支持这个事情)。 其实,javascript,除了返回值和不能按名调用参数,基本上已经满足你了;只要你写javascript的时候别写参数,全部用arguments,然后再加点函数式编程的思想。就ok了。 这样做有一个问题。就是类型!由于统统是Hashmap,参数类型就没有了,你需要自己做类型检查,类型转换,抛异常! |
|
返回顶楼 | |
发表时间:2011-03-31
没有类型检查,典型的依赖具体!有利于快速开发,后期维护基本会让人骂娘!连重构的机会都不大可能
|
|
返回顶楼 | |
发表时间:2011-04-05
hubeen 写道 首先赞一下楼主的创新精神,但是还是有很多疑问。
参数和返回值是什么,参数和返回值就是规范,你把规范写到代码里不比写到文档里好?还有编译器替你检查,多方便。 java为了通用,可以使用泛型,可以使用重载,可以使用覆盖,没必要把方法模仿成弱类型的。强类型虽然限制较多,但是也有个好处,编译器会告诉你很多低级错误。不然int你传个long进去,系统怎么挂的都不知道。就算你要加参数,重载一下就好了,也不需要你改全部的代码。 非要一个方法能让所有人都能用,参数全部Object...,返回值全部Object不就行了么。 还有,所有人都用一个login会不会太容易搞混?一个login不包含任何语义,也许customer.login和manager.login根本就是两个没有任何共同点的行为。 个人意见,请楼主考虑一下。 顶上 |
|
返回顶楼 | |