论坛首页 Java企业应用论坛

面向行为编程!继面向对象的新的软件开发模式

浏览 32998 次
该帖已经被评为新手帖
作者 正文
   发表时间:2011-01-31   最后修改:2011-02-21

 

首先这不是一样新技术,而是一种新思想,是基于面向对象思想的一种更符合人的思维习惯的编程模式。如果说面向对象是对现实世界的抽象,那么面向行为就是对人如何与现实世界的交互而做的更易于理解,更动态的封装。该思想的核心是:以“行为”为程序模块的基本单位,在模块开发之前,只需确定该模块 用来干什么”,而模块的实现,所需参数,返回结果一律不需要关心。从而极大降低模块之间的耦合。

 

传统的软件开发通常以函数为模块的基本单位,其弊端是很明显的。而面向对象的概念中则提供了对象和接口,它的特色是将有关现实世界的一切“名词”封装成一个代码块(类),从而使模块的内聚性有了很大的提高。但在封装一些功能,或者行为等抽象概念时则表现较差,因为在封装成类之前,仍必须先定义(声明)好类的属性、方法的参数、返回值,而这些在程序没有执行之前可能都是未知,无法确定的,我们必须根据经验去定义,说白了点就是猜测。简单来说:一个基本的功能(方法)模块,主要由四个部分组成:方法名、参数、实现、返回值,如图:

 

通过面向对象的思想,可以通过接口或抽象方法,只定义方法名,参数和返回值,而不去理会实现

 

但这在具体的项目运用中还是不够的,因为有时候一个模块的参数和返回结果根本是不能事先确定定义的!于是笔者很自然地想到当需要一个功能的时候,只需要知道确定这个功能用来干什么(行为),把参数和返回值也统统忽略呢?


 

比如说我们需要实现一个网站的登录功能,首先我们想到的是定义方法:

bool Login(String account, String password); 根据经验,要登录,我们需要:account(账号)password(密码),返回结果是成功或者失败(true or false)。但事实可能并不这么简单,因为假如在登录成功后,我们可能还需要向服务器的session变量里保存该用户的信息(对象),我们还需要一个参数:服务器Session, 和一个结果:对象User. 假如登录失败,我们可能还需要知道失败的原因(错误码),因为登录失败的原因有许多种:比如密码错误,账号不存在,数据库异常等等,这时网站管理员可能就需要返回一个错误码。

 

而面向行为的编程则能很好的解决这一点,假设我们要实现一个网站的登录功能,我们只需声明一下这个行为:Behavior Login;就这么简单。要实现该功能,只需重写该行为下的doing()方法。而该功能所需要的参数,返回结果集在实现里用:this.getParameter(String paraName),  this.resultSet.set(String resultName, Object value)方法获取。

 

于是我用Java类对“行为”进行了一个封装,用来模拟“行为”的用法。并定义了一个服务器行为ServerBehavior, 实现了一个简单的面向行为的J2EE框架。实际上这不是个框架,我只是将服务器(Servlet)的“行为”进行了一个定义,定义是(笔者对服务器行为的理解):接收页面表单参数,调用相关业务行为,页面跳转(或者传出ajax数据)。

 

再拿网站登录来说吧,首先,我们只需确定一个行为:"登录(Login)",然后将其定义,继承一个行为类:

 

public class Login extends Behavior {
		
		protected void doing() throws ParameterNotFoundException,
				ResultNotFoundException, BehaviorNotFoundException {
			
			
		}

}

 

然后我们就可以不管参数,结果如何直接实现该行为:

首先得到账户名和密码:

 

protected void doing() throws ParameterNotFoundException,
				ResultNotFoundException, BehaviorNotFoundException {
			
	//登录名
	String name = (String) this.getParameter("name");
	//密码
	String password = (String) this.getParameter("password");
}
 

然后我们声明并调用下一个“行为”:账户验证,这个行为将登录名和密码提交到数据库中进行验证,如果登录成功,返回User实体。但我们根本不必关心这个行为是如何实现的,在项目开发中,它可能完全由另一个人负责。所以,我只需直接声明该行为:

 

protected void doing() throws ParameterNotFoundException,
				ResultNotFoundException, BehaviorNotFoundException {
			
	//登录名
	String name = (String) this.getParameter("name");
	//密码
	String password = (String) this.getParameter("password");
				
			
	Behavior checking = Behavior.getInstance("checking");
}

 然后将它可能需要的参数name 和 password进行注入,执行,得到一个结果集:

 

Behavior checking = Behavior.getInstance("checking");
checking.setParameter("name", name);
checking.setParameter("password", password);
ResultSet resultSet = checking.execute();

 最后,从结果集里取我们想要的,是否成功:

 

boolean success = (Boolean) resultSet.get("success");

 如果成功,再从结果集中取出User实体,并跳转到登录成功的界面,如果失败,则提示登录失败:

 

if (success) {

	HttpSession session = (HttpSession) this.getParameter("session");
	session.setAttribute("user", resultSet.get("user"));
	this.resultSet.set("redirect", "/boApp/success.jsp");
} else {

	this.resultSet.set("redirect", "/boApp/failed.jsp");
}
			
 

