responseText,responseXML,responseBody,responseStream
PP_MV_Technology Center _Members
1 可以在js中对label赋值;
如:document.getElementById("Label1").innerHTML=xhr.responseText;
2 可以传递text和接收text,在aspx中,可以传递text接收xml,在aspx中
如:string text = Request["text"];
Response.ContentType = "text/xml";
Response.Write("<a>"+text+"</a>");
Response.End();
在客户端:
var xml=xhr.responseXML;
var node=xml.getElementsByTagName("a");
var value1=node[0].childNodes[0].nodeValue;
document.getElementById("Label1").innerHTML=value1;
3 在客户端创造节点和值,就是创造一个table类似的,
如: var table1=document.createElement("table");
var tbody1=document.createElement("tbody");
//var tbody1=document.getElementById("tbody1");
var tr1=document.createElement("tr");
var td1=document.createElement("td");
var t=document.createTextNode(value1);
td1.appendChild(t);
tr1.appendChild(td1);
tbody1.appendChild(tr1);
table1.appendChild(tbody1);
document.getElementById ("body1").appendChild(table1);
//var table1=document.getElementById("table1");
table1.setAttribute("border",1);
//table.appenChild(tbody);
//table.setAttributes("border","1");
4 可以得到xml文件的值
如: var xml=xhr.responseXML;
var node=xml.getElementsByTagName("b");
for(var i=0;i<node.length;i++){
var node1=node[i];
for(var j=0;j<node1.childNodes.length;j++){
var node2=node1.childNodes[j];
alert(node2.childNodes[0].nodeValue);
value1=value1+"\n"+node2.childNodes[0].nodeValue;
}
}
document.getElementById("Label1").innerHTML=value1;
5 终于解决了验证码的问题,利用ajax的技术,当你点击看不清,换一张时,图片的属性:src是路径,如果路径不变则不会改变,则解决方法可以添加时间
如:ar img1=document.getElementById("img1");
var time1=new Date().getTime();
img1.src="Default2.aspx?"+time1;
注意路径后有参数要加“?”,
完全的代码:<script language="javascript" type="text/javascript">
// <!CDATA[
var xhr;
function createXHR(){
if(window.ActionXObject){
xhr=new ActionXObject("Microsoft.XMLHTTP");
}
else if(window.XMLHttpRequest){
xhr=new XMLHttpRequest();
}
}
function Button1_onclick() {
// var text=document.getElementById("Text1");
var url="Default2.aspx?";
createXHR();
xhr.open("GET",url);
xhr.onreadystatechange=callback;
xhr.send(null);
}
function callback(){
if(xhr.readyState==4&&xhr.status==200){
//alert(xhr.responseStream);
// var s=xhr.responseStream;
//alert(Session["CheckCode"]);
var img1=document.getElementById("img1");
var time1=new Date().getTime();
img1.src="Default2.aspx?"+time1;
//img1.setAttribute("src","images/1.jpg");
//img1.setAttribute("src","Default2.aspx");
}
}
function Button2_onclick() {
//window.location.reload();
var url="Default2.aspx";
//alert(url);
createXHR();
xhr.open("GET",url);
xhr.onreadystatechange=callback;
xhr.send(null);
}
6 得到验证码的图片,有不少技术:
public void getab() {
string c1="0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
string[] a1 ={ "," };
string[] stringvalue = c1.Split(a1, StringSplitOptions.RemoveEmptyEntries);
string code="";
Random r = new Random();
for (int i = 0; i < 4; i++) {
code = code + stringvalue[r.Next(stringvalue.Length)];
}
Response.Write(code);
Bitmap image = new Bitmap(100, 40);
Graphics g = Graphics.FromImage(image);
g.Clear(Color.White);
for (int i = 0; i < 2000; i++) {
int a = r.Next(100);
int b = r.Next(40);
int c = r.Next(100);
int d = r.Next(40);
g.DrawLine(new Pen(Color.Silver), a, b, c, d);---画背景线
}
LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, 100-1, 40-1), Color.Black, Color.Red, 2f, true);--其中的2f为渐近线的角度,linearGradientBrush为具有颜色逐渐变化的
g.DrawString(code,new Font("Arial",22,FontStyle.Bold|FontStyle.Italic),brush,10,3);
for (int i = 0; i < 100; i++) {
image.SetPixel(r.Next(100), r.Next(40), Color.FromArgb(r.Next()));---设置位图的像素
}
g.DrawRectangle(new Pen(Color.Silver), 0, 0, 100, 40);---设置边框。
MemoryStream ms = new MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
Response.ClearContent();
Response.ContentType = "image/Gif";
Response.BinaryWrite(ms.ToArray());
Response.End();
}
7 可以在客户端对html控件的可见性进行控制
如:if(curpage==1){
document.getElementById("Button2").disabled=true;
document.getElementById("Button3").disabled=true;
document.getElementById("Button4").disabled=false;
document.getElementById("Button5").disabled=false;
}
8 可以在客户端进行switch语句
如:function onclick1(sr){
switch(sr){
case "start":curpage=1;Button1_onclick();break;
case "previous":curpage=curpage-1;Button1_onclick();break;
case "next":curpage=curpage+1;Button1_onclick();break;
case "end":curpage=total_page;Button1_onclick();break;
default:curpage=1;
}
}
9js中对string转化为int
如:var num=document.getElementById("Select1").value;
var num_int=parseInt(num);
10 可以利用Math的ceil方法为返回大于等于该值的最小整数
如:total_page=Math.ceil(num_int/pagesize);
11 学会了服务器控件在客户单的取值,赋值,设置可见性,
如:document.getElementById("Button6").style.display="";--显示
document.getElementById("Button6").style.display="none";--隐藏
取值:document.getElementById("TextBox1").value; ----取值
赋值:document.getElementById("Label1").innerHTML=....--对label控件赋值
12 可以利用html validator来检查html的语句,
13 在js中可以利用模式了,首先类的继承,
如:function Button1_onclick() {
var a1=new a();
abc(a1);
}
function Button2_onclick() {
var b1=new b();
abc(b1);
}
function Button3_onclick() {
var c1=new c(); abc(c1);
}
function abc(abc1){
text=text+"\n"+abc1.name;
text=text+"\n"+abc1.age;
text=text+"\n"+abc1.getName();
text=text+"\n"+abc1.getAge();
alert(text);
text="";
}
function a(){}
a.prototype.name="a";
a.prototype.age=12;
a.prototype.getName=function(){return "a";};
a.prototype.getAge=function(){return 12;};
function b(){}
b.prototype=new a();
b.prototype.name="b";
b.prototype.age=13;
b.prototype.getName=function(){return "b";};
b.prototype.getAge=function(){return 13;};
function c(){}
c.prototype=new a();
c.prototype.name="c";
c.prototype.age=14;
c.prototype.getName=function(){return "c";};
c.prototype.getAge=function(){return 14;};
14 在js中一个类的构造函数中,通过var定义的是私有属性,外界不能访问,否则是undefined,如果想要访问,必须通过在构造函数中定义的this开头的函数,
如: function a(){
var name="4";
var age=12;
this.getName=function(){return name;}
this.getAge=function(){return age;}
}
function Button1_onclick() {
var a1=new a();
alert(a1.getName()+";"+a1.getAge());
}
15 通过prototype动态创建的属性为公有属性,
如:
function a(){
var name="4";
var age=12;
this.getName=function(){return name;}
this.getAge=function(){return age;}
}
a.prototype.sex="1234";
function Button1_onclick() {
var a1=new a();
alert(a1.getName()+";"+a1.getAge());
alert(a1.sex);
}
16 除了使用prototype来实现继承外,还可以通过另外一种方法来实现
如:function extend_from_a(a1,b1){
var member;
for(member in a1){
if(!b1[member]){
b1[member]=a1[member];
}
}
}
a1为父类,b1为子类,对于member为定义的成员(属性和方法),对于for循环,对于每一个在父类中的成员,如果在子类中没有,则从父类中复制到子类中。
具体的例子:function a(){
var name="4";
var age=12;
this.getName=function(){return name;}
this.getAge=function(){return age;}
}
function b(){
}
function extend_from_a(a1,b1){
var member;
for(member in a1){
if(!b1[member]){
b1[member]=a1[member];
}
}
}
function Button1_onclick() {
var a1=new a();
var b1=new b();
extend_from_a(a1,b1);
alert(b1.getName()+"--"+b1.getAge());
}
17 可以利用另外一种方法类实现继承
如:jsvar text="";
function extend(parent,children){
var memeber;
for(member in parent){
if(!children[member]){
children[member]=parent[member];
}
}
}
function description(class_name){
text=text+"name:"+class_name.getName()+"\n";
text=text+"age:"+class_name.getAge()+"\n";
alert(text);
text="";
}
function Button1_onclick() {
var a1=new a();
description(a1);
}
function Button2_onclick() {
var b1=new b();
extend(new a(),b1);
b1.setName("b");
b1.setAge(13);
description(b1);
}
function Button3_onclick() {
var c1=new c();
extend(new a(),c1);
c1.setName("c");
c1.setAge(16);
description(c1);
}
18 注意在jsunit中时,需要有正确的书写,
如: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
<script type="text/javascript" src="../app/jsUnitCore.js"></script>
<script type="text/javascript">
function add1(v1,v2){
return v1+v2;
}
function test_add(){
assertEquals("ddd",4,add1(2,2));
}
</script>
必须要加meta标签,不然会错误,必须放在jsunit中的tests文件夹里。
19 jsunit中的assertEquals为判断时候相等。
20 也可以把测试的函数单独放在一个js文件中,然后引用即可
如:<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<script type="text/javascript" src="../app/jsUnitCore.js"></script>
<script type="text/javascript" src="jsunit_example.js"></script>---引用。
<script type="text/javascript" language="javascript">
function test_add(){
assertEquals("2+2=4",4,add(2,2));
}
function test_add1(){}
{
assertEquals("-2+-2=4",4,add(-2,-2));
}
jsunit_example.js:
function add(v1,v2){
return v1+v2;
}
21 如果找不到测试函数,就需要添加exposeTextFunctionNames这个函数
如: function exposeTestFunctionNames(){
var tests=new Array(1);
tests[0]="test_add1";---该函数为测试函数有test开头的
return tests;
}
22 有setUp函数和tearDown函数,setUp函数是在每个测试之前调用的,而tearDown是在每个测试之后调用的
如:function setUp(){
document.getElementById("Text1").value="2";
document.getElementById("Text2").value="2";
}
function addNum(){
// setUp();
var v1=document.getElementById("Text1").value;
var v2=document.getElementById("Text2").value;
var v1_1=parseInt(v1);
var v2_1=parseInt(v2);
//alert(v1_1+";"+v2_1);
return add(v1_1,v2_1);
}
function test_add(){
assertEquals("2+2=4",4,addNum());
}
function tearDown(){
document.getElementById("Text1").value="";
document.getElementById("Text2").value="";
}
23 对setUpPage是在所有的测试函数调用之前调用,而且只调用一次,在函数内部,如果预处理完成后要填上setUpPageStatus=“complete”;,加上这条语句,则jsunit就可以继续了,
如: var v1=document.getElementById("Text1").vlaue;
var v2=document.getElementById("Text2").vlaue;
function setUpPage(){
v1="2";
v2="2";
setUpPageStatus="complete";
}
function test_add(){
assertEquals("2+2+4",4,add(v1,v2));
}
function test_jian(){
assertEquals("2-2=0",0,jian(v1,v2));
}
function test_cheng(){
assertEquals("2*2=4",4,cheng(v1,v2));
}
function test_div(){
assertEquals("2/2=1",1,div(v1,v2));
}
function add(v1,v2){
return parseInt(v1)+parseInt(v2);
}
function jian(v1,v2){
return parseInt(v1)-parseInt(v2);
}
function cheng(v1,v2){
return parseInt(v1)*parseInt(v2);
}
function div(v1,v2){
return parseInt(v1)/parseInt(v2);
}
24 对于jsunit测试只要路径对了就可以了,首先要在solution中打开jsunit中的testRunner.html,然后直接打开那个需要测试的用例,把网址复制到testRunner中,即可,
如:<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<script type="text/javascript" src="jsunit/app/jsUnitCore.js"></script>
<script type="text/javascript" src="jsunit_example.js"></script>
<script type="text/javascript" language="javascript">
var v1=document.getElementById("Text1").vlaue;
var v2=document.getElementById("Text2").vlaue;
function setUpPage(){
v1="2";
v2="2";
setUpPageStatus="complete";
}
function test_add(){
assertEquals("2+2+4",4,add(v1,v2));
}
function test_jian(){
assertEquals("2-2=0",0,jian(v1,v2));
}
function test_cheng(){
assertEquals("2*2=4",4,cheng(v1,v2));
}
function test_div(){
assertEquals("2/2=1",1,div(v1,v2));
}
25 也可以在浏览器中输入网址,这样就可以自动找到了,首先输入C:\Inetpub\wwwroot\WebSite5\jsunit\testRunner.html,这是testRunner的位置。再在最前面输入file:///,这样就可以了,然后在末尾添加数据:?testPage=你要测试的文件的地址,就可以了,
如:file:///C:\Inetpub\wwwroot\WebSite5\jsunit\testRunner.html?testPage=C:\Inetpub\wwwroot\WebSite5\jsunit_test.html
26 还可以在后面再加一个参数,为autoRun表示自动运行,为true,
如:file:///C:\Inetpub\wwwroot\WebSite5\jsunit\testRunner.html?testPage=C:\Inetpub\wwwroot\WebSite5\jsunit_test.html&autoRun=true,
27 有testPage和autoRun这两个参数
28 单件模式
这是用的最多的模式,每一个正式的软件都要用它,全局配置、唯一资源、还有一个就是所有的工厂我都设计为单件模式,因此它的使用量大于工厂模式和抽象工厂模式之和。
工厂模式和抽象工厂模式
为了在程序代码中避免出现大量的New,因此我编写的软件代码这两三年基本都使用了工厂,由于深受受王咏武大侠关于舍熊掌取小鱼的影响,因此我较多地选用工厂模式,感觉确实有扩展需要的情况下才使用抽象工厂模式,其实工厂模式就是一个抽象工厂的特例,扩展为抽象工厂也非常容易。
适配器模式
适配器模式有两种类的适配器和对象适配器,对象适配器更多一些,对象适配器的优点在很多大侠的著作了已经论述n次了,我这里不多啰嗦,我用的较多的原因还有一个,我从C++转到C#,由于C#不支持多重继承,我又不比较懒,较少定义interface,因此大多数情况下用C#时也只能使用对象适配器模式了。其实适配器和装饰模式功能上有很大的相似性,在下面的装饰模式中加以论述。
装饰模式
也叫油漆工模式,装饰模式和适配器模式相似都是用来利用现成代码加以调整来满足新的需求,其实采用设计模式的目的之一就是复用,这两个模式正是复用的体现。当你要用这两种模式的时候都是为你现有软件新增新的功能,一般情况下,如果你是让你的软件新增新的功能操作,你一般要用装饰模式,你如果要为软件新增功能支持,你最好选择适配器模式,你如果想为你的类新增操作你用装饰模式,你如果要引入其他来源的现成代码,你用适配器模式。
观察者模式
这个模式我用的多一个原因就是它可以实现事件功能,当然在C#中可以直接使用事件,但是在C++中却是用可以用此模式发挥的淋漓尽致了,网上曾经的一个考题(猫大叫一声,主人醒来,耗子跑开),就是使用这个模式的最好应用。
外观模式
开发就是能复用的地方就复用,这样才能节省资源,提高效率,外观模式也是一个提供复用其他现成代码的解决方案,你需要实现一个功能,可能现成的代码中就有此功能,但是现成代码可能远远多于你所需要的功能,此时你把这些功能封装起来,再重新提供一个你所需要的接口,这就是这个模式的精髓所在。
PP_MV_Technology Center _Members
1 可以在js中对label赋值;
如:document.getElementById("Label1").innerHTML=xhr.responseText;
2 可以传递text和接收text,在aspx中,可以传递text接收xml,在aspx中
如:string text = Request["text"];
Response.ContentType = "text/xml";
Response.Write("<a>"+text+"</a>");
Response.End();
在客户端:
var xml=xhr.responseXML;
var node=xml.getElementsByTagName("a");
var value1=node[0].childNodes[0].nodeValue;
document.getElementById("Label1").innerHTML=value1;
3 在客户端创造节点和值,就是创造一个table类似的,
如: var table1=document.createElement("table");
var tbody1=document.createElement("tbody");
//var tbody1=document.getElementById("tbody1");
var tr1=document.createElement("tr");
var td1=document.createElement("td");
var t=document.createTextNode(value1);
td1.appendChild(t);
tr1.appendChild(td1);
tbody1.appendChild(tr1);
table1.appendChild(tbody1);
document.getElementById ("body1").appendChild(table1);
//var table1=document.getElementById("table1");
table1.setAttribute("border",1);
//table.appenChild(tbody);
//table.setAttributes("border","1");
4 可以得到xml文件的值
如: var xml=xhr.responseXML;
var node=xml.getElementsByTagName("b");
for(var i=0;i<node.length;i++){
var node1=node[i];
for(var j=0;j<node1.childNodes.length;j++){
var node2=node1.childNodes[j];
alert(node2.childNodes[0].nodeValue);
value1=value1+"\n"+node2.childNodes[0].nodeValue;
}
}
document.getElementById("Label1").innerHTML=value1;
5 终于解决了验证码的问题,利用ajax的技术,当你点击看不清,换一张时,图片的属性:src是路径,如果路径不变则不会改变,则解决方法可以添加时间
如:ar img1=document.getElementById("img1");
var time1=new Date().getTime();
img1.src="Default2.aspx?"+time1;
注意路径后有参数要加“?”,
完全的代码:<script language="javascript" type="text/javascript">
// <!CDATA[
var xhr;
function createXHR(){
if(window.ActionXObject){
xhr=new ActionXObject("Microsoft.XMLHTTP");
}
else if(window.XMLHttpRequest){
xhr=new XMLHttpRequest();
}
}
function Button1_onclick() {
// var text=document.getElementById("Text1");
var url="Default2.aspx?";
createXHR();
xhr.open("GET",url);
xhr.onreadystatechange=callback;
xhr.send(null);
}
function callback(){
if(xhr.readyState==4&&xhr.status==200){
//alert(xhr.responseStream);
// var s=xhr.responseStream;
//alert(Session["CheckCode"]);
var img1=document.getElementById("img1");
var time1=new Date().getTime();
img1.src="Default2.aspx?"+time1;
//img1.setAttribute("src","images/1.jpg");
//img1.setAttribute("src","Default2.aspx");
}
}
function Button2_onclick() {
//window.location.reload();
var url="Default2.aspx";
//alert(url);
createXHR();
xhr.open("GET",url);
xhr.onreadystatechange=callback;
xhr.send(null);
}
6 得到验证码的图片,有不少技术:
public void getab() {
string c1="0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
string[] a1 ={ "," };
string[] stringvalue = c1.Split(a1, StringSplitOptions.RemoveEmptyEntries);
string code="";
Random r = new Random();
for (int i = 0; i < 4; i++) {
code = code + stringvalue[r.Next(stringvalue.Length)];
}
Response.Write(code);
Bitmap image = new Bitmap(100, 40);
Graphics g = Graphics.FromImage(image);
g.Clear(Color.White);
for (int i = 0; i < 2000; i++) {
int a = r.Next(100);
int b = r.Next(40);
int c = r.Next(100);
int d = r.Next(40);
g.DrawLine(new Pen(Color.Silver), a, b, c, d);---画背景线
}
LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, 100-1, 40-1), Color.Black, Color.Red, 2f, true);--其中的2f为渐近线的角度,linearGradientBrush为具有颜色逐渐变化的
g.DrawString(code,new Font("Arial",22,FontStyle.Bold|FontStyle.Italic),brush,10,3);
for (int i = 0; i < 100; i++) {
image.SetPixel(r.Next(100), r.Next(40), Color.FromArgb(r.Next()));---设置位图的像素
}
g.DrawRectangle(new Pen(Color.Silver), 0, 0, 100, 40);---设置边框。
MemoryStream ms = new MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
Response.ClearContent();
Response.ContentType = "image/Gif";
Response.BinaryWrite(ms.ToArray());
Response.End();
}
7 可以在客户端对html控件的可见性进行控制
如:if(curpage==1){
document.getElementById("Button2").disabled=true;
document.getElementById("Button3").disabled=true;
document.getElementById("Button4").disabled=false;
document.getElementById("Button5").disabled=false;
}
8 可以在客户端进行switch语句
如:function onclick1(sr){
switch(sr){
case "start":curpage=1;Button1_onclick();break;
case "previous":curpage=curpage-1;Button1_onclick();break;
case "next":curpage=curpage+1;Button1_onclick();break;
case "end":curpage=total_page;Button1_onclick();break;
default:curpage=1;
}
}
9js中对string转化为int
如:var num=document.getElementById("Select1").value;
var num_int=parseInt(num);
10 可以利用Math的ceil方法为返回大于等于该值的最小整数
如:total_page=Math.ceil(num_int/pagesize);
11 学会了服务器控件在客户单的取值,赋值,设置可见性,
如:document.getElementById("Button6").style.display="";--显示
document.getElementById("Button6").style.display="none";--隐藏
取值:document.getElementById("TextBox1").value; ----取值
赋值:document.getElementById("Label1").innerHTML=....--对label控件赋值
12 可以利用html validator来检查html的语句,
13 在js中可以利用模式了,首先类的继承,
如:function Button1_onclick() {
var a1=new a();
abc(a1);
}
function Button2_onclick() {
var b1=new b();
abc(b1);
}
function Button3_onclick() {
var c1=new c(); abc(c1);
}
function abc(abc1){
text=text+"\n"+abc1.name;
text=text+"\n"+abc1.age;
text=text+"\n"+abc1.getName();
text=text+"\n"+abc1.getAge();
alert(text);
text="";
}
function a(){}
a.prototype.name="a";
a.prototype.age=12;
a.prototype.getName=function(){return "a";};
a.prototype.getAge=function(){return 12;};
function b(){}
b.prototype=new a();
b.prototype.name="b";
b.prototype.age=13;
b.prototype.getName=function(){return "b";};
b.prototype.getAge=function(){return 13;};
function c(){}
c.prototype=new a();
c.prototype.name="c";
c.prototype.age=14;
c.prototype.getName=function(){return "c";};
c.prototype.getAge=function(){return 14;};
14 在js中一个类的构造函数中,通过var定义的是私有属性,外界不能访问,否则是undefined,如果想要访问,必须通过在构造函数中定义的this开头的函数,
如: function a(){
var name="4";
var age=12;
this.getName=function(){return name;}
this.getAge=function(){return age;}
}
function Button1_onclick() {
var a1=new a();
alert(a1.getName()+";"+a1.getAge());
}
15 通过prototype动态创建的属性为公有属性,
如:
function a(){
var name="4";
var age=12;
this.getName=function(){return name;}
this.getAge=function(){return age;}
}
a.prototype.sex="1234";
function Button1_onclick() {
var a1=new a();
alert(a1.getName()+";"+a1.getAge());
alert(a1.sex);
}
16 除了使用prototype来实现继承外,还可以通过另外一种方法来实现
如:function extend_from_a(a1,b1){
var member;
for(member in a1){
if(!b1[member]){
b1[member]=a1[member];
}
}
}
a1为父类,b1为子类,对于member为定义的成员(属性和方法),对于for循环,对于每一个在父类中的成员,如果在子类中没有,则从父类中复制到子类中。
具体的例子:function a(){
var name="4";
var age=12;
this.getName=function(){return name;}
this.getAge=function(){return age;}
}
function b(){
}
function extend_from_a(a1,b1){
var member;
for(member in a1){
if(!b1[member]){
b1[member]=a1[member];
}
}
}
function Button1_onclick() {
var a1=new a();
var b1=new b();
extend_from_a(a1,b1);
alert(b1.getName()+"--"+b1.getAge());
}
17 可以利用另外一种方法类实现继承
如:jsvar text="";
function extend(parent,children){
var memeber;
for(member in parent){
if(!children[member]){
children[member]=parent[member];
}
}
}
function description(class_name){
text=text+"name:"+class_name.getName()+"\n";
text=text+"age:"+class_name.getAge()+"\n";
alert(text);
text="";
}
function Button1_onclick() {
var a1=new a();
description(a1);
}
function Button2_onclick() {
var b1=new b();
extend(new a(),b1);
b1.setName("b");
b1.setAge(13);
description(b1);
}
function Button3_onclick() {
var c1=new c();
extend(new a(),c1);
c1.setName("c");
c1.setAge(16);
description(c1);
}
18 注意在jsunit中时,需要有正确的书写,
如: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
<script type="text/javascript" src="../app/jsUnitCore.js"></script>
<script type="text/javascript">
function add1(v1,v2){
return v1+v2;
}
function test_add(){
assertEquals("ddd",4,add1(2,2));
}
</script>
必须要加meta标签,不然会错误,必须放在jsunit中的tests文件夹里。
19 jsunit中的assertEquals为判断时候相等。
20 也可以把测试的函数单独放在一个js文件中,然后引用即可
如:<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<script type="text/javascript" src="../app/jsUnitCore.js"></script>
<script type="text/javascript" src="jsunit_example.js"></script>---引用。
<script type="text/javascript" language="javascript">
function test_add(){
assertEquals("2+2=4",4,add(2,2));
}
function test_add1(){}
{
assertEquals("-2+-2=4",4,add(-2,-2));
}
jsunit_example.js:
function add(v1,v2){
return v1+v2;
}
21 如果找不到测试函数,就需要添加exposeTextFunctionNames这个函数
如: function exposeTestFunctionNames(){
var tests=new Array(1);
tests[0]="test_add1";---该函数为测试函数有test开头的
return tests;
}
22 有setUp函数和tearDown函数,setUp函数是在每个测试之前调用的,而tearDown是在每个测试之后调用的
如:function setUp(){
document.getElementById("Text1").value="2";
document.getElementById("Text2").value="2";
}
function addNum(){
// setUp();
var v1=document.getElementById("Text1").value;
var v2=document.getElementById("Text2").value;
var v1_1=parseInt(v1);
var v2_1=parseInt(v2);
//alert(v1_1+";"+v2_1);
return add(v1_1,v2_1);
}
function test_add(){
assertEquals("2+2=4",4,addNum());
}
function tearDown(){
document.getElementById("Text1").value="";
document.getElementById("Text2").value="";
}
23 对setUpPage是在所有的测试函数调用之前调用,而且只调用一次,在函数内部,如果预处理完成后要填上setUpPageStatus=“complete”;,加上这条语句,则jsunit就可以继续了,
如: var v1=document.getElementById("Text1").vlaue;
var v2=document.getElementById("Text2").vlaue;
function setUpPage(){
v1="2";
v2="2";
setUpPageStatus="complete";
}
function test_add(){
assertEquals("2+2+4",4,add(v1,v2));
}
function test_jian(){
assertEquals("2-2=0",0,jian(v1,v2));
}
function test_cheng(){
assertEquals("2*2=4",4,cheng(v1,v2));
}
function test_div(){
assertEquals("2/2=1",1,div(v1,v2));
}
function add(v1,v2){
return parseInt(v1)+parseInt(v2);
}
function jian(v1,v2){
return parseInt(v1)-parseInt(v2);
}
function cheng(v1,v2){
return parseInt(v1)*parseInt(v2);
}
function div(v1,v2){
return parseInt(v1)/parseInt(v2);
}
24 对于jsunit测试只要路径对了就可以了,首先要在solution中打开jsunit中的testRunner.html,然后直接打开那个需要测试的用例,把网址复制到testRunner中,即可,
如:<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<script type="text/javascript" src="jsunit/app/jsUnitCore.js"></script>
<script type="text/javascript" src="jsunit_example.js"></script>
<script type="text/javascript" language="javascript">
var v1=document.getElementById("Text1").vlaue;
var v2=document.getElementById("Text2").vlaue;
function setUpPage(){
v1="2";
v2="2";
setUpPageStatus="complete";
}
function test_add(){
assertEquals("2+2+4",4,add(v1,v2));
}
function test_jian(){
assertEquals("2-2=0",0,jian(v1,v2));
}
function test_cheng(){
assertEquals("2*2=4",4,cheng(v1,v2));
}
function test_div(){
assertEquals("2/2=1",1,div(v1,v2));
}
25 也可以在浏览器中输入网址,这样就可以自动找到了,首先输入C:\Inetpub\wwwroot\WebSite5\jsunit\testRunner.html,这是testRunner的位置。再在最前面输入file:///,这样就可以了,然后在末尾添加数据:?testPage=你要测试的文件的地址,就可以了,
如:file:///C:\Inetpub\wwwroot\WebSite5\jsunit\testRunner.html?testPage=C:\Inetpub\wwwroot\WebSite5\jsunit_test.html
26 还可以在后面再加一个参数,为autoRun表示自动运行,为true,
如:file:///C:\Inetpub\wwwroot\WebSite5\jsunit\testRunner.html?testPage=C:\Inetpub\wwwroot\WebSite5\jsunit_test.html&autoRun=true,
27 有testPage和autoRun这两个参数
28 单件模式
这是用的最多的模式,每一个正式的软件都要用它,全局配置、唯一资源、还有一个就是所有的工厂我都设计为单件模式,因此它的使用量大于工厂模式和抽象工厂模式之和。
工厂模式和抽象工厂模式
为了在程序代码中避免出现大量的New,因此我编写的软件代码这两三年基本都使用了工厂,由于深受受王咏武大侠关于舍熊掌取小鱼的影响,因此我较多地选用工厂模式,感觉确实有扩展需要的情况下才使用抽象工厂模式,其实工厂模式就是一个抽象工厂的特例,扩展为抽象工厂也非常容易。
适配器模式
适配器模式有两种类的适配器和对象适配器,对象适配器更多一些,对象适配器的优点在很多大侠的著作了已经论述n次了,我这里不多啰嗦,我用的较多的原因还有一个,我从C++转到C#,由于C#不支持多重继承,我又不比较懒,较少定义interface,因此大多数情况下用C#时也只能使用对象适配器模式了。其实适配器和装饰模式功能上有很大的相似性,在下面的装饰模式中加以论述。
装饰模式
也叫油漆工模式,装饰模式和适配器模式相似都是用来利用现成代码加以调整来满足新的需求,其实采用设计模式的目的之一就是复用,这两个模式正是复用的体现。当你要用这两种模式的时候都是为你现有软件新增新的功能,一般情况下,如果你是让你的软件新增新的功能操作,你一般要用装饰模式,你如果要为软件新增功能支持,你最好选择适配器模式,你如果想为你的类新增操作你用装饰模式,你如果要引入其他来源的现成代码,你用适配器模式。
观察者模式
这个模式我用的多一个原因就是它可以实现事件功能,当然在C#中可以直接使用事件,但是在C++中却是用可以用此模式发挥的淋漓尽致了,网上曾经的一个考题(猫大叫一声,主人醒来,耗子跑开),就是使用这个模式的最好应用。
外观模式
开发就是能复用的地方就复用,这样才能节省资源,提高效率,外观模式也是一个提供复用其他现成代码的解决方案,你需要实现一个功能,可能现成的代码中就有此功能,但是现成代码可能远远多于你所需要的功能,此时你把这些功能封装起来,再重新提供一个你所需要的接口,这就是这个模式的精髓所在。