wenus


CnForums1.2针对Beta1版中用户反馈的一些问题,基本修正了大家反馈Beta1中存在的所有BUG,新增了一些功能,如:
支持框架式皮肤界面
支持动网等论坛的导入(动网论坛导入程序及源码随后发布)
版务管理
私人留言可以显示留言条数
桌面提醒功能(Popup提示)
……


现在有某个别团队直接在CnForum Beta1的源码基础上作简单修改即声称是自己的作品,保留对其进一步追究的权利。(如果在同类产品中直接使用CnForums源码,请征得作者同意并在作出相关申明)



谢谢大家对CnForums的支持


如果有任何问题请到论坛提问:http://www.cnforums.net

下载:http://bbs.openlab.net.cn/ShowThread.aspx?PostID=376725


PSP:CnForums 开发团队
2005-01-10


学习C++/CLI发现的一些问题,算不算Bug?

    内容篇幅较长,请点击这里阅读全文

枚举转化和判断方法的总结

定义枚举:
public enum DisplayType
{
  All=10,
  Up=20,
  Down=30
}

1.数值转化
(1)字符转化为枚举
string str="up";
DisplayType displayType;
displayType=(DisplayType)System.Enum.Parse(typeof(DisplayType),str,true);
Response.Write(displayType.ToString());

结果是:Up
Enum.Parse 方法第3个参数,如果为 true,则忽略大小写;否则考虑大小写。

(2)数字转化为枚举
int i=30;
DisplayType displayType;
displayType=(DisplayType)System.Enum.Parse(typeof(DisplayType),i.ToString());
Response.Write(displayType.ToString());
结果是:Down
(3)枚举转化为字符
DisplayType displayType=DisplayType.Down;
string str=displayType.ToString();
Response.Write(str);
结果是:Down

(4)枚举转化为数字
方法一:
DisplayType displayType=DisplayType.Down;
int i=Convert.ToInt32(displayType.ToString("d"));
Response.Write(i.ToString());
结果是:30

方法二:
DisplayType displayType=DisplayType.Down;
int i=((IConvertible)((System.Enum)displayType)).ToInt32(null);
Response.Write(i.ToString());
结果是:30

枚举的父类是System.Enum,父类继承了接口IConvertible

2.数值判断
有时候枚举数值由外界输入,这时候我们就得判断输入数值的正确性了.
(1)字符判断
方法一:
string str="u";
if(Enum.IsDefined(typeof(DisplayType),str))
{
 Response.Write("ok");
}
else
{
 Response.Write("error");
}
结果是:error

方法二:
string str="Up";
try
{
 Enum.Parse(typeof(DisplayType),str);
 Response.Write("ok");
}
catch(ArgumentException)
{
 Response.Write("error");
}
结果是:ok

Enum.Parse 方法的第2个参数,value 为空字符串或只包含空白或value 是一个名称,但不是为该枚举定义的已命名常数之一就发生异常

(2)数字判断
int i=30;
if(Enum.IsDefined(typeof(DisplayType),i))
{
 Response.Write("ok");
}
else
{
 Response.Write("error");
}
结果是:ok

在JScript中实现函数覆盖(override)

众所周知,JScrip中没有override关键字,但是我们可以构造一个调度函数来实现

<script language="JavaScript">
function Test1(param)
{
  alert(param);
}

function Test2(param1,param2)
{
  alert(param1 
+ param2);
}

function TestOverride(param1,param2)
{
  
if(param2==null)
    Test1(param1);
  
else
    Test2(param1,param2);
}

TestOverride(
1);
TestOverride(
1,2);
</script>

在使用Repeater、DataList 或 DataGrid 的模板列表时,根据不同状态,显示不同颜色

我们经常使用用于类似 Repeater、DataList 或 DataGrid 的模板列表,有时候需要根据不同状态,显示不同字帖颜色,以提示用户.

例如:在datagrid中,紧急显示红色,一般显示黑色,复杂显示蓝色

<asp:TemplateColumn HeaderText="紧急程度">
<ItemTemplate>
<font  color=\'<%# 