一个登录行为就这样实现好了!具体的内部与数据库交互的实现由行为Checking来完成,当然它也可能调用别的行为,这就要看项目之前的设计文档了。

 

 最后页面表单:(表单action提交的url正是我们刚刚定义的Login行为。为了区别与一般的servlet,我在行为url后加了后缀".bh")

 

<form action="/boApp/login.bh" method="post">
		<p>账号:<input type="text" name="name"/></p>
		<p>密码:<input type="password" name="password"/></p>
		<p><button type="submit">登陆</button></p>
</form>

 

由于我们运用了“行为”作为模块的基本单位,而模块所需的参数,返回结果都不需要事先声明定义,所以在模块独立性,可扩展性上都有了一个质的飞跃。但有利必有弊,模块灵活性独立性的提高,必将带来运行效率的降低。

 

最后附上源码,其实代码的实现非常简单,核心只有两个类,主要表达的是面向行为的思想。里面还有我用面向行为框架做的一个小demo,一个简单的网页聊天系统。本来这个系统我用传统的jsp+servlet实现的非常复杂,模块代码也比较混乱,但使用“行为”包装后,系统的各个模块功能,步骤都显得非常清晰,只用了几个“行为”的“组装”就统统搞定了。

 

欢迎各位大虾与我探讨!

   发表时间:2011-01-31  
跟Action层有什么不一样吗?
0 请登录后投票
   发表时间:2011-01-31  
我感觉这是概念性的错误!

请回答一个最为简单的问题:行为是谁的行为?

面向对象的核心有几个,比如对象、属性、行为等。
login应该是User对象域的一个行为,仅此而已


有想法是好事,可能是楼主没讲明白
0 请登录后投票
   发表时间:2011-01-31   最后修改:2011-01-31
itstarting 写道
我感觉这是概念性的错误!

请回答一个最为简单的问题:行为是谁的行为?

面向对象的核心有几个,比如对象、属性、行为等。
login应该是User对象域的一个行为,仅此而已


有想法是好事,可能是楼主没讲明白

谁的行为并不重要啊,“谁”只是一个行为里可能需要被注入的参数,因为“谁”可能也是一个功能中的不确定因素,比如回帖这个行为:可能是用户回的,也有可能是机器的自动回复。总之行为是比对象更广泛的一个概念
0 请登录后投票
   发表时间:2011-01-31  
lyw985 写道
跟Action层有什么不一样吗?


我定义的ServerBehavior跟struts里的Action的确很像!因为struts的本质也就是强制实现MVC的分层,细化servlet和jsp之间的“行为”,将展示层和代码层的分离开来。页面只负责向servlet提交数据,而servlet负责接收数据并调用其它业务Bean,然后转发(重定向)页面,跟我定义的服务器行为ServerBehavior其实是一回事
0 请登录后投票
   发表时间:2011-01-31  
企业应用架构模式
作者: (美)Martin Fowler

Transaction Script
特点:一个Transaction Script把它所要做的事情统统放在一起,自己把它做了(没有什么消息链,除了调用更底层的数据库操作)。比如订一个房间,就包含了检查是否有空房,计算租金,更新数据库这系列操作,全由自己完成,放在一个函数中。 很像过程化编程。
优点:
1.   简单。性能高,理解容易。
2.   一个事务的处理,不会影响到其他事务。
缺点:
很难处理复杂的逻辑。如果你在不同的Transaction Script中发现了很多的重复代码,就表示Transaction Script模式已经力不从心了。
说明:
把一个个Transaction Script分开,至少放到不同的函数中,而且最好与UI和数据库操作分开(不同的类和包中)。而且由于它位于中间层,不应该有调用UI的方法。
Transaction Scripts有两种方法来组织类结构。
1.一个类放几个Transaction Scripts,它们都是逻辑相关的。
2.每个Transaction Script对应一个类,这样可以套用Command模式,但是似乎没有必要。
0 请登录后投票
   发表时间:2011-01-31  
行为里的参数调用跟spring里的依赖注入有点像,只不过spring注入的一般是很大的业务
类,而行为里注入的是细化到基本数据类型的参数!
0 请登录后投票
   发表时间:2011-01-31  
我看了一下,觉得LZ的意思是把传入的参数和返回的结果与实际的行为分离开来。
但表面上看好像是分离了,实则还有有关,这个东西分离不了的。
LZ所说的另外的一点好处是具体行为的编写可以由另外一个人来负责,
那不用这个面向行为变成也完全没问题啊,一个人专写action,处理参数和返回页面,
一个人专门写service层。

不知道面向行为编程有什么原则?

不过LZ挺有突破创新意识的,挺好
0 请登录后投票
   发表时间:2011-01-31  
lz很有想法啊,代码研究中
0 请登录后投票
   发表时间:2011-01-31  
写了一堆的command,外面通过名字调用command。
好像把每个方法各分到一个类里了,原来想过通过反射实行类似的东西。但是觉得行为多的时候不好维护吧,会比较泛滥。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics