??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲 自拍 另类小说综合图区,久久久亚洲裙底偷窥综合,亚洲第一香蕉视频http://www.tkk7.com/antsoul/category/20417.html它L在行赎ͼ行走Q永q的行走…? 行走是它生存的恒久姿态和最佳造型? 它似乎有一双不知疲倦的脚? ———我说的是蚂蚁? zh-cnWed, 04 Apr 2007 16:15:16 GMTWed, 04 Apr 2007 16:15:16 GMT60Creational Pattern学习(fn)之Simple Factoryhttp://www.tkk7.com/antsoul/archive/2007/03/31/107608.htmlantsoulantsoulSat, 31 Mar 2007 02:53:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/31/107608.htmlhttp://www.tkk7.com/antsoul/comments/107608.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/31/107608.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/107608.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/107608.htmlCreational Pattern是对cȝ实例化过E的抽象化。一些系l在创徏对象Ӟ需要动态的军_怎么样创建对象,创徏那些对象Q以?qing)如何组合和表示q些对象。Creational Pattern描述了怎么h造和装q些动态的军_?br />    Creational Pattern分ؓ(f)cȝ创徏模式和对象的创徏模式两种?br />    cȝ创徏模式Q   ?cȝ创徏模式使用l承关系Q把cȝ创徏延迟到子c,从而封装了客户端将得到的哪些具体类的信息,q且?藏了q?cȝ实例是如何被创徏和放CL(fng)?br />    对象的创建模式:(x) 对象的创建模式是把对象的创徏q程动态的委派l另一个对象,从而动态地军_客户端将得到哪些具体的类的实例,以及(qing)q些cȝ实例是如何被创徏和组合在一L(fng)?br />    Simple Factory是类的创建模式,又称为Static Factory Method模式Q它是由一个工厂对象决定创造出哪一U品类的实例。工厂模式负责将大量有共同接口的cd例化。工厂模式可以动态的军_哪一个类实例化,不必事先知道每次要实例化哪一个类。工厂模式有如下的几UŞ?/font>:
?Simple Factory 模式Q又叫Static Factory Method.
?Factory Method模式Q又U多态工厂(Polymorphic FactoryQ模式?br />?Abstract Factory模式Q又U工L(fng)QKit或ToolKitQ模式?br />单工厂模式涉?qing)到工厂角色Q抽象品角色以?qing)具体品角色等三个角色Q?br />?工厂c(CreatorQ角Ԍ(x)担Qq个角色的是工厂Ҏ(gu)模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客L(fng)的直接调用下创徏产品对象Q它往往׃个具体的javacd现?br />?抽象产品QProductQ角Ԍ(x)担Qq个角色的是由工厂方法模式所创徏的对象的父类Q或它们共同拥有的接口。抽象品可以由一个Java接口或Java抽象cd现?br />?具体产品QConcrete ProductQ角Ԍ(x)工厂模式所创徏的Q何对象都是这个角色的实例Q具体品角色由一个具体的Javacd现?br />demo:
 以农Zؓ(f)例子Q农场公怸门向市场销售水果。农场得有专门的园丁来管理水果?br />interface Fruti
{
 //水果的接?br /> /**
 * 生长
 */
 void grow(); 
 
 /**
 * 收获
 */
 void harvest();
 
 /**
 * U植
 */
 void plant();
}
具体的水?Ҏ(gu)Q葡萄,草莓
Apple.java:
class Apple implements Fruit
{
 private int treeAge;   //Ҏ(gu)的树(wi)?br /> 
 /**
 * 生长
 */
 public void grow()
 {
  log("Apple is growing......");
 }
 
 /**
 * 收获
 */
 pubic void harvest()
 {
  log("Apple has been harvested.");
 }
 
 /**
 * U植
 */
 public void plant()
 {
  log("Apple has been planted");
 }
 
 /**
 * 辅助Ҏ(gu)
 */
 public static void log(String str)
 {
  System.out.println(str);
 }
 
 /**
 * ?wi)龄的取值方?br /> */
 public int getTreeAge()
 {
  return this.treeAge;
 }
 
 /**
 * ?wi)龄的赋值方?br /> */
 public void setTreeAge(int treeAge)
 {
  this.treeAge = treeAge;
 }
}

Grape.java
class Grape implements Fruit
{
 private boolean seedless;  //葡萄的籽
 
 /**
 * 生长
 */
 public void grow()
 {
  log("Grape is growing.....");
 }
 
 /**
 * 收获
 */
 public void harvest()
 {
  log("Grape has been harveted");
 }
 
 /**
 * U植
 */
 public void plant()
 {
  log("Grape has been planted");
 }
 
 /**
 * 辅助Ҏ(gu)
 */
 public static void log(String msg)
 {
  System.out.println(msg);
 }
 
 /**
 * 有无c的取值方?br /> */
 public boolean getSeedless()
 {
  return this.seedless;
 }
 
 /**
 * 有无c的赋值方?br /> */
 public void setSeedless(boolean seedless)
 {
  this.seedless = seedless;
 }
}

Strawberry.java
class Strawberry implements Fruit
{
 /**
 * 生长
 */
 public void grow()
 {
  log("Strawberry is growing.....");
 }
 
 /**
 * 收获
 */
 public void harvest()
 {
  log("Strawberry has been harvested");
 }
 
 /**
 * U植
 */
 public void plant()
 {
  log("Strawberry has been planted");
 }
 
 /**
 * 辅助Ҏ(gu)
 */
 public static void log(String msg)
 {
  System.out.println(msg);
 }
}

具体的园?
public class FruitGradener
{
 /**
 * 静态工厂方?br /> */
 public static Fruti factory(String witch)throws BadFruitException
 {
  if(witch.equalsIgnoreCase("apple"))
  {
   return new Apple();
  }
  else if(withc.equalsIgnoreCase("Grape"))
  {
   return new Grape();
  }
  else if(witch.equalsIgnoreCase("Strawberry"))
  {
   return new Strawberry();
  }
  else
  {
   thow new BasFruitException("Bad fruit request");
  }
 }
}

抽象产品角色的主要目的就是给所有的具体产品提供一个共同的cdQ在最单的情况下可以简化ؓ(f)一个标识接口。如:
public interface Product
{
}

工厂c角色就是创Z个新的具体品实例返回给调用者。如:
public class  Creator
{
   /**
   * 静态工厂方?br />   */
    return new ConreteProduct();
}

具体的品就是实际的对象了,?
public class ConreteProduct implemnts Product
{
    public ConcreteProduct(){}
}

如果模式所产生的具体品类彼此之间没有共同的商业逻辑Q那么抽象品可以由一个JAVA接口扮演Q如果有共同的商务逻辑则应当用抽象角色扮演。这样共同的逻辑都放到抽象类里去了,辑ֈ׃n的目的?img src ="http://www.tkk7.com/antsoul/aggbug/107608.html" width = "1" height = "1" />

antsoul 2007-03-31 10:53 发表评论
]]>
Java接口与Java抽象cȝ区别http://www.tkk7.com/antsoul/archive/2007/03/29/107131.htmlantsoulantsoulThu, 29 Mar 2007 02:00:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/29/107131.htmlhttp://www.tkk7.com/antsoul/comments/107131.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/29/107131.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/107131.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/107131.html        在Java语言中,可以定义一U抽象类型,q且提供q种q一抽象cd的各U具体实现。实际上Javal我们提供不只是一U机制而是两种让我们可以做到这一炏V它们是Java接口和Java抽象cR二者的区别如下Q?br />       (1) 两者最明显的区别在于,Java抽象cd以提供部分方法的实现Q而Java接口不能。这是Java抽象cȝ有点也是优势。如果向一个抽象类加入一个新的具体的Ҏ(gu)Q那么所有的子类一下子得Cq个新的具体的方法。如果向一个接口中加入一个新的方法,所有实现这个接口的c都不能全部成功的通过~译Q因为它们没有实现这个新声明的方法。这是Java接口的一个缺点了?br />       (2) 一个抽象类的实现只能由q个抽象cȝ子类l出Q那么,q个实现出在抽象cL定义出的l承的等U结构中Q而由于Java语言限制多承,因此抽象cM为类型定义工L(fng)效果大打折扣了。反之,M一个实CJava接口所规定的方法的c都可以hq个接口的类型,而一个类可以实现多个接口。这也是两者最重要的区别之一?br />      (3) 从代码重构的角度上看Q将一个单独的Java具体c重构ؓ(f)一个Java接口的实现是很容易的。我们只需要声明一个接口,q将重要的方法添家到接口声明中,然后在具体的cd义语句后加上一个何时的implmentsO(jin)K了。而ؓ(f)一个已有的具体cL加一个抽象类作ؓ(f)抽象cd却不是那么的Ҏ(gu)了,因ؓ(f)q个具体cL可能已经有了一个超c,q样以来Q这个新定义的抽象类只好l箋向上UdQ变成这个超cȝ类Q如此@环,最后这个新定义的抽象类必定处于整个{cdl构的最上端Q从而得等U结构中的所有成员都受到影响?br />      (4) Java接口是定义؜合类型的理想工具。Mixin Type是在一个类ȝ型之外的ơ类型。一个؜合类表明一个类不仅hȝ型的行ؓ(f)Q而且q具有其它的行ؓ(f)。比如Hashtablcdh多个cd。它的主cd为MapQ这是一UJava聚集。而Cloneable接口则给Z一个次要类型,q个cd说明q个cL可以安全克隆的。同PSerializable也是一个次要类型,它表明这个类是可以串行化的?/font>

antsoul 2007-03-29 10:00 发表评论
]]>
Relation in Classeshttp://www.tkk7.com/antsoul/archive/2007/03/28/107033.htmlantsoulantsoulWed, 28 Mar 2007 09:34:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/28/107033.htmlhttp://www.tkk7.com/antsoul/comments/107033.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/28/107033.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/107033.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/107033.htmlRelation in Class

Generalization(一般化)Q?br />表示cMcM间的l承关系Q接口与接口之间的承关pLcd接口的实现关pR?br />Association(兌)Q?br />cMcM间的q接Q它使一个类知道另一个类的属性和Ҏ(gu)。每个Association都有两个端点Q每个端炚w可以是一个角Ԍ昄出关联的本质。Driver------------>>>>Car.
Aggregation(聚合)Q?br />聚合是一U强烈的兌关系。它整体与个体的关系。区分关联与聚合的关键ؓ(f)逻辑关系?br />Composition(合成)Q?br />兌关系的一U,是比聚合关系q要强的关系。它要求普通的聚合关系中代表整体的对象负责代表部分对象的生命周期,合成关系不能׃n?br />Dependency(依赖)Q?br />cMcM间的q接Q依赖是单向的表CZ个类依赖另一个类的定义?br />



antsoul 2007-03-28 17:34 发表评论
]]>
设计模式之Proxy(代理)【{?/title><link>http://www.tkk7.com/antsoul/archive/2007/03/28/107025.html</link><dc:creator>antsoul</dc:creator><author>antsoul</author><pubDate>Wed, 28 Mar 2007 09:08:00 GMT</pubDate><guid>http://www.tkk7.com/antsoul/archive/2007/03/28/107025.html</guid><wfw:comment>http://www.tkk7.com/antsoul/comments/107025.html</wfw:comment><comments>http://www.tkk7.com/antsoul/archive/2007/03/28/107025.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/antsoul/comments/commentRss/107025.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/antsoul/services/trackbacks/107025.html</trackback:ping><description><![CDATA[ <p>作?banq<br />理解q用设计模?能够培养我们良好的面向对象编E习(fn)?同时在实际应用中,可以如鱼得水,享受游刃有余的乐?</p> <p>代理模式是比较有用途的一U模?而且变种较多,应用场合覆盖从小l构到整个系l的大结?Proxy是代理的意?我们也许有代理服务器{概?代理概念可以解释?在出发点到目的地之间有一道中间层,意ؓ(f)代理.</p> <p> <b>设计模式中定?/b>: 为其他对象提供一U代理以控制对这个对象的讉K.</p> <p> <b>Z么要使用Proxy?</b> <br />1.授权机制 不同U别的用户对同一对象拥有不同的访问权?如Jive论坛pȝ?׃用Proxyq行授权机制控制,讉K论坛有两Uh:注册用户和游?未注册用?,Jive中就通过cMForumProxyq样的代理来控制q两U用户对论坛的访问权?</p> <p>2.某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动.<br />举例两个具体情况: <br />(1)如果那个对象是一个是很大的图?需要花费很长时间才能显C出?那么当这个图片包含在文档中时,使用~辑器或览器打开q个文档,打开文档必须很迅?不能{待大图片处理完?q时需要做个图片Proxy来代替真正的囄.<br /><br />(2)如果那个对象在Internet的某个远端服务器?直接操作q个对象因ؓ(f)|络速度原因可能比较?那我们可以先用Proxy来代曉K个对?<br /></p> <p>M原则?对于开销很大的对?只有在用它时才创徏,q个原则可以为我们节省很多宝늚Java内存. 所?有些为Java耗费资源内存,我以和程序编制思\也有一定的关系.</p> <p> <b>如何使用Proxy?</b> <br />?a >Jive论坛pȝ</a>Z,讉K论坛pȝ的用h多种cd:注册普通用?论坛理?pȝ理?游客,注册普通用h能发a;论坛理者可以管理他被授权的论坛;pȝ理者可以管理所有事务等,q些权限划分和管理是使用Proxy完成?</p> <p>Forum是Jive的核心接?在Forum中陈列了有关论坛操作的主要行?如论坛名U?论坛描述的获取和修改,帖子发表删除~辑{?</p> <p>在ForumPermissions中定义了各种U别权限的用?</p> <table cellspacing="3" cellpadding="3" width="80%" border="0"> <tbody> <tr> <td bgcolor="#cccccc">public class ForumPermissions implements Cacheable { <p>/**<br />* Permission to read object.<br />*/<br />public static final int READ = 0;</p><p>/**<br />* Permission to administer the entire sytem.<br />*/<br />public static final int SYSTEM_ADMIN = 1;</p><p>/**<br />* Permission to administer a particular forum.<br />*/<br />public static final int FORUM_ADMIN = 2;</p><p>/**<br />* Permission to administer a particular user.<br />*/<br />public static final int USER_ADMIN = 3;</p><p>/**<br />* Permission to administer a particular group.<br />*/<br />public static final int GROUP_ADMIN = 4;</p><p>/**<br />* Permission to moderate threads.<br />*/<br />public static final int MODERATE_THREADS = 5;</p><p>/**<br />* Permission to create a new thread.<br />*/<br />public static final int CREATE_THREAD = 6;</p><p>/**<br />* Permission to create a new message.<br />*/<br />public static final int CREATE_MESSAGE = 7;</p><p>/**<br />* Permission to moderate messages.<br />*/<br />public static final int MODERATE_MESSAGES = 8;</p><p>.....</p><p>public boolean isSystemOrForumAdmin() {<br />  return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]);<br />}</p><p>.....</p><p>}</p></td> </tr> </tbody> </table> <p>因此,Forum中各U操作权限是和ForumPermissions定义的用L(fng)别有关系?作ؓ(f)接口Forum的实?ForumProxy正是这U对应关p联pv?比如,修改Forum的名U?只有论坛理者或pȝ理者可以修?代码如下:</p> <table cellspacing="3" cellpadding="3" width="80%" border="0"> <tbody> <tr> <td bgcolor="#cccccc"> <p>public class ForumProxy implements Forum {</p> <p>private ForumPermissions permissions;<br />private Forum forum; <br />this.authorization = authorization; <br /><br />public ForumProxy(Forum forum, Authorization authorization,<br />ForumPermissions permissions)<br />{<br />this.forum = forum;<br />this.authorization = authorization;<br />this.permissions = permissions;<br />}<br /><br />.....</p> <p>public void setName(String name) throws UnauthorizedException,<br />ForumAlreadyExistsException<br />{<br />  //只有是系l或论坛理者才可以修改名称<br />  if (permissions.isSystemOrForumAdmin()) {<br />    forum.setName(name);<br />  }<br />  else {<br />    throw new UnauthorizedException();<br />  }<br />}</p> <p>...</p> <p>}<br /></p> </td> </tr> </tbody> </table> <p>而DbForum才是接口Forum的真正实?以修改论坛名UCؓ(f)?</p> <table cellspacing="3" cellpadding="3" width="80%" border="0"> <tbody> <tr> <td bgcolor="#cccccc"> <p>public class DbForum implements Forum, Cacheable {<br />...</p> <p>public void setName(String name) throws ForumAlreadyExistsException {<br /><br />  ....<br /><br />  this.name = name;<br />  //q里真正新名称保存到数据库?<br />  saveToDb();</p> <p>  ....<br />}<br /></p> <p> <br />... </p> <p>}</p> </td> </tr> </tbody> </table> <p>凡是涉及(qing)到对论坛名称修改q一事g,其他E序都首先得和ForumProxy打交?由ForumProxy军_是否有权限做某一样事?ForumProxy是个名副其实?|关","安全代理pȝ".</p> <p>在^时应用中,无可避免总要涉及(qing)到系l的授权或安全体p?不管你有无意识的使用Proxy,实际你已l在使用Proxy?</p> <p>我们l箋l合Jive谈入׃?下面要涉?qing)到工厂模式?如果你不了解工厂模式,L(fng)我的另外一文?<a target="_blank">设计模式之Factory</a></p> <p>我们已经知道,使用Forum需要通过ForumProxy,Jive中创Z个Forum是用Factory模式,有一个ȝ抽象cForumFactory,在这个抽象类?调用ForumFactory是通过getInstance()Ҏ(gu)实现,q里使用了Singleton(也是设计模式之一,׃介绍文章很多,我就不写?<a target="_blank">看这?/a>),getInstance()q回的是ForumFactoryProxy.</p> <p>Z么不q回ForumFactory,而返回ForumFactory的实现ForumFactoryProxy?<br />原因是明昄,需要通过代理定是否有权限创建forum.</p> <p>在ForumFactoryProxy中我们看C码如?</p> <table cellspacing="3" cellpadding="3" width="98%" border="0"> <tbody> <tr> <td bgcolor="#cccccc">public class ForumFactoryProxy extends ForumFactory { <p>  protected ForumFactory factory;<br />  protected Authorization authorization;<br />  protected ForumPermissions permissions;</p><p>  public ForumFactoryProxy(Authorization authorization, ForumFactory factory,<br />  ForumPermissions permissions)<br />  {<br />    this.factory = factory;<br />    this.authorization = authorization;<br />    this.permissions = permissions;<br />  }</p><p>  public Forum createForum(String name, String description)<br />      throws UnauthorizedException, ForumAlreadyExistsException<br />  {<br />    //只有pȝ理者才可以创徏forum <br />    if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) {<br />      Forum newForum = factory.createForum(name, description);<br />      return new ForumProxy(newForum, authorization, permissions);<br />    }<br />    else {<br />      throw new UnauthorizedException();<br />  }<br />}<br /></p></td> </tr> </tbody> </table> <p>Ҏ(gu)createForumq回的也是ForumProxy, Proxyp一道墙,其他E序只能和Proxy交互操作.</p> <p>注意到这里有两个Proxy:ForumProxy和ForumFactoryProxy. 代表两个不同的职?使用Forum和创建Forum;<br />至于Z么将使用对象和创建对象分开,q也是ؓ(f)什么用Factory模式的原因所?是ؓ(f)?装" "分派";换句话说,可能功能单一?方便l护修改.</p> <p>Jive论坛pȝ中其他如帖子的创建和使用,都是按照Forumq个思\而来?</p> <p>以上我们讨论了如何用Proxyq行授权机制的访?Proxyq可以对用户隐藏另外一U称为copy-on-write的优化方?拯一个庞大而复杂的对象是一个开销很大的操?如果拯q程?没有对原来的对象有所修改,那么q样的拷贝开销没有必?用代理gq这一拯q程.</p> <p>比如:我们有一个很大的Collection,具体如hashtable,有很多客L(fng)?x)ƈ发同时访问?其中一个特别的客户端要q行q箋的数据获?此时要求其他客户端不能再向hashtable中增加或删除 东东.</p> <p>最直接的解x案是:使用collection的lock,让这特别的客L(fng)获得q个lock,q行q箋的数据获?然后再释放lock.<br />public void foFetches(Hashtable ht){<br />  synchronized(ht){<br />    //具体的连l数据获取动?. <br />  } </p> <p>}<br /></p> <p>但是q一办法可能锁住Collection?x)很长时?q段旉,其他客户端就不能讉K该Collection?</p> <p>W二个解x案是cloneq个Collection,然后让连l的数据获取针对clone出来的那个Collection操作.q个Ҏ(gu)前提?q个Collection是可clone?而且必须有提供深度clone的方?Hashtable提供了对自qcloneҎ(gu),但不是Key和value对象的clone,关于Clone含义可以参?a target="_blank">专门文章</a>.<br />public void foFetches(Hashtable ht){<br /></p> <p>  Hashttable newht=(Hashtable)ht.clone();</p> <p>}</p> <p>问题又来?׃是针对clone出来的对象操?如果原来的母体被其他客户端操作修改了, 那么对clone出来的对象操作就没有意义?</p> <p>最后解x?我们可以{其他客L(fng)修改完成后再q行clone,也就是说,q个特别的客L(fng)先通过调用一个叫clone的方法来q行一pd数据获取操作.但实际上没有真正的进行对象拷?直至有其他客L(fng)修改了这个对象Collection.</p> <p>使用Proxy实现q个Ҏ(gu).q就是copy-on-write操作.</p> <p>Proxy应用范围很广,现在行的分布计方式RMI和Corba{都是Proxy模式的应?</p> <p>更多Proxy应用,?a target="_blank">http://www.research.umbc.edu/~tarr/cs491/lectures/Proxy.pdf</a></p> <p>Sun公司?<a target="_blank">Explore the Dynamic Proxy API</a><a target="_blank">Dynamic Proxy Classes</a></p> <img src ="http://www.tkk7.com/antsoul/aggbug/107025.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/antsoul/" target="_blank">antsoul</a> 2007-03-28 17:08 <a href="http://www.tkk7.com/antsoul/archive/2007/03/28/107025.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式之Singleton(单?http://www.tkk7.com/antsoul/archive/2007/03/28/107024.htmlantsoulantsoulWed, 28 Mar 2007 09:06:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/28/107024.htmlhttp://www.tkk7.com/antsoul/comments/107024.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/28/107024.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/107024.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/107024.html 单态定?/strong>:
Singleton模式主要作用是保证在Java应用E序中,一个类Class只有一个实例存在?

在很多操作中Q比如徏立目?数据库连接都需要这L(fng)单线E操作?/p>

q有, singleton能够被状态化; q样Q多个单态类在一起就可以作ؓ(f)一个状态仓库一样向外提供服务,比如Q你要论坛中的帖子计数器Q每ơ浏览一ơ需要计敎ͼ单态类能否保持住这个计敎ͼq且能synchronize的安全自动加1Q如果你要把q个数字怹保存到数据库Q你可以在不修改单态接口的情况下方便的做到?/p>

另外斚wQSingleton也能够被无状态化。提供工h质的功能,

Singleton模式׃ؓ(f)我们提供了这样实现的可能。用Singleton的好处还在于可以节省内存Q因为它限制了实例的个数Q有利于Java垃圾回收Qgarbage collectionQ?br />
我们常常看到工厂模式中类装入?class loader)中也用Singleton模式实现?因ؓ(f)被装入的cd际也属于资源?br />

如何使用?
一般Singleton模式通常有几UŞ?

public class Singleton {

  private Singleton(){}

  //在自己内部定义自׃个实例,是不是很奇怪?
  //注意q是private 只供内部调用

  private static Singleton instance = new Singleton();

  //q里提供了一个供外部讉K本class的静态方法,可以直接讉K  
  public static Singleton getInstance() {
    return instance;   
   }
}

 

W二UŞ?

public class Singleton {

  private static Singleton instance = null;

  public static synchronized Singleton getInstance() {

  //q个Ҏ(gu)比上面有所改进Q不用每ơ都q行生成对象Q只是第一ơ     
  //使用时生成实例!
  if (instance==null)
    instanceQnew Singleton();
  return instance;   }

}

 

使用Singleton.getInstance()可以讉K单态类?/p>

上面W二中Ş式是lazy initializationQ也是说第一ơ调用时初始SingletonQ以后就不用再生成了?/p>

注意到l(f)azy initialization形式中的synchronizedQ这个synchronized很重要,如果没有synchronizedQ那么用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉?qing)double-checked locking (DCL)的讨论,有兴者进一步研I?/p>

一般认为第一UŞ式要更加安全些?br />

使用Singleton注意事项Q?br />有时在某些情况下Q用Singletonq不能达到Singleton的目的,如有多个Singleton对象同时被不同的c装入器装蝲Q在EJBq样的分布式pȝ中用也要注意这U情况,因ؓ(f)EJB是跨服务器,跨JVM的?/p>

我们以SUN公司的宠物店源码(Pet Store 1.3.1)的ServiceLocatorZE微分析一下:(x)

在Pet Store中ServiceLocator有两U,一个是EJB目录下;一个是WEB目录下,我们(g)查这两个ServiceLocator?x)发现内容差不多Q都是提供EJB的查询定位服务,可是Z么要分开呢?仔细研究对这两种ServiceLocator才发现区别:(x)在WEB中的ServiceLocator的采取Singleton模式QServiceLocator属于资源定位Q理所当然应该使用Singleton模式。但是在EJB中,Singleton模式已经失去作用Q所以ServiceLocator才分成两U,一U面向WEB服务的,一U是面向EJB服务的?/p>

Singleton模式看v来简单,使用Ҏ(gu)也很方便Q但是真正用好,是非怸Ҏ(gu)Q需要对Java的类 U程 内存{概忉|相当的了解?/p>

MQ如果你的应用基于容器,那么Singleton模式用或者不用,可以使用相关替代技术?/p>

antsoul 2007-03-28 17:06 发表评论
]]>
设计模式之Factoryhttp://www.tkk7.com/antsoul/archive/2007/03/28/107011.htmlantsoulantsoulWed, 28 Mar 2007 08:33:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/28/107011.htmlhttp://www.tkk7.com/antsoul/comments/107011.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/28/107011.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/107011.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/107011.html 厂模式定?span lang="EN-US">:提供创徏对象的接?

Z使用?
工厂模式是我们最常用的模式了,著名的Jive论坛 ,大量用了工厂模式Q工厂模式在JavaE序pȝ可以说是随处可见?/span>

