最新发布:

十二 16th, 2010  |  (0)iframe自适应高度的多种方法方法小结

今天公司有个页面需要用到Iframe,但是高度不能自适应,调用的页面高度不一,开始时是显示滚动条,但是又有浏览器的滚动条,显得太难看了。Iframe的height设置成100%也不行。后来到网上看到有不少的解决方法。总结出来和大家分享一下。

不带边框的iframe因为能和网页无缝的结合从而不刷新页面的情况下更新页面的部分数据成为可能,可是 iframe的大小却不像层那样可以“伸缩自如”,所以带来了使用上的麻烦,给iframe设置高度的时候多了也不好,少了更是不行,现在,让我来告诉大 家一种iframe动态调整高度的方法,主要是以下JS函数:
第一种方法:代码简单,兼容性还可以,大家可以先测试下。
复制代码 代码如下:
function SetWinHeight(obj)
{
var win=obj;
if (document.getElementById)
{
if (win && !window.opera)
{
if (win.contentDocument && win.contentDocument.body.offsetHeight)
win.height = win.contentDocument.body.offsetHeight;
else if(win.Document && win.Document.body.scrollHeight)
win.height = win.Document.body.scrollHeight;
}
}
}

最后,加入iframe,不能丢掉onload属性,当然了,id也必须也函数中的win匹配
复制代码 代码如下:

这么的这种也是跟上面的解决方法类似的代码
经典代码 iFrame 自适应高度,在IE6/IE7/IE8/Firefox/Opera/Chrome/Safari通过测试。
HTML代码:
复制代码 代码如下:
Javascript代码:

下面这个兼容性更好一些
复制代码 代码如下:

另一种情况的iframe解决方案(超简单)
重要提示:src=中你必须填写的网页地址,一定要和本页面在同一个站点上,否则,会抱错,说“拒绝访问!”(实际上这是因为Js的跨域问题导致拒绝访问的)
之前自己也碰到过这个问题,为了得到答案去网上搜索,发现有不少人也遇到了这样的问题,现在就把解决方法共享一下
1、建立一个bottom.js的文件,然后输入下面的代码(只有两行哦)
复制代码 代码如下:
parent.document.all(“框架ID名”).style.height=document.body.scrollHeight;
parent.document.all(“框架ID名”).style.width=document.body.scrollWidth;

这里的 框架ID名 就是Iframe的ID,比如:
复制代码 代码如下:

2、给你网站里所有的被包含文件里面每个都加入
复制代码 代码如下:
3、OK,收工!在WINXP、IE6下面测试通过。很简单吧!实现 iframe 的自适应高度实现 iframe 的自适应高度,能够随着页面的长度自动的适应以免除页面和 iframe 同时出现滚动条的现象。复制代码 代码如下:

第三中方法批量iframe自适应:
工作中遇到iframe随所含内容自适应高度的问题,以前在网上看到过类似问题的解决方法,于是搜索一下,找到了一个比较完整的能够兼容浏览器的解决方法,省得自己写了。
虽然不用自己写,思路还是要明白,基本上就是取得iframe属性src所指定的包含文档中内容的高度,然后用来设置iframe自身的高度,在iframe所在页面载入时对页面中的所有需要自适应高度的iframe进行自动设置,省时省力,如果确定页面中全部iframe都需要自适应高度,直接取得iframe数组给代码,就连ID都不用自己写了,完成程序搞定。(代码贴上来:)
复制代码 代码如下:

网上有人改进了方法,解决了当iframe所包含文档内容高度动态变化时自动调整iframe高度的问题,原理是在iframe所在页面不断扫描iframe包含文档的内容高度并改变iframe自身高度,这种方法貌似解决了问题,但是对页面速度和系统资源占用是否有影响还很难说,感觉方法有些偏执,应该有更好的解决方法。
第四种方法,只针对知道的iframe的ID调用 不推荐
复制代码 代码如下:
function iframeAutoFit(iframeObj){
setTimeout(function(){if(!iframeObj) return;iframeObj.height=(iframeObj.Document?iframeObj.Document.body.scrollHeight:iframeObj.contentDocument.body.offsetHeight);},200)
}
使用方法呢,大家在需要自适应的iframe上加个id,然后js执行就可以了

以上详细出处参考:http://www.jb51.net/article/15780.htm

还有一种超级简单的方法:

十二 2nd, 2010  |  (0)经典mysql语句

最近在学Mysql,不会就得学啊,正在看《MYSQL培训经典教程》,很好理解,很简单。下面和你分享一下Mysql的经典语句:

SQL分类:  
DDL—数据定义语言(Create,Alter,Drop,DECLARE)  
DML—数据操纵语言(Select,Delete,Update,Insert)  
DCL—数据控制语言(GRANT,REVOKE,COMMIT,ROLLBACK)  
 
首先,简要介绍基础语句:  
1、说明:创建数据库  
Create DATABASE database-name  
2、说明:删除数据库  
drop database dbname  
3、说明:备份sql server  
— 创建 备份数据的 device  
USE master  
EXEC sp_addumpdevice ‘disk’, ‘testBack’, ‘c:\mssql7backup\MyNwind_1.dat’ 
— 开始 备份  
BACKUP DATABASE pubs TO testBack  
4、说明:创建新表  
create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)  
根据已有的表创建新表:  
A:create table tab_new like tab_old (使用旧表创建新表)  
B:create table tab_new as select col1,col2… from tab_old definition only  
5、说明:删除新表  
drop table tabname  
6、说明:增加一个列  
Alter table tabname add column col type  
注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。  
7、说明:添加主键: Alter table tabname add primary key(col)  
说明:删除主键: Alter table tabname drop primary key(col)  
8、说明:创建索引:create [unique] index idxname on tabname(col….)  
删除索引:drop index idxname  
注:索引是不可更改的,想更改必须删除重新建。  
9、说明:创建视图:create view viewname as select statement  
删除视图:drop view viewname  
10、说明:几个简单的基本的sql语句  
选择:select * from table1 where 范围  
插入:insert into table1(field1,field2) values(value1,value2)  
删除:delete from table1 where 范围  
更新:update table1 set field1=value1 where 范围  
查找:select * from table1 where field1 like ’%value1%’ —like的语法很精妙,查资料!  
排序:select * from table1 order by field1,field2 [desc]  
总数:select count * as totalcount from table1  
求和:select sum(field1) as sumvalue from table1  
平均:select avg(field1) as avgvalue from table1  
最大:select max(field1) as maxvalue from table1  
最小:select min(field1) as minvalue from table1  
11、说明:几个高级查询运算词  
A: UNION 运算符  
UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。  
B: EXCEPT 运算符  
EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。  
C: INTERSECT 运算符  
INTERSECT 运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL 随 INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。  
注:使用运算词的几个查询结果行必须是一致的。  
 
12、说明:使用外连接  
A、left outer join:  
左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。  
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c  
B:right outer join:  
右外连接(右连接):结果集既包括连接表的匹配连接行,也包括右连接表的所有行。  
C:full outer join:  
全外连接:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。  
 
其次,大家来看一些不错的sql语句  
1、说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用)  
法一:select * into b from a where 1<>1 
法二:select top 0 * into b from a  
 
2、说明:拷贝表(拷贝数据,源表名:a 目标表名:b) (Access可用)  
insert into b(a, b, c) select d,e,f from b;  
 
3、说明:跨数据库之间表的拷贝(具体数据使用绝对路径) (Access可用)  
insert into b(a, b, c) select d,e,f from b in ‘具体数据库’ where 条件  
例子:..from b in ‘”&Server.MapPath(“.”)&”\data.mdb” &”‘ where..  
 
4、说明:子查询(表名1:a 表名2:b)  
select a,b,c from a where a IN (select d from b ) 或者: select a,b,c from a where a IN (1,2,3)  
 
5、说明:显示文章、提交人和最后回复时间  
select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b  
 
6、说明:外连接查询(表名1:a 表名2:b)  
select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c  
 
7、说明:在线视图查询(表名1:a )  
select * from (Select a,b,c FROM a) T where t.a > 1;  
 
8、说明:between的用法,between限制查询数据范围时包括了边界值,not between不包括  
select * from table1 where time between time1 and time2  
select a,b,c, from table1 where a not between 数值1 and 数值2 
 
9、说明:in 的使用方法  
select * from table1 where a [not] in (‘值1’,’值2’,’值4’,’值6’)  
 
10、说明:两张关联表,删除主表中已经在副表中没有的信息  
delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )  
 
11、说明:四表联查问题:  
select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where …..  
 
12、说明:曰程安排提前五分钟提醒  
SQL: select * from 曰程安排 where datediff(‘minute’,f开始时间,getdate())>5 
 
13、说明:一条sql 语句搞定数据库分页  
select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段  
 
14、说明:前10条记录  
select top 10 * form table1 where 范围  
 
15、说明:选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.)  
select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)  
 
16、说明:包括所有在 TableA 中但不在 TableB和TableC 中的行并消除所有重复行而派生出一个结果表  
(select a from tableA ) except (select a from tableB) except (select a from tableC)  
 
17、说明:随机取出10条数据  
select top 10 * from tablename order by newid()  
 
18、说明:随机选择记录  
select newid()  
 
19、说明:删除重复记录  
Delete from tablename where id not in (select max(id) from tablename group by col1,col2,…)  
 
20、说明:列出数据库里所有的表名  
select name from sysobjects where type=’U' 
 
21、说明:列出表里的所有的  
select name from syscolumns where id=object_id(‘TableName’)  
 
22、说明:列示type、vender、pcs字段,以type字段排列,case可以方便地实现多重选择,类似select 中的case。  
select type,sum(case vender when ‘A’ then pcs else 0 end),sum(case vender when ‘C’ then pcs else 0 end),sum(case vender when ‘B’ then pcs else 0 end) FROM tablename group by type  
显示结果:  
type vender pcs  
电脑 A 1 
电脑 A 1 
光盘 B 2 
光盘 A 2 
手机 B 3 
手机 C 3 
 
23、说明:初始化表table1  
TRUNCATE TABLE table1  
 
24、说明:选择从10到15的记录  
select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc  
    
