??xml version="1.0" encoding="utf-8" standalone="yes"?>
~程思想
优秀E序?8大原则:http://sd.csdn.net/a/20110729/302424.html
试相关
easyMock教程Q?a >http://skydream.iteye.com/blog/829340
]]>
]]>
]]>
二、Visitor Pattern
目的Q封装一些施加于某种数据l构元素之上的操作?br /> UML图:
主要原理Q?#8220;反传?#8221;QElement来Visitor之间二轮调用Q调用过E中用sinlge dispatch定cd
]]>
]]>
]]>
2Q多U程Q把接受h和处理请求的U程分开Q接受后交给 worker处理
3Q线E池Q性能最佻I有效地防止负载过重,重复利用U程Q请求多Ӟ让请求排队接收处?br />
4Q主要用socket来通信Q?ServerSocket ?Socket
具体文章LQhttp://tutorials.jenkov.com/java-multithreaded-servers/index.html
]]>
回调是一U双向调用模式,也就是说Q被调用方在接口被调用时也会调用Ҏ的接口;
异步调用是一U类似消息或事g的机Ӟ不过它的调用方向刚好相反Q接口的服务在收到某U讯息或发生某种事gӞ会主动通知客户方(卌用客h的接口)Q如JMSQ?
阅读全文
]]>
]]>
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
数组c?/span>Array?/span>Java中最基本的一个存储结构。它用于存储一l连l的对象或基本类型的数据。其中的元素的类型必ȝ同?/span>
Array是最有效率的一 U:
1、效率高Q但定w固定且无法动态改变?/span> Arrayq有一个缺ҎQ无法判断其中实际存有多元素,length只是告诉我们Array的容量?/span>
2?/span>Java中有一?/span>Arraysc,专门用来操作ArrayQ提供搜索、排序、复制等静态方法?/span> equals()Q比较两?/span>Array是否相等Q?/span>Array拥有相同元素个数Q且所有对应元素两两相{?/span> fill()Q将值填?/span>Array中?/span> sort()Q用来对Arrayq行排序?/span> binarySearch()Q在排好序的Array中寻扑օ素?/span> System.arraycopy()Q?/span>Array的复制?/span>
Java Collections Framework成员主要包括两种cdQ即Q?/span>Collection?/span>Mapcd?/span> ?/span>Java中提供了Collection?/span>Map接口。其?/span>List?/span>Setl承?/span>Collection接口Q?/span>Vector?/span>ArrayList?/span> LinkedList三个cd?/span>List接口Q?/span>HashSet?/span>TreeSet实现Set接口Q?/span>HashTable?/span>HashMap?/span> TreeMap实现Map接口。由此可见,Java中用8U类型的基本数据l构来实现其Collections FrameworkQ下面分别进行介l?/span>
VectorQ基?/span>Array?/span>ListQ性能也就不可能超?/span>ArrayQƈ?/span>Vector?/span>"sychronized"?/span>Q这个也?/span>Vector?/span>ArrayList的唯一的区别?/span>
ArrayListQ同Vector一h一个基?/span>Array的,但是不同的是ArrayList不是同步?/span>。所以在性能上要?/span>Vector优越一些,?/span> 是当q行到多U程环境中时Q可需要自己在理U程的同步问题。从其命名中可以看出它是一U类似数l的形式q行存储Q因此它的随问速度极快?/span>
LinkedListQ?/span>LinkedList不同于前面两U?/span>ListQ它不是ZArray的,所以不?/span>Array性能的限制。它每一个节点(NodeQ?/span> 都包含两斚w的内容:
1、节Ҏw的数据Q?/span>dataQ;
2、下一个节点的信息Q?/span>nextNodeQ。所以当?/span>LinkedList做添加,删除动作的时?/span> ׃用像ZArray?/span>List一P必须q行大量的数据移动。只要更?/span>nextNode的相关信息就可以实现了所以它适合于进行频J进行插入和删除?/span> 作。这是LinkedList的优ѝ?/span>Iterator只能对容器进行向前遍历,?/span> ListIterator则承了Iterator的思想Qƈ提供了对Listq行双向遍历的方法?/span>
ListȝQ?/span>
1、所有的List中只能容U_个不同类型的对象l成的表Q而不?/span>KeyQ?/span>Value键值对。例如:[ tom,1,c ]Q?/span>
2、所有的List中可以有相同的元素,例如Vector中可以有 [ tom,koo,too,koo ]Q?/span>
3、所有的List中可以有null元素Q例?/span>[ tom,null,1 ]Q?/span>
4、基?/span>Array?/span>ListQ?/span>VectorQ?/span>ArrayListQ适合查询Q?/span>LinkedListQ链表)适合dQ删除操?/span>?/span>
HashSetQ虽?/span>Set?/span>List都实CCollection接口Q但是他们的实现方式却大不一栗?/span>List基本上都是以Array为基。但?/span> Set则是?/span>HashMap的基上来实现的,q个是Set?/span>List的根本区别?/span>HashSet的存储方式是?/span>HashMap中的Key作ؓSet?/span> 对应存储,q也是ؓ什么在Set中不能像?/span>List中一h重复的项的根本原因,因ؓHashMap?/span>key是不能有重复的?/span>HashSet能快速定?/span> 一个元素,但是攑ֈHashSet中的对象需要实?/span>hashCode()Ҏ0?/span>
TreeSet则将攑օ其中的元素按序存放,q就要求你放入其中的对象是可排序的,q就用到了集合框架提供的另外两个实用c?/span>Comparable?/span> Comparator。一个类是可排序的,它就应该实现Comparable接口。有时多个类h相同的排序算法,那就不需要重复定义相同的排序法Q只要实?/span>Comparator接口卛_?/span>TreeSet?/span>SortedSet的子c,它不同于HashSet的根本就?/span>TreeSet是有序的。它是通过SortedMap来实现的?/span>
SetȝQ?/span>
1?/span>Set实现的基?/span>MapQ?/span>HashMapQ;
2?/span>Set中的元素是不能重复的Q如果?/span>add(Object obj)Ҏd已经存在的对象,则会覆盖前面的对象; Set里的元素是不能重复的Q那么用什么方法来区分重复与否?/span>? 是用==q是equals()? 它们有何区别? Set里的元素是不能重复的Q即不能包含两个元素e1?/span>e2Q?/span>e1.equalsQ?/span>e2Q)。那么用iterator()Ҏ来区分重复与否?/span> equals()是判M?/span>Set是否相等?/span>==Ҏ军_引用?/span>(句柄)是否指向同一对象?/span>
HashMap?/span>TreeMap?/span>HashtableQ?/span>
1?/span>HashMap也用C哈希码的法Q以便快速查找一个键Q?/span>TreeMap则是寚w按序存放Q因此它有一些扩展的ҎQ比?/span> firstKey(),lastKey(){?/span>
2?/span>HashtableQ不允许I(nullQ键Q?/span>keyQ或|valueQ,Hashtable的方法是Synchronize的,在多个线E访?/span> HashtableӞ不需要自׃ؓ它的Ҏ实现同步Q?/span>HashMap 必Mؓ之提供外同步?/span> Hashtable?/span>HashMap采用?/span>hash/rehash法都大概一P所以性能不会有很大的差异?/span>
3?/span>HashMap?/span>Hashtable的区别:HashMap?/span>Hashtable(U程案例?/span>)的轻量实现Q非U程安全的实玎ͼQ他们都完成?/span>Map接口。主要区别在?/span>HashMap允许I(nullQ键Q?/span>keyQ或|valueQ?/span>,非同步,׃非线E安全,效率上可能高?/span>Hashtable?/span>
MapȝQ?/span>
是一U把键对象和值对象进行关联的容器Q?/span>Map有两U比较常用的实现Q?/span> HashTable?/span>HashMap?/span>TreeMap?/span>
创徏模式 |
l构模式 |
行ؓ模式 |
单工厂模?/span> |
适配器模?/span> |
不变模式 |
工厂Ҏ模式 |
~省适配模式 |
{略模式 |
抽象工厂模式 |
合成模式 |
模版Ҏ模式 |
单例模式 |
装饰模式 |
观察者模?/span> |
多例模式 |
代理模式 |
q代子模?/span> |
建造模?/span> |
享元模式 |
责Q链模?/span> |
原始模型模式 |
门面模式 |
命o模式 |
桥梁模式 |
备忘录模?/span> |
|
状态模?/span> |
||
讉K者模?/span> |
||
解释器模?/span> |
||
调停者模?/span> |
模式 |
定义 |
描述 |
装饰?/span> |
动态地责任附加到对象上。若要扩展功能,装饰者提供了比承更有弹性的替代Ҏ |
包装一个对象,以提供新的行?/span> |
状?/span> |
允许对象在内部状态改变时改变它的行ؓQ对象看h好像修改了它的类 |
装了基本状态的行ؓQƈ使用委托在行Z间切?/span> |
q代?/span> |
提供一U方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表C?/span> |
在对象的集合之中游走Q而不暴露集合的实?/span> |
外观Q门面) |
提供一个统一的接口,用来讉K子系l中的一接口。外观定义了一个高层接口,让子pȝ更多Ҏ使用 |
化一类的接?/span> |
{略 |
定义法族,分别装hQ让它们之间可以互相替换Q此模式让算法的变化独立于用算法的客户 |
装可以互换的行为,q用委托来军_使用那一U?/span> |
代理 |
为另一个对象提供一个替w或点位W以讉Kq个对象 |
包装对象Q以控制Ҏ对象的访?/span> |
工厂Ҏ |
定义了一个创建对象的接口Q但由子cd定要实例化的cL哪一个。工厂方法让cL实例化推q到子类 |
由子cd定要创徏是具体类是哪一?/span> |
抽象工厂 |
提供一个接口,用于创徏相关或依赖对象的家族Q而不需要明指定具体类 |
允许客户创徏对象的家族,而无需指定他们的具体类 |
适配?/span> |
一个类的接口,转换成客h望另一个接口。适配器让原来不兼容的cd以合作无?/span> |
装对象Qƈ提供不同的接?/span> |
观察?/span> |
在对象之间定义一对多的依赖,q样一来,当一个对象改变时Q依赖它的对象都会收到通知q自动更?/span> |
让对象能够在状态改变时被通知 |
模板Ҏ |
在一个方法中定义一个算法的骨架Q而将一些步骤gq到子类中。模板方法得子cd以在不改变算法结构的情况下,重新定义法中的某些步骤 |
由子cd定如何实C个算法中的步?/span> |
l合 |
允许你将对象l成树结构来表现“整体/部分”的层ơ结构。组合能让客户以一致的方式处理个别对象和对象组?/span> |
客户用一致的方式处理对象集合和单个对?/span> |
单gQ单体) |
保一个类只有一个实例,q提供全局讉K?/span> |
保只有一个对象被创徏 |
命o |
请求封装成对象Q这可以让你使用不同的请求、队列,或者日志请求来参数化其它对象。命令模式也可以支持撤销操作 |
装h为对?/span> |
一、在单元试领域里,JUnit可以说是王者,它不但精_而且使用方便。最后有些时_把JUnit源码读读Q顺便复习下设计模式 Q)
二、参考文?br />
在深入看代码之前Q先看下面的文章Q对JUnit有一个基本的了解后,看代码会更有目的性?br />
JUnit官方|站Q?a >http://www.junit.org/
分析 JUnit 框架源代码: http://www.ibm.com/developerworks/cn/java/j-lo-junit-src/
JUnit A cook's tour: http://junit.sourceforge.net/doc/cookstour/cookstour.htm
三、核心架?br />
我分析的源码的版本是JUnit 3.8.2Q这个版本相对简略,把核心思想表现出来了,没有4.X版本那么多附加的功能
JUnit是一个模式密集型的框Ӟ主要用组合模式、模h法、观察者模式、参数收集方法、命令模式、装饰者模式和适配器模式。其中核心是 前三U?br />
核心cM间的关系
Test、TestCase和TestSuit构成了测试框架的基础Q它们用composite模式l合在一P使得客户端可以将对象的集合以及个别的对象(TestCase)一视同?TestRusult用来保存试l果Q和TestListnerl成observer模式Q支持文本界面、图形界面和 Eclipse 集成lg三种监听?/font>
和JUnit A cook's tour中提到的模式囑־怼
cMcM间的关系在此׃作解释了Q可以看看参考文章。有兴趣的朋友,Ƣ迎一赯?Q)
多用l合Q少用?/span>
针对接口~程Q不针对实现~程
Z互对象之间的松耦合设计而努?/span>
cd该对扩展开放,对修改关?/span>
只和朋友交谈
别找我,我会找你
cd该只有一个改变的理由
38、只针对不正常的条g使用异常
异常只应该被用于不正常的条gQ它们永q不应该被用于不正常的条?br />
设计API启示Q一个良好的API不应该强q它的客户ؓ了正常的控制而用异常。对于边界的判断常用的有两种ҎQ状态测试方法和可被识别的返回?/p>
40、对于可以恢复的条g使用被检查的异常Q对于程序错误用运行时异常
ThowableQ可抛出异常Q有三种l构Q被查的异常(checked exception)、运行时异常Qrun-time exception)和错?error)
如果期望调用者能够恢复,那么Q对于这L条g应该使用被检查的异常
q行时异常和错误Q不需要也不应该是被捕L抛出?br />
用运行时异常来指明程序错?br />
对于被检查的异常Q提供一些辅助方法是非常重要的,通过q些ҎQ调用者可以获得一些有助于恢复的信?/p>
41、避免不必要C用被查的异常
42、尽量用标准异?br />
43、抛出的异常要适合于相应的抽象
高层的实现应该捕获低层的异常Q同时导Z个可以按照高层抽象进行解释的---异常转译
低层的异常对于调试该异常被拨出的情Ş非常有帮助的话,可以使用异常链接。即低层的异常被高层的异怿存v来,q且高层的异常提供一个公有的讉KҎ来获得低层异?/p>
44、每个异常的抛出都必L文档
45、在l节消息中包含失?-捕获信息
Z捕获p|Q一个异常的的字W串表示应该包含所?#8220;对异常有贡献”的参数和域的?
在异常构造函C以参数Ş式引入这些信?/p>
46、努力p|保持原子?br />
一个失败方法调用应该用对象保?#8220;它在被调用之前的状?#8221; ---failure atomic
几种解决ҎQ在执行操作之前查参数的有效?br />
调整计算E,使得M可能会失败的计算部分发生在对象状态被修改之前
~写一D|复代?br />
在对象上临时都拷贝一份,当操作完成之后把临时拯中的l果复制l原来的对象。如QCollections.sort
47、不要忽略异?br />
写上try catch?/p>