Z么工厂模式是如此常用Q因为工厂模式就相当于创建实例对象的newQ我们经常要Ҏ(gu)cClass生成实例对象Q如A a=new A() 工厂模式也是用来创徏实例对象的,所以以后new时就要多个心|是否可以考虑实用工厂模式Q虽然这样做Q可能多做一些工作,但会(x)l你pȝ带来更大的可扩展性和量的修改量?/span>

我们以类SampleZQ?如果我们要创建Sample的实例对?

Sample sample=new Sample();

可是Q实际情冉|Q通常我们都要在创?span lang="EN-US">sample实例时做点初始化的工?比如赋?查询数据库等?/span>

首先Q我们想到的是,可以使用Sample的构造函敎ͼq样生成实例写?

Sample sample=new Sample(参数);

但是Q如果创?span lang="EN-US">sample实例时所做的初始化工作不是象赋DL(fng)单的事,可能是很长一D代码,如果也写入构造函CQ那你的代码很难看了Q就需要Refactor重整Q?/span>

Z么说代码很难看,初学者可能没有这U感觉,我们分析如下Q初始化工作如果是很长一D代码,说明要做的工作很多,很多工作装入一个方法中Q相当于很多鸡蛋放在一个篮子里Q是很危险的Q这也是有背?span lang="EN-US">Java面向对象的原则,面向对象的封?Encapsulation)和分z?Delegation)告诉我们Q尽量将长的代码分派“切剜y成每段Q将每段再“封装”v?减少D和D之间偶合联pL?Q这P׃(x)风险分散,以后如果需要修改,只要更改每段Q不?x)再发生牵一动百的事情?/span>

在本例中Q首先,我们需要将创徏实例的工作与使用实例的工作分开, 也就是说Q让创徏实例所需要的大量初始化工作从Sample的构造函C分离出去?/span>

q时我们需?span lang="EN-US">Factory工厂模式来生成对象了Q不能再用上面简单new Sample(参数)?/span>q有,如果Sample有个l承如MySample, 按照面向接口~程,我们需要将Sample抽象成一个接?现在Sample是接?有两个子cMySample 和HisSample .我们要实例化他们?如下:

Sample mysample=new MySample();
Sample hissample=new HisSample();

随着目的深?span lang="EN-US">,Sample可能q会(x)"生出很多儿子出来", 那么我们要对q些儿子一个个实例?更糟p的?可能q要对以前的代码q行修改:加入后来生出儿子的实?q在传统E序中是无法避免?

但如果你一开始就有意识用了工厂模式,q些ȝ(ch)没有了.

工厂Ҏ(gu)
你会(x)建立一个专门生?span lang="EN-US">Sample实例的工?

public class Factory{

  public static Sample creator(int which){

  //getClass 产生Sample 一般可使用动态类装蝲装入cR?br />  if (which==1)
    return new SampleA();
  else if (which==2)
    return new SampleB();

  }

}

那么在你的程序中,如果要实例化Sample?׃?/span>

Sample sampleA=Factory.creator(1);

q样,在整个就不涉?qing)到Sample的具体子c?辑ֈ装效果,也就减少错误修改的机?q个原理可以用很通俗的话来比?是具体事情做得多,容易范错误.q每个做q具体工作的人都深有体会(x),相反,官做得越?说出的话抽象越W统,范错误可能性就少.好象我们从编E序中也能?zhn)Zh生道?呵呵.

使用工厂Ҏ(gu) 要注意几个角Ԍ首先你要定义产品接口Q如上面的Sample,产品接口下有Sample接口的实现类,如SampleA,其次要有一个factoryc,用来生成产品SampleQ如下图Q最双是生产的对象SampleQ?/p>

q一步稍微复杂一点,是在工厂类上进行拓展,工厂cM有承它的实现类concreteFactory?b>?/i>

抽象工厂
工厂模式中有: 工厂Ҏ(gu)(Factory Method) 抽象工厂(Abstract Factory).

q两个模式区别在于需要创建对象的复杂E度上。如果我们创建对象的Ҏ(gu)变得复杂?如上面工厂方法中是创Z个对象Sample,如果我们q有新的产品接口Sample2.

q里假设QSample有两个concretecSampleA和SamleBQ而Sample2也有两个concretecSample2A和SampleB2

那么Q我们就上例中Factory变成抽象c?共同部分封装在抽象cM,不同部分使用子类实现Q下面就是将上例中的Factory拓展成抽象工?

public abstract class Factory{

  public abstract Sample creator();

  public abstract Sample2 creator(String name);

}

public class SimpleFactory extends Factory{

  public Sample creator(){
    .........
    return new SampleA

  }

  public Sample2 creator(String name){
    .........
    return new Sample2A

  }

}

public class BombFactory extends Factory{

  public Sample creator(){
    ......
    return new SampleB

  }

  public Sample2 creator(String name){
    ......
    return new Sample2B
  }

}

 

从上面看C个工厂各自生产出一套Sample和Sample2,也许你会(x)疑问Qؓ(f)什么我不可以用两个工厂方法来分别生Sample和Sample2?

抽象工厂q有另外一个关键要点,是因?SimpleFactory内,生Sample和生产Sample2的方法之间有一定联p,所以才要将q两个方法捆l在一个类中,q个工厂cL其本w特征,也许刉过E是l一的,比如Q制造工艺比较简单,所以名U叫SimpleFactory?/span>

在实际应用中Q工厂方法用得比较多一些,而且是和动态类装入器组合在一起应用,

举例

我们?span lang="EN-US">Jive的ForumFactoryZQ这个例子在前面的Singleton模式中我们讨Q现在再讨论其工厂模?

public abstract class ForumFactory {

  private static Object initLock = new Object();
  private static String className = "com.jivesoftware.forum.database.DbForumFactory";
  private static ForumFactory factory = null;

  public static ForumFactory getInstance(Authorization authorization) {
    //If no valid authorization passed in, return null.
    if (authorization == null) {
      return null;
    }
    //以下使用了Singleton 单态模?br />    if (factory == null) {
      synchronized(initLock) {
        if (factory == null) {
            ......

          try {
              //动态{载类
              Class c = Class.forName(className);
              factory = (ForumFactory)c.newInstance();
          }
          catch (Exception e) {
              return null;
          }
        }
      }
    }

    //Now, q回 proxy.用来限制授权对forum的访?br />    return new ForumFactoryProxy(authorization, factory,
                    factory.getPermissions(authorization));
  }

  //真正创徏forum的方法由l承forumfactory的子cd完成.
  public abstract Forum createForum(String name, String description)
  throws UnauthorizedException, ForumAlreadyExistsException;

  ....

}

 

 

因ؓ(f)现在?span lang="EN-US">Jive是通过数据库系l存放论坛帖子等内容数据,如果希望更改为通过文gpȝ实现,q个工厂Ҏ(gu)ForumFactory提供了提供动态接?

private static String className = "com.jivesoftware.forum.database.DbForumFactory";

你可以用自己开发的创徏forum的方法代替com.jivesoftware.forum.database.DbForumFactory可?

在上面的一D代码中一q了三U模?span lang="EN-US">,除了工厂模式?q有Singleton单态模?以及(qing)proxy模式,proxy模式主要用来授权用户对forum的访?因ؓ(f)讉Kforum有两Uh:一个是注册用户 一个是游客guest,那么那么相应的权限就不一?而且q个权限是诏I整个系l的,因此建立一个proxy,cM|关的概?可以很好的达到这个效?  

看看Java宠物店中的CatalogDAOFactory:

public class CatalogDAOFactory {

  /**

  * 本方法制定一个特别的子类来实现DAO模式?br />  * 具体子类定义是在J2EE的部|描q器中?br />  */