(string)DataBinder.Eval(Container.DataItem,"IdeaStateName")=="紧急"?"#FF0000":((string)DataBinder.Eval(Container.DataItem,"Id

eaStateName")=="一般")?"#000000":"#000080" %>\'>
<%#  (string)DataBinder.Eval(Container.DataItem,"IdeaStateName")  %>
</font>
</ItemTemplate>
</asp:TemplateColumn>   

效果如下:



这种方式有个要求,就是必须知道颜色的代码数值
如果这样<%#  (string)DataBinder.Eval(Container.DataItem,"IdeaStateName")=="紧急"?"RED":"Blue" %>页面会发生异常


那我们有没有在不知道颜色的代码数值的情况下的数据绑定解决办法呢?
      
<asp:TemplateColumn HeaderText="是否阅读">
<ItemTemplate>
<div ><%# ((bool)DataBinder.Eval(Container.DataItem,"IsRead"))?"<font>YES</font>":"<font color=red>NO</font>" %>  

</div>              

</ItemTemplate>             

</asp:TemplateColumn>

未阅读的显示红色的NO,阅读过的显示黑色的YES(本系统默认黑色)

PopoBBS 开发之 需求分析 ! (完善中)

说明:
设计中考虑到的 D 标识 (Desgin);
该动能完成的 C 标识 (Complete);

1 用户功能要求
1.1 注册:注册时验证邮箱,用户名
1.2 登陆:登陆后,强制其他机器上登陆的用户下线,隐身
1.3 修改资料,修改自己的在线状态
1.4 忘记密码用Email取回功能
1.5 发贴:发贴限制,Mp看贴限制,Html UBB编码,
1.3 看贴:积分需求看贴,今日新贴
1.4 换肤功能
1.5 论坛版面显示风格 (Mop型 Popo型 国字形状)
1.6 发投票贴:投票分多投和单投票,查看投票用户
1.7 传呼:(另外即时发送到手机功能)
1.8 在线功能: 用户积分排行,管理员列表,在线用户,站点信息(访问量最高,客户端信息等)

2 系统管理员功能
2.1 系统设置:论坛开启,注册,登陆,道具,查看异动,记录日志,页面缓存,查询,匿名访问(游客),传呼
2.2 参数设置:发贴Mp,列表最大数量,回复Mp限制,发UBB代码贴Mp限制,发Html代码贴Mp限制
   在线人数限制,敏感字过滤,预留用户名
2.3 帖子:锁定,删除,设置精华,修改(转移),查看发贴人Ip,固顶,总固顶
2.4 文件:图片上传(太大生成缩略图),文件管理
2.5 奖励惩罚用户,锁定用户(禁闭),帮派设置管理
2.6 用户管理:参看修改删除用户资料,设定用户管理权限(斑竹),设定认证会员
2.7 版块:添加修改删除版块,设置版块排序,锁版
2.8 Ip: 屏蔽Ip和Ip段功能
2.9 友情连接
2.10 直接执行Sql语句.
2.11 发布公告
2.12 统计: 最高访问日,计算发贴数量,传呼数量,用户数,发贴分布统计等等!
2.13 数据备份修复
2.14 清除在线用户
2.15 群发传呼,群发邮件
2.16 查看,清空论坛日志

3 斑竹功能
3.1 具有本版帖子的管理功能

4 聊天室管理员功能

5 留言板管理员功能

BUG: The Submit button on ASP.NET pages does not work after you install the .NET Framework 1.1 Service Pack 1

SYMPTOMS
After you install the Microsoft .NET Framework Service Pack 1, the Submit button on Microsoft ASP.NET pages may not work. You do not receive any error messages.
CAUSE
This problem occurs because client-side script files that are in the Web site are not synchronized with the .NET Framework 1.1. The PostBack event on client-side validation is stopped.
RESOLUTION
To resolve this problem, install the client-side scripts to the Aspnet_client subfolder of each Microsoft Internet Information Services (IIS) site folder. To do this, click Start, click Run, type the following command in the Open box, and then click OK:
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322.aspnet_regiis.exe -c
If you use source control, the "aspnet_regiis.exe –c" command might not work because script files are considered read only. If the command does not work, remove the Aspnet_client folder from source control.
STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed in the "Applies to" section.

APPLIES TO
Microsoft .NET Framework 1.1
Microsoft ASP.NET 1.1

What\'s new document web part for SharePoint [Free]

What\'s new document web part for SharePoint [Free]

 

 

Written by: Rickie Lee (rickieleemail # yahoo.com)

编写了一个简单的Web Part,用来显示SharePoint Site中所有Document Libraries1个或多个)和子目录中最新文档。如果需要显示所有列表(list)中最新内容,请参考《What\'s new on site Web Part for SPS [Free]》,Jan Tielens\' Bloggings提供的Web Part可以用来实现该目的,不过,该Web Part不能够检索Document Library下一级子目录subfolder中的内容。

这里提供的What\'s new document web part可以检索并显示Document Libraries所有子目录中最新文档,并且可以显示Modified by, Subfolder name and Document Library等等信息。

Web Part demo界面:

 

     Web Part Property界面:

安装方法:

stsadm.exe -o addwppack -name WhatsNewDocumentsWebPart.cab

 

卸载Web Part

stsadm.exe -o deletewppack -name WhatsNewDocumentsWebPart.cab

 

Download URL

https://files.cnblogs.com/rickie/WhatsNewDocumentsWebPart.rar

 

***

Special thanks go out to Jan Tielens.

 

 

 

用户定制Web页中元素的排版布局策略

    在"Web页中的HTML元素的排版布局规则"一文中,我们简述了browser是以怎样的策略来排版布局的,但很多时候默认的排版却不能完全满足我们的需要,所以我们还需要靠自己来定制Web页中HTML元素的排版布局策略。 
    我们可以使用这些下css属性来定制页面的显示效果,它们是:clear、float、clip、overflow(又可分别分为overflow-x和overflow-y)、display和visibility。不过属性clipoverflowvisibility不是我们关心的重点,因为它们虽然影响页面的最终显示的效果,可是它们却不能影响browser里元素的布局规则。
     我们可以查看msdn看看clearfloatdisplay的详细含义,简单说一下呢。这三个css属性都是影响我们在\'规则\'一文中说道的HTML元素的inline-level和block-level问题的。其中clear和float是相对的两个属性,clear:none是默认值,允许元素两边都有inline-level的box存在;clear:left,不允许元素左边有inline-level的box存在;clear:right,不允许元素右边有inline-level的box存在;clear:both,不允许有inline-level的box存在于一行。float:none是默认值,元素不漂浮;float:left,元素漂浮于对象布局流的右边,float:right,元素飘浮于对象布局流的左边。
    属性display看起来比较麻烦,因为它有很多的取值,可是实际上我们可以简单的把display属性看成是用来定义box的level方式的,到底是inline的还是block的。比如我们知道div默认是block-level的,我们可以使用<div style="display:inline">...</div>,它就变成inline-level的了,同时它也就遵循inline-level的排版布局策略了。display属性着重的是描述元素的render方式,所以当我们使用display:none时,元素将完全的消失掉,就和html代码中没有这个元素的显示效果一样(当然元素仍然在DHTML树中,可以使用脚本取到)。顺便插一句,display:none和visibility:hidden的区别,元素如果设置了属性后者,虽然也是不会再显示出来了,可是该元素的物理位置却是被browser保留了的,页面中将会显示一个和元素bounds一样的空白区域。
    布局说完了,再来说一下元素的定位问题,定位是由属性:position、top(还有left、right、bottom,下面简称为TLRB)和z-index来控制的。其中TLRB四个属性是依赖于position的取值而起作用的,position取值为static、absolute和relative。如果postion取static,TLRB将不会起任何的定位作用;position取absolute,TLRB将把其所在的viewport(下面有解释)的左上角作为top和left的(0,0)起点,由此来定位元素;position取relative,TLRB将把元素本来布局流中的位置的左上角坐标作为top和left的(0,0)起点,并由此来定位元素。比如代码:

<div id="div1" style="border: solid 1px blue; width: 200; height: 200; position: absolute;
    top: 50; left: 50"
>
    
<div id="div2" style="border: solid 1px green; width: 100; height: 100; position: absolute;
         top: 25; left: 25"
>
    
</div>
</div>

    将显示为:
   
    上面说到的viewport是什么呢?在这个示例中,对于容器元素div来说,div1圈起来的蓝色区域就是div2的viewport,所以div2的position虽然是absolute,但是它的top&left(25,25)却不是相对于上图中的(0,0)。所以在viewport中定位元素时,要仔细却别于position为relative时的情况,虽然代码:

<div id="div1" style="border: solid 1px blue; width: 200; height: 200; position: absolute;
    top: 50; left: 50"
>
    
<div id="div2" style="border: solid 1px green; width: 100; height: 100; position: relative;
         top: 25; left: 25"
>
    
</div>
</div>

的显示效果和上图相同,但是元素的定位原理却是不同的。 

    :所有示例都只针对IE6.0sp1。

应用服务层的缓冲设计策略

        最近在开发一个n-tiers的应用系统,应用服务层主要以WebService作为服务的提供方式。为了提高系统的效率,在服务层做业务模型数据的缓冲是必要也是必须的。在具体设计缓冲的对象模型时,得出以下几点结论:

1。缓冲是可写的。即更新业务模型数据时,不仅需要更新到数据库,同时需要更新缓冲。比起模型变更后清空缓冲再重新加载的方法,此方法可以提供更好的性能,但必须保证缓冲和数据库的数据的一致性,这也无形中增加了对系统可靠性的高要求。

2。业务模型更新的唯一途径是经由系统提供的服务接口。对于直接操作数据库更改模型的做法应该杜绝,因为这与缓冲策略是背道而驰的。

3。以ADO.NET中的DataSet作为被缓冲对象的数据结构。通过使用DataView提供的筛选、排序等特性可以简化从缓冲中加载数据的实现。

4。被缓冲数据的粒度。对于同种类型的数据(通常在一张数据表中的数据),我认为一次性加载到缓冲中比较好,比起增量缓冲(即用一个加载一个)的做法,此方法实现简单、效率高,而且从系统长期运行后的效果看,最终同种类型的数据都将被遍历、即都被加载到缓冲中,那晚加载不如早加载,“早投资早享用”啊!但我也有所担心,使用DataSet一次性缓冲大量的业务模型数据,可能会占用大量的内存(我现在设计的系统估计得有200M左右),不知这会不会是成为系统性能的瓶颈。这有待系统成形、测试后才能得知,毕竟在系统设计的初期,概念的完整性和统一性以及实现的简单实用性才是最重要的,至于性能问题只是放在第二位的。

5。需要考虑应用服务集群时的缓冲策略。在有多个对等的应用服务形成集群服务时,当一个服务的缓冲更新时,集群中别的服务需要与其同步,以保证各个服务缓冲中的数据都是数据库中被缓冲业务模型数据的完整镜像。

定义相同FullName的类型

在用.Net Framework 1.1编写一个程序集的时候,编译器禁止你在同一个名字空间中设计两个名称相同的类,这似乎是理所当然的事情。
但我最近发现,在两个不同的程序集中倒是可以分别设计两个名字空间和类型名称完全相同的类,并可将此两个程序集最终编译到同一个可执行程序中正常运行。对此我十分疑惑,若在运行时有一个程序集同时引用定义了该名称类型的两个程序集,那在创建该类实例的时候究竟以哪份类的定义为准呢?
继续思考中......

测试驱动开发随笔------测试驱动还是测试辅助

这篇随笔本不在计划之中,由我和寒风天伤的一个小争论引起。

我们从争论的起点出发。

测试代码在类外部还是内部。

这是一个看上去很简单的问题,似乎无足轻重。以至于,我一开始也没太把它当一回事。
然而它却体现了TDD的一个根本问题。

测试先行还是代码先行??!!

测试驱动开发的一个很重要的观点就是测试先行,如果测试代码出现在类的内部就显然成为了代码先行。
你认为这样有些教条,但是这才是真正的测试驱动开发!!!

测试驱动开发是软件开发的方法学!extreme program 是软件开发方法学吗?是的。 而TDD就是其中的重要组成部分,它直接导致了代码的产生。其余的pair work,continue integration,work flesh等等这些技术和TDD构成了xp的整体。那么TDD在其中的地位可想而知,是它直接产生了我们的源代码。

测试驱动开发不是写完源代码再去写测试代码。
而是先写测试代码,然后为了使测试通过再写源代码,所以一切的代码都是由测试所产生的,这难道还不是软件开发的方法学?

如果你把测试驱动开发当作插件,那么是你误解了测试驱动开发的本意,这里的驱动可不是帮助的意思,而是完全的依靠于它。当然你可以把编写测试代码当作帮助你开发的手段,这在我们的编程经历中可能都发生过。
然而记住仅仅这样可不是测试驱动开发!我起个名字这应该叫测试辅助开发。

可能有些人会怀疑测试驱动的能力,这也是在接下来的随笔中,我将尽力向大家解释的。

测试驱动是如何驱动开发的,甚至如何在测试的指引下产生了模式(还是你心中早就有了模式的概念),这些也是我对TDD所持有的问题,希望在大家的指导下我们可以加深对测试驱动开发的理解。


不要误解设计

  代码的耦合度,是指代码中的单元代码的紧密程度,其中一个单元代码的更改对其它单元代码的影响力与作用。代码间的耦合度越高,系统就在变动时就更加难以控制,但并非不能控制,只是你将为此付出巨大的代价。
  软件的设计,不仅是理清思路,更多的意义是将软件中的逻辑结构进行合理地描述,力图减少各单元代码间的影响力,使得系统在控制上更加容易,减少出错的机会。

  根据现实而言,系统是一个客观的东西,现在科学终究其力,也无法探索出任何完整系统的内部结构,也不可能对其进行详尽的描述,因为在量子级别上的测不准性,已经使得系统具有太大的不可观测性。

  那么软件设计的本质在哪儿?软件开发是一门科学,这句话的含义不仅仅是一个定义,它说明了“软件开发是一门科学
        科学的本义是什么?想想牛顿的万有引力,想想爱因斯坦的相对论吧。
  它们都建立在宏观的物理学之上,无论是万有引力公式还是能量等于质量乘以光速的平方,都意味着对系统的描述,而这个系统并不是原来的完整系统,他们的公式描述是建立在人的脑海里的一个宏观系统。
  目前在哲学上深入了现代科学的观点是:人的大脑的作用是建立对现实世界在意识中的一种映射。这种反映可能是现实的,可能是不现实的,没有人知道自己大脑中的反映有哪些是正确的,因为“正确”的本身含义就很模糊概念。
  试想一下,太阳系中的众多行星与卫星加上宇宙尘埃对间的影响力,如果都一一进行分析,那么计算两颗行星间的作用力,将是一件十分恐怖的工作。
  但现实是:我们可爱的高中生们大多数能够计算出两颗行星间的作用力,这是为什么呢?
  这是因为对系统本身层次上的抽象,对于九大行星来说(是不是有第十颗我不知道,一直是传说),其它的作用力是微不足道的(至少现代科学是这样认为的),所以可以把太阳系的模型进行简化地抽象,忽略系统中其它细节的存在,从而让系统能够有一个简洁明了的抽象,以至于高中生都可以对行星间的作用力进行计算。

  软件的设计是对系统的描述,而这个系统的细化程度,是由根据用户的需求与设计人员思考来制定的。而且一个复杂系统,从不同的角度去观察与抽象,就可以得到不同的理解,也就可以得到不同的分析结果。各分析结果在相对而言,都不是错误的,只是个人视角的问题罢了。
  由于人与人间有着不同的观念,软件设计的设计者的职责就是力图理解用户想要构造的系统的想法,并与用户交互,对系统进行仔细的了解,然后再用不同的角度观察它,力图把系统的构架简洁地描述出来。
  代码所代表的现实单元间的耦合性,如果在现实中是有的,永远也不会消失,只是被系统的构造者或设计人员给在他的理解层次上给忽略掉了,正确地估计单元间的耦合性,是系统设计成功的关键,也是提供项目进度与复杂性控制的一个良好参考。
  根据现实经验,白盒的系统的微小变化,通常只会导致黑箱系统的微小改变,因为在中间层次开发人员的努力,可以在很大的一部分上消除白盒系统中变化对黑箱系统的影响。
  说白了一些就是,由于有代码编写人员的参与,在明确的流程与代码结构中,内部的细微调整,并不会使得输入与输出有太大的改变,它对系统中的其它部分的影响也将会根据振荡原理,变得越来越小(一定程度的健壮系统可以承受并化解外力对系统的部分影响)。
    
  在实际代码编写中,设计对代码及代码对设计中的变化的影响,并不如我们想像得那么复杂,因为合理的设计,一般情况下都可以满足用户当时的合理需求,而最可怕的应该是用户需求的更换有可能对颠覆设计者对系统的理解,这个影响是巨大的。
  另一方面,代码人员间的交互,也是头痛的问题,这不是通过文档就可以解决的,软件的外部文档,更多的机会是给项目管理者看的,而不是给设计者与其它代码人员看的。长期以来,代码的清晰性与可读性都在实践中进行着规范,比如较通用的代码编写规范就是一个好的例子,大家都遵守了后,相互交流起代码更易理解。
  
  保证代码的清晰性与保证软件单元之间的耦合最低,虽然有关系,但却不密切。因为毕竟它们是两个不同层次的东西,面向的中心也完全不一样。
  换而言之,你在一个类中,无论写多少代码,如果它与外部有联系,这个耦合度就一定存在,随着复杂程度的增加,耦合度也会长。在这种情况下,就需要对软件进行重构,使用耦合度较高的代码合并成为一个单元,但合并为一个单元,不一是指合并为一个类或一个方法,它指的是一组类的群集,这与设计模式中描述的模式是一样的。

        在TDD的使用中,我们是应该把代码写在类中,还是应该写在被测试类的外部,这都是一样的,根据上面原因,可以明白,代码间的耦合度不会因为你把它从类的内部提升到外部就会消失。
  实际上,使用TDD的耦合是NUnit本身的框架与程序集间的直接耦合,它们永远不会消失。
  不过,虽然NUnit本身的框架与程序集间的直接耦合虽然繁多,但因为在测试与被测试代码之间,开发人员会尽量使他们的调用更加直接,所以它们之间的耦合度较弱。
  关于降低测试代码与被测试代码间耦合度的问题,请参考,<<十种构建可测试代码的方法>>。

        另外说一下:
       TDD本身由于并不是方法学,也不是开发过程,它只是一种方法,一种实现手段,所以它在软件开发中,是对系统内部进行细部的调整。正如它自己所描述的是:测试驱动开发。
  它是假设在外力存在的情况下,系统是否经得起外力考验的方法。这与现代不少机械的生产是一样的,如轿车的的挡风玻璃抗击力测试力,就是让高速射出的一只冷冻的鸡击向玻璃,只要在指定的情况下,该玻璃如不会碎,就可以证明该玻璃抗击力是合格的。然后,无论什么材质的挡风玻璃,只要能够通过该测试,都可以认为此玻璃的抗击力测试是成功了的。
  TDD在软件开发的过程中,也是起到这样一个作用,只要愿意,你可以把此方法插入到你喜欢的软件开发过程,用软件的开发中的视度来看,它是一个有很强集成能力的“插件”。
  TDD把自己定位是定位在那些开发人员可以触摸,测试人员不易触摸的范围之内的,也就是曾经提到过的函数与方法级别的保证的测试手段,也正因为这样,我们不要认为它是一个复杂的东西而不敢接触,也不要因为TDD炒得火热,就认为它好到惊天动地、鬼哭神嚎的地步。

  国内IT业的浮躁是冰冻三尺非一日之寒的事,但我们是否应该带个头,先冷静一下自己呢?

测试代码在实际类的内部写还是外部写的思考

  在我的<<也谈测试驱动开发>>里,提出了对方法级别的测试应该在实际代码的旁边来写的建议。
  不同的博客有不同的看法,我尊重大家的意思,但某些问题似乎不是提得很明确,也可能是因为文中说得不够清楚,这里我来简单地澄清一下。

  在一个类内写实际的代码与测试性的代码,可以采用如下的形式:
using System;

if #DEBUG
using NUnit.Framework;
endif
if #DEBUG
[TestFixture]
endif
public class Sample
{
    public Sample();

    #region 将测试代码写在这个块里面
    if #DEBUG
    [Test]
    public void 测试用例
    {
         Sample sample = new Sample();
         Assert.IsTrue(sample.sum(1,1)==2);
         Assert.IsTrue(sample.sum(1,2)==3);
         Assert.IsTrue(sample.sum(0,9)==9);
    }

    public int 求和(int a,int b)
    {
           return sum(a,b)   
    }

    #endif
    #endregion

    private int sum(int a,int b)
    {
            return a+b;
    }
}

  这是对sum方法进行测试的一个例子,上面用彩色标记出来的方法,是在预编译指令中写的,在不破坏sum函数的合理封装性的前提之下,仍然能够对sum函数进行测试,同时这样也避免了许多问题的出现。
  测试应该只关注输入与输入与输出,采用白盒测试,更多的情况是为了寻找并验证代码的逻辑,用于寻找造成bug之所在的代码(既然要敏捷,就不要受局限)。
  Java中没有把它们写在一起,更多的原因是,Java的编辑器中,很少有Visual Studio.net2003这样的好东本,并提供#region...#endregion这样的宝贝:)
  既然用了工具,我们就是充分使用,发挥它最大的作用,这样才能提高生产效率。
        关于,代码中的清晰性与耦合度的问题,我下一篇随笔再提及。

论Web控件开发 - 树状控件(三)

为了更好的让大家对我前面编写的两个控件有所理解,我特意架设了一个临时站点供大家测试http://www.keyss.cn:8888,由于这台主机只是我家的一台电脑所以并不保证一直开放:)

下面我对DropDownTree的几个主要知识点作一个介绍:

一、关于选择叶子节点及支持验证控件:

在DropDownTree前面声明的 ValidationPropertyAttribute("SelectedValue")属性保证了验证器控件在服务器端对所选的值进行验证,但为了同时支持在客户端的验证则控件必需在客户端提供一个基于inputHTML元素的form元素,由于DropDownTree在客户端就是dropdownlist控件,所以这里我只要保证在绘制dropdownlist时同时绘制他的ID属性和服务器端的一样即可支持客户端验证。而这一点在WebControl控件的addattributestorender中已经实现。 而为了支持是否选择叶子节点验证,我在控件render过程中会作一个判断,如果起用了仅可选择叶子节点属性,并且不是叶子节点则不输出item的value属性这样我们只要我们在页面上加一个Requirefieldvalidatior不充许dropdowntree值为空即可达到强制用户选择叶子节点的功能。

二、IPostBackDataHandler接口 
 为了支持当选择条目变化时触发后台事件实现此接口,当回送时比较现值和原值,如果不一样则触发事件。

自己开发了一个SmartPhone用的手机归属地软件SmartPhone

我自己用.net开发的。欢迎大家使用。
功能如下:
可以通过身份证(至少输入15位)、手机号码(至少输入7位)、区号(任意位,前面可不加0)和邮编(任意位)查找地区,并通过县市名和省名查邮编及区号。数据库不是很全最新,有误希望大家谅解并提供数据库

下载地址1:http://www.52smartphone.com/bbs/viewFile.asp?Boardid=57&ID=4836
下载地址2:http://www.91mobile.com/viewfile.asp?ID=85927&path=UploadFile/smartphone_main/

Smartphone2003自带.net运行环境。只需要把压缩包中的SmartCode目录拷贝到手机里,自己为SmartCode.exe建立一个快捷方式就行了。
如果不能正常运行,请安装netcf.phone.wce4.ARMV4.cab

开发进行技术可行性研究的时候,准备使用DataSet序列化的Xml来保存数据。但是数据文件有7M之大,显然是不现实的。后来打算用eSql的,结果在Win平台下,我Insert 3000条数据都没有响应了。
后来,用到了OpenNETCF.Data.CSV.CSVDataAdapter,但是这个东西,是把一个CSV文件全部加载到一个DataTable中,这样肯定对手机的内存肯定是地狱。
最后,我修改了CSVDataAdapter,加入了过滤器机制,只加载符合条件的数据到DataTable中。这样性能就比较好了。
我稍后有空了,就会尝试把我对CSVDataAdapter的修改合并到OpenNETCF的CSV中。

使用IE的地址栏来辅助调试Web页脚本

    不小心使用Shift + Left Click去点击了一个链接目标(href)是脚本的超链接,结果却把是否调试脚本的对话框弄了出来。点击yes居然可以打开调试这一句脚本,可是这句脚本是哪里来的呢?
    
     回头看看被新打开的那个IE,结果地址栏里就写着:javascript:open(url)呢。原来IE的地址栏可以使用"JavaScript:"这个声明来执行脚本也,在试试JavaScript:alert(\'ok\'),果然ok!

     好玩的特性,再写点复杂的脚本:javascript: var s=\'\'; for( var i=0; i < 10 ; i++ ) s +=i;。结果是出来了"0123456789",可是执行结果显示在浏览器的主显示区域里了,把IE里原有的内容弄没了。要是可以不影响原有的页面,岂不是可以读些页面里的内容,修后继续提交吗?其实可以办到了,只要保证脚本最有一句是alert(),在浏览器里执行完脚本后就不会跳离当前页面的内容。例如打开http://www.google.com,在地址栏里输入:javascript: document.getElementsByTagName(\'Input\')[1].disabled = true; alert(\'\');,会看见什么呢?不能输入查询关键字了吧

     其实在地址栏里运行脚本的作用域就是当前页面的脚本作用域,利用这个特点我们除了可以简单的执行脚本语句,还可以辅助我们调试脚本,比如我希望察看一些变量的值,而我们又不需要进入复杂的调试模式。下图就是我调试popup菜单时的一个例子,用这个办法可以避免在代码调试时到处写status=...。
    
     这里我们除了可以在地址栏里写JavaScript:外,同时还可以写vbscirpt: alert("ok!"),ecmascript:和jscirpt。不过ecmascript会自动被转为javascirpt,jscript会被转为vbscript。

     这个特性虽然简单,希望大家都能来玩玩,并且玩出更多的花样哦

申请加入 “WebGIS” 团队

WebGIS 团队

我们在这里主要探讨WebGIS的开发与应用,也包括在其他各个方面GIS的技术发展。

加入WebGIS团队必须具备以下条件:
1. 博客园用户(新博客注册请到新博客注册)。
2. 有开发GIS相关系统经验。
3. 有共同交流合作的精神。


申请格式:(示例)
博客园帐户名:avlee(注:非博客的显示名称,而应是你的注册名)
电子邮件:
avlee@163.com
博客地址:http://www.cnblogs.com/avlee
申请目的:愿意探讨和研究GIS相关开发与应用,和大家共同学习和交流(这里应写入你的申请目的)。

如果有兴趣加入,请点击这里:申请加入

通过申请后,将会以邮件的方式通知。

测试驱动开发随笔------一个最简单的例子

如果你懒得去看那些很长很长的例子,不妨看看下面这个小例子,这个例子能让你对测试驱动开发有一个直观的了解.
最起码让你知道测试驱动开发是一种开发技术而不是一项测试的技术
Fibonacci 数列,呵呵可能有不少人都忘了怎么编的了吧,那正好带你看看tdd的威力

测试驱动开发,那么测试先行是必然的了.

第一个测试来了

public void testFibonacci()//不要以为这是junit,nunit也可以这样写,而不是非要用属性哦,不信你试试
{
  AssertEquals(
0,Fib(0));
}


Fibonacci 数列的第一个数是0,人人都知吧,好了现在测试代码有了,那么我们先运行一下测试吧.
失败,报错,可恶的red进度条.
显然,因为我们还甚至还没有Fib()这个函数呢.
那么让我们赶紧让这个测试通过吧.

int Fib(int n)
{
 
return 0;
}



ok!!!  green  这将是你在tdd中最喜欢看到的颜色(多看绿色对我们的视力也是好事)

第二个测试

public void testFibonacci()
{
  AssertEquals(
0,Fib(0));
  AssertEquals(
1,Fib(1));
}



那我们赶紧让它也通过吧

int Fib(int n)
{
  
if(n==0return 0;
  
return 1;
}


通过了!

从测试代码中我们看到了
AssertEquals(0,Fib(0));
AssertEquals(1,Fib(1));

重复!不仅在源代码,就是在测试代码中,我们也要避免重复!!(测试代码中也会出现模式哦~~)

这里,我们用一个最简单的方法避免重复,用表驱动.

我们开始改写测试代码.

public void testFibonacci
{
  
int cases[][]={{0,0},{1,1},{2,1}};
  
for(int i=0; i<case.Length;i++)
  AssertEquals(
case[i][1],fib[i][0]));
 }


这样添加测试代码就容易多了.
测试代码改过了!!!小心哦,让我们再运行下,哦还能通过,那我们就可以放心继续了.

public void testFibonacci
{
  
int cases[][]={{0,0},{1,1},{2,1},{3,2}};
  
for(int i=0; i<case.Length;i++)
  AssertEquals(
case[i][1],fib[i][0]));
 }


oh! 失败了,赶快解决它

int Fib(int n)
{
 
if(n==0return 0;
 
if(n<=2return 1;
 
return 2;
}


哦,够了难道你打算一直这样写下去,呵呵,那我们开始一般化吧.

int Fib(int n)
{
 
if(n==0return 0;
 
if(n<=2return 1;
 
return 1+1;
}

第一个1是Fib(n-1)的实例
第二个1是Fib(n-2)的实例

int Fib(int n)
{
 
if(n==0return 0;
 
if(n<=2return 1;
 
return Fib(n-1)+Fib(n-2);
}


运行一下!green!!哈哈,我们得到了Fibonacci 数列,完全的测试驱动!

以上例子来源于Kent Beck的<<测试驱动开发-by example>>,我稍加了修改.

(注意在这里测试代码和源代码是在一起的,那是因为我们只要实现一个功能函数,通常情况下应将他们分开在两个不同的类中
我的理解如下:

在一个类的内部如何测试这个类的使用,难道测试类成员的相互调用??!!!

从代码的整洁性来看也是分开来好. )


从这个简单的例子我们还是能看出测试驱动最本质的一些东西. (更结合实际的例子见 wayfarer 的文章)

在此发表一下我在design pattern讨论会上对Tdd的一些看法,其中大多数可以在上面的例子中得到验证,当然难免有理解错误的地方,欢迎大家指正.

  1. 讨论测试如何做 其实就不是讨论tdd了,应该讨论test如何驱动开发
  2. TDD 很重要的一点是测试"驱动"开发!!!  不是为了测试
  3. 测试代码是由程序员自己写的
  4. TDD只是unit test而已,单元测试不是整个测试!!
  5. 代码是为了测试代码写的
  6. 根据需求产生测试案例,根据测试案例产生测试代码,为了使测试代码通过产生源程序,对需求变化导致测试案例的变化,从而导致测试代码的变化,最终导致源代码的变化
  7. 做TDD要不要测试案例完全覆盖需求啊?  测试用例的覆盖率往往低于需求, 在tdd中就会导致代码的缺少,不过我没有实战过,我也考虑的完全覆盖的可能性,也就是tdd是否应用于整个项目

这篇随笔只是一个简单介绍,有关tdd的详细内容将在以后的随笔中完善.

我的的一点看法.

看了第一期杂志中的<程序人生>, 颇有感触, 也谈谈自己这几年程序人生的看法.  另外想说明一点, 技术对于从事软件行业的人而言,绝对是至关重要的, 无论对于PM还是开发人员. 当然这里的技术并非指如何编写一个控件, 如何实现一个算法.

 

大凡开发了几年程序的人,特别是不同类型或系统的人,对于程序语言肯定有不少经验,在解决事情时肯定也有一些心得或体会.从软件项目本身出发,个人认为如果没有技术上的重视,一个项目要做好是不容易的,在国内做项目关系当然是第一位的,从技术人员的角度出发,自然是希望自己做的东西很牛,但并不一定要使用非常独特的技术,也并非要为了某个问题寻找一个最优的解决方案.

 

假如一个公司或一个项目组成员真的不重视技术的发展中国家,仍然停留在以前的PB/VB/PHP中, 当然对于不同的项目或行业而言,这是有可能的, 不过从大环境来看, 如果真是这样, 那真应该为这家公司和那些技术人员的前途感到担心. 前不久在CSDN上说有个35岁的同志只会PB,虽然在公司干了N年, 结果还是被开掉的事, 事情的真实性不得而知,不过对于从事软件行业的兄弟们来说, 如果你没有把握或了解新技术的发展, 那么估计得换换岗位才能胜任了.  以前写ASP的时候采用JavaScript验证, 需要Copy/Paste代码, 而且出错了不容易调试, 现在asp.net中有自己的validate控件, 绑定后设置相应的参数即可, 无论从开发效率还是维护性方面都提高了. 但前提是必须掌握这个平台技术.

 

一个新上的项目采用什么平台,什么技术, 具体的公司肯定有自己的政策, 项目组内也会根据成员的能力进行评估. 但这些选择都是基于技术的, 与客户关系和项目管理的水平没有直接关系. 众所周知,WEB界面不如WINFORM界面操作复杂, 一个WINFORM的界面可能在WEB上实现时需要用几个单独的页面通过参数传递来实现. 如果从技术上说, 可能选择B/S也可能选择C/S, 出于一大堆理由, 在基于internet环境有很大用户的情况下,当然最重要的是程序的升级及维护方面, 现在尽量会选择B/S结构, 这会造成一种看法,就是现在使用C/S结构已经无路可走, 似乎所有的人都要转移到B/S结构上来. 只是,MS现在又推出了smartclient, 列出了使用SC的一大堆好处, 最重要的当然是其界面操作性和可以离线使用. 如果项目组内或公司内缺乏掌握这种技术或有这种眼光的人, 那么选择的开发平台技术将对项目造成很大的影响. MS去年又推出了visual tools for office, 对于普通用户而言, 可能使用WORD或EXCEL的时候更多, 也更得心应手, 如果用WEB或WINFORM的形式开发应用, 估计效果不是很好. 并非是在此给MS做广告, 想说明一点, 如果没有技术上的广泛了解, 那么在选择的时候肯定范围就比较窄, 掌握一门技术并非是要深入到细节, 关键是要有宏观判断的能力, 深入细节是在开发阶段每个开发人员需要掌握的.   


为什么国内的程序员过了30就不好做了? 而国外40多了都有人还在从事软件开发等技术活动. 在codeproject上看见一位40多的同志还在写unittest的文章, 很是羡慕. 一个人能凭自己的兴趣工作也是一件好事. 国内的环境不同,如果你总是做技术, 看见许多新来的人爬得比你高, 薪水也比你多, 自然会产生不平衡. 大家的官位意识太重, 技术上当然就得不到发展, 操作系统, 数据库没有一个自己的, 为什么? 因为等你做到一定程度之后, 你必须得换个岗位, 否则日子不好过. 这是国内软件行业的现状, 会写代码的人到处都是, 每年都有上百万的毕业人员, 大家都在写代码, 但能有多少人坚持了五年,十年的. 项目经理不懂技术还可以依赖技术负责人, 如果连技术负责人也不行, 项目成员始终保持在一种初级水平, 那这个项目的质量就有问题了. 上层领导关心的是项目的验收, 而技术人员靠能力和技术吃饭, 只能脚踏实地做事, 把技术钻研透彻, 才可能保住自己的饭碗, 拿更高的薪水.

 

每个人都有自己的发展方向和目标, 但并非每个人都适合做PM. 如果做技术,你就必须把握新技术的动向, 并一定要精通, 但这些新的技术可以开阔视野, 在思考问题的时候可以拓宽思路. 也许这里的"技术"用"思想"一词更准确些, 要在新的技术中磨练自己, 提升自己的思想, 将各方面的知识融会贯通. 孔子说"学而不思则殆, 思而不学则为罔", 如果不学新的技术, 没有去实践, 只是在那里想什么是设计模式, 估计要升华自己的思想还是有困难的.

 

如果不是想在技术上有所突破, 只是想做个"人上人"的角色, 那还是趁早学点PMP之类的东西.     

分类:

技术点:

相关文章:

  • 2021-10-08
  • 2021-11-10
  • 2022-12-23
  • 2021-08-04
  • 2021-04-24
  • 2021-05-22
  • 2022-01-03
猜你喜欢
  • 2021-08-08
  • 2021-12-28
  • 2021-12-13
  • 2022-12-23
  • 2022-12-23
  • 2021-11-12
相关资源
相似解决方案