王翔的《设计模式》读书笔记

今天读王翔的《设计模式 – 基于C#的工程化实现及扩展》,刚把第一章读完。作为一个C#初学者和工作者,发现了55页,也就是第一章的最后一段关于依赖注入的实例代码中有一个很明显的错误。本来想直接联系作者的,可是实在找不到他的联系方式,就发在自己博客上了。如果同样读过这本书的人能看到,不胜荣幸。

代码如下:

这段代码是依赖注入。使用Attribute把外部对接口的实现注入到类中。通过修改Attribute来改变依赖。
其中第29行和第35行中,有一个明显的错误。
先从第35行说起

这行代码说明要注入ITimeProvider类型,但是我们知道接口是不能被直接实例化的。所以这里的ITimeProvider应该改成TimeProvider。
但是这个时候第35行的条件判断就出现问题了,因为我们要得到的是ITimeProvider,而Decorator给的参数是TimeProvider,这两个类型是不会相等的。
这个时候我们还必须修改第35行的代码为

通过寻找实现接口的实例,才能够真正找到我们要的Decorator。

hr高度、颜色设置的通用方法

发现最近记性越来越差了,遇到什么tips还是记录下来比较好。

Words fly away, writings remain.

OK,废话不多少,下面介绍一下hr高度、颜色设置的通用方法。
原来一直以为用height和color的组合就可以设置,结果发现只有在IE下可以。
经过反复试验,发现hr其实是个框。所以,我们把它当做一个框来处理就可以了。
可是又经过反复试验以后,发现设置background-color的方法在IE下无效,所以只能选择设置border,这是在FF、IE、Chrome下通用的方法。

以下给出代码:

C#动态加载DLL

利用反射进行动态加载和调用.
Assembly ass=Assembly.LoadFrom(DllPath); //利用dll的路径加载,同时将此程序集所依赖的程序集加载进来,需后辍名.dll
Assembly.LoadFile 只加载指定文件,并不会自动加载依赖程序集.Assmbly.Load无需后辍名

加载dll后,需要使用dll中某类.
Type type=ass.GetType(“TypeName”);//利用类型的命名空间和名称获得类型

需要实例化类型,才可以使用,参数可以人为的指定,也可以无参数,静态实例可以省略
Object obj = Activator.CreateInstance(type,params[]);//利用指定的参数实例话类型

调用类型中的某个方法:
需要首先得到此方法
MethodInfo mi=type.GetMethod(“MehtodName”);//通过方法名称获得方法

然后对方法进行调用,多态性利用参数进行控制
mi.Invoke(obj,params[]);//根据参数直线方法,返回值就是原方法的返回值

C語言教程 — (一)環境配置

市面上的C語言書很多,我也看過一些,但始終沒有找到很好的范本,要么誤人子弟,要么不適合入門。這也是為什么那么多人說C語言難學,甚至有人說至少需要1年才能精通C語言。雖然我不知道他所謂的精通是達到什么程度,我不敢自稱精通,但至少引導入門的水平算是達到了吧。我現在寫的是入門級的教程

介紹一門語言,不得不講一下這門語言的歷史。C語言發布的時候并不是作為一門編程語言的研究成果,它只是作為一個偉大產品--Unix被發明的附屬物。是的,它是在Unix編寫的過程中,為了簡化編碼,加強邏輯性編程的一個工具。算是一個誤打誤撞的產品而流行至今,算是一個奇跡。但它的出現,為編程世界打開了一道新的大門,要知道當時的程序員寫的是最接近機器碼的匯編。C語言的出現,讓他們可以使用更接近人類語言和語法的代碼去同機器的世界溝通。

想知道更多關于C語言的歷史,可以查看: http://www.livinginternet.com/i/iw_unix_c.htm

接下來,簡單的介紹一下編程語言是怎么一回事。這要從計算機程序運行的方式說起。普通的應用程序都是運行在操作系統之上的。當然,操作系統也是一個程序,它作為普通程序的底層支持,溝通應用程序、計算機硬件還有使用計算機的用戶,在三者之間建立起聯系,作為三者溝通的橋梁。對于操作系統的介紹,這里略去10W字,不作為本文的內容。 我們要學習的是用編程語言來編寫應用程序。