  public static CatalogDAO getDAO() throws CatalogDAOSysException {

    CatalogDAO catDao = null;

    try {

      InitialContext ic = new InitialContext();
      //动态装入CATALOG_DAO_CLASS
      //可以定义自己的CATALOG_DAO_CLASSQ从而在无需变更太多代码
      //的前提下Q完成系l的巨大变更?/p>

      String className =(String) ic.lookup(JNDINames.CATALOG_DAO_CLASS);

      catDao = (CatalogDAO) Class.forName(className).newInstance();

    } catch (NamingException ne) {

      throw new CatalogDAOSysException("
        CatalogDAOFactory.getDAO: NamingException while
          getting DAO type : \n" + ne.getMessage());

    } catch (Exception se) {

      throw new CatalogDAOSysException("
        CatalogDAOFactory.getDAO: Exception while getting
          DAO type : \n" + se.getMessage());

    }

    return catDao;

  }

}


CatalogDAOFactory是典型的工厂Ҏ(gu)QcatDao是通过动态类装入器className获得CatalogDAOFactory具体实现子类Q这个实现子cdJava宠物店是用来操作catalog数据库,用户可以Ҏ(gu)数据库的cd不同Q定制自q具体实现子类Q将自己的子cdl与CATALOG_DAO_CLASS变量可以?/span>

由此可见Q工厂方法确实ؓ(f)pȝl构提供了非常灵zd大的动态扩展机Ӟ只要我们更换一下具体的工厂Ҏ(gu)Q系l其他地Ҏ(gu)需一点变换,有可能系l功能进行改头换面的变化?/p>

antsoul 2007-03-28 16:33 发表评论
]]>初学者如何开发出一个高质量的J2EEpȝ【{?/title><link>http://www.tkk7.com/antsoul/archive/2007/03/28/107007.html</link><dc:creator>antsoul</dc:creator><author>antsoul</author><pubDate>Wed, 28 Mar 2007 08:30:00 GMT</pubDate><guid>http://www.tkk7.com/antsoul/archive/2007/03/28/107007.html</guid><wfw:comment>http://www.tkk7.com/antsoul/comments/107007.html</wfw:comment><comments>http://www.tkk7.com/antsoul/archive/2007/03/28/107007.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/antsoul/comments/commentRss/107007.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/antsoul/services/trackbacks/107007.html</trackback:ping><description><![CDATA[        J2EE学习(fn)者越来越多,J2EE本n技术不断在发展Q涌现出各种概念Q本文章试图从一U容易理解的角度对这些概念向初学者进行解释,以便掌握学习(fn)J2EE学习(fn)方向? <p>  首先我们需要知道Java和J2EE是两个不同概念,Java不只是指一U语aQ已l代表与微Y不同的另外一个巨大阵营,所以Java有时是指一UY件系l的派Q当然目前主要是.NET和Java两大L体系?/p><p>  J2EE可以说指Java在数据库信息pȝ上实玎ͼ数据库信息系l从早期的dBase、到Delphi/VB{C/Sl构Q发展到B/SQBrowser览?Server服务器)(j)l构Q而J2EE主要是指B/Sl构的实现?/p><p>  J2EE又是一U框架和标准Q框架类似API、库的概念,但是要超出它们。如果需要详l了解框Ӟ可先从设计模式开始学?fn)?/p><p>  J2EE是一个虚的大的概念,J2EE标准主要有三U子技术标准:(x)WEB技术、EJB技术和JMSQ谈到J2EE应该说最l要落实到这三个子概念上?/p><p>  q三U技术的每个技术在应用旉涉及(qing)两个部分Q容器部分和应用部分QW(xu)eb容器也是指Jsp/Servlet容器Q你如果要开发一个Web应用Q无论是~译或运行,都必要有Jsp/Servlet库或API支持Q除了JDK/J2SE以外Q?/p><p>  Web技术中除了Jsp/Servlet技术外Q还需要JavaBeans或Java Class实现一些功能或者包装携带数据,所以Web技术最初裸体简UCؓ(f)Jsp/Servlet+JavaBeanspȝ?/p><p>  谈到JavaBeans技术,涉?qing)到lg构g技术(componentQ,q是Java的核心基部分Q很多Y件设计概念(设计模式Q都是通过JavaBeans实现的?/p><p>  JavaBeans不属于J2EE概念范畴中,如果一个JavaBeans对象被Web技术(也就是Jsp/ServletQ调用,那么JavaBeansp行在J2EE的Web容器中;如果它被EJB调用Q它?yu)p行在EJB容器中?/p><p>  EJBQ企业JavaBeansQ是普通JavaBeans的一U提升和规范Q因Z业信息系l开发中需要一个可伸羃的性能和事务、安全机Ӟq样能保证企业系l^滑发展,而不是发展到一U规模重新更换一套Y件系l?/p><p>  xQJavaBeanslg发展到EJB后,q不是说以前的那UJavaBeans形式消׃Q这p然Ş成了两种JavaBeans技术:(x)EJB和POJOQPOJO完全不同于EJB概念Q指的是普通JavaBeansQ而且q个JavaBeans不依附某U框Ӟ或者干脆可以说Q这个JavaBeans是你个应用程序单独开发创建的?/p><p>  J2EE应用pȝ开发工h很多Q如JBuilder、Eclipse{,q些IDE首先是Java开发工P也就是说Q它们首要基本功能是可以开发出JavaBeans或Java classQ但是如果要开发出J2EEpȝQ就要落实到要么是Web技术或EJB技术,那么有可能要一些专门模块功?如eclipse需要lomboz插g)Q最重要的是Q因为J2EEpȝ区分为容器和应用两个部分Q所以,在Q何开发工具中开发J2EE都需要指定J2EE容器?/p><p>  J2EE容器分ؓ(f)WEB容器和EJB容器QTomcat/Resin是Web容器QJBoss是EJB容器+Web容器{,其中Web容器直接使用Tomcat实现的。所以你开发的Web应用E序可以在上面两U容器运行,而你开发的Web+EJB应用则只可以在JBoss服务器上q行Q商业品Websphere/Weblogic{和JBoss属于同一U性质?/p><p>  J2EE容器也称为J2EE服务器,大部分时它们概念是一致的?/p><p>  如果你的J2EE应用pȝ的数据库q接是通过JNDI获得Q也是说是从容器中获得Q那么你的J2EE应用pȝ基本与数据库无关Q如果你在你的J2EE应用pȝ耦合了数据库JDBC驱动的配|,那么你的J2EE应用pȝ有数据库概念色彩,作ؓ(f)一个成熟需要推q的J2EE应用pȝQ不推荐和具体数据库耦合Q当然这其中如何保证J2EE应用pȝq行性能又是体现你的设计水^了?/p><p>  衡量J2EE应用pȝ设计开发水q高低的标准是Q解耦性;你的应用pȝ各个功能是否能够dqQ是否不怺依赖Q也只有q样Q才能体现可l护性、可拓展性的软g设计目标?/p><p>  Z辑ֈq个目的Q诞生各U框架概念,J2EE框架标准一个系l划分ؓ(f)WEB和EJB主要部分Q当然我们有时不是以q个具体技术区分,而是从设计上抽象现层、服务层和持久层Q这三个层次从一个高度将J2EE分离开来,实现解耦目的?/p><p>  因此Q我们实际编E中Q也要将自己的功能向q三个层ơ上靠,做到大方向清楚,泾渭分明Q但是没有技术上U束限制要做到这Ҏ(gu)很不Ҏ(gu)的,因此我们q是必须借助J2EE具体技术来实现Q这Ӟ你可以用EJB规范实现服务层和持久层,W(xu)eb技术实现表现层Q?/p><p>  EJBZ么能服务层从Jsp/Servlet手中分离出来Q因为它对JavaBeans~码有强制的U束Q现在有一U对JavaBeansq束,使用Ioc模式实现的(当然EJB 3.0也采取这U方式)(j)Q在Ioc模式诞生前,一般都是通过工厂模式来对JavaBeansU束QŞ成一个服务层Q这也是是Jiveq样开源论坛设计原理之一?/p><p>  由此Q将服务层从表现层中分离出来目前有两U可选架构选择Q管理普通JavaBeansQPOJOQ框?如Spring?a target="_blank">JdonFramework</a>)以及(qing)理EJB的EJB框架Q因为EJB不只是框Ӟq是标准Q而标准可以扩展发展,所以,q两U区别将来是可能模糊Q被U_同一个标准了。 但是Q个为:(x)标准制定是ؓ(f)某个目的服务的,总要牺牲一些换取另外一些,所以,q两U架构会(x)长时间ƈ存?/p><p>  q两U架构分歧也曄诞生一个新名词Q完全POJO的系l也UCؓ(f)轻量U系l?lightweight)Q其实这个名词本w就没有一个严格定义,更多是一个吸引h的招牌,轻量是指Ҏ(gu)学习(fn)Ҏ(gu)使用吗?按照q个定义Q其实轻量Spring{系lƈ不容易学?fn);而且EJB 3.0Q依然叫EJBQ以后的pȝ是否可称量了呢Q?/p><p>  前面谈了服务层框Ӟ使用服务层框架可以将JavaBeans从Jsp/Servlet中分d来,而用表现层框架则可以将Jsp中剩余的JavaBeans完全分离Q这部分JavaBeans主要负责昄相关Q一般是通过标签库(taglibQ实玎ͼ不同框架有不同自q标签库,Struts是应用比较广泛的一U表现层框架?/p><p>  q样Q表现层和服务层的分L通过两种框架辑ֈ目的Q剩余的是持久层框架了Q通过持久层的框架数据库存储从服务层中分d来是其目的,持久层框架有两种方向Q直接自q写JDBC{SQL语句Q如iBatisQ;使用O/R Mapping技术实现的Hibernate和JDO技术;当然q有EJB中的实体Bean技术?/p><p>  持久层框架目前呈现百花齐放,各有优缺点的现状Q所以正如表现层框架一P目前没有一个框架被指定为标准框Ӟ当然Q表现层框架现在又出来了一个JSFQ它代表的页面组件概忉|一个新的发展方向,但是复杂的实现让人有些忘而却步?/p><p>  在所有这些J2EE技术中Q虽然SUN公司发挥了很大的作用Q不qM来说Q网l上有这样一个评P(x)SUN的理论天下无敌;SUN的品用h撞墙Q对于初学者,特别是那些试N过或已l通过SUN认证的初学者,赶快摆脱SUN的阴影,立即开溜,使用开源领域的产品来实现自q应用pȝ?/p><p>  最后,你的J2EE应用pȝ如果采取上面提到的表现层、服务层和持久层的框架实玎ͼ基本你也可以在无需深刻掌握设计模式的情况下开发出一个高质量的应用系l了?/p><p>  q要注意的是: 开发出一个高质量的J2EEpȝq需要正的业务需求理解,那么域徏模提供了一U比较切实可行的正确理解业务需求的Ҏ(gu)Q相兌l知识可从UML角度l合理解?/p><p>  当然Q如果你惌计自q行业框架Q那么第一步从设计模式开始吧Q因计模式提供你一个实现JavaBeans或类之间解耦参考实现方法,当你学会(x)了系l基本单元JavaBean或类之间解耦时Q那么系l模块之间的解耦你可能掌握,q而你可以实现行业框架的提炼了,q又是另外一个发展方向了?/p><p>  以上理念可以ȝZ句话Q?br />J2EE开发三件宝: Domain ModelQ域建模Q、patternsQ模式)(j)和frameworkQ框Ӟ(j)?/p><img src ="http://www.tkk7.com/antsoul/aggbug/107007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/antsoul/" target="_blank">antsoul</a> 2007-03-28 16:30 <a href="http://www.tkk7.com/antsoul/archive/2007/03/28/107007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Liskov Substitution Principlehttp://www.tkk7.com/antsoul/archive/2007/03/25/106252.htmlantsoulantsoulSun, 25 Mar 2007 09:39:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/25/106252.htmlhttp://www.tkk7.com/antsoul/comments/106252.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/25/106252.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/106252.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/106252.htmlLSPQ如果对每一个类型ؓ(f)T1的对象的O1Q都有类型ؓ(f)T2的对象O2Q得以T1定义的所有的E序P在所有对象O1都代换ؓ(f)O2ӞE序P没有发生变化Q那么类型T2是类型T1的子cd。换aQ一个Y件实体如果用的是一个基cȝ话,那么一定适合与其子类Q而且它根本不能察觉出基类对象与子cd戏的区别?/font>
eg:
假设有两个类Q一个是Basec,一个是Subc,q且SubcLBasecȝ子类。那么有一个方法如果可以接受基cd象b的话Qmethod(Base b),那么它必然也可以接受一个子cd象sQ也xQmethod(Sub s);LSP是承复用的基石Q只有当衍生cd以替换掉基类QY件单位的功能?x)收到?jing)响时Q基cL能真正被复用Q而衍生类也能够在基类的基上增加新的功能。LSP反之׃成立了?/font>

antsoul 2007-03-25 17:39 发表评论
]]>
OCPhttp://www.tkk7.com/antsoul/archive/2007/03/25/106249.htmlantsoulantsoulSun, 25 Mar 2007 09:26:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/25/106249.htmlhttp://www.tkk7.com/antsoul/comments/106249.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/25/106249.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/106249.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/106249.htmll典力学的奠基石是牛的三大定律。而OOD的奠基石是OCP。OCP是Bertrand Meyer提出? Software entities should be open for extension , but close for modifaction 。在设计一个模块的时候;应当使这个模块可以在不被修改的前提下被扩展。换aQ应当不必修Ҏ(gu)代码的情况下Q改变这个模块的行ؓ(f)?/font>