随机选择数据库记录的方法(使用Randomize函数,通过SQL语句实现)  
  对存储在数据库中的数据来说,随机数特性能给出上面的效果,但它们可能太慢了些。你不能要求ASP“找个随机数”然后打印出来。实际上常见的解决方案是建立如下所示的循环:  
Randomize  
RNumber = Int(Rnd*499) +1 
   
While Not objRec.EOF  
If objRec(“ID”) = RNumber THEN  
… 这里是执行脚本 …  
end if 
objRec.MoveNext  
Wend  
   
  这很容易理解。首先,你取出1到500范围之内的一个随机数(假设500就是数据库内记录的总数)。然后,你遍历每一记录来测试ID 的值、检查其是否匹配RNumber。满足条件的话就执行由THEN 关键字开始的那一块代码。假如你的RNumber 等于495,那么要循环一遍数据库花的时间可就长了。虽然500这个数字看起来大了些,但相比更为稳固的企业解决方案这还是个小型数据库了,后者通常在一个数据库内就包含了成千上万条记录。这时候不就死定了?  
  采用SQL,你就可以很快地找出准确的记录并且打开一个只包含该记录  
的recordset,如下所示:  
Randomize  
RNumber = Int(Rnd*499) + 1 
   
SQL = “Select * FROM Customers Where ID = ” & RNumber  
   
set objRec = ObjConn.Execute(SQL)  
Response.WriteRNumber & ” = ” & objRec(“ID”) & ” ” & objRec(“c_email”)  
   
  不必写出RNumber 和ID,你只需要检查匹配情况即可。只要你对以上代码的工作满意,你自可按需操作“随机”记录。Recordset没有包含其他内容,因此你很快就能找到你需要的记录这样就大大降低了处理时间。  
再谈随机数  
  现在你下定决心要榨干Random 函数的最后一滴油,那么你可能会一次取出多条随机记录或者想采用一定随机范围内的记录。把上面的标准Random 示例扩展一下就可以用SQL应对上面两种情况了。  
  为了取出几条随机选择的记录并存放在同一recordset内,你可以存储三个随机数,然后查询数据库获得匹配这些数字的记录:  
SQL = “Select * FROM Customers Where ID = ” & RNumber & ” or ID = ” & RNumber2 & ” or ID = ” & RNumber3  
   
  假如你想选出10条记录(也许是每次页面装载时的10条链接的列表),你可以用BETWEEN 或者数学等式选出第一条记录和适当数量的递增记录。这一操作可以通过好几种方式来完成,但是 Select 语句只显示一种可能(这里的ID 是自动生成的号码):  
SQL = “Select * FROM Customers Where ID BETWEEN ” & RNumber & ” AND ” & RNumber & “+ 9″ 
 
  注意:以上代码的执行目的不是检查数据库内是否有9条并发记录。  
 
   
随机读取若干条记录,测试过  
Access语法:Select top 10 * From 表名 orDER BY Rnd(id)  
Sql server语法:select top n * from 表名 order by newid()  
MySql语法:Select * From 表名 order By rand() Limit n  
Access左连接语法(最近开发要用左连接,Access帮助什么都没有,网上没有Access的SQL说明,只有自己测试, 现在记下以备后查)  
语法:Select table1.fd1,table1,fd2,table2.fd2 From table1 left join table2 on table1.fd1,table2.fd1 where …  
使用SQL语句 用…代替过长的字符串显示  
语法:  
SQL数据库:select case when len(field)>10 then left(field,10)+’…’ else field end as news_name,news_id from tablename  
Access数据库:Select iif(len(field)>2,left(field,2)+’…’,field) FROM tablename;  
   
Conn.Execute说明  
Execute方法  
  该方法用于执行SQL语句。根据SQL语句执行后是否返回记录集,该方法的使用格式分为以下两种:  
    1.执行SQL查询语句时,将返回查询得到的记录集。用法为:  
    Set 对象变量名=连接对象.Execute(“SQL 查询语言”)  
   Execute方法调用后,会自动创建记录集对象,并将查询结果存储在该记录对象中,通过Set方法,将记录集赋给指定的对象保存,以后对象变量就代表了该记录集对象。  
 
    2.执行SQL的操作性语言时,没有记录集的返回。此时用法为:  
    连接对象.Execute “SQL 操作性语句” [, RecordAffected][, Option]  
      ·RecordAffected 为可选项,此出可放置一个变量,SQL语句执行后,所生效的记录数会自动保存到该变量中。通过访问该变量,就可知道SQL语句队多少条记录进行了操作。  
      ·Option 可选项,该参数的取值通常为adCMDText,它用于告诉ADO,应该将Execute方法之后的第一个字符解释为命令文本。通过指定该参数,可使执行更高效。  
 
·BeginTrans、RollbackTrans、CommitTrans方法  
  这三个方法是连接对象提供的用于事务处理的方法。BeginTrans用于开始一个事物;RollbackTrans用于回滚事务;CommitTrans用于提交所有的事务处理结果,即确认事务的处理。  
  事务处理可以将一组操作视为一个整体,只有全部语句都成功执行后,事务处理才算成功;若其中有一个语句执行失败,则整个处理就算失败,并恢复到处里前的状态。  
  BeginTrans和CommitTrans用于标记事务的开始和结束,在这两个之间的语句,就是作为事务处理的语句。判断事务处理是否成功,可通过连接对象的Error集合来实现,若Error集合的成员个数不为0,则说明有错误发生,事务处理失败。Error集合中的每一个Error对象,代表一个错误信息。

十一 29th, 2010  |  (0)EDM邮件模板制作注意事项大全

最近单位一直在做EDM,很是让人抓狂啊。比调浏览器的兼容性还让人头疼。尤其是一些布局上,如果你再碰到一个不懂兼容性的和EDM的设计生手, 那你完蛋了……

  一、格式编码:

  1. 页面宽度在600到800px(像素)以内,长度1024px以内

  2. 使用utf-8编码

  3. HTML代码在15kb以内

  4. 用table表格布局, td不能拆分,但是可以多级嵌套 line-height: 要把该styel放入td标签中 不要放在p或font等标签里,保证outlook和foxmail里都有行高属性

  5. 邮件居中时,在table里设定align=”center”

  6. 图片必须加上style=”border:0; display:block;”(border:0 – 防止给图片加上超链接出现蓝色边框; display:block – 如果不给图片加上该属性,则某些web邮箱显示图片之间有4px的间距。)

  7. 没有使用外链的css样式定义文字和图片

  8. 无动态图片

  9. 没使用<table></table>以外的body、meta和html之类的标签

  10. 背景图片代码写法为:<table background=”background.gif” cellspacing=”0″ cellpadding=”0″>

  11. 没有出现”onMouseOut” “onMouseOver”

  12. 没使用alt

  13. font-family属性不为空

      14. 不使用Flash、Java、Javascript、frames、i-frames、ActiveX 以及 DHTML,如果页面中的图片一定要是动态的,请将FLASH文件转换成GIF动画使用。(Outlook 2007限制GIF动画,在Outlook 2007里,GIF将不能正常显示)

  15. 在同一个<td>里最好只放一个图片。如<td><img src=” photo.JPG” ></td>;所有的图片都要定义高和宽。

      16. 邮件内容里不要出现鼠标经过的事件”onMouseOut” “onMouseOver”,即使在<td>里设置了,发送到邮箱后也将被过滤,将不能显示设定鼠标经过所显示的内容。

17. 某些EDM是有系统自动触发的,比如注册网站或论坛后,系统自动发出EDM成功注册,这些EDM一般都是带有参数的。如果有参数,参数所在行的行高必须大于或等于24像素。这样保证图片之间没有空白间距。

      二、文字:

  1. 邮件主题在18个字以内,没有――!……等符号

  2. 邮件主题和内容中不存在带有网站地址的信息

  3. 文字内容、版面简洁,主题突出

  4. 没有敏感及带促销类的文字

  5. 本次模板发送不超过20万封

  三、图片:

  1. 尽量使用图片,减少文字量

  2. 整页图片在8张以内,每张图片最大不超过15kb

  3. 图片地址要用绝对路径

  4. 图片名称不含有ad字符

  5. 整个邮件模板不是一张图

  四、链接:

  1. 链接数量不超过10个

  2. 链接是绝对地址

  3. 链接地址的长度不超过255个字符

  4. 不要使用map(锚点)功能

  5. 制作一份和邮件内容一样的web页面,在邮件顶部写:“如果您无法查看邮件内容,请点击这里”,链接到放有同样内容的web页面

————————-另类的outlook2007 ——————————————————————

Outllook 2007基于商业考量,Outlook 2007的网页信件解析软体不再是IE,而是Word2007,因此寄出的网页形式信件必须符合Word2007规格,而非IE。

而Word 2007对于HTML的支援较少,造成许多语法是无法在outlook 2007上被正确显现,在发包设计时要多加注意。

————————————————————————-

Word 2007 不支援以下这几个网页常用的 CSS 属性:

#background-attachment

#background-image

#background-position

#background-repeat

#clear

#display

#float

#list-style-image

#list-style-position

另外,也不支援以下项目:

1. 不要使用 <DIV>标籤 , 因为定位一定会出错

2. 不要使用<style></style>, 如果一定要使用,

请网页设计时将一个点就要让它变成两个点

例如: .test{font-size:10pt } 要改成 ..test{font-size:10pt }

3. 如果要用背景图 background语法 只有<body>标籤支援,其他如<table><TR><TD>

等其他标籤完全不支援background语法但支援bgcolor语法,所以如果要做背景图或是某个

造型表格,请不要使用背景图请直接切表格在配合使用 <img>以及<bgcolor>这两个语法

4.不支援Flash及Plugins

5.不支援列表清单替代图示

6.不支援 Float 跟 Position (css裡面用来定位或是调整 Layout的语法)

7.不支援动态GIF

这个连结是 Microsoft 列出来 Outlook2007对Html的支援列表。

另外还有一个 validator, 可以测试所做出来的 Email template 是否支援 Office 2007

————————————————————————-

Outlook 2007 将採用 word 2007 取代原本的 Internet Explorer 来当做预设的 Html render 核心,

以下是一些对设计产业比较有影响的变革

No background images – Background images in divs and table cells are gone, meaning Mark’s image replacement technique is out the window.

Poor background color support – Give a div or table cell a background color, add some text to it and the background color displays fine. Nest another table or div inside though and the background color vanishes.