這里介紹幾個概念:
1. 源代碼:我們使用編程語言,寫出的智慧的結晶
2. 可執行文件:可以直接在操作系統之上運行的應用程序 我們的目標是,寫出源代碼,并把它轉化成為可執行文件。

從源代碼到可執行文件的過程,叫做編譯。從事編譯這項工作的程序,叫做編譯器。C語言問世至今,已經有30幾年的歷史了,所以C語言的編譯器也有很多各種各樣不同的版本。C語言本身也出現了很多分支,這些分支當然有各自的編譯器來支持。我想推薦一個自認為最正統的分支:ASNI C99標準[1]。很好的實現這個標準,并被廣泛使用的編譯器是gcc[2]

終于要進入正題了。下面我們了解一下怎么在自己的機子上配置C語言編程的開發環境。鑒于大多數初學者都是使用Windows系統,這里只介紹Windows下的編譯環境配置。

我們需要的有:
1. 編譯器、系統頭文件、引用庫
2. 集成開發環境(IDE[3]

很幸運,Dev-cpp為我們提供了完整的1,至于2,我推薦Eclipse-cpp。
他們的下載地址:
Dev-cpp:http://www.bloodshed.net/dev/devcpp.html
Eclipse-cpp:http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/R/eclipse-cpp-galileo-win32.zip
Dev-cpp需要安裝在非中文目錄下,建議直接安裝在D盤根目錄下。D:\dev-cpp\ 安裝完成以后,右鍵單擊我的電腦-屬性-高級-環境變量,在系統變量里面找到Path,單擊編輯,在變量值的最后面加上:

也就是你安裝的目錄下面的bin目錄,注意,千萬別把原來的給刪了,后果很嚴重哦。保存好之后,點開開始菜單-運行,輸入:

在打開的黑色DOS窗口里輸入:

如果出現gcc的版本號,說明剛才的修改成功了,如果提示gcc不是命令,說明剛剛沒設置成功,請仔細查看以上步驟,重試。 接下來安裝Eclipse-cpp,其實不用安裝,找個地方解壓就行了。
然后運行Eclipse.exe。第一次運行會出現:

第一次打開Eclipse

第一次打開Eclipse


這個是設置工作目錄,也就是你創建工程和源代碼默認的根路徑。建議改成圖中的地址,這樣就把工作路徑設置成你安裝Eclipse的目錄下的workspace目錄下了。這樣做的好處是,以后可以直接打包整個Eclipse文件夾到別的電腦,而保持工程文件的完整性。以后每次打開Eclipse都會彈出這個窗口,詢問工作目錄,如果嫌麻煩,可以把下面的復選框勾上,這樣以后就不會再詢問了。
點擊OK,進入歡迎界面:
Eclipse的Welcome界面

Eclipse的Welcome界面

關掉歡迎界面,就見到Eclipse的主界面啦,如圖所示:

Eclipse主界面

Eclipse主界面

右鍵單擊Project Explore下面的空白處,選擇New-C Project,新建一個C工程,在彈出的窗口中選擇Hello World ANSI C Project。然后給你的第一個工程起個名字,輸入上面的Project name中。單擊Finish,第一個工程就創建成功啦。
現在可以在Project Explore中看到你剛剛創建的工程了。這個工程包含四個東西:
1.Binaries:生成的二進制文件
2.Debug:用于編譯輸出的文件夾
3.Includes:系統頭文件
4.src:我們的源文件,這里會有一個現成的文件,雙擊打開它。

用以下內容替換原來的內容:

然后單擊綠色的像播放一樣的按鈕Run(以下簡稱Run按鈕),右邊的黑色小箭頭,選擇Run Configurations…,這里我們要進行運行程序的配置。
雙擊左邊列表中的C/C++ Application,新建一個運行配置。現在把視線移到右邊。單擊Project右邊的Browse,由于我們現在只有一個工程,所以就選中這個唯一的工程。
再單擊C/C++ Application右邊的Search Project,此時也只有一個二進制文件可以選。Apply,我們的設置完成了,單擊Close關閉浮動窗口。
在下面一排的標簽,我們選中Console,也就是命令行。命令行是系統的標準輸入輸出。至于什么是系統的標準輸入輸出,將在下一節中講解。
現在直接單擊Run按鈕,如果Console中出現了應該出現的文字,那說明環境配置成功了。 至于應該出現什么文字呢?試試就知道了。

PS: 安裝Dev-cpp和Eclipse的這一段,我自己沒有測試過,是憑著自己以前的記憶寫下來的,可能會出現一些細節性的問題。沒辦法,我沒有寬帶,剛剛重裝過的電腦里也沒這兩個軟件。我的網速更沒辦法下載這兩個軟件。如果遇到什么問題,請留言。我明天去公司把這兩個東西載下來,再修正一下上面這段。

附錄:
[1] ASNI C99標準:American National Standards Institute C99
[2] gcc:Gnu C Compiler
[3] IDE:Integrated Development Environment

Array.indexOf in Internet Explorer

According to this document at Mozilla Developer Center, Javascript 1.5 has been implemented in a browser since at least the first releases of Mozilla as open source browser, which means, in other words, since around 1998. Let’s assume it was 2002 which is marked as the release of the 1.0 version.

And I was doing some interface programming lately and I needed to check if an element was in an array. Went to Gecko’s documentation (that’s the one I normally use, since it’s less overbloated with crappy ads) and checked that Array objects had an indexOf function. Cool! I used that function on my code. Then once I finished with all the development, went to The Horror (i.e. Internet Explorer) and tested it.

Surprise! It was broken! What had I done? (You know the debugger for Internet Explorer is not specially helpful)

I suspected of the indexOf function, and recalled vague memories about doing a custom search function in the past for looking into arrays and not having to write a for(i=0; i<ar.length;i++) thing each time…

Mmmm… did a alert(‘Array.indexO’) in ie and what did I get?: undefined

So they have been spent five years for releasing ie7 and still they didn’t implement Array.indexOf!

No worries, though. Javascript is flexible! Look, IE, I don’t care if you choke on the mere seeing of indexOf, you’re going to run it whether you like it or not!


and voila! my script wasn’t broken anymore!

jlUtil For Javascript

昨天用js写了一个Json_encode的工具函数,附上模仿jQuery并加强的extend函数。
对于extend函数,主要加强的是可以遍历子对象来extend,而不是简单的覆盖。

getJSON的使用方法:

extend的使用方法:

下面是代码:

Pro Javascript Techniques – 目录

先来一段废话:

今天是周五,终于可以放松啦,蛮累的,今天上班的时候萌生这个想法,自己的博客流量总是上不去,多写点有用的东西,带动一下流量,嘿嘿。
本来是想继续翻译的,后来发现这本书已经有译本了,并且不允许在网络上发布其内容,只好放弃翻译,改写读后感好了,继续使用这个目录。两个半小时的心血啊。

正文:

目录

关于作者

关于技术校对者

感谢

第一部分 介绍现代Javascript

第一章   现代Javascript编程

1.1 面向对象Javascript

1.2 测试你的代码

1.3 打包和发布

1.4 非侵入的DOM脚本

1.4.1 文档对象模型DOM

1.4.2 事件

1.4.3 Javascript和CSS

1.5 Ajax

1.6 浏览器支持

1.7 总结

第二部分 专业Javascript开发

第二章   面向对象Javascript

2.1 语言特性

2.1.1 引用

2.1.2 函数重载和类型校验

2.1.3 命名域

2.1.4 闭包

2.1.5 语境

2.2 面向对象基础

2.2.1 对象

2.2.2 对象的创建

2.3 总结

第三章   编写可重用的代码

3.1 标准的面向对象代码

3.1.1 原型继承

3.1.2 经典继承

3.1.3 基础类库

3.1.4 原型类库

3.2 打包

3.2.1 名称空间

3.2.2 整理你的代码

3.2.3 压缩

3.3 发布

3.4 总结

第四章   Debug和测试的工具

4.1 Debug

4.1.1 错误命令行

4.1.2 DOM查看器

4.1.3 Firebug

4.1.4 Venkman

4.2 测试

4.2.1 JSUnit

4.2.2 J3Unit

4.2.3 测试实例

4.3总结

第三部分 非侵入的Javascript

第五章   文档对象模型DOM

5.1 介绍文档对象模型DOM

5.2 初识DOM

5.2.1 操作DOM中的空白部分

5.2.2 简单展示DOM的功能

5.2.3 绑定每个HTML节点

5.2.4 标准DOM方法

5.3 等待HTML DOM的载入

5.3.1 等待页面载入

5.3.2 等待大多数DOM载入

5.3.3 当DOM载入完成时

5.4 在HTML文档中搜索节点

5.4.1 通过class名称搜索节点

5.4.2 通过CSS选择器查找节点

5.4.3 XPath

5.5 取得节点的内容

5.5.1 取得节点的文字内容

5.5.2 取得节点的HTML内容

5.6 操作节点属性

5.6.1 取得和设置节点的属性值

5.7 操作DOM

5.7.1新建节点

5.7.2 插入节点

5.7.3 注入HTML

5.7.4 删除节点

5.8 总结

第六章   事件

6.1 介绍Javascript事件

6.1.1 异步事件和线程

6.1.2 事件阶段

6.2 常规事件特性

6.2.1 事件对象

6.2.2 this关键字

6.2.3 取消事件冒泡

6.2.4 重写浏览器的默认事件

6.3 绑定事件监听器

6.3.1 常规绑定

6.3.2 DOM绑定:W3C

6.3.3 DOM绑定:IE

6.3.4 添加和删除事件

6.4 事件的类型

6.5 非入侵的DOM脚本

6.5.1 Javascript被禁用时的准备

6.5.2 确保链接不依赖于Javascript

6.5.3 监视CSS是否禁用

6.5.4 事件的可访问性

6.6 总结

第七章   Javascript和CSS

7.1 访问样式信息

7.2 动态节点对象

7.2.1 节点的位置

7.2.2 节点的大小

7.2.3 节点的可见度

7.3 动画

7.3.1 滑入

7.3.2 隐现

7.4 浏览器

7.4.1 鼠标位置

7.4.2 可视范围

7.5 拖拽

7.6 脚本类库

7.6.1 moo.fx和jQuery

7.6.2 Scriptaculous

7.7 总结

第八章   增强表单功能

8.1 表单校验

8.1.1 必填字段

8.1.2 正则匹配

8.1.3 设置规则

8.2 显示错误信息

8.2.1 校验

8.2.2 什么时候校验

8.3 增强用户体验

8.3.1 悬停说明

8.3.2 标记必填字段

8.4 总结

第九章   创建一个相册

9.1 示例相册

9.1.1 Lightbox

9.1.2 ThickBox

9.2 创建相册

9.2.1 分离加载

9.2.2 透明掩盖层

9.2.3 定位容器

9.2.4 导航

9.2.5 幻灯片展示

9.3 总结

第四部分 Ajax

第十章   介绍Ajax

10.1 使用Ajax

10.1.1 HTTP请求

10.1.2 HTTP响应

10.2 处理响应数据

10.3 完整的Ajax类库

10.4 不同数据使用方式的示例

10.4.1 RSS

10.4.2 HTML选择器

10.4.3 JSON和Javascript:远程执行

10.5 总结

第十一章   使用Ajax增强博客功能

11.1 永不结束的博客

11.1.1 博客模板

11.1.2 数据源

11.1.3 事件检测

11.1.4 请求

11.1.5 结果

11.2 生动的博客

11.3 总结

第十二章   自动补全的搜索栏

12.1 自动补全搜索栏的例子

12.2 创建页面

12.3 监视键盘输入

12.4 搜索自动补全结果

12.5 导航结果列表

12.5.1 键盘导航

12.5.2 鼠标导航

12.6 最终结果

12.7 总结

第十三章   Ajax Wiki

13.1 什么是Wiki

13.2 关于数据库

13.3 Ajax请求

13.4 服务器端代码

13.4.1 处理一个请求

13.4.2 执行和格式化SQL脚本

13.5 处理JSON响应

13.6 额外的学习:一个Javascript博客

13.7 应用程序代码

13.7.1 Javascript核心代码

13.7.2 Javascript SQL类库

13.7.3 Ruby服务器端代码

13.8 总结

第五部分 Javascript的未来

第十四章   Javascript将去向何处

14.1 Javascript 1.6和1.7

14.1.1 Javascript 1.6

14.1.2 Javascript 1.7

14.2 Web应用程序1.0

14.2.1 创建一个时钟

14.2.2 简单的星球模拟

14.3 彗星

14.4 总结

第六部分 附录

附录A  DOM索引

A.1 资源

A.2 术语

A.3 全局变量

A.3.1 document

A.3.2 HTMLElement

A.4 DOM对象

A.4.1 body

A.4.2 childNodes

A.4.3 documentElement

A.4.4 firstChild

A.4.5 getElementById( elemID )

A.4.6 getelementsByTagName( tagName )

A.4.7 lastChild

A.4.8 nextSibling

A.4.9 parentNode

A.4.10 previousSibling

A.5 节点信息

A.5.1 innerText

A.5.2 nodeName

A.5.3 nodeType

A.5.4 nodeValue

A.6 节点属性

A.6.1 className

A.6.2 getAttribute( attrName )

A.6.3 removeAttribute( attrName )

A.6.4 setAttribute( attrName, attrValue )

A.7 DOM操作

A.7.1 appendChild( nodeToAppend )

A.7.2 cloneNode( true|false )

A.7.3 createElement( tagName )

A.7.4 createElementNS( namespace, tagName )

A.7.5 createTextNode( textString )

A.7.6 innerHTML

A.7.7 insertBefore( nodeToInsert, nodeToInsertBefore )

A.7.8 removeChild( nodeToRemove )

A.7.9 replaceChild( nodeToInsert, nodeToReplace )

附录B  事件索引

B.1 资源

B.2 术语

B.3 事件对象

B.3.1 常规事件

B.3.2 鼠标事件

B.3.3 键盘事件

B.4 页面事件

B.4.1 载入

B.4.2 关闭之前

B.4.3 错误

B.4.4 缩放

B.4.5 滚动

B.4.6 关闭

B.5 UI事件

附录C  浏览器

C.1 现代浏览器

C.1.1 Internet Explorer

C.1.2 Mozilla

C.1.3 Safari

C.1.4 Opera

Javascript Timeout Hacks

Our first user script simply displays an alert saying “Hello world!” when it is executed.

Example: Display the “Hello world!” alert

Although this code looks obvious enough, and does exactly what you would expect, Greasemonkey is actually doing a number of things behind the scenes to ensure that user scripts do not interact badly with other scripts defined by the original page. Specifically, it automatically wraps your user script in an anonymous function wrapper. Ordinarily you can ignore this, but it will eventually creep up and bite you in the ass, so you may as well learn about it now.

One of the most common ways this can bite you is that variables and functions that you define in a user script are not available to other scripts. In fact, they are not available at all once the user script has finished running. This means that you will run into problems if you are expecting to be able to call your own functions later by using the window.setTimeout function, or by setting string-based onclick attributes on links and expecting Javascript to evaluate your function names later.

For example, this user script defines a function helloworld, then attempts to set a timer to call it one second later.

Example: Bad way to delay calling a function

This will not work; no alert will be displayed. If you open JavaScript Console, you will see an exception displayed: Error: helloworld is not defined. This is because, by the time the timeout expires and the call to helloworld() is evaluated, the helloworld function no longer exists.

If you need to reference your user script’s variables or functions later, you will need to explicitly define them as properties of the window object, which is always available.

Example: Better way to delay calling a function

This works as expected: one second after the page loads, an alert pops up proudly displaying “Hello world!

However, setting properties on window is still not ideal; it’s a bit like using a global variable when a local one will do. (Actually, it’s exactly like that, since window is global and available to all scripts on the page.) More practically, you could end up interfering with other scripts that were defined on the page, or even other user scripts.

The best solution is to define an anonymous function yourself and pass it as the first argument to window.setTimeout.

Example: Best way to delay calling a function

What I’m doing here is creating a function without a name (an “anonymous function”), then immediately passing the function itself to window.setTimeout. This accomplishes the same thing as the previous example, but it leaves no trace, i.e. it’s undetectable to other scripts.

I find that I use anonymous functions regularly while writing user scripts. They are ideal for creating “one-off” functions and passing them as arguments to things like window.setTimeout, document.addEventListener, or assigning to event handlers like click or submit.