antsoul 2007-03-25 17:26 发表评论
]]>
你还在用if else吗?【{?/title><link>http://www.tkk7.com/antsoul/archive/2007/03/17/104436.html</link><dc:creator>antsoul</dc:creator><author>antsoul</author><pubDate>Sat, 17 Mar 2007 05:29:00 GMT</pubDate><guid>http://www.tkk7.com/antsoul/archive/2007/03/17/104436.html</guid><wfw:comment>http://www.tkk7.com/antsoul/comments/104436.html</wfw:comment><comments>http://www.tkk7.com/antsoul/archive/2007/03/17/104436.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/antsoul/comments/commentRss/104436.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/antsoul/services/trackbacks/104436.html</trackback:ping><description><![CDATA[ <font size="2">本帖转自 </font> <a > <font size="2">板桥里h</font> </a> <font size="2">  2006.1.11  文章 <<你还在用if else吗?>><br /><br />面向q程设计和面向对象设计的主要区别是:(x)是否在业务逻辑层用冗长的if else判断。如果你q在大量使用if elseQ当?dng)界面表现层除外,即你用Java/C#q样完全面向对象的语aQ也只能说明你的思维停留在传l的面向q程语言上?/font> <p> <strong> <font size="2">传统思维?fn)惯分?/font> </strong> </p> <p> <font size="2">  Z么会(x)业务逻辑层用if elseQ其实用者的目的也是Z重用Q但是这是面向过E编E的重用Q程序员只看C码重用,因ؓ(f)他看到if else几种情况下大部分代码都是重复的,只有个别不同Q因此用if else可以避免重复代码Qƈ且认是模板Template模式?/font> </p> <p> <font size="2">  他范的错误是Q程序员只从代码q行序q个方向来看待它的代码,q种思维cM水管或串行电(sh)路,水沿着水管动Q代码运行次序)(j)Q当遇到几个分管Q子)(j)Q就分到q几个分子在流动,q里q当于到代码的if else处了?/font> </p> <p> <font size="2">  而用OOQ则首先打破q个代码׃向下序{同于运行时的先后@序这个规律,代码l构不由执行循序军_Q由什么决定呢Q由O(jin)O设计Q设计模式会(x)取代q些if elseQ但是最后L׃个Service{ȝ按照q行序l装q些OO模块Q只有一处,q处可包含事务,一般就是ServiceQEJB中是Session bean?/font> </p> <p> <font size="2">  一旦需求变化,我们更多的可能是Service中各个OO模块Q甚x只改动Service中的OO模块执行序pW合需求?/font> </p> <p> <font size="2">  q里我们也看到OO分离的思\Q将以前q程语言的一个Main函数d分解Q将q行序与代码其他逻辑分离开来,而不是象面向q程那样混ؕ在一赗所以有人感慨,OO也是要顺序的Q这是肯定的Q关键是q行序要单独分d来?/font> </p> <p> <font size="2">  是否有if else可以看出你有没有运行顺序分d家?/font> </p> <p> <strong> <font size="2">设计模式的切入口</font> </strong> </p> <p> <font size="2">  l常有h反映Q设计模式是不错Q但是我很难用到Q其实如果你使用if else来写代码Ӟ除显C控制以外)(j)Q就是在写业务逻辑Q只不过使用单的判断语句来作为现实情늚替代者?/font> </p> <p> <font size="2">   q是以大家熟(zhn)的论坛帖子Z子,如ForumMessage是一个模型,但是实际中帖子分两种性质Q主题脓(chung)Q第一个根_(d)(j)和回帖(回以前帖子的帖子Q,q里有一个朴素的解决Ҏ(gu)Q?br />建立一个ForumMessageQ然后在ForumMessage加入isTopicq样判断语句Q注意,你这里一个简单属性的判断引入Q可能导致你的程序其他地方到处存在if else 的判断?/font> </p> <p> <font size="2">  如果我们改用另外一U分析实现思\Q以对象化概늜待,实际中有主题贴和回帖Q就是两U对象,但是q两U对象大部分是一致的Q因此,我将ForumMessage设ؓ(f)表达主题_(d)然后创徏一个承ForumMessage的子cForumMessageReply作ؓ(f)回帖Q这P我在E序地方Q如Service中,我已l确定这个Model是回帖了Q我q接下溯ؓ(f)ForumMessageReply卛_Q这个有点类似向Collection攑օ对象和取出时的强制类型{换。通过q个手段我消灭了以后E序中if else的判断语句出现可能?/font> </p> <p> <font size="2">  从这里体CQ如果分析方向错误,也会(x)D误用模式?/font> </p> <p> <font size="2">  讨论设计模式举例Q不能没有业务上下文场景的案例,否则无法军_是否该用模式Q下面D两个Ҏ(gu)的例子:(x)</font> </p> <p> <font size="2">  W一.</font> <a target="_blank"> <font size="2"> q个帖子</font> </a> <font size="2">中D例的W一个代码案例是没有上下文的Q文中只说明有一D代码:(x)</font> </p> <table cellspacing="1" cellpadding="1" width="100%" bgcolor="#cccccc" border="0"> <tbody> <tr> <td> <font size="2">main() { </font> <p> <font size="2">ifQcase AQ{ </font> </p> <p> <font size="2">//do with strategy A </font> </p> <p> <font size="2">}else(case B){</font> </p> <p> <font size="2">//do with strategy B </font> </p> <p> <font size="2">}else(case C){ </font> </p> <p> <font size="2">//do with strategy C </font> </p> <p> <font size="2">}</font> </p> <p> <font size="2">} </font> </p> </td> <td> <font size="2"> </font> </td> </tr> </tbody> </table> <p> <font size="2">  q段代码只是Ua(b)的代码,没有业务功能Q所以,在这U情况下Q我们就很难定使用什么模式,是一定用{略模式{,也逃不q还是用if else的命q,设计模式不是法Q不能将一D|无意义的代码变得单了Q只能将其体现的业务功能更加Ҏ(gu)可拓展了?/font> </p> <p> <font size="2">  W二.?/font> <a target="_blank"> <font size="2">q个帖子</font> </a> <font size="2">中,作者D了一个PacketParser业务案例Q这D代码是体现业务功能的,是一个数据包的分析,作者也比较了各U模式用的不同Q所以我们还是用动态代理模式或Command模式来消灭那些可能存在的if else</font> </p> <p> <font size="2">  ׃上两个案例表明:(x)业务逻辑是我们用设计模式的切入点,而在分解业务逻辑Ӟ我们?fn)惯则可能用if else来实玎ͼ当你有这U企图或者已l实C码了Q那么就应该考虑是否需要重构Refactoring了?br /></font> </p> <p> <strong> <font size="2">if else替代?/font> </strong> </p> <p> <font size="2">  那么实战中,哪些设计模式可以替代if else呢?其实GoF设计模式都可以用来替代if elseQ我们分别描q如下:(x)</font> </p> <li> <font size="2">状态模式 <br />  当数据对象存在各U可能性的状态,而且q种状态将?x)?jing)响到不同业务l果Ӟ那么我们应该考虑是否使用状态模式,当然Q用状态模式之前,你必首先有内存状态这个概念,而不是数据库概念Q因为在传统的面向过E的/面向数据库的pȝ中,你很隑֏现状态的Q从数据库中d某个|然后Ҏ(gu)q个D行代码运行分,q是很多初学者常q的事情。参考文?</font> <a target="_blank"> <font size="2">状态对象:(x)数据库的替代?/font> </a> <br /> <font size="2">  使用传统语言思维的情况还有:(x)使用一个类整数变量标识状态:(x)<br /></font> <table cellspacing="1" cellpadding="1" width="100%" bgcolor="#cccccc" border="0"> <tbody> <tr> <td> <p> <font size="2"> </font> </p> <p> <font size="2">public class Order{</font> </p> <p> <font size="2">private int status;</font> </p> <p> <font size="2">//说明Q?</font> </p> <p> <font size="2">//status=1 表示订货但ؓ(f)查看 Q?/font> </p> <p> <font size="2">//status=2 表示已经查看未处理;</font> </p> <p> <font size="2">//status=3 表示已经处理未付?gu)?/font> </p> <p> <font size="2">//status=4 表示已经付款未发?/font> </p> <p> <font size="2">//status=5 表示已经发货</font> </p> <p> <font size="2">} </font> </p> </td> </tr> </tbody> </table> <br /> <font size="2">  上述c设计,无疑是将cMZl语a的函数来使用Q这样导致程序代码中存在大量的if else?br /><br /></font> </li> <li> <font size="2">{略模式 <br />  当你面(f)几种法或者公式选择Ӟ可以考虑{略模式Q传l过E语a情况是:(x)从数据库中读取算法数|数?表示{略1Q例如保存到数据库;数gؓ(f)2表示{略2Q例如保存到XMl文g中。这里用if else作ؓ(f){略选择的开兟?<br /><br /></font> </li> <li> <font size="2">command模式 <br />  传统q程的思维情况是:(x)如果客户端发Zh1?A"Q那么我调用A.javaq个对象来处理;如果代号??B"Q我p用B.java来处理,通过if else来判断客L(fng)发送过来的代码Q然后按事先U定的对应表Q调用相应的cL处理?br /><br /></font> </li> <li> <font size="2">MVC模式 <br />  MVC模式的传l语a误用和Command模式cMQ在一个ActioncMQ用if elseq行前后台调度,如果客户端传送什么命令;我就调用后台什么结果;如果后台处理什么结构,再决定推什么页面,不过Q现在我们用Struts/JSFq样MVC模式的框架实现者就不必范这U低U错误?br /><br /></font> </li> <li> <font size="2">职责链模式 <br />  职责链模式和Command模式是可选的Q如果你实在不知道客L(fng)?x)发Z么代P也没有一个事先定义好的对照表Q那么你只能~写一个个cd运气一h开q个包看一下就可以。与Command是不同在</font> <a target="_blank"> <font size="2">AOP vs Decorator</font> </a> <font size="2">一文中有分析?br /><br /></font> </li> <li> <font size="2">代理或动态代理模式 <br />  代理对象可以是符合某U条件的代表者,比如Q权限检验,传统面向q程思维是:(x)当一个用L(fng)陆后Q访问某资源Ӟ使用if elseq行判断Q只有某U条件符合时Q才能允许访问,q样权限判断和业务数据逻辑混ؕ在一P使用代理模式可以清晰分离Q如果嫌不太好,使用动态代理,或者下面AOP{方式?br /><br /></font> </li> <li> <font size="2">AOP或Decorator模式<br />  <br />  其实使用filterqo(h)器也可以替代我们业务中的if elseQ过滤器起到一U过滤和{选作用,符合本qo(h)器条件的对象拦截下来做某件事情,q就是一个过滤器的功能,多个qo(h)器组合在一起实际就是if else的组合?br />  所以,如果你实在想不出什么办法,可以使用qo(h)器,过滤器看成防火墙就比较好理解,当客L(fng)有一个请求时Q经q不同性质的防火墙Q这个防火墙是拦截端口的Q那个防火墙是安全检查拦截等{。过滤器也如同红蓝白各种光o(h)镜;U色滤镜只能通过光线中的U色拦截了;蓝色滤镜光U中的蓝色拦截下来,q实际上是对光线使用if elseq行分解?br /><br /><img height="182" src="http://www.jdon.com/artichect/images/ifelse.gif" width="285" /><br />  如图Q通过一个个条gqo(h)器我们立体地实现了对信号的分,如果你用if elseQ说明你是将图中的条?/2/3/4合ƈ在一P在同一个地方实现条件判断?br />  需要深入了解过滤器的实现细节和微小区别Q请参考文章:(x)</font> <a target="_blank"> <font size="2">AOP vs Decorator</font> </a> <br /> <p> <font size="2"> <strong>OO设计的ȝ</strong>   </font> </p> <p> <font size="2">  q有一U伪模式Q虽然用了状态等模式Q但是在模式内部实质q是使用if else或switchq行状态切换或重要条g判断Q那么无疑说明还需要进一步努力。更重要的是Q不能以模式自居Q而且ZCZh?/font> </p> <p> <font size="2">  真正掌握面向对象q些思想是一件困隄事情Q目前有各种属于揪着自己头发向上拔的解说Q都是误人子弟的Q所以我觉得初学者读Thinking in JavaQJava~程思想Q是没有用,它试图从语言层次来讲OO~程思想Q非常失败,作ؓ(f)语言参考书可以Q但是作为Java体现的OO思想的学?fn)资料,错了?/font> </p> <p> <font size="2">  OO~程思想是一U方法论Q方法论如果没有应用比较Q是无法体会(x)q个Ҏ(gu)论的特点的,是古代一个方法论Q?zhn)是靠挑水砍柴这些应用才能体会(x)?/font> </p> <p> <font size="2">  那么OO思想靠什么应用能够体?x)到了?是GoF设计模式QGoF设计模式是等于Y件h员的挑水砍柴{基本活Q所以,如果一个程序员q基本活都不?x),他何以自居OOE序员?从事OO专业设计~程q个工作Q如果不掌握设计模式基本功,p一个做和尚的h不愿意挑水砍_(d)他何以立个行业?早就被师傅赶下山?/font> </p> <p> <font size="2">  最后ȝQ将if else用在地方还可以Q如单的数值判断;但是如果按照你的传统?fn)惯思维Q在实现业务功能时也使用if elseQ那么说明你的思维可能需要重塑,你的~程l验丰富,传统q程思维模式容易根p固,想靠自己改变很困难;接受</font> <a target="_blank"> <font size="2">专业头脑风暴培训</font> </a> <font size="2">?/font> </p> <p> <font size="2">  用一句话ȝQ如果你做了不少pȝQ很久没有用if else了,那么说明你可能真正进入OO设计的境C。(q是本h自己发明的实战性的衡量考核标准Q?/font> </p> </li> <img src ="http://www.tkk7.com/antsoul/aggbug/104436.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/antsoul/" target="_blank">antsoul</a> 2007-03-17 13:29 <a href="http://www.tkk7.com/antsoul/archive/2007/03/17/104436.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么是OO思想?http://www.tkk7.com/antsoul/archive/2007/03/17/104433.htmlantsoulantsoulSat, 17 Mar 2007 05:17:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/17/104433.htmlhttp://www.tkk7.com/antsoul/comments/104433.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/17/104433.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/104433.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/104433.html看见人家在谈OO思想Q我很惶恐,也很qhQ到底什么是地OO思想Q怎么来培养自qOO思想呢?
OO思想a之,我们谈的 想的 ~的 做的 都是围绕一个个对象。怎么来培养自qOO思想呢?


antsoul 2007-03-17 13:17 发表评论
]]>一个有意思的面试?/title><link>http://www.tkk7.com/antsoul/archive/2007/03/17/104431.html</link><dc:creator>antsoul</dc:creator><author>antsoul</author><pubDate>Sat, 17 Mar 2007 05:06:00 GMT</pubDate><guid>http://www.tkk7.com/antsoul/archive/2007/03/17/104431.html</guid><wfw:comment>http://www.tkk7.com/antsoul/comments/104431.html</wfw:comment><comments>http://www.tkk7.com/antsoul/archive/2007/03/17/104431.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/antsoul/comments/commentRss/104431.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/antsoul/services/trackbacks/104431.html</trackback:ping><description><![CDATA[l定一个非负整数n,L(fng)JAVA写一个程序打印其对应的二q制倹{例?n=25 其对应的二进制ؓ(f): 11001<img src ="http://www.tkk7.com/antsoul/aggbug/104431.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/antsoul/" target="_blank">antsoul</a> 2007-03-17 13:06 <a href="http://www.tkk7.com/antsoul/archive/2007/03/17/104431.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一道面试题?/title><link>http://www.tkk7.com/antsoul/archive/2007/03/17/104419.html</link><dc:creator>antsoul</dc:creator><author>antsoul</author><pubDate>Sat, 17 Mar 2007 04:19:00 GMT</pubDate><guid>http://www.tkk7.com/antsoul/archive/2007/03/17/104419.html</guid><wfw:comment>http://www.tkk7.com/antsoul/comments/104419.html</wfw:comment><comments>http://www.tkk7.com/antsoul/archive/2007/03/17/104419.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/antsoul/comments/commentRss/104419.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/antsoul/services/trackbacks/104419.html</trackback:ping><description><![CDATA[ <span id="6111166" class="tpc_content">一个整敎ͼ大于0Q不用@环和本地变量Q按照nQ?nQ?nQ?n的顺序递增Q当值大?000Ӟ把值按照指定顺序输出来?br />例:(x)n=1237<br />则输Zؓ(f)Q?br />1237Q?br />2474Q?br />4948Q?br />9896Q?br />9896Q?br />4948Q?br />2474Q?br />1237Q?br /></span> <img src ="http://www.tkk7.com/antsoul/aggbug/104419.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/antsoul/" target="_blank">antsoul</a> 2007-03-17 12:19 <a href="http://www.tkk7.com/antsoul/archive/2007/03/17/104419.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>致面向对象技术初学者的一公开信【{?/title><link>http://www.tkk7.com/antsoul/archive/2007/03/17/104418.html</link><dc:creator>antsoul</dc:creator><author>antsoul</author><pubDate>Sat, 17 Mar 2007 04:01:00 GMT</pubDate><guid>http://www.tkk7.com/antsoul/archive/2007/03/17/104418.html</guid><wfw:comment>http://www.tkk7.com/antsoul/comments/104418.html</wfw:comment><comments>http://www.tkk7.com/antsoul/archive/2007/03/17/104418.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/antsoul/comments/commentRss/104418.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/antsoul/services/trackbacks/104418.html</trackback:ping><description><![CDATA[ <font size="2">致面向对象技术初学者的一公开?<br />Alistair Cockburn 著(1996 q? 月)(j)Q袁??<br /><br />介绍 <br /> 首先我要解释一下ؓ(f)什么会(x)写这公开信。这g已经成了一U习(fn)惯,但这个步骤还是需要的。过? q中Q?我曾l无数次地在饭店、酒吧、旅店大厅等各种地方以同一U方式度q愉快而O长的夜晚Q和同样q求真理、光明和智慧的伙伴一h讨面向对象的真谛。现在,我已l可以回{很多当q我遇到的问题。这些同L(fng)问题也在困扰着我的一位新同事Q在一安店里Q我׃整整一个晚上和他讨些问题。结果第二天Q他的同事又来问q些问题Qƈ把我们的谈话内容记录下来Q这样他可以拿去l他的同事看。考虑到还有很多和他的同事一栯问这些同样问题的人,我决定写下这文章?<br />主要的问题是Q?<br />z Z么只要稍有一点不是严格或U面向对象的做法、说法,OO 专家大惊小怪的Quse case q不是面向对象的Qؓ(f)什么还q么行Q而且QOO 建模g和数据徏模非常相| <br />z 数据建模Qdata modelQ得到的模型和对象模型的l构部分?x)不会(x)很像?程建模Qprocess modelQ和对象模型的行为部分呢Q?<br />z 业务l构建模中ؓ(f)什么要用use case 和场景(scenarioQ? <br />OO 的新手们反复问这些问题,但实际上Q只有在日常工作中坚持应用面向对象的思维q行工作Q积累一定的l验Q才能得到满意的{案。ؓ(f)什么只要稍有一点不是严格或U面向对象的做法、说法,OO 专家大惊小怪的Quse case q不是面向对象的Qؓ(f)什么还q么行Q而且QOO 建模g和数据徏模非常相| <br />我想分三步来回答q个问题?<br /><br />首先Q我举我和BobQ著名的OO 专家Q一起工作的例子Q?当我们讨论OO 的时候,彼此都有一个共识,知道Ҏ(gu)拥有面向对象工作的丰富经验ƈ且是q项技术的坚定支持者。而且Q对诸如对象识别Qobject identityQ、多态、数据和行ؓ(f)的封装、实例职责、承等对象技术都是手到擒来。因此,当我_(d)(x)“明天对E序表单q行数据建模吧”,Bob 不会(x)产生我要?x)因为关p表而放弃对象这L(fng)误解Q他知道我指的是在对象模型中体现出来的结构化Ҏ(gu)进行徏模。他知道我会(x)说些什么,因此我用或误用q些术语不会(x)造成什么误解。但作ؓ(f)一个对象技术的初学者,如果Bob 发现你把数据和行为完全分d了, q且没有使用Q?或者说忽视了)(j)对象识别或者多态等技术, q时候, 如果你说?数据建模”,Bob ?x)像一堵墙一样D你,直到你明白该怎样改变。这样工作几个月Q你?x)发玎ͼ你的模型Q以?qing)徏模?j)中渐渐有了对象识别、多态、数据和行ؓ(f)的绑定,q时候再用?数据建模”这个词׃是那么危险了Q?但Bob q可能会(x)担心你走回到老\上。换句话_(d) 他对你还不够信QQ?因此Q你不得不很心C用这些术语?<br />q一个对象模型可以分为“结构”和“行为”特性,我们也不?x)用“对象徏模”和“流E徏模?q种术语Q以免引h؜淆。事实上Qؓ(f)对象模型的“结构”特性徏模可以看成是数据建模的特DŞ式,只不q徏模的对象不再是表Q而是需要捕L(fng)信息的结构。我们将它称为?概念数据模型”,而不是逻辑数据模型或物理数据模型。第二步Q让我们考虑两个OO 使用者一赯论的情况。如果其中一个家伙说到“流E徏模”这L(fng)词,肯定?x)让他的拍档琢磨半天Q这家伙是说用标准数据流图作程建模吗?如果q样的话Q以后OO 实现的时候不是相当麻?ch)了吗?他是不是指模型的行?f)Ҏ(gu)?是不是说在一个对象内部对程q行建模Q(如果q样的话Q那?x)很有意思,因ؓ(f)很少有hq么做的。)(j) 通过q个例子我们可以看到Q这U谈话中使用?程建模?q种意图不明的词实在是太危险了,很容易就交变得非常困难?<br />最后来说use case 和场景的问题Q它们都是获取需求的主要手段Q和实现技术无兟뀂其好处是可以ؓ(f)设计时的讨论提供内容和范围。它们不是“面向对象”的Q这是事实,它们cM于功能分解,q也是事实,而且q一点吓坏了很多人,但这些都无所谓。重要的是它们ؓ(f)设计提供了内容,在用来描q内部设计时Q它们表Cpȝ的行为。Flow chart 、交互图、Petri |、数据流图、use case 都可以用来描q系l的行ؓ(f)Ҏ(gu), 但各自用途不同,各有优劣。关键是要知道:(x)对象不仅有数据,也有行ؓ(f)Q?认识到这一点, 可以大胆地去考虑怎样可以更好地捕捉、描q对象内部和对象之间的行为?<br />数据建模Qdata model Q得到的模型和对象模型的l构部分?x)不会(x)很像?程建模Qprocess modelQ?和对象模型的行ؓ(f)部分呢?Ҏ(gu)我的l验Q数据徏模h员可以分ZU-一U是为存储的数据建模Q而另一U是为系l或l织中的信息建模。这两者截然不同。前者讨论和思考所用的概念通常都很具体Q比如说数据表。他们的模型和OO 建模者的模型大相径庭Q而且他们q不愿意看到q些技术之间的怼性。在数据建模C֌中,只有讨论逻辑数据模型或物理数据模型才不会(x)受到d后者得到的是概忉|据模型。根据我的经验,他们得到的模型和那些有经验的OO 建模者得到的模型非常怼。他们的工作更加cM于业务h员,而不是逻辑数据建模人员Q这U说法可能会(x)有助于理解概忉|据模型和逻辑数据模型的区别?<br />g有一套学问可以帮助h们比OO 建模人员更快地得到结果。我多次发现q样的事实:(x)OO 建模人员׃三四ơP代才得到的模型,实际上和Q概念)(j)数据建模人员一个@环得到的模型是一L(fng)。这个发C我对数据建模人员充满了敬佩。事实上Q在q行对象设计的时候,我有时就直接L数据建模人员的品拷贝过来看看, 从中来看我最后得到的模型大概?x)是什么样的?<br />我曾l召开q数据徏模h员和对象建模人员之间的会(x)议。采取的Ҏ(gu)是?一个听众的CRC ?x)议QCRC sessions for an audienceQ。四个经验丰富的OO 设计师坐在长桌一端,业务专家沿着长桌坐下Q他们负责回{问题ƈU正对业务的误解。接着是数据徏模h员,长桌的另一头是其它有关人员。ȝ来说Q屋里大概是十几个hQ但谈话主要是在四个OO 设计师之间进行?<br />讨论大概一个小时之后,OO 设计师可以得到对象设计的一部分。这时候,咨询数据建模人员Q这个模型和他们已经得到的模型本质上是不是一L(fng)。他们说Q“是的”,重复q个q程两次以上Q每ơ都询问数据建模人员同样的问题,除了使用的符h术是不同的,例如Q他们没有用l承Q但在同L(fng)地方有同L(fng)占位W,在本质上Q这个模型和他们的模型没有什么不同的。接着Q我们分成几个小l,每个组包括一个业务专家、一个数据徏模专家和一个OO 专家Q很快就剩下的设计达成一_(d)扑և技术上一些小的不同之处,q且q行排序。一般情况都是这L(fng)Q要么数据徏模h员考虑得更加合理,要么OO 建模人员考虑得更加合理,组要做的是在他们的设计之间q行协调?<br />从上面的q些l验可以看到Q用CRC q行OO 建模得到的模型和概念数据建模得到的结果非常相伹{另外,Ҏ(gu)l验Q基于逻辑Q存储的信息Q的关系建模和OO 建模是不同的。大多数情况下,区别是由于技术的不同D的,例如Q在OO 模型中可以自由地使用l承和多对多的关pR由于技术上的差异,两种建模人员之间不能很好C,q是最大的困难?<br />数据建模部分的问题就说这么多吧?<br /></font> <img src ="http://www.tkk7.com/antsoul/aggbug/104418.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/antsoul/" target="_blank">antsoul</a> 2007-03-17 12:01 <a href="http://www.tkk7.com/antsoul/archive/2007/03/17/104418.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>I?标识)接口的重要性【{?http://www.tkk7.com/antsoul/archive/2007/03/15/104067.htmlantsoulantsoulThu, 15 Mar 2007 10:06:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/15/104067.htmlhttp://www.tkk7.com/antsoul/comments/104067.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/15/104067.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/104067.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/104067.htmlq是昨天我跟天意在一ơ闲聊中一ơ有L(fng)讨论Q标{接口真有那么重要吗Q比如说很多初学者认为java.io.Serializableq样的接口,很多时候可用可不用Q不用一栯执行对象pd化功能?br />

  为此Q我们通过一个通俗而有的CZQ这个示例是设计一个猎人,其持有一把智能猎枪,q就是说q把猎枪?x)自动识别hc,若发现瞄准的目标是hc,׃?x)开火,而其它的M事物都通杀?br />  为此Q我们用了下面三个接口Q?br />   一个用来表CZ事万物的SomeThing
    
  public interface SomeThing {}  

  人类的接口:(x)
  public interface Humans extends SomeThing {}

   动物的接口:(x)