No support for float or position – Completely breaking any CSS based layouts right from the word go. Tables only.

Shocking box model support – Very poor support for padding and margin, and you thought IE5 was bad!

将不会有背景图片 不管是 div, Table 裡的 Background, 将会不能使用

更差的背景颜色支援

将不支援 Float 跟 Position (css裡面用来定位或是调整 Layout的语法)

差劲的 Css 支援 (差劲的 Padding, Margin 定位, 差不多就像 IE5 对 Css 那样差的支援度)

这个连结是 Microsoft 列出来 Outlook2007对H

十 19th, 2010  |  (0)常用JavaScript语法107条

文章总结了JS中常用的语法,希望能对大家提供帮助.

1.输出语句:document.write(“”)
2.JS中的注释为://
3.传统的HTML文档顺序是:document->html->(head,body)
4.一个浏览器窗口中的DOM顺序是:window->(navigator,screen,history,location,document)
5.得到表单中元素的名称和值:document.getElementById(“表单中元素的ID号”).name(或value)
6.一个小写转大写的JS:
document.getElementById(“output”).value = document.getElementById(“input”).value.toUpperCase();
7.JS中的值类型:String,Number,Boolean,Null,Object,Function
8.JS中的字符型转换成数值型: parseInt(),parseFloat()
9.JS中的数字转换成字符型: (“”+变量)
10.JS中的取字符串长度是: (length)
11.JS中的字符与字符相连接使用+号.
12.JS中的比较操作符有: ==等于,!=不等于,>,>=,<.<=
13.JS中声明变量使用: var来进行声明
14.JS中的判断语句结构: if(condition){}else{}
15.JS中的循环结构: for([initial e¬xpression];[condition];[upadte e¬xpression]) {inside loop}
16.循环中止的命令是: break
17.JS中的函数定义: function functionName([parameter],…){statement[s]}
18.当文件中出现多个form表单时.可以用document.forms[0],document.forms[1]来代替.
19.窗口:打开窗口window.open(), 关闭一个窗口:window.close(), 窗口本身:self
20.状态栏的设置: window.status=”字符”;
21.弹出提示信息:window.alert(“字符”);
22.弹出确认框:window.confirm();
23.弹出输入提示框:window.prompt();
24.指定当前显示链接的位置:window.location.href=”/blog/URL”
25.取出窗体中的所有表单的数量:document.forms.length
26.关闭文档的输出流:document.close();
27.字符串追加连接符:+=
28.创建一个文档元素:document.createElement(),document.createTextNode()
29.得到元素的方法:document.getElementById()
30.设置表单中所有文本型的成员的值为空:
var form = window.document.forms[0]
for (var i = 0; i<form.elements.length;i++){
     if (form.elements.type == “text”){
         form.elements.value = “”;
     }
}
31.复选按钮在JS中判断是否选中:document.forms[0].checkThis.checked (checked属性代表为是否选中返回TRUE或FALSE)
32.单选按钮组(单选按钮的名称必须相同):取单选按钮组的长度document.forms[0].groupName.length
33.单选按钮组判断是否被选中也是用checked.
34.下拉列表框的值:document.forms[0].selectName.options[n].value (n有时用下拉列表框名称加上.selectedIndex来确定被选中的值)
35.字符串的定义:var myString = new String(“This is lightsword”);
36.字符串转成大写:string.toUpperCase(); 字符串转成小写:string.toLowerCase();
37.返回字符串2在字符串1中出现的位置:String1.indexOf(“String2″)!=-1则说明没找到.
38.取字符串中指定位置的一个字符:StringA.charAt(9);
39.取出字符串中指定起点和终点的子字符串:stringA.substring(2,6);
40.数学函数:Math.PI(返回圆周率),Math.SQRT2(返回开方),
Math.max(value1,value2)返回两个数中的最在值,
Math.pow(value1,10)返回value1的十次方,
Math.round(value1)四舍五入函数,
Math.floor(Math.random()*(n+1))返回随机数
41.定义日期型变量:var today = new Date();
42.日期函数列表:
dateObj.getTime()得到时间,
dateObj.getYear()得到年份,
dateObj.getFullYear()得到四位的年份,
dateObj.getMonth()得到月份,
dateObj.getDate()得到日,
dateObj.getDay()得到日期几,
dateObj.getHours()得到小时,
dateObj.getMinutes()得到分,
dateObj.getSeconds()得到秒,
dateObj.setTime(value)设置时间,
dateObj.setYear(val)设置年,
dateObj.setMonth(val)设置月,
dateObj.setDate(val)设置日,
dateObj.setDay(val)设置星期几,
dateObj.setHours设置小时,
dateObj.setMinutes(val)设置分,
dateObj.setSeconds(val)设置秒   [注意:此日期时间从0开始计]
43.FRAME的表示方式:
[window.]frames[n].ObjFuncVarName,frames["frameName"].ObjFuncVarName,frameName.ObjFuncVarName
44.parent代表父亲对象,top代表最顶端对象
45.打开子窗口的父窗口为: opener
46.表示当前所属的位置: this
47.当在超链接中调用JS函数时用: (javascript : ) 来开头后面加函数名
48.在老的浏览器中不执行此JS:<!–       //–>
49.引用一个文件式的JS:<script type=”text/javascript” src=”/blog/aaa.js”></script>
50.指定在不支持脚本的浏览器显示的HTML:<noscript></noscript>
51.当超链和onCLICK事件都有时,则老版本的浏览器转向a.html,否则转向b.html.例:<a href=”/blog/a.html” onclick=”location.href=”/blog/b.html”;return false”>dfsadf</a>
52.JS的内建对象有:
Array,Boolean,Date,Error,EvalError,Function,Math,Number,Object,RangeError,ReferenceError,RegExp,String,SyntaxError,TypeError,URIError
53.JS中的换行:\n
54.窗口全屏大小:
<script>function fullScreen(){ this.moveTo(0,0);this.outerWidth=screen.availWidth;this.outerHeight=screen.availHeight;}window.maximize=fullScreen;</script>
55.JS中的all代表其下层的全部元素
56.JS中的焦点顺序:document.getElementByid(“表单元素”).tabIndex = 1
57.innerHTML的值是表单元素的值:如<p id=”para”>”how are <em>you</em>”</p>,则innerHTML的值就是:how are <em>you</em>
58.innerTEXT的值和上面的一样,只不过不会把<em>这种标记显示出来.
59.contentEditable可设置元素是否可被修改,isContentEditable返回是否可修改的状态.
60.isDisabled判断是否为禁止状态.disabled设置禁止状态
61.length取得长度,返回整型数值
62.addBehavior()是一种JS调用的外部函数文件其扩展名为.htc
63.window.focus()使当前的窗口在所有窗口之前.
64.blur()指失去焦点.与FOCUS()相反.
65.select()指元素为选中状态.
66.防止用户对文本框中输入文本: onfocus=”this.blur()”
67.取出该元素在页面中出现的数量:document.all.tags(“div(或其它HTML标记符)”).length
68.JS中分为两种窗体输出:模态和非模态.window.showModaldialog(),window.showModeless()
69.状态栏文字的设置:window.status=’文字’,默认的状态栏文字设置:window.defaultStatus = ‘文字.’;
70.添加到收藏夹:external.AddFavorite(“http://bbs.blueidea.com/”;,”jaskdlf”);
71.JS中遇到脚本错误时不做任何操作:window.onerror = doNothing; 指定错误句柄的语法为:window.onerror = handleError;
72.JS中指定当前打开窗口的父窗口:window.opener,支持opener.opener…的多重继续.
73.JS中的self指的是当前的窗口
74.JS中状态栏显示内容:window.status=”内容”
75.JS中的top指的是框架集中最顶层的框架
76.JS中关闭当前的窗口:window.close();
77.JS中提出是否确认的框:if(confirm(“Are you sure?”)){alert(“ok”);}else{alert(“Not Ok”);}
78.JS中的窗口重定向:window.navigate(“http://bbs.blueidea.com/”;);
79.JS中的打印:window.print()
80.JS中的提示输入框:window.prompt(“message”,”defaultReply”);
81.JS中的窗口滚动条:window.scroll(x,y)
82.JS中的窗口滚动到位置:window.scrollby
83.JS中设置时间间隔:setInterval(“expr”,msecDelay)或setInterval(funcRef,msecDelay)或setTimeout
84.JS中的模态显示在IE4+行,在NN中不行:showModalDialog(“URL”[,arguments][,features]);
85.JS中的退出之前使用的句柄:function verifyClose(){event.returnValue=”we really like you and hope you will stay longer.”;}}   window.onbeforeunload=verifyClose;
86.当窗体第一次调用时使用的文件句柄: onload()
87.当窗体关闭时调用的文件句柄: onunload()
88.window.location的属性:
protocol(http : ),hostname(www.example.com),port(80),host(www.example.com:80),pathname(“/a/a.html”),hash(“#giantGizmo”,指跳转到相应的锚记),href(全部的信息)
89.window.location.reload()刷新当前页面.
90.window.history.back()返回上一页,window.history.forward()返回下一页,window.history.go(返回第几页,也可以使用访问过的URL)
91.document.write()不换行的输出,document.writeln()换行输出
92.document.body.noWrap=true;防止链接文字折行.
93.变量名.charAt(第几位),取该变量的第几位的字符.
94.”abc”.charCodeAt(第几个),返回第几个字符的ASCii码值.
95.字符串连接:string.concat(string2),或用+=进行连接
96.变量.indexOf(“字符”,起始位置),返回第一个出现的位置(从0开始计算)
97.string.lastIndexOf(searchString[,startIndex])最后一次出现的位置.
98.string.match(regExpression),判断字符是否匹配.
99.string.replace(regExpression,replaceString)替换现有字符串.
100.string.split(分隔符)返回一个数组存储值.
101.string.substr(start[,length])取从第几位到指定长度的字符串.
102.string.toLowerCase()使字符串全部变为小.
103.string.toUpperCase()使全部字符变为大写.
104.parseInt(string[,radix(代表进制)])强制转换成整型.
105.parseFloat(string[,radix])强制转换成浮点型.
106.isNaN(变量):测试是否为数值型.
107.定义常量的关键字:const,定义变量的关键字:var

文章来源:博客园

十 12th, 2010  |  (2+)Adobe征集的五星配色方案

十 12th, 2010  |  (1)<转>新人怎么获取稳定进步及收入 – 谈工作态度

作者:biyibird (如果侵犯了您的权利,请联系我,我会尽快删除。)

我经常看到身边刚入职的新人无所适从,不知道怎么才能得到更高的收入。其实一般企业员工收入无非来自两个渠道:1、职业收入(工资、奖金、福利等);2、额外收入。

我就这两方面说说,我本人在长沙混着,收入远比不上那些一线城市的大牛,只是希望给同类城市的朋友们一些启示。

 首先说说职业收入。

奔高薪还能有其它方法不?没有。老板信任你,给你升职加薪是唯一途径。当然做到一定高度的职位,可以有项目奖金、项目提成(甚至比工资都高),那都是建立在职位基础上的。

我最喜欢的新人什么样?

1、勤奋:不懂可以,但是要懂得如何改进。今天给你讲了,下次就知道做了,这是基本要求。下次能自己举一反三了,这是高级要求。尤其是技术类部门,具体的技术问题我会讲得很详细–新人应该用笔记要点,必要的代码要记到软件的收藏夹中–甚至发布在自己的BLOG上。

2、有响应、有汇报:

不喜欢那种“无响应”型的员工-按钮都有hover-active-visited几个状态呢,何况活人乎?比如上级交待你一个任务,你要怎么做?首先记录-然后复述-制作过程中报告进度、询问疑难-完成以后及时汇报-向领导询问改进意见。新人跟老员工不一样,老员工闷声不响可以解决问题,而且领导信任他。新人必须做足姿态,时刻提醒领导:我在进步中!当然,我不是让你象闹钟一样时时去打铃,自己选择汇报的时机,但是一定要多汇报。

3、让直属上级省心、多做流水活儿

每个领导都很懒,都希望看到部下象个仪器一样自动运转。你帮上司把事情做漂亮了,他就可以腾出手去研发、去休息、去向自己的更上级做更有意义的事–不要说这是小兵当炮灰,每个人都是这么爬上来的。尤其是小公司,有很多所谓的“流水活”,就是没什么技术含量的、半打杂的活儿,如果新人愿意做,技术核心和主管是甘心分利润出来的,这样他们少赚点,但少累点。

4、学习再学习

我曾经试着给很多新人朋友布置学习任务,并告之以学成后的收入提升额度–当然这一方面也是为自己寻找新鲜力量。遗憾的是,最终成功的凤毛麟角。受学校教育的遗毒太深,总觉得学习是用来应付考试的。天知道,我的学习计划,都是实战经验,都是可以做单赚钱的。比起那种上万元一学期的“*大*鸟”之类,我的学习课真是便宜又实惠呀!

新人要学会从网络学习、向身边的老人学习、自己买书学习。最好的学习机会,其实就在你身边。

5、高调的表现自己

我老是劝新人们,多在论坛里写点心得,多发表作品,多更新自己的BLOG,他们无非就是这么几句说:1、就我这样的菜鸟,还写心得、发作品?2、这点东西也值得一写?(地球人都知道)3、我每天忙得要死,哪有空写?4、发了谁看呀?

我的对应观点是:1、菜鸟更要写,你需要人知道你在做事(尤其是上司及未来的贵人);2、哥看的不是内容,是你的进步;3、养成习惯就好,看视频和打游戏你就有时间?4、写了总有人看,几年后说不定你就是巨星–纯原创!

 扯远了,新人如能做到以上几点,技术核心、管理核心你都有份的,还怕收入不高?

 至于第二类收入,其实是第二阶段的。当你技术有成、人脉稳定了,自然就会来的。咱就不说创业之类的大动作了。一般接个私活儿、收点技术咨询费、技术改造费、讲课费什么的,都会积少成多的。

 现在的新人,机会是真多,至少比我们那时候强太多了。记住,你随便做两个冲刺,甩下的就是一大片,将来你就是主管和老板,那些落后分子,就是你的打工仔。你啥都不做,吃好喝好玩好,几年后,你就是一被人领导的命–看过蜗居吧,没错,就小贝那型。

文章引用地址:http://www.visionunion.com/article.jsp?code=201010070015

九 25th, 2010  |  (3+)<转>面向对象的开发方法(Object Oriented,OO)

    从事软件开发的工程师们常常有这样的体会:在软件开发过程中,使用者会不断地提出各种更改要求,即使在软件投入使用后,也常常需要对其做出修改,在用结构化开发的程序中,这种修改往往是很困难的,而且还会因为计划或考虑不周,不但旧错误没有得到彻底改正,又引入了新的错误;另一方面,在过去的程序开发中,代码的重用率很低,使得程序员的效率并不高,为提高软件系统的稳定性、可修改性和可重用性,人们在实践中逐渐创造出软件工程的一种新途径――面向对象方法学。

一、面向对象的方法(OO方法)简介

 面向对象方法学的出发点和基本原则是尽可能模拟人类习惯的思维方式,使开发软件的方法与过程尽可能接近人类认识世界、解决问题的方法与过程。由于客观世界的问题都是由客观世界中的实体及实体相互间的关系构成的,因此我们把客观世界中的实体抽象为对象(Object)。持面向对象观点的程序员认为计算机程序的结构应该与所要解决的问题一致,而不是与某种分析或开发方法保持一致,他们的经验表明,对任何软件系统而言,其中最稳定的成分往往是其相应问题论域(problem domain)中的成分。(例如在过去几百年中复式计帐的原则未做任何实质性的改变,而其使用的工具早已从鹅毛笔变成了计算机。)

    所以,“面向对象”是一种认识客观世界的世界观,是从结构组织角度模拟客观世界的一种方法。一般人们在认识和了解客观现实世界时,通常运用的一些构造法则:

  • 区分对象及其属性,例如区分台式计算机和笔记本计算机;
  • 区分整体对象及其组成部分,例如区分台式计算机组成(主机、显示器等);
  • 不同对象类的形成以及区分,例如所有类型的计算机(大、中、小型计算机、服务器、工作站和普通微型计算机等)。

 通俗地讲,对象指的是一个独立的、异步的、并发的实体,它能“知道一些事情” (即存储数据),“做一些工作”(即封装服务),并“与其它对象协同工作”(通过交换消息),从而完成系统的所有功能。

 因为所要解决的问题具有特殊性,所以对象是不固定的。一个雇员可以作为一个对象,一家公司也可以作为一个对象,到底应该把什么抽象为对象,由所要解决的问题决定。

 从以上的简单介绍中我们可以看出,面向对象所带来的好处是程序的稳定性与可修改性(由于把客观世界分解成一个一个的对象,并且把数据和操作都封装在对象的内部)、可复用性(通过面向对象技术,我们不仅可以复用代码,而且可以复用需求分析、设计、用户界面等等)。

 面向对象方法具有下述四个要点:

1.认为客观世界是由各种对象组成的,任何事物都是对象,复杂的对象可以由比较简单的对象以某种方式组合而成。按照这种观点,可以认为整个世界就是一个最复杂的对象。因此,面向对象的软件系统是由对象组成的,软件中的任何元素都是对象,复杂的软件对象由比较简单的对象组合而成。

2.把所有对象都划分成各种对象类(简称为类(Class)),每个对象类都定义了一组数据和一组方法,数据用于表示对象的静态属性,是对象的状态信息。因此,每当建立该对象类的一个新实例时,就按照类中对数据的定义为这个新对象生成一组专用的数据,以便描述该对象独特的属性值。

 例如,荧光屏上不同位置显示的半径不同的几个圆,虽然都是Circle类的对象,但是,各自都有自己专用的数据,以便记录各自的圆心位置、半径等等。

    类中定义的方法,是允许施加于该类对象上的操作,是该类所有对象共享的,并不需要为每个对象都复制操作的代码。

3.按照子类(或称为派生类)与父类(或称为基类)的关系,把若干个对象类组成一个层次结构的系统(也称为类等级)。

4.对象彼此之间仅能通过传递消息互相联系。

二、OO方法的基本思想

   对象:是事物运行方式、处理方法和属性值的一种抽象表述。它是严格信息包和有关信息包的操作描述;它是事物的本质,不会随周围环境改变而变化的相对固定的最小的集合。它可用一组属性和可以执行的一组操作来定义。

    例:在计算机屏幕上画多边形,每个多边形是一个用有序顶点的集所定义的对象。

    这些顶点的次序决定了它们的连接方式,顶点集定义了一个多边形对象的状态,包括它的形状和它在屏幕上的位置,在多边形上的操作包括:draw(屏幕显示)、 move(移动)、 contains(检查某点是否在多边形内)。

    类:是一组具有相同数据结构和相同操作的对象的集合。

    类的定义包括一组数据属性和在数据上的一组合法的操作。在一个类中,每个对象都是类的实例(instance)。同类的对象具有相同的方法集。

    类还具有父类、子类之分。父类高层次的类,表达共性,子类低层次表达个性。子类通过继承机制获得父类的属性和操作。例如:电视机、电话、计算机等都是电子产品,它们具有电子产品的公共特性,当定义电视机类Video,电话类Telephone和计算机类Computer时候,为避免它们公共特性的重复编码,可将这些电子产品的公共特性部分定义为电子产品类,将Video,Telephone和Computer定义为它的子类,子类继承了父类的所有属性和操作,而且子类自己还可扩充定义自己的属性和操作:如电子产品类具有型号、价格、颜色等属性,computer则继承了这些属性,并扩充自己的属性:显示类型、内存大小等属性。

1.发现对象的途经

(1)古典法
候选的对象和类通常来自下列来源:
有形事物:汽车、气象数据、压力传感器。
角色:父亲、教师、医生、女兵。
事件:降落、中断、要求。
交互作用:借款、会议、交叉。
候选的对象还可能来自:
结构:“ 是一个”及“ …的部分”关系。
其它系统:与待研制系统有交往的其它系统。
承担的角色:用户与待研制系统交往时所承担的不同角色,如站长、站调、统计员等。
地点:待研制系统中重要的具体地点、办公处以及场所,如信号楼、技术科、调度室。
组织单位:用户所属组织,如生产部、经营部、总务处等。
(2)领域分析法
    古典法是集中于问题的有形事物,而领域分析法则集中于问题领域中重要的对象、操作以及关系识别。其任务是在某一问题领域中识别出所有一切应用问题共有的客体和类,例如,销售、会计、债券交易、编译程序等都是问题领域。
    领域分析法举例
    例如,需要研制一个邮政销售(函售)系统,所考虑的函售应用问题如它们的关健对象一时想不出来,可对整个销售领域进行领域分析,即从现存的零售、批发系统中发现那些一时想不出来的对象,或得到启发而定出所需对象。
(3)结构化分析法

  它是利用结构化分析的成果,如DFD(数据流程图)、实体关系图、数据字典等,找出和识别对象。
    数据流程图中的数据存储、外部实体,有些非系统内部的数据流(它可来自外部的刺激或系统对外界的响应)等均可以作为候选对象。如存户来银行存款,即是外部对银行存款系统的的一个刺激,其数据内容是存户款;给存户的月终结算,是系统对外部的响应。 

2.对象具有如下特征

   模块性:对象是一个独立存在的实体。从外部可以了解它的功能,其内部细节是“ 隐蔽”的, 不受外界干扰。对象之间的相互依赖性很小。所以,模块性体现了抽象和信息的隐蔽。它使得一个复杂的软件系统可以通过定义一组相对独立的模块来实现,这些独立模块彼此之间只需交换那些为了完成系统功能所必须交换的信息。当模块内部实现发生变化而导致代码修改时,只要对外接口操作的功能不变,就不会给软件系统带来影响。

    继承和类比性:对象之间属性关系的共同性,即子模块继承了父模块的属性;通过类比方法抽象出典型对象的过程为类比。

    继承:是利用已有的定义作为基础来建立新的定义,而不必重复定义它们。
例如,汽车具有“ 型号”、“ 年代”和“ 引擎”等属性,其子类吉普车、轿车及卡车都继承了这些属性。

    动态连接性:各个对象之间统一、方便、动态的消息传递机制。它是面向对象语言的共同特性,其含义是将一条发送给一个对象的消息与包含该消息的方法的对象联接起来,它使得增加新的数据类型不需要改变现有的代码。

3.以对象为主体的OO方法

  (1)客观事物都是由对象(object)组成的,对象是在原事物基础上抽象的结果。任何复杂的事物都可以通过对象的组合构成。

   (2)对象由属性(attribute)和方法组成。属性反映了对象的信息特征,如:特点、值、状态等等;方法(method)则是用来定义改变属性状态的各种操作。

    例如:电视机对象的属性有颜色、音量、亮度、频道等,其上的操作有调节颜色、调节音量、调节亮度、调节频道等。

    如:图书馆系统中其业务过程和业务实体中,最基本的对象类只有读者和复本。最基本的业务操作只有借阅和查询。

  (3)对象之间的联系主要是通过传递消息(message)来实现的,而传递的方式是通过消息模式(message pattern)和方法所定义的操作过程来完成的。

    例如当用户请求document的对象打印它自己时,该文档可发送一消息给对象printer以在打印队列中请求一位置,而printer则可发送一消息返回至该文档以要求对信息加以格式化。消息还可包含解释一请求的信息。如请求一对象打印其自身的消息可包含打印机名。

  (4)对象可按照其属性进行归类(class),类有一定的结构,类上有超类(父类),类下有子类。这种对象或类之间的层次结构是靠继承关系维系着的。一般父类具有通用性,子类具有特殊性。例如:

图4-4-1 类、子类、超类关系
    segment是一个对象,paragraph和table共享某些性质,则可用更抽象的类text表示;paragraph也是一个类,它虽是segment的父类却是text的子类,text是类document的子类,text是table的超类(父类)。

    又如汽车是轿车、吉普车及卡车的父类,轿车、吉普车及卡车是汽车的子类。父类和子类是相对的。父类之上可有另一父类,而成为其子类。

   (5)对象是一个被严格模块化的实体,称为封装(encapsulation)。这种封装了的对象满足软件工程的一切要求,而且可以直接被面向对象的程序设计语言所接受。

    例如,电视机箱将电视内部的显象管、印刷板、元件和线路都封装起来了。人们只能通过电视机面板上按钮改变其属性(颜色、音量、亮度、频道、制式等)。

    有关对象的概念还有下列相关的一些内容:

  •   实例(Instance)

    实例就是由某个特定的类所描述的一个具体的对象。类是对具有相同属性和行为的一组相似的对象的抽象,类在现实世界中并不能真正存在。在地球上并没有抽象的“中国人”,只有一个个具体的中国人,例如,张三、李四、王五,同样,谁也没见过抽象的“圆”。

    实际上类是建立对象时使用的“样板”,按照这个样板所建立的一个个具体的对象,就是类的实际例子,通常称为实例。

  •   消息(Message) 

对象之间进行通信的一种构造叫做消息,当一个消息发送给某个对象时,包含要求接收对象去执行某些活动的信息。接收到消息的对象经过解释,然后予以响应。这种通信机制叫做消息传递。发送消息的对象不需要知道接收消息的对象如何对请求予以响应。通常,一个消息由下述三部分组成:

(a)接收消息的对象;

(b)消息选择符(也称为消息名);

(c)零个或多个变元。

  •   方法(Method) 

    方法,就是对象所能执行的操作,也就是类中所定义的服务。方法描述了对象执行操作的算法,响应消息的方法。在C++语言中把方法称为成员函数。

    例如,在录音机的例子中,为了能让使用者按下“放音键”就开始播放磁带,必须在录音机类中给出“按下放音键”的定义,也就是给出这个动作的实现方法。

  •   属性(Attribute) 

    属性,就是类中所定义的数据,它是对客观世界实体所具有的性质的抽象。类的每个实例都有自己特有的属性值。

    例如,在录音机类中定义的代表录音机的型号、外观、电压等数据就是属性。

  •   继承(Inheritance)

    广义地说,继承是指能够直接获得已有的性质和特性,而不必重复定义它们。在面向对象的软件技术中,继承是子类自动地共享基类(或父类)中定义的数据和方法的机制。一个类直接继承其父类的全部描述(数据和操作)。

    继承具有传递性,继承性使得相似的对象可以共享程序代码和数据结构,从而大大减少了程序中的冗余信息。使得对软件的修改变得比过去容易得多了。

    继承性使得用户在开发新的应用系统时不必完全从零开始,可以继承原有的相似系统的功能或者从类库中选取需要的类,再派生出新的类以实现所需要的功能,所以,继承的机制主要是支持程序的重用和保持接口的一致性。

  •   多态性(Polymorphism)

    在面向对象的软件技术中,多态性是指子类对象可以像父类对象那样使用,同样的消息既可以发送给父类对象也可以发送给子类对象。也就是说,在类等级的不同层次中可以共享(公用)一个行为(方法)的名字,然而不同层次中的每个类却各自按自己的需要来实现这个行为。当对象接收到发送给它的消息时,根据该对象所属于的类动态选用在该类中定义的实现算法。

  •   重载(Overloading)

    有两种重载:函数重载是指在同一作用域内的若干个参数特征不同的函数可以使用相同的函数名字;运算符重载是指同一个运算符可以施加于不同类型的操作数上面。当然,当参数特征不同或被操作数的类型不同时,实现函数的算法或运算符的语义是不相同的。

    重载进一步提高了面向对象系统的灵活性和可读性。

三、OO方法的开发过程

   OO方法开发过程分为4个阶段:

  1.系统调查和需求分析:对系统面临的问题和用户的开发需求进行调查研究。

  2.分析问题的性质和求解问题:在复杂的问题域中抽象识别出对象及其行为、结构、属性和方法。这一个阶段一般称为面向对象分析,即OOA。

  3.整理问题:对分析的结果进一步抽象、归类整理,最终以范式的形式确定下来,即OOD。

  4.程序实现:使用面向对象的程序设计语言将其范式直接映射为应用程序软件,即OOP(它是一个直接映射过程)。

四、OOA方法(面向对象分析)

本节着重讨论面向对象分析(Object-Oriented Analysis, OOA)。

面向对象分析与其它分析方法一样,是提取系统需求的过程。

面向对象分析的关键,是识别出问题域内的对象,并分析他们相互间的关系,最终建立起问题域的正确模型。

通常,面向对象分析过程从分析陈述用户需求的文件开始。需求陈述的内容包括:问题范围,功能需求,性能需求,应用环境及假设条件等。总之,需求陈述应该阐明“做什么”而不是“怎样做”。它应该描述用户的需求而不是提出解决问题的方法。在利用面向对象开发方法时,书写需求陈述要尽力做到语法正确,而且应该慎重选用名词、动词、形容词和同义词。

接下来,系统分析员应该深入理解用户需求,抽象出目标系统的本质属性,并用模型准确地表示出来。

面向对象分析大体上按照下列顺序进行:建立功能模型、建立对象模型、建立动态模型、定义服务。

1.建立功能模型

    功能模型从功能角度描述对象属性值的变化和相关的函数操作,表明了系统中数据之间的依赖关系以及有关的数据处理功能,它由一组数据流图组成。其中的处理功能可以用IPO图、伪码等多种方式进一步描述。

    建立功能模型首先要画出顶层数据流图,然后对顶层图进行分解,详细描述系统加工、数据变换等,最后描述图中各个处理的功能。

2.建立对象模型

    复杂问题(大型系统)的对象模型由下述五个层次组成:主题层(也称为范畴层)、类-&-对象层、结构层、属性层和服务层,如图4-4-2所示。

图4-4-2 对象模型的层次 

    这五个层次很像叠在一起的五张透明塑料片,它们一层比一层显现出对象模型的更多细节。在概念上,这五个层次是整个模型的五张水平切片。

    建立对象模型典型的工作步骤是:首先确立对象类和关联,对于大型复杂的问题还要进一步划分出若干主题;然后给类和关联增添属性,以进一步描述它们;接下来利用适当的继承关系进一步合并和组织类。

(1)确定类-&-对象

    类-&-对象是在问题域中客观存在的,系统分析员的主要任务就是通过分析找出这些类-&-对象。首先,找出所有候选的类-&-对象;然后,从候选的类-&-对象中筛选掉不正确的或不必要的项。

步骤1:找出候选的类-&-对象

    对象是对问题域中有意义的事物的抽象,它们既可能是物理实体,也可能是抽象概念,在分析所面临的问题时,可以参照几类常见事物,找出在当前问题域中的候选类-&-对象。

    另一种更简单的分析方法,是所谓的非正式分析。这种分析方法以用自然语言书写的需求陈述为依据,把陈述中的名高速作为类-&-对象的候选者,用形容词作为确定属性的线索,把动高速作为服务(操作)候选者。当然,用这种简单方法确定的候选者是非常不准确的,其中往往包含大量不正确的或不必要的事物,还必须经过更进一步的严格筛选。通常,非正式分析是更详细、更精确的正式的面向对象分析的一个很好的开端。

步骤2:筛选出正确的类-&-对象

    非正式分析仅仅帮助我们找到一些候选的类-&-对象,接下来应该严格考察候选对象,从中去掉不正确的或不必要的,仅保留确实应该记录其信息或需要其提供服务的那些对象。筛选时主要依据下列标准,删除不正确或不必要的类-&-对象:

<1>冗余(如果两个类表达了同样的信息)

<2>无关(仅需要把与本问题密切相关的类-&-对象放进目标系统中)

<3>笼统(需求陈述中笼统的、泛指的名词)

<4>属性(在需求陈述中有些名词实际上描述的是其它对象的属性)

<5>操作(正确地决定把某些词作为类还是作为类中定义的操作)

<6>实现(去掉仅和实现有关的候选的类-&-对象)

()确定关联

    两个或多个对象之间的相互依赖、相互作用的关系就是关联。分析确定关联,能促使分析员考虑问题域的边缘情况,有助于发现那些尚未被发现的类-&-对象。

步骤1.初步确定关联

    在需求陈述中使用的描述性动词或动词词组,通常表示关联关系。因此,在初步确定关联时,大多数关联可以通过直接提取需求陈述中的动词词组而得出。通过分析需求陈述,还能发现一些在陈述中隐含的关联。最后,分析员还应该与用户及领域专家讨论问题域实体间的相互依赖、相互作用关系,根据领域知识再进一步补充一些关联。

步骤2.自顶向下

    把现有类细化成更具体的子类,这模拟了人类的演绎思维过程。从应用域中常常能明显看出应该做的自顶向下的具体化工作。例如,带有形容词修饰的名词词组往往暗示了一些具体类。但是,在分析阶段应该避免过度细化。

()定义结构

    结构指的是多种对象的组织方式,用来反映问题空间中的复杂事物和复杂关系。这里的结构包括两种:分类结构与组装结构。分类结构针对的是事物的类别之间的组织关系,组织结构则对应着事物的整体与部件之间的组合关系。

    使用分类结构,可以按事物的类别对问题空间进行层次化的划分,体现现实世界中事物的一般性与特殊性。例如在交通工具、汽车、飞机、轮船这几件事物中,具有一般性的是交通工具,其它则是相对特殊化的。因此可以将汽车、飞机、轮船这几种事物的共有特征概括在交通工具之中,也就是把对应于这些共有特征的属性和服务放在“交通工具”这种对象之中,而其它需要表示的属性和服务则按其特殊性放在“汽车”、“飞机”、“轮船”这几种对象之中,在结构上,则按这种一般与特殊的关系,将这几种对象划分在两个层次中,如图4-4-3所示:

4-4-3  分类结构示例 

    组织结构表示事物的整体与部件之间的关系。例如把汽车看成一个整体,那么发动机、变速箱、刹车装置等都是汽车的部件,相对于汽车这个整体就分别是一个局部。

()识别主题

    对一个实际的目标系统,特别是大的系统而言,尽管通过对象和结构的认定对问题空间中的事物进行了抽象和概括,但对象和结构的数目仍然是可观的,因此如果不对数目众多的对象和结构进行进一步的抽象,势必造成对分析结果理解上的混乱,也难以搞清对象、结构之间的关联关系,因此引入主题的概念。

主题是一种关于模型的抽象机制,它给出了一个分析模型的概貌。

主题直观地来看就是一个名词或名词短语,与对象的名字类似,只是抽象的程度不同。识别主题的一般方法是:为每一个结构追加一个主题;为每一种对象追加一个主题;如果当前的主题的数目超过了7个,就对已有的主题进行归并,归并的原则是,当两个主题对应的属性和服务有着较密切的关联时,就将它们归并成一个主题。

()认定属性

属性是数据元素,用来描述对象或分类结构的实例。

认定一个属性有三个基本原则:首先,要确认它对响应对象或分类结构的每一个实例都是适用的;其次,对满足第一个条件的属性还要考察其在现实世界中与这种事物的关系是不是足够密切;第三,认定的属性应该是一种相对的原子概念,即不依赖于其它并列属性就可以被理解。

3.建立动态模型

当问题涉及交互作用和时序时(例如用户界面及过程控制等),建立动态模型则是很重要的。

建立动态模型的第一步,是编写典型交互行为的脚本。脚本是指系统在某一执行期间内出现的一系列事件。编写脚本的目的,是保证不遗漏重要的交互步骤,它有助于确保整个交互过程的正确性和清晰性。

第二步从脚本中提取出事件,确定触发每个事件的动作对象以及接受事件的目标对象。

第三步,排列事件发生的次序,确定每个对象可能有的状态以及状态间的转换关系。

最后,比较各个对象的状态,检查它们之间的一致性,确保事件之间的匹配。 

4.定义服务

    通常在完整地定义每个类中的服务之前,需要先建立起动态模型和功能模型,通过对这两种模型的研究,能够更正确更合理地确定每个类应该提供那些服务。

    正如前面已经指出的那样,“对象”是由描述其属性的数据,及可以对这些数据施加的操作(即服务)封装在一起构成的独立单元。因此,为建立完整的动态模型,既要确定类的属性,又要定义类的服务。在确定类中应有的服务时,既要考虑类实体的常规行为,又要考虑在本系统中特殊需要的服务。

 首先考虑常规行为:在分析阶段可以认为类中定义的每个属性都是可以访问的,即假设在每个类中都定义了读、写该类每个属性的操作。

 其次,从动态模型和功能模型中总结出特殊服务。

 最后应该尽量利用继承机制以减少所需定义的服务数目。

五、OOD方法(面向对象的设计)

    如前所述,分析是提取和整理用户需求,并建立问题域精确模型的过程。设计则是把分析阶段得到的需求转变成符合成本和质量要求的、抽象的系统实现方案的过程。从面向对象分析到面向对象设计(通常缩写为OOD),是一个逐渐扩充模型的过程。或者说,面向对象设计就是用面向对象观点建立求解域模型的过程。

    尽管分析和设计的定义有明显区别,但是在实际的软件开发过程中二者的界限是模糊的。许多分析结果可以直接映射成设计结果,而在设计过程中又往往会加深和补充对系统需求的理解,从而进一步完善分析结果。因此,分析和设计活动是一个多次反复迭代的过程。面向对象方法学在概念和表示方法上的一致性,保证了在各项开发活动之间的平滑(无缝)过渡,领域专家和开发人员能够比较容易地跟踪整个系统开发过程,这是面向对象方法与传统方法比较起来所具有的一大优势。

1.面向对象设计的准则

    在以前的软件设计中人们总结出几条基本原理,这些原理在进行面向对象设计时仍然成立,但是增加了一些与面向对象方法密切相关的新特点,从而具体化为下列的面向对象设计准则:

(1)  模块化

    面向对象软件开发模式,很自然地支持了把系统分解成模块的设计原理:对象就是模块。它是把数据结构和操作这些数据的方法紧密地结合在一起所构成的模块。

(2)  抽象

    抽象表示对规格说明的抽象(abstraction by specification)和参数化抽象(abstraction by parametrization)。

(3)  信息隐藏

    在面向对象方法中,信息隐藏通过对象的封装性实现:类结构分离了接口与实现,从而支持了信息隐藏。对于类的用户来说,属性的表示方法和操作的实现算法都应该是隐藏的。

(4)  弱耦合

    在面向对象方法中,对象是最基本的模块,因此,耦合主要指不同对象之间朴素关联的紧密程度。弱耦合是优秀设计的一个重要标准,因为这有助于使得系统中某一部分的变化对其它部分的影响降到最低程度。

    当然,对象不可能是完全孤立的,当两个对象必须朴素联系、朴素依赖时,应该通过类的协议(即公共接口)实现耦合,而不应该依赖于类的具体实现细节。

(5)  强内聚

    设计中使用的一个构件内的各个元素,对完成一个定义明确的目的所做出的贡献程度。在设计时应该力求做到高内聚。在面向对象设计中存在下述三种内聚:

    <1>服务内聚

    一个服务应该完成一个且仅完成一个功能。

    <2>类内聚

    一个类应该只有一个用途。

    <3>一般-特殊内聚

    设计出的一般-特殊结构,应该符合多数人的概念。

(6)  可重用

    软件重用是提高软件开发生产率和目标系统质量的重要途径。重用也叫再用或复用,是指同一事物不作修改或稍加改动就多次重复使用。重用是从设计阶段开始的。重用有两方面的含义:一是尽量使用已有的类(包括开发环境提供的类库,及以往开发类似系统时创建的类),二是如果确实需要创建新类,则在设计这些新类的协议时,应该考虑将来的可重复使用性。

    软件成分的重用可以进一步划分成以下三个级别:

<1>代码重用

<2>设计结果重用

 设计结果重用指的是,重用某个软件系统的设计模型(即求解域模型)。这个级别的重用有助于把一个应用系统移植到完全不同的软/硬平台上。

<3>分析结果重用

 这是一种更高级别的重用,即重用某个系统的分析模型。这种重用特别适用于用户需求未改变,但系统体系结构发生根本变化的场合。

 通过分析软件重用的效果发现,重用率越高,生产率并不一定就越高。仅当开发人员使用已有软构件构造系统时,其工作效率比重新从底层编写程序的效率高时,重用率的提高才会导致生产率提高。可见,通过软件重用来提高软件生产率,并不是一件轻而易举的事情。软构件的实用程序和程度,以及软件开发人员的素质、开发环境等因素,都直接影响软件重用的效果。事实上,自20世纪60年代以来,人们就开始研究软件重用技术,主要目的是大幅度提高软件生产率,降低软件成本。但是,多年来始终没能有效地实现软件重用,直到面向对象技术崛起之后,才为软件重用带来了新的希望。

2.面向对象设计的内容

    采用面向对象方法设计软件系统时,面向对象设计模型(即求解域的对象模型)与面向对象分析模型(即求问题域的对象模型)一样,也由主题、类-&-对象、结构、属性、服务等五个层次组成。这五个层次表示的细节一层比一层多,我们可以把这五个层次想象为整个模型的水平切片。此外,大多数系统的面向对象设计模型,在逻辑上都由四大部分组成。这四大部分对应于组成目标系统的四个子系统,它们分别是问题域子系统、人-机交互子系统、任务管理子系统和数据管理子系统。

(1)设计问题域子系统

 通过面向对象分析所得出的问题域精确模型,为设计问题域子系统奠定了良好的基础,建立了完整的框架。只要可能,就应该保持面向对象分析所建立的问题域结构。通常,面向对象设计仅需从实现角度对问题域模型作一些补充或修改,主要是增添、合并或分解类-&-对象、属性及服务,调整继承关系等等。当问题域子系统过分复杂庞大时,应该把它进一步分解成若干个更小的子系统。

 下面介绍在面向对象设计过程中,可能对面向对象分析所得出的问题域模型的补充或修改:

<1>调整需求

    有两种情况出现需要调整需求:用户需求或外部环境发生了变化;分析员对问题的理解存在问题。无论哪种情况出现,通常都只需要简单地修改分析的结果,然后把这些修改的结果反映到问题域子系统中。

<2>重用已有的类

    代码重用从设计阶段开始,在研究面向对象分析结果时就应该寻找使用已有类的方法。若因为没有合适的类可以重用而确实需要创建新的类,则在设计这些新类的协议时,考虑到将来的可重用性。

<3>把问题域类组合在一起

    在面向对象设计过程中,设计者往往通过引入一个根类而把问题域组合在一起,但这是在没有更先进的组合机制时才采用的一种组合方法。

<4>增添一般化类以建立协议

在设计过程中常常发现,一些具体类需要有一个公共的协议,也就是说,它们都需要定义一组类似的服务(很可能还需要相应的属性)。在这种情况下可以引入一个附加类(例如,根类)。

<5>调整继承层次

    如果面向对象分析模型中包含了多重继承关系,然而所使用的程序设计语言却并不提供多重继承机制,则必须修改面向对象分析的结果。即使使用支持多重继承的语言,有时也会出于实现考虑而对面向对象分析结果作一些调整。

(2)设计人-机交互子系统

    在面向对象分析过程中,已经对用户界面需求作了初步分析,在面向对象设计过程中,则应该对系统的人-机子系统进行详细设计,以确定人-机交互的细节,其中包括指定窗口和报表的形式、设计命令层次等项内容。人-机交互部分的设计结果,将对用户情绪和工作效率产生重要影响。

    <1> 设计人-机交互界面的准则

一致性

减少步骤

及时提供反馈信息

提供撤消命令

无须记忆

易学

富有吸引力

    <2>设计人-机交互子系统的策略

  • 分类用户

    为设计好人-机交互子系统,设计者应该认真研究使用它的用户。设计者首先应该把将来可能与系统交互的分类。通常从下列几个不同角度进行分类:

按技能水平分类(新手/初级/中级/高级)。

按职务分类(总经理/经理/职员)。

按所属集团分类(职员/顾客)。

  • 描述用户

    应该仔细了解未来使用系统的每类用户的情况,把获得的下列各项信息记录下来:

用户类型。

使用系统欲达到的目的。

特征(年龄、性别、受教育程度、限制因素等)。

关键的成功因素(需求、爱好、习惯等)。

技能水平。

完成本职工作的脚本。

  •   设计命令层次

设计命令层次的工作通常包含以下几项内容:

研究现有的人-机交互含义和准则

现在,Windows已经成了微机上图形用户界面事实上的工业标准。

确切初始的命令层次

所谓命令层次,实质上是用过程抽象机制组织起来的、可供选用的服务的表示形式。

精化命令层次

精化命令层次应考虑以下因素:次序、整体—部分关系、操作步骤。

  •   设计人-机交互类

人-机交互类与所使用的操作系统及编程语言密切相关。

(3)设计任务管理子系统

虽然从概念上说,不同对象可以并发地工作。但是,在实际系统中,许多对象之间往往存在相互依赖关系。此外,在实际使用的硬件中,可能仅由一个处理器支持多个对象。因此,设计工作的一项重点就是,确定哪些是必须同时操作的对象,哪些是相互排斥的对象。然后进一步设计任务管理子系统。

<1> 分析并发性

彼此间不存在交互,或者它们同时接受事件,则这两个对象在本质上是并发的。通过检查各个对象的状态图及它们之间交换的事件,能够把若干个非并发的对象归并到一条控制线中。所谓控制线,是一条遍及状态图集合的路径,在这条路径上每次只有一个对象是活动的。在计算机系统中用任务(task)实现控制线,一般认为任务是进程(process)的别名。通常把多个任务的并发执行称为多任务。

<2>  设计任务管理子系统

常见的任务有事件驱动型任务、时钟驱动型任务、优先任务、关键任务和协调任务等。设计任务管理子系统,包括确定各类任务并把任务分配给适当的硬件或软件去执行。

  • 确定事件驱动型任务

某些任务是由事件驱动的,这类任务可能主要完成通信工作。例如,设备、屏幕窗口、其它任务、子系统、另一个处理器或其它系统通信。事件通常是表明某些数据到达的信号。

  • 确定时钟驱动任务

某些任务每隔一定时间间隔就被触发以执行某些处理,例如,某些设备需要周期性地获得数据;某些人-机接口、子系统、任务、处理器或其它系统也可能需要周期性地通信。在这些场合往往需要使用时钟驱动型任务。

  •   确定优先任务

优先任务可以满足高优先级或低优先级的处理需求。

高优先级:某些服务具有很高的优先级,为了在严格限定的时间内完成这种服务,可能需要把这类服务分离成独立的任务。

低优先级:与高优先级相反,有些服务是低优先级的,属于低优先级处理(通常指那些背景处理)。设计时可能用额外的任务把这样的处理分离出来。

  •   确定关键任务

关键任务是关系到系统成功或失败的那些关键处理,这类处理通常都有严格的可靠性要求。

  •   确定协调任务

当系统中存在三个以上任务时,就应该增加一个任务,用它作为协调任务。

  •   确定资源需求

使用多处理器或固件,主要是为了满足高性能的需求。设计者必须通过计算系统载荷来估算所需要的CPU(或其它固件)的处理能力。

(4)设计数据管理子系统

数据管理子系统是系统存储或检索对象的基本设施,它建立在某种数据存储管理系统之上,并且隔离了数据存储管理模式。

<1>  选择数据存储管理模式

文件管理系统、关系数据库管理系统、面向对象数据管理系统三种数据存储管理模式有不同的特点,适用范围也不同,其中文件系统用来长期保存数据,具有成本低和简单等特点,但文件操作级别低,为提供适当的抽象级别还必须编写额外的代码;关系数据库管理系统提供了各种最基本的数据管理功能,采用标准化的语言,但其缺点是运行开销大,数据结构比较简单;面向对象数据管理系统增加了抽象数据类型和继承机制,提供了创建及管理类和对象的通用服务。

<2>  设计数据管理子系统

设计数据管理子系统,既需要设计数据格式又需要设计相应的服务。设计数据格式包括用范式规范每个类的属性表以及由此定义所需的文件或数据库;设计相应的服务是指设计被存储的对象如何存储自己。

OOP方法( 面向对象实现)

面向对象实现主要包括两项工作:把面向对象设计结果翻译成用某种程序语言书写的面向对象程序;测试并调试面向对象的程序。

面向对象程序的质量基本上由面向对象设计的质量决定,但是,所采用的程序语言的特点和程序设计风格也将对程序的生成、可重用性及可维护性产生深远影响。

1.程序设计

(1)面向对象的语言与非面向对象的语言

面向对象语言的形成借鉴了历史上许多程序语言的特点,从中吸取了丰富的营养。当今的面向对象语言,从50年代诞生的LISP语言中引进了动态联编的概念和交到式开发环境的思想,从60年代推出的SIMULA语言中引进了类的概念和继承机制,此外,还受到70年代末期开发的Modula-2语言和Ada语言中数据抽象机制的影响。

100年代以来,面向对象语言像雨后春笋一样大量涌现,形成了两大类面向对象语言。一类是纯面向对象语言,如Smalltalk和Eiffel等语言。另一类是混合型面向对象语言,也就是在过程语言的基础上增加面向对象机制,如C++等语言。

一般说来,纯面向对象语言着重支持面向对象方法研究和快速原型的实现,而混合型面向对象语言的目标则是提高运行速度和使传统程序员容易接受面向对象思想。成熟的面向语言通常都提供丰富的类库和强有力的开发环境。

下面介绍在选择面向对象语言时应该着重考察的一些技术特点。

<1>支持类与对象概念的机制

所有面向对象语言都允许用户动态创建对象,并且可以用指针引用动态创建的对象。允许动态创建对象,就意味着系统必须处理内存管理问题,如果不及时释放不再需要的对象所占用的内存,动态存储分配就有可能耗尽内存。

<2>实现整体–部分结构的机制

一般说来,有两种实现方法,分别使用指针和独立的关联对象实现整体一部分结构。大多数现有的面向对象语言并不显示支持独立的关联对象,在这种情况下,使用指针是最容易的实现方法,通过增加内部指针可以方便地实现关联。

<3>实现一般–特殊结构的机制

既包括实现继承的机制也包括解决名字冲突的机制。所谓解决名字冲突,指的是处理在多个基类中可能出现的重名问题,这个问题仅在支持多重继承的语言中才会遇到。某些语言拒绝接受有名字冲突的程序,另一些语言提供了解决冲突的协议。不论使用何种语言,程序员都应该尽力避免出现名字冲突。

<4>实现属性和服务的机制

对于实现属性的机制应该着重考虑以下几个方面:支持实例连接的机制;属性的可见性控制;对属性值的约束。对于服务来说,主要应该考虑下列因素:支持消息连接(即表达对象交互关系)的机制;控制服务可见性的机制;动态联编。

<5>类型检查

程序设计语言可以按照编译时进行类型检查的严格程度来分类。如果语言仅要求每个变量或属性隶属于一个对象,则是弱类型的;如果语法规定每个变量或属性必须准确地隶属于某个特定的类,则这样的语言是强类型的。

<6>效率

许多人认为面向对象语言的主要缺点是效率低。事实上,如有完整类库的面向对象语言,有时能比使用非面向对象语言得到运行更快的代码。这是因为类库中提供了更高效的算法和更好的数据结构。

<7>持久保存对象

<8>参数化类

所谓参数化类,就是使用一个或多个类型去参数化一个类型的机制,有了这种机制,程序员就可以先定义一个参数化的类模板(即在类定义中包含以参数形式出现的一个或多个类型),然后把数据类型作为参数传递进来,从而把这个类模板用在不同的应用程序中,或用在同一应用程序的不同部分。Eiffel语言中就有参数化类,C++语言也提供了类模板。

<9>开发环境

软件工具和软件工程环境对软件生产率有很大影响。由于面向对象程序中继承关系和动态联编等引入的特殊复杂性,面向对象语言所提供的软件工具或开发环境就显得尤其重要了。至少应该包括下列一些最基本的软件工具:编辑程序,编译程序或解释程序,浏览工具,调试器(debugger)等。

(2)程序设计风格

良好的程序设计风格对保证程序质量的重要性。良好的程序设计风格对面向对象实现来说尤其重要,不仅能明显减少维护或扩充的开销,而且有助于在新项目中重用已有的程序代码。

良好的面向对象程序设计风格,既包括传统的程序设计风格和准则,也包括为适应面向对象方法所特有的概念(例如,继承性)而必须遵循的一些新准则。

<1>提高可重用性

面向对象方法的一个主要目标,就是提高软件的可重用性。正如本书11.3节所述,软件重用有多个层次,在编码阶段主要涉及代码重用问题。一般说来,代码重用有两种:一种是本项目内的代码重用,另一种是新项目重用旧项目的代码。内部重用主要是找出设计中相同或相似的部分,然后利用继承机制共享它们。

  • 提高方法的内聚
  • 减小方法的规模
  • 保持方法的一致性

保持方法的一致性,有助于实现代码重用。一般说来,功能相似的方法应该有一致的名字、参数特征(包括参数个数、类型和次序)、返回值类型、使用条件及出错条件等。

  • 把策略与实现分开
  • 全面覆盖

如果输入条件的各种组合都可能出现,则应该针对所有组合写出方法,而不能仅仅针对当前用到的组合情况写方法。

此外,一个方法不应该只能处理正常值,对空值、极限值及界外值等异常情况也应该能够作出有意义的响应。

  • 尽量不使用全局信息

应该尽量降低方法与外界的耦合程度,不使用全局信息是降低耦合度的一项主要措施。

  • 利用继承机制

在面向对象程序中,继承机制是实现共享和提高重用程度的主要途径。

有时提高相似类代码可重用性的一个有效途径,是从不同类的相似方法中分解出不同的“因子”(即不同的代码),把余下的代码作为分用方法中的公共代码,把分解出的因子作为名字相同算法不同的方法,放在不同类中定义,并被这个公用方法调用。

    程序员往往希望重用其它方法编写的、解决同一类应用问题的程序代码。重用这类代码的一个比较安全的途径,是把被重用的代码封装在类中。

<2>  提高健壮性

    为提高健壮性应遵守以下几条准则:预防用户的误操作,不要预先限制条件,先测试后优化。

2、面向对象测试

一般说来,对面向对象软件的测试可分为下列四个层次进行:

(1)算法层

测试类中定义的每个方法,基本上相当于传统软件测试中的单元测试。

(2)类层

测试封装在同一个类中的所有方法与属性之间的相互作用。在面向对象软件中类是基本模块,因此可以认为这是面向对象测试中所特有的模块(单元)测试。

(3)主题层

测试一组协同工作的类-&-对象之间的相互作用。大体上相当于传统软件测试中的子系统测试,但是也有面向对象软件的特点(例如,对象之间通过发送消息相互作用)。

(4)系统层

把各个子系统组装完整的面向对象软件系统,在组装过程中同时进行测试。

设计测试方案的传统技术,例如,逻辑覆盖、等价划分、边界值分析和错误推测等方法,仍然可以作为测试类中每个方法的主要技术。面向对象测试的主要目标,也是用尽可能低的测试成本和尽可能少的测试方案,发现尽可能多的错误。但是,面向对象程序中特有的封装、继承和多态等机制,也给面向对象测试带来一些新特点,增加了测试和调试的难度。

七、面向对象的语言(产品)
      面向对象的语言应该具备的特征
    1.用对象而非过程(功能或算法)作为程序设计的基本逻辑构件;
    2.每个对象属于应该类(型),并为该类的一个实例;
    3.一个类可继承其它类的性质。
       面向对象的语言有:
    1.SmallTalk-76,80,(80年代下半叶)

    2.Actor(80年代下半叶)
    3.C++,Objective-C (20世纪80年代下半叶)
    4.Object Pascal, Object-Oriented Turbo Pascal,Apple ObjectPascal (80年代初开始)
    5.Eiffel (80年代上半叶) 

    6.Ada9X 
      但Microsoft Visual C++, Boland C++等都属于混合型面向对象的语言,因为它们是在原来的过程语言的基础上发展起来的,都保留了原来的数据类型,如整数、浮点数、字符以及记录等。

    几个有代表性的商品软件
    Microsoft Visual Basic先从软件的可视化、速成化和组件化开始的,这3化已经开始或正在形成信息与软件工艺的主流之一。
    Bland Delphi是组件软件和复合文书工艺的软件。它包含面向对象Pascal的编辑程序、查错程序、可视研制环境和工具、强大的数据库存取(BDE-Database Engine)工具;它用Object Pascal做情节描述语言。
    Optima++ Developer 是Sybase/Powersoft出版的可视化、速成化的研制工具。它是采用C++的一种纯可视编辑工具,用拖扔编程技术,从一组标准的和可增的控件制模板中拖出组件,将其扔进应用图表中去,并编辑其性质。它可在Windows 9X和NT下运行,它不仅是一个GUI(图形用户接口)建造程序,而且还是一个C/S(客户/服务器)数据库构造工具。
    IBM的VisualAge(SmallTalk版),用一套图标来代表应用组件(对象),并提供许多标准函数(例程)、部件,供GUI配置关系数据库存取、通信、等之用。
    用户编程时,只需用鼠标把要用的部件(图标)拖扔到屏幕中的工作面内,按要求设置这些图标的缺省项和参数值,再把这些图标用线段连接起来,表示它们之间的关系和交互操作,并最后加以测试。在组装过程中,要添加复杂的计算/控件流,可用VisualAge的描述语言(Scripting Language-一种4GL)来编写。如果这还不行,VisualAge则提供SmallTalk编辑环境,以添加所需的语句。
    Digitalk(现叫ParcPlace-Digitalk)的Visual Smalltalk提供组件组装的可视研制环境和工具,用拖扔手段,可视地把组件组装成一个软件(程序),它还能自建新的组件。它最适宜研制软件雏形的OO程序设计语言。应用完成之后,使用Digitalk Smalltalk编译程序编译,其计算效率据称可增加25%,GUI效率增加了100%。
    Prograph CPX(跨平台)将程序面向对象结构的可视化方面做得较突出:
    -它用图标代表一个软件的组成部分,对象、类、组件全部可视化;
    -全套图标都用多面体图标,如类具有“ 方法”面和“ 属性”面;
    -能对图标加以注释,对象和类关系可用线段表示;
    -通过工具可方便地将方法加入Tools菜单;
    -既有解释程序、又有编译程序,可解除解释程序速度慢的问题。

八、OO方法特点和优缺点

1.特点

    (1)利用特定软件直接从对象客体的描述到软件结构的转换。

    (2)解决了传统结构化方法中客观世界描述工具与软件结构的不一致性。

    (3)减少了从系统分析、设计到软件模块结构之间的多次转换映射的繁杂过程。

2.OO方法优缺点

    优点:

     (1)是一种全新的系统分析设计方法(对象、类、结构属性、方法)。

     (2)适用于各类信息系统的开发。

     (3)实现了对客观世界描述到软件结构的直接转换 ,大大减少后续软件开发量。

     (4)开发工作的重用性、继承性高,降低重复工作量。

     (5)缩短了开发周期。

    缺点:

    (1)需要一定的软件支持环境。

    (2)不太适宜大型的MIS开发,若缺乏整体系统设计划分,易造成系统结构不合理、各部分关系失调等问题。

    (3)只能在现有业务基础上进行分类整理,不能从科学管理角度进行理顺和优化。

    (4)初学者不易接受、难学。

    面向对象方法学把分析、设计和实现很自然地联系在一起了。虽然面向对象设计原则上不依赖于特定的实现环境,但是实现结果和实现成本却在很大程度上取决于实现环境。因此,直接支持面向对象设计范式的面向对象程序语言、开发环境及类库,对于面向对象实现来说是非常重要的。

为了把面向对象设计结果顺利地转变成面向对象程序,首先应该选择一种适当的程序设计语言。面向对象的程序设计语言适合用来实现面向对象设计结果。事实上,具有方便的开发环境和丰富的类库的面向对象程序设计语言,是实现面向对象设计的最佳选择。

良好的程序设计风格对于面向对象实现来说格外重要。它既包括传统的程序设计风格准则,也包括与面向对象方法的特点相适应的一些新准则。

面向对象方法学使用独特的概念和完成软件开发工作,因此,在测试面向对象程序的时候,除了继承传统的测试技术之外,还必须研究与面向对象程序特点相适应的新的测试技术。在这方面需要做的研究工作还很多,目前已逐渐成为国内外软件工程界研究的一个新的热门课题。

本文引用地址:http://www.cnblogs.com/x8023z/archive/2008/12/04/oo33.html

八 18th, 2010  |  (1)北京至永清公交通车 – 943支

今天通车剪裁,明天正式开通
运营时间:永清 首班:5:00, 末班:19点

站牌:943支路线图

943支路线图

线路图:943支路线图