public interface Animals extends SomeThing {}

然后是一pd的实玎ͼ(x)
   中国人:(x)     
public class Chinese implements Humans {}

   日本人:(x)
public class Japanese {}

   狗:(x)
public class Dog implements Animals {}

妖?他很聪明,l自己帖上了人的标签)Q?br />public class Monster implements Humans {}

下面q个E序的核心部分, 猎hcd(qing)客户端程序:(x)
public class Hunter {
public void fire(Object target)
{
 if(target instanceof Humans)
 {
  System.out.println("q下完了Q打中了一个hQ该d牢了Q?);
 }
 else
 {
  System.out.println("恭喜你,打中了一只动?");
 }
}
//的枪
public void intelligentFire(Object target)
{
 if(target instanceof Humans)
 {
  return;
 }
 System.out.println("开了一?"+target.getClass());
 //下面q行U杀{相兛_?br /> //销毁他
 target=null;
}
public static void main(String[] args) {
Hunter hunter=new Hunter();
Object[] objects=new Object[]{new Dog(),new Japanese(),new Japanese(),new Chinese(),new Monster(),new SomeThing(){}};
for(int i=0;i<objects.length;i++)
 hunter.intelligentFire(objects[i]);
}
}

 q行E序Q你?x)发现输出类g面结果:(x)

开了一?class springroad.demo.taginterface.Dog
开了一?class springroad.demo.taginterface.Japanese
开了一?class springroad.demo.taginterface.Japanese
开了一?class springroad.demo.taginterface.Hunter$1

  由此可见Q智能猎枪瞄?个目标,开?枪。只对Chinese、及(qing)Monster的实例没有开枪。因里讨论的是标{接口,虽然Humans没有MҎ(gu)Q但从智能猎枪的角度来看Q他是通过q个标签来判断是否可以开火的?/font> 他不用管也管不了目标的层ơ等U关p(比如Japanese肯定很非帔R明等U结?Q即l承关系。他也管不了目标的来自于哪儿。比如,是用new操作W创建,q是从容器中取,或者是从网l某个地方加载一个?br />   Hunter只是制订了一个简单的规则Q你要想不让我的枪对你开火,你就必须在自pn上帖上一个Humans的标{。也是说你必须遵守q个规则?br />  现在回过头来看,因ؓ(f)妖怪Monster真n应该是一条蛇或其它什么动物,但是他懂得Hunter制订的规则,于在巧妙的给自己帖上了一个Humans的标{,以致于欺骗了我们的智能猎枪?br />  而Japanese则自认ؓ(f)自己了不P不按规则办事Q我׃理你Hunter制订的规则,什么Humans标签Q我是不用。于是放到我们的E序中当然就只有挨杀的䆾了?/font>

  由此可见Q空接口(标签接口)的重要性,在像本例中,l不l自己帖不标{,q是一个性命莜关的问题。其实在OO的世界中Q空接口可以是最高的层像?/strong>



antsoul 2007-03-15 18:06 发表评论
]]>
Java SE 5.0新特性之一【静态导入?/title><link>http://www.tkk7.com/antsoul/archive/2007/03/12/103405.html</link><dc:creator>antsoul</dc:creator><author>antsoul</author><pubDate>Mon, 12 Mar 2007 14:18:00 GMT</pubDate><guid>http://www.tkk7.com/antsoul/archive/2007/03/12/103405.html</guid><wfw:comment>http://www.tkk7.com/antsoul/comments/103405.html</wfw:comment><comments>http://www.tkk7.com/antsoul/archive/2007/03/12/103405.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/antsoul/comments/commentRss/103405.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/antsoul/services/trackbacks/103405.html</trackback:ping><description><![CDATA[ <font size="2">        最qJDK变化的速度真快Q刚用上JDK1.4Q马上就跛_Java SE5.0Q这不刚用上5.0马上又出?.0了,6.0暂时是用不上了,5.0较之前的版本有了新的变化Q搞不好{到中国奥运的时候SUNZ表示贺也搞个JAVA SE8Q呵呵,玩笑Q?先把5.0的新变化了解了再说吧Q?br />        5.0较之前的版本新增加了6个新的特性。包括范型,自动装箱Q类型安全枚丄。今天想学习(fn)其中之一的静态导入吧Q静态导入得开发h员可以将一套静态方法和域放入作用域。它是关于调用的一U羃写,可以忽略有效的类名。比如说Math.abs(x)可以写成abs(x).Z静态的导入所有的静态域和方法,可以使用"import static java.lang.Math"?br /><br /><br />比如说打C句话,原始的写?<br />System.out.println("this words is what i want to say!");<br />你导入静态包后可以这样写:<br />out.println("haha,i can do it like this!");<br /><br /></font> <img src ="http://www.tkk7.com/antsoul/aggbug/103405.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/antsoul/" target="_blank">antsoul</a> 2007-03-12 22:18 <a href="http://www.tkk7.com/antsoul/archive/2007/03/12/103405.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Objects Clonehttp://www.tkk7.com/antsoul/archive/2007/03/12/103331.htmlantsoulantsoulMon, 12 Mar 2007 07:30:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/12/103331.htmlhttp://www.tkk7.com/antsoul/comments/103331.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/12/103331.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/103331.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/103331.html    有的时候我们ؓ(f)了获取对象的一份copyQ可以利用ObjectcȝcloneҎ(gu)来实玎ͼ要想实现克隆Q我们必dzcM实现Cloneable interfaceq覆盖基cȝclone()Ҏ(gu)Qƈ扩大讉K权限为public,在派生类的clone()Ҏ(gu)Q调用super.clone()?br />
 demo:
class StringTest
{
 public static void main(String[] args)
 {
  Professior p = new Professior("wangwu",50);
  Student s1 = new Student("zhangsan",18,p);
  Student s2 = (Student)s1.clone();
  s2.p.name = "lisi";
  s2.p.age = 20;
  
  System.out.println("s1.p.name="+s1.p.name+","+"s1.p.age="+s1.p.age);
 }
}

class Student implements Cloneable
{
  Professior p;
  String name;
  int age;
 
 public Student(String name,int age,Professior p)
 {
  this.name =name;
  this.age = age;
  this.p = p;
 }
 
 public Object clone()
 {
  Object o = null;
  try
  {
   o=super.clone();
  }
  catch(CloneNotSupportedException e)
  {
   System.out.println(e.toString());
  }
  return o;
 }
 
 public String toString()
 {
  return "name="+name+","+"age="+age;
 }
}

class Professior
{
 String name;
 int age;
 public Professior(String name,int age)
 {
  this.name = name;
  this.age = age;
 }
}

Result:
D:\jcode>java StringTest
s1.p.name=lisi,s1.p.age=20
通过l果看得Z个问题,当我们修改s2的Professior后,s1对象的Professior对象的D修改了。不是有clone?份copy吗?那怎么修改S1的值却影响了S2的gQ那是因为我们克隆的时候只是把Professior的引用复制了一份,而ƈ没有实际在内存中l它分配C块内存,所以我们clone的时候,其实是把同一个值给复制?ơ,所以s1和s2操作的professior都是同一个对象,所以修改S1Q必然就影响了S2的professior的|那我们的本意q如此Q有没有办法解决呢?{案是肯定的。其实我们刚才所做的操作是一个浅克隆Q当我们克隆的对象是引用cd的时候,可以用深克隆来实现。就如下面的Demo.
class CloneTest
{
 public static void main(String[] args)
 {
  Boss boss = new Boss("antsoul",25);
  Leader leader = new Leader("linda",30);
  Employee ep1 = new Employee("zhangsan",107,leader,boss);
    Employee ep2 = (Employee)ep1.clone();
    ep2.boss.name = "gll";
    ep2.boss.age = 60;
    System.out.println("ep1.leader.name="+ep1.boss.name);
    System.out.println("ep1.leader.age="+ep1.boss.age);
 } 
}

class Employee implements Cloneable
{
 String name;
 int eid;
 Leader leader;
 Boss boss;
 
 Employee(String name,int eid,Leader leader,Boss boss)
 {
  this.name = name;
  this.eid = eid;
  this.leader = leader;
  this.boss = boss;
 }
 
 public Object clone()
 {
  Employee o = null;
  try
  {
   o = (Employee)super.clone();
  }
  catch(CloneNotSupportedException e)
  {
   System.out.println(e.toString());
  }
  o.leader = (Leader)leader.clone();
  o.boss = (Boss)boss.clone();
  return o;
 }
}

class Leader implements Cloneable
{
 String name;
 int age;
 
 Leader(String name,int age)
 {
  this.name = name;
  this.age = age;
 }
 
 public Object clone()
 {
  Object o = null;
  try
  {
   o = super.clone();
  }
  catch(CloneNotSupportedException e)
  {
   System.out.println(e.toString());
  }
  return o;
 }
}

class Boss implements Cloneable
{
 String name;
 int age;
 
 Boss(String name,int age)
 {
  this.name = name;
  this.age = age;
 }
 
 public Object clone()
 {
  Object o = null;
  try
  {
   o = super.clone();
  }
  catch(CloneNotSupportedException e)
  {
   System.out.println(e.getMessage());
  }
  return o;
 }
}

q里有个疑问了,Z么我们要在派生类中over writte Object的clone()Ҏ(gu)Ӟ一定要调用super.clone()?
原因? 在运行时刻,Object中的clone()识别Z要clone的是哪一个对象,然后为此对象分配内存I间Qƈq行对象的复Ӟ原始对象的内容一一复制到新的对象空间中厅R?/font>



antsoul 2007-03-12 15:30 发表评论
]]>
集合框架学习(fn)(?http://www.tkk7.com/antsoul/archive/2007/03/10/103015.htmlantsoulantsoulSat, 10 Mar 2007 10:02:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/10/103015.htmlhttp://www.tkk7.com/antsoul/comments/103015.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/10/103015.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/103015.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/103015.html?TreeSet (实现了SortedSet接口的类)
1.  TreeSet是依靠TreeMap来实现的?br />2.  TreeSet是一个有序集?TreeSet中的元素按照升序排列Q缺省是按照自然排序Q一位着TreeSet要实现Comparable接口?br />3.  可以在构造TreeSet对象Ӟ传递实CComparable接口的比较器对象?br />demo

import java.util.*;

class TreeSetTest
{
 public static void main(String[] args){
   TreeSet ts = new TreeSet();
  
   ts.add(new Student("one",1));
   ts.add(new Student("two",4));
   ts.add(new Student("three",3));
  
   Iterator it = ts.iterator();
   while(it.hasNext()){
    System.out.println(it.next());
  }
 }
}

class Student implements Comparable
{
 private String name;
 private int num;
 
 //Z调用方便声明为static
 static class StudentComparator implements Comparator
 {
   public int compare(Object o1,Object o2){
    Student s1 =(Student)o1;
    Student s2 =(Student)o2;
    int result;
   
    result = s1.num > s2.num ? 1 :(s1.num==s2.num ? 0 : -1);
    if(result == 0){ //student的num相同Q比较name,因ؓ(f)name为StringcdQ它实现了Comparable<String>
      result = s1.name.compareTo(s2.name);
    }
    return result;
   } 
 }
 
 public Student(String name,int num){
  this.name = name;
  this.num = num;
 }
 
 public int compareTo(Object o){
  Student s =(Student)o;
  return num > s.num ? 1 : (num == s.num ? 0 : -1);
 }
 
 public String toString(){
  return "num="+num+" "+"name="+name;
 }
}



antsoul 2007-03-10 18:02 发表评论
]]>
集合框架学习(fn)Q二Q?/title><link>http://www.tkk7.com/antsoul/archive/2007/03/10/103011.html</link><dc:creator>antsoul</dc:creator><author>antsoul</author><pubDate>Sat, 10 Mar 2007 09:35:00 GMT</pubDate><guid>http://www.tkk7.com/antsoul/archive/2007/03/10/103011.html</guid><wfw:comment>http://www.tkk7.com/antsoul/comments/103011.html</wfw:comment><comments>http://www.tkk7.com/antsoul/archive/2007/03/10/103011.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/antsoul/comments/commentRss/103011.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/antsoul/services/trackbacks/103011.html</trackback:ping><description><![CDATA[ <p> LinkedList<br /><font size="2">1)  LinkedList是采用双向@环链表来实现的?br />2)  利用LinkedList实现Stack,queen,double-ended queen?br /><br /></font><font size="3"> 数据l构<br /></font><font size="2"> 一般将数据l构分ؓ(f)Z大类Q线性数据结构,非线性数据结构。线性数据结构有U性表Q栈Q队列,Ԍ数组和文Ӟ非线性数据结构有?wi)和图?br />1) U性表<br />a. U性表的逻辑l构是n个数据元素的有序队列:<br />     (a1,a2,a3,a4......an)<br />n为线性表的长?n>>0), n=0 的表UCؓ(f)I?br />b. 数据元素呈线性关pR必存在唯一的称为“第一个”的数据元素Q必存在唯一的称为“最后一个”的数据元素Q除W一个 ?元素外,每个元素都有且只有一个前驱元素;除最后一个元素外Q其它的每个元素都有且只有一个后l元素?br />c. 所有数据元素在同一个线性表中必L相同的数据类型?br />d. U性表按其存储l构可分为顺序表和链表。用序存储l构存储的线性表UCؓ(f)<strong><em>序?/em></strong>Q用铑ּl构存储的线性表UCؓ(f)<strong><em>链表</em></strong>?br />e. 线性表中的数据元素依次存放在某个存储区域中,所形成的表UCؓ(f)U性表。一l数l就是顺序方式存储的U性表?br /><br />2) Stack<br />a.  Stack也是一U特D的U性表,是一U后q先?LIFO)的结构?br />b.  Stack是限定在表尾q行插入和删除的U性表Q表为栈?top),表头UCؓ(f)栈底(bottom)?br />c.  Stack的物理存储可以顺序存储结构,也可以用铑ּ存储l构?卻I(x)可以用数l或链表实现) <br />actualize Stack:<br />import java.util.*;<br />class MyStack<br />{<br /> private LinkedList ll = new LinkedList();<br /> //要实现LIFO<br /> public void push(Object o){<br />  ll.addFirst(o);<br /> }<br /> public Object pop(){<br />  //出栈<br />  return ll.removeFirst();<br /> }<br /> public Object peek(){<br />  //查看栈顶元素Q但是不U走<br />  return ll.getFirst();<br /> }<br /> public boolean empty(){<br />  //判断是否为空<br />  return ll.isEmpty();<br /> }<br /> <br /> public static void main(String[] args){<br />  MyStack ms = new MyStack();<br />  ms.push("one");<br />  ms.push("two");<br />  ms.push("three");<br />  ms.push("four");<br />  <br />  System.out.println(ms.pop());<br />  System.out.println(ms.peek());<br />  System.out.println(ms.empty());<br /> }<br />}<br /><br />3) Queen<br />a.  queen是限定所有的插入只能在表的一端进行,而所有的删除在表的另一端进行的U性表?br />b.  queen中允许插入的一端称为队?Rear)Q允许删除的一端称为队?Front)?br />c.   queen的操作是按先q先?FIFO)的原则进行的?br />d.   queen的物理存储可以用序存储l构Q也可以用链式存储结构?br /><br />actualize Stack:<br />import java.util.*;</font></p> <p> <font size="2">class MyQueen<br />{<br />   private LinkedList aa = new LinkedList();<br />   public void put(Object o){<br />      //d元素<br />      aa.addLast(o);<br />   }<br />   <br />   public Object get(){<br />      //获得元素<br />      return aa.removeFirst();<br />   }<br />   <br />   public boolean empty(){<br />     return aa.isEmpty();<br />   }<br />   <br />   public static void main(String[] args){<br />      MyQueen mq = new MyQueen();<br />      mq.put("one");<br />      mq.put("two");<br />      mq.put("three");<br />      <br />      System.out.println(mq.get());<br />      System.out.println(mq.empty());<br />   }<br />}<br /><br />] ArrayList ?LinkedList<br />a. ArrayList底层采用数组完成Q而LinkedList则是以一般的双向链表(double-linked list)完成Q其内每个对象,除了数据本n外,q有两个引用Q分别指向前一个元素和后一个元素?br />b. 如果我们l常在List的开始处增加元素,或则在List中进行插入和删除操作Q我们应该用LinkedListQ否则的话,使用ArrayList则更快?br /><br /><br /><font size="3"> HashSet<br /></font>1.   实现Set接口的hash table,依靠HashMap来实现?br />2.   应该为存攑ֈ散列表中的各个对象定义hashCode()和equals()?br />3.   散列表又U哈希表。散列表法的基本思想:<br />以节点的关键字ؓ(f)自变量,通过一定的函数关系(散列函数)计算出对应的函数|以这个g节点存储在散列表中的地址?br />4.   当散列表中元素存攑֤满,必d散列Q将产生一个新的散列表,所有元素存攑ֈ新的散列表中,原先的散列表被删除。Jaav语言中,通过负蝲因子(load factor)来决定何时对散列表再q行散列。例如:(x)如果负蝲因子?.75,当散列表中有75%被存满,进行再散列?br />5.   负蝲因子高(?.0近)Q内存的使用效率高,元素的寻找时间越ѝ负载因子越?接q?.0),元素的寻找时间越短,内存?gu)费多?br />6.   HashSet的缺省因子是0.75?br /><br />HashSet demo:<br />import java.util.*;</font> </p> <p> <font size="2">class HashSetTest<br />{<br /> public static void main(String[] args){<br />  HashSet hs = new HashSet();<br />   <br />  hs.add(new Student("zhangsan",1));<br />  hs.add(new Student("lisi",2));<br />  hs.add(new Student("wangwu",3));<br />  hs.add(new Student("zhangsan",1));<br />  <br />  Iterator it = hs.iterator();<br />  while(it.hasNext()){<br />   System.out.println(it.next());<br />  }<br /> }<br />}</font> </p> <p> <font size="2">class Student<br />{<br />  String name;<br />  int num;<br /> <br /> public Student(String name,int num){<br />  this.name = name;<br />  this.num = num;<br /> }<br /> <br /> public int hashCode(){<br />  return num * name.hashCode();<br /> }<br /> <br /> public boolean equals(Object o){<br />  Student s =(Student)o;<br />  return num==s.num && name.equals(s.name);<br /> }<br /> <br /> public String toString(){<br />  return num+":"+name;<br /> }<br />}</font> </p> <img src ="http://www.tkk7.com/antsoul/aggbug/103011.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/antsoul/" target="_blank">antsoul</a> 2007-03-10 17:35 <a href="http://www.tkk7.com/antsoul/archive/2007/03/10/103011.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>集合框架的学?一)http://www.tkk7.com/antsoul/archive/2007/03/10/102982.htmlantsoulantsoulSat, 10 Mar 2007 05:03:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/10/102982.htmlhttp://www.tkk7.com/antsoul/comments/102982.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/10/102982.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/102982.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/102982.html 所谓框架就是一个类库的集合。集合框架就是一个用来表C和操作集合的同意架构,包含了实现集合的接口和类。Java中的集合框架l构囑֦?

        Collection (i)               Map(i)
            /     \                              |
          /         \                            |
       Set(i)   List(i)               SortedMap(i)
        /
    SortedSet(i)
区别:
Collection: 集合层次中的Ҏ(gu)口?br />Set: 不能包含重复的element。SortedSet按照升序排列elements的Set?br />List: 有序(不是排序Q而是指elements按照一定的序排列)Q可以包含重复elementQ提供了索引讉K的方式?br />
△ArrayList
1)  ArrayList 我们可以看作是一个可以自动增长的数组Q这是和数组的不同之处?br />2)  利用ArrayList的toArray()Ҏ(gu)q回一个对象数l?br />3)  Arrays的asList()q回一个列表?? q回固定寸的列表。asList()q回的列表不支持remove()Ҏ(gu)?br />4)  q代?Iterator)提供了一l访问集合的通用Ҏ(gu)?hasNext(),  next(),   remove(),调用remove()Ҏ(gu)之前必须臛_调用一ơnext().
5)  cCollections与ArraysQ前者对列表排序Q后者对数组排序?br /> * 当我们在打印一个集合类的对象的时候,它会(x)调用集合cM的toString()Ҏ(gu)Q所以我们自定义的类必重写toString()Ҏ(gu).
 * List stooges = Arrays.asList("Larry", "Moe", "Curly");
 * public static void printElements(Collecion c){
        Iterator it = c.iterator();
         while(it.hasNext()){
             System.out.println(it.next());
         }
    }

 
   ?Collections
   1) 排序Collections.sort()
        a. 自然排序(natural ordering);
        b. 实现比较?Comparator)接口.
   2)  取最大最element: Collections.max();  Collections.min();
   3)  在已l排序的List中搜索指定的element:  Collections.binarySerach()?br />

   ?一般方法实?br />   import java.util.*;

class ArrayListTest
{
 public static void printElements(Collection c){
  Iterator it = c.iterator();
  while(it.hasNext()){
   System.out.println(it.next());
  }
 }
 
 public static void main(String[] args){
   Student s1 = new Student("antsoul",25);
   Student s2 = new Student("feiyang",35);
   Student s3 = new Student("gll",24);
   Student s4 = new Student("andylau",40);
  
   ArrayList al = new ArrayList();
   al.add(s1);
   al.add(s2);
   al.add(s3);
   al.add(s4);
  
   Collections.sort(al);
   printElements(al);
 }
}

class Point
{
 int x,y;
 public Point(int x,int y){
  this.x = x;
  this.y = y;
 }
 
 public String toString(){
  return ("x="+x+","+"y="+y);
 }
}

class Student implements Comparable
{
 private String name;
 private int num;
 
 public Student(String name,int num){
  this.name = name;
  this.num = num;
 }
 
 public int compareTo(Object o){
  Student s =(Student)o;
  return num > s.num ? 1 : (num == s.num ? 0 : -1);
 }
 
 public String toString(){
  return "num:"+num+" "+"name:"+name;
 }
}    

   ?比较器L和特定的cȝ关的Q具体到某一个类。比如说对student排序Q你要用到学P所以排序前必须要{换Object为Student,也就是ؓ(f)某一个类指定一个比较器Q可以写一个类d现比较器的接口,但是Z联系紧密Q可以在q里用内部类在实现比机器接口?br />import java.util.*;

class ArrayListTest
{
 public static void printElements(Collection c){
  Iterator it = c.iterator();
  while(it.hasNext()){
   System.out.println(it.next());
  }
 }
 
 public static void main(String[] args){
   Student s1 = new Student("antsoul",2);
   Student s2 = new Student("feiyang",1);
   Student s3 = new Student("gll",3);
   Student s4 = new Student("andylau",4);
  
   ArrayList al = new ArrayList();
   al.add(s1);
   al.add(s2);
   al.add(s3);
   al.add(s4);
  
   Collections.sort(al,new Student.StudentComparator()); //student提供自己的比较器
   printElements(al);
 }
}

class Point
{
 int x,y;
 public Point(int x,int y){
  this.x = x;
  this.y = y;
 }
 
 public String toString(){
  return ("x="+x+","+"y="+y);
 }
}

class Student implements Comparable
{
 private String name;
 private int num;
 
 //Z调用方便声明为static
 static class StudentComparator implements Comparator
 {
   public int compare(Object o1,Object o2){
    Student s1 =(Student)o1;
    Student s2 =(Student)o2;
   
    return s1.num > s2.num ? 1 :(s1.num==s2.num ? 0 : -1);
   } 
 }
 
 public Student(String name,int num){
  this.name = name;
  this.num = num;
 }
 
 public int compareTo(Object o){
  Student s =(Student)o;
  return num > s.num ? 1 : (num == s.num ? 0 : -1);
 }
 
 public String toString(){
  return "num:"+num+" "+"name:"+name;
 }
}

如果student的num相等的情况下Q要以name来排序可以这样实?
import java.util.*;

class ArrayListTest
{
 public static void printElements(Collection c){
  Iterator it = c.iterator();
  while(it.hasNext()){
   System.out.println(it.next());
  }
 }
 
 public static void main(String[] args){
   Student s1 = new Student("antsoul",2);
   Student s2 = new Student("feiyang",1);
   Student s3 = new Student("dorydoo",3);
   Student s4 = new Student("sun",4);
   Student s5 = new Student("gll",4);
  
   ArrayList al = new ArrayList();
   al.add(s1);
   al.add(s2);
   al.add(s3);
   al.add(s4);
   al.add(s5);
  
   Collections.sort(al,new Student.StudentComparator()); //student提供自己的比较器
   printElements(al);
 }
}

class Point
{
 int x,y;
 public Point(int x,int y){
  this.x = x;
  this.y = y;
 }
 
 public String toString(){
  return ("x="+x+","+"y="+y);
 }
}

class Student implements Comparable
{
 private String name;
 private int num;
 
 //Z调用方便声明为static
 static class StudentComparator implements Comparator
 {
   public int compare(Object o1,Object o2){
    Student s1 =(Student)o1;
    Student s2 =(Student)o2;
    int result;
   
    result = s1.num > s2.num ? 1 :(s1.num==s2.num ? 0 : -1);
    if(result == 0){ //student的num相同Q比较name,因ؓ(f)name为StringcdQ它实现了Comparable<String>
      result = s1.name.compareTo(s2.name);
    }
    return result;
   } 
 }
 
 public Student(String name,int num){
  this.name = name;
  this.num = num;
 }
 
 public int compareTo(Object o){
  Student s =(Student)o;
  return num > s.num ? 1 : (num == s.num ? 0 : -1);
 }
 
 public String toString(){
  return "num="+num+" "+"name="+name;
 }
}






antsoul 2007-03-10 13:03 发表评论
]]>
有意思的题目http://www.tkk7.com/antsoul/archive/2007/03/10/102973.htmlantsoulantsoulSat, 10 Mar 2007 03:46:00 GMThttp://www.tkk7.com/antsoul/archive/2007/03/10/102973.htmlhttp://www.tkk7.com/antsoul/comments/102973.htmlhttp://www.tkk7.com/antsoul/archive/2007/03/10/102973.html#Feedback0http://www.tkk7.com/antsoul/comments/commentRss/102973.htmlhttp://www.tkk7.com/antsoul/services/trackbacks/102973.htmlQ2: L(fng)JAVA或者C~写一个程序,扑և2个整数的最大公U数?br />Q3: 有一?00层高的大厦,你手中有2个相同的ȝ珠子。从q个大厦的某一层扔下去׃(x),用你手中?颗珠子,扑և一个最优的{案Q来得知那个临界层面?img src ="http://www.tkk7.com/antsoul/aggbug/102973.html" width = "1" height = "1" />

antsoul 2007-03-10 11:46 发表评论
]]>
不用W三个变量来互换变量?/title><link>http://www.tkk7.com/antsoul/archive/2007/03/07/102438.html</link><dc:creator>antsoul</dc:creator><author>antsoul</author><pubDate>Wed, 07 Mar 2007 09:05:00 GMT</pubDate><guid>http://www.tkk7.com/antsoul/archive/2007/03/07/102438.html</guid><wfw:comment>http://www.tkk7.com/antsoul/comments/102438.html</wfw:comment><comments>http://www.tkk7.com/antsoul/archive/2007/03/07/102438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/antsoul/comments/commentRss/102438.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/antsoul/services/trackbacks/102438.html</trackback:ping><description><![CDATA[ <p>  不用W三个变量从而达C换变量x,y的|无意在网上看Cq个问题Q感觉很有意思,研究了一下,觉得用以下的办法来做最单!:-)<br /><br />   假如 x = 2, y=3;<br /><br />   x = x + y;<br /><br />   y = x - y;<br /><br />   x = x - y;<br /><br />q样把x,y的值给换了Q呵呵!<br />【code】:(x)<br />class Exchange{<br />  void doExchange(int x,int y){<br />     x = x + y;<br />     y = x - y;<br />     x = x - y;  <br />     System.out.println("x="+x);<br />     System.out.println("y="+y);<br />  }<br />  public static void main(String[] args){<br />    Exchange ex = new Exchange();<br />    ex.doExchange(2,3);<br />  }<br />}<br />ResultQ?br /><br />D:\jcode>javac Exchange.java</p> <p>D:\jcode>java Exchange<br />x=3<br />y=2</p> <img src ="http://www.tkk7.com/antsoul/aggbug/102438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/antsoul/" target="_blank">antsoul</a> 2007-03-07 17:05 <a href="http://www.tkk7.com/antsoul/archive/2007/03/07/102438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://lfpfjc.com" target="_blank">ߵƵ߹ۿ</a>| <a href="http://58f8.com" target="_blank">ҰȫƵ</a>| <a href="http://ziniurj.com" target="_blank">츾xxxxx</a>| <a href="http://kph37.com" target="_blank">AV֮Ʒ</a>| <a href="http://shcxsoft.com" target="_blank">Ʒۿ˳</a>| <a href="http://guhey.com" target="_blank">һƬƵ</a>| <a href="http://gzmkqp.com" target="_blank">߹ۿƵ</a>| <a href="http://653349.com" target="_blank">˾Ʒҹapp</a>| <a href="http://popodino.com" target="_blank">ŮˬƵȫ</a>| <a href="http://0888qb.com" target="_blank">߹ۿƬ</a>| <a href="http://66eeb.com" target="_blank">ƷŮߵӰ </a>| <a href="http://dajiaody.com" target="_blank">ŷպɫ</a>| <a href="http://zhuanjiao521.com" target="_blank">AVAV˵ò</a>| <a href="http://91haikala.com" target="_blank">һһһëƬëƬ</a>| <a href="http://changfafangzhi.com" target="_blank">þþþóƬѹۿѿ </a>| <a href="http://2023852.com" target="_blank">jlzzjlzzѲ</a>| <a href="http://yzddcpj.com" target="_blank">޾Ʒ456</a>| <a href="http://gkhnf.com" target="_blank">͵͵Ʒ</a>| <a href="http://www-566846.com" target="_blank">ŷAV</a>| <a href="http://ww11axax.com" target="_blank">õɫƵȫ</a>| <a href="http://3baimm.com" target="_blank">ձƬѹۿһ</a>| <a href="http://www3ratcom.com" target="_blank">žžƵ</a>| <a href="http://qsqse1.com" target="_blank">A޾VƷ</a>| <a href="http://18yinren.com" target="_blank">Ʒþþþþ޾Ʒ</a>| <a href="http://xsjxp.com" target="_blank">һػaƬ</a>| <a href="http://jybelt.com" target="_blank">㽶Ƶ</a>| <a href="http://ebanyou.com" target="_blank">ȫaһëƬ˰</a>| <a href="http://zjszbwzl.com" target="_blank">㽶Ƶ߹ۿ</a>| <a href="http://wwwks2424.com" target="_blank">ŷպۺϰȥ</a>| <a href="http://kkjk123.com" target="_blank">߹ۿƵ</a>| <a href="http://woaisouluo.com" target="_blank">AVַ߹ۿ</a>| <a href="http://mlhcd.com" target="_blank">ۺС˵</a>| <a href="http://9aiba.com" target="_blank">޹˾þۺһ</a>| <a href="http://catalna.com" target="_blank">ҹƵ </a>| <a href="http://ww11axax.com" target="_blank">ȫƵѹۿ</a>| <a href="http://zzdyzj.com" target="_blank">þþþAVרɫ</a>| <a href="http://jomujy.com" target="_blank">޾Ʒѿ</a>| <a href="http://www-566846.com" target="_blank">ѹۿ˳վ</a>| <a href="http://hylaowu.com" target="_blank">24СʱѿƬ</a>| <a href="http://haohaoshuo.com" target="_blank">޹Ʒһ</a>| <a href="http://avxyz.com" target="_blank">޵һվȫ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>