??xml version="1.0" encoding="utf-8" standalone="yes"?>国产精品美乳一区二区免费,亚洲国产精品ⅴa在线观看,宅男av一区二区三区http://www.aygfsteel.com/kyleYang/category/43596.html孩儿立志Z养I学不成名誓不q? 风华正茂乑֝圎ͼ人生无处不青山? 光阴如同水去,珍惜时光最宝贵? 鹏程万里靠自己,飞黄腾达青少q? zh-cnWed, 20 Jan 2010 12:02:21 GMTWed, 20 Jan 2010 12:02:21 GMT60设计模式ȝQState模式http://www.aygfsteel.com/kyleYang/archive/2010/01/18/310012.html飞熊飞熊Mon, 18 Jan 2010 14:31:00 GMThttp://www.aygfsteel.com/kyleYang/archive/2010/01/18/310012.htmlhttp://www.aygfsteel.com/kyleYang/comments/310012.htmlhttp://www.aygfsteel.com/kyleYang/archive/2010/01/18/310012.html#Feedback0http://www.aygfsteel.com/kyleYang/comments/commentRss/310012.htmlhttp://www.aygfsteel.com/kyleYang/services/trackbacks/310012.htmlhttp://www.aygfsteel.com/pengpenglin/archive/2008/04/07/191325.html

飞熊 2010-01-18 22:31 发表评论
]]>
设计模式ȝQStrategy模式http://www.aygfsteel.com/kyleYang/archive/2010/01/18/310011.html飞熊飞熊Mon, 18 Jan 2010 14:29:00 GMThttp://www.aygfsteel.com/kyleYang/archive/2010/01/18/310011.htmlhttp://www.aygfsteel.com/kyleYang/comments/310011.htmlhttp://www.aygfsteel.com/kyleYang/archive/2010/01/18/310011.html#Feedback0http://www.aygfsteel.com/kyleYang/comments/commentRss/310011.htmlhttp://www.aygfsteel.com/kyleYang/services/trackbacks/310011.htmlhttp://www.aygfsteel.com/pengpenglin/archive/2008/04/08/191422.html

飞熊 2010-01-18 22:29 发表评论
]]>
设计模式ȝQVisitor模式http://www.aygfsteel.com/kyleYang/archive/2010/01/18/310010.html飞熊飞熊Mon, 18 Jan 2010 14:28:00 GMThttp://www.aygfsteel.com/kyleYang/archive/2010/01/18/310010.htmlhttp://www.aygfsteel.com/kyleYang/comments/310010.htmlhttp://www.aygfsteel.com/kyleYang/archive/2010/01/18/310010.html#Feedback0http://www.aygfsteel.com/kyleYang/comments/commentRss/310010.htmlhttp://www.aygfsteel.com/kyleYang/services/trackbacks/310010.htmlhttp://www.aygfsteel.com/pengpenglin/archive/2008/04/15/193170.html

飞熊 2010-01-18 22:28 发表评论
]]>
设计模式ȝ-Composite模式http://www.aygfsteel.com/kyleYang/archive/2010/01/18/310005.html飞熊飞熊Mon, 18 Jan 2010 14:04:00 GMThttp://www.aygfsteel.com/kyleYang/archive/2010/01/18/310005.htmlhttp://www.aygfsteel.com/kyleYang/comments/310005.htmlhttp://www.aygfsteel.com/kyleYang/archive/2010/01/18/310005.html#Feedback0http://www.aygfsteel.com/kyleYang/comments/commentRss/310005.htmlhttp://www.aygfsteel.com/kyleYang/services/trackbacks/310005.html 一、Composite模式的定?br />
对象以树Şl构l织h,以达成“部分-整体?的层ơ结构,使得客户端对单个对象和组合对象的使用h一致?/strong>.

二、Composite模式的特?/strong>

Composite比较Ҏ理解Q想到Composite应该想到树形结构图。组合体内这?strong style="COLOR: red">对象都有共同接口,当组合体一个对象的Ҏ被调用执行时QComposite?strong style="COLOR: red">遍历(Iterator)整个树Şl构,L同样包含q个Ҏ的对象ƈ实现调用执行。可以用牵一动百来Ş宏V?/span>

所以Composite模式使用到Iterator模式Q和Chain of Responsibility模式cM?/span>

三、Composite好处

1.使客L调用单,客户端可以一致的使用l合l构或其中单个对象,用户׃必关p自己处理的是单个对象还是整个组合结构,q就化了客户端代码?br />2.更容易在l合体内加入对象部g. 客户端不必因为加入了新的对象部g而更改代码?/span>

四、如何用Composite

首先定义一个接口或抽象c,q是设计模式通用方式了,其他设计模式Ҏ口内部定义限制不多,Composite却有个规定,那就是要在接口内部定义一个用于访问和理Compositel合体的对象们(或称部gComponentQ?

    ---- 以上内容摘自Jdon|站的《Gof 23U设计模式》系列文?br />
五、Composite模式的分?/strong>

·Composite模式的结构:
基类/接口(构g抽象)
    |
    |--- 原子构g(extends 基类 / implements 接口)
    |
    |--- l合构g(extends 基类 / implements 接口)
               |--- 原子构g1
               |--- 原子构g2
               |--- l合构g3
               |--- 原子构g3-1
                        |--- 原子构g3-2

·Composite模式的特点:
   ·Composite模式一般都有一个抽象类或接口来表示最基本的构件?br />   ·Composite模式一般都׃cd象构成:表示单个元素的对?Primitive)和表C多个元素组合的对象(Composite)
   ·Composite模式下Primitive和Composite对象都承或实现上层接口或父c?br />   ·Composite模式下每个构仉含有三个基础ҎQadd(构g)、remove(构g)、iterator()
   ·Composite对象含有一个用来保存其下所有基元素的的集合Q例如:VectorQArrayListQHashMap
   ·Composite对象的方法被调用时一般都会引起其下所有基元素相同Ҏ的调用,即递归调用?br />
·Composite模式中Primitive对象和Composite对象的方法区别:
   ·add(构g)Q如果是基础对象Q则此方法直接返回falseQ如果是l合对象Q则先添加新构g然后q回true
   ·remove(构g)Q如果是基础对象Q则此方法直接返回falseQ如果是l合对象Q则先删除构件然后返回true
   ·iterator()Q如果是基础对象Q则此方法直接返回nullQ如果是l合对象Q则q回一个包含所有对象的集合

·客户端调用Composite模式的代码示例:
   ·创徏一个原子构件对?br />   ·创徏一个组合构件对?br />   ·调用l合构g对象的add/removeҎd/删除对象
   ·调用l合够对象的iteratoreҎq代昄对象
本文摘自Q?a href="/pengpenglin/archive/2008/01/21/176675.html">http://www.aygfsteel.com/pengpenglin/archive/2008/01/21/176675.html
l:

一个二叉树的例子:
1.Component 是抽象组?br />Tree 和Leaf l承Component

private String name; //树或叶子的名U?br />addChild(Component leftChild,Component rightChild);
//l一个树上加上一个左孩子Q一个右孩子
getName(){return name;}
getTreeInfo(){} //得到树或叶子的详l信?br />getLength(); //得到树的高度

2.Tree 二叉树,一个左孩子Q一个右孩子

3.Leaf 是叶子节?br />4.Test 是测试节?

/** Component.java **************/
package binarytree;

public abstract class Component {
 private String name;

 public abstract Component addChild(Component leftChild, Component rightChild);

 public String getName() {
  return name;
 }

 public void getTreeInfo() {
 }

 public abstract int getLength();
}


/** Leaf.java **************/
package binarytree;

public class Leaf extends Component {
 private String name;

 private Component leaf = null;

 public Leaf(String name) {
  this.name = name;
 }

 public Component addChild(Component leftChild, Component rightChild) {
  return this;
 }

 public String getName() {
  return name;
 }

 public int getLength() {
  return 1;
 }

 public static void main(String[] args) {
 }
}

/** Tree.java **************/
package binarytree;

public class Tree extends Component {
 private String name;

 private Component leftChild;

 private Component rightChild;

 public Tree(String name, Component leftChild, Component rightChild) {
  this.name = name;
  this.leftChild = leftChild;
  this.rightChild = rightChild;
 }

 public Tree(String name) {
  this.name = name;
  this.leftChild = null;
  this.rightChild = null;
 }

 public Component addChild(Component leftChild, Component rightChild) {
  this.leftChild = leftChild;
  this.rightChild = rightChild;
  return this;
 }

 public String getName() {
  return name;
 }

 public void getTreeInfo()
 // 得到树或叶子的详l信?br /> // 先打印自q名字Q再遍例左孩子,再遍例右孩子
 // 如果左孩子或叛_子是树,递归调用
 {
  System.out.println(" this trees name is " + getName());
  if (this.leftChild instanceof Leaf) {
   System.out.println(getName() + "s left child is "
     + this.leftChild.getName() + ",it is a Leaf");
  }
  if (this.leftChild instanceof Tree) {
   System.out.println(getName() + "s left child is "
     + this.leftChild.getName() + ",it is a Tree");
   this.leftChild.getTreeInfo();
  }
  if (this.leftChild == null) {
   System.out.println(getName() + "s left child is a null");
  }
  if (this.rightChild instanceof Leaf) {
   System.out.println(getName() + "s right child is "
     + this.rightChild.getName() + ",it is a Leaf");
  }
  if (this.rightChild instanceof Tree) {
   System.out.println(getName() + "s right child is "
     + this.rightChild.getName() + ",it is a Tree");
   this.rightChild.getTreeInfo();
  }
  if (this.rightChild == null) {
   System.out.println(getName() + "s right child is a null");
  }
  // System.out.println(getName()+"s 高度 ?"+getLength());
 }

 public int getLength() {
  // 比较左孩子或叛_子的高度Q谁大,+1 q回
  // I孩子的处理
  if (this.leftChild == null) {
   if (this.rightChild == null)
    return 1;
   else
    return this.rightChild.getLength() + 1;
  } else {
   if (this.rightChild == null) {
    return this.leftChild.getLength() + 1;
   } else {
    if ((this.leftChild.getLength()) >= (this.rightChild
      .getLength()))
     return this.leftChild.getLength() + 1;
    else
     return this.rightChild.getLength() + 1;
   }
  }
 }

 public static void main(String[] args) {
 }
}

/** Test.java 试c?**************/
package binarytree;

public class Test {

 public Test() {
 }

 public static void main(String[] args) {
  Component tree = new Tree("luopeng");
  Component left_child = new Leaf("luopeng1");
  Component right_child = new Leaf("luopeng2");
  tree = tree.addChild(left_child, right_child);
  // tree=tree.addRightChild(right_child);
  tree.getTreeInfo();
  Component tree1 = new Tree("luopeng2");
  tree1.addChild(tree, left_child);
  tree1.getTreeInfo();
  Component tree2 = new Tree("luopeng3");
  tree2.addChild(tree, null);
  tree2.getTreeInfo();
  Component tree4 = new Tree("luopeng4");
  tree4.addChild(null, tree);
  tree4.getTreeInfo();
  System.out.println(tree4.getName() + "的高度是 " + tree4.getLength());
 }
}



飞熊 2010-01-18 22:04 发表评论
]]>
q代器模?Iterator pattern)http://www.aygfsteel.com/kyleYang/archive/2010/01/18/310004.html飞熊飞熊Mon, 18 Jan 2010 13:51:00 GMThttp://www.aygfsteel.com/kyleYang/archive/2010/01/18/310004.htmlhttp://www.aygfsteel.com/kyleYang/comments/310004.htmlhttp://www.aygfsteel.com/kyleYang/archive/2010/01/18/310004.html#Feedback0http://www.aygfsteel.com/kyleYang/comments/commentRss/310004.htmlhttp://www.aygfsteel.com/kyleYang/services/trackbacks/310004.html

一?引言
  q代q个名词对于熟悉Java的h来说l对不陌生。我们常怋用JDK提供的P代接口进行java collection的遍历:
Iterator it = list.iterator();
while(it.hasNext()){
 //using “it.next();”do some businesss logic
}
而这是关于q代器模式应用很好的例子?br />
  二?定义与结?/strong>

  q代器(IteratorQ模式,又叫做游标(CursorQ模式。GOFl出的定义ؓQ提供一U方法访问一个容器(containerQ对象中各个元素Q而又不需暴露该对象的内部l节?br />
  从定义可见,q代器模式是为容器而生。很明显Q对容器对象的访问必然涉及到遍历法。你可以一股脑的将遍历Ҏ塞到容器对象中去Q或者根本不L供什么遍历算法,让用容器的己去实现d。这两种情况好像都能够解决问题?br />
  然而在前一U情况,容器承受了过多的功能Q它不仅要负责自己“容器”内的元素维护(d、删除等{)Q而且q要提供遍历自n的接口;而且׃遍历状态保存的问题Q不能对同一个容器对象同时进行多个遍历。第二种方式倒是省事Q却又将容器的内部细节暴露无遗?br />
  而P代器模式的出玎ͼ很好的解决了上面两种情况的弊端。先来看下P代器模式的真面目吧?

  q代器模式由以下角色l成Q?br />
  1) q代器角ԌIteratorQ:q代器角色负责定义访问和遍历元素的接口?br />
  2) 具体q代器角ԌConcrete IteratorQ:具体q代器角色要实现q代器接口,q要记录遍历中的当前位置?br />
  3) 容器角色QContainerQ:容器角色负责提供创徏具体q代器角色的接口?br />
  4) 具体容器角色QConcrete ContainerQ:具体容器角色实现创徏具体q代器角色的接口——这个具体P代器角色于该容器的结构相兟?br />
  q代器模式的cd如下Q?br />


  从结构上可以看出QP代器模式在客户与容器之间加入了P代器角色。P代器角色的加入,可以很好的避免容器内部l节的暴Ԍ而且也得设计符号“单一职责原则”?br />
  注意Q在q代器模式中Q具体P代器角色和具体容器角色是耦合在一L——遍历算法是与容器的内部l节紧密相关的。ؓ了客户E序从与具体q代器角色耦合的困境中q出来Q避免具体P代器角色的更换给客户E序带来的修改,q代器模式抽象了具体q代器角Ԍ使得客户E序更具一般性和重用性。这被称为多态P代?br />
  三?举例

  ׃q代器模式本w的规定比较松散Q所以具体实C׃花八门。我们在此仅举一例,Ҏ不能实现方式一一呈现。因此在举例前,我们先来列D下P代器模式的实现方式?

  1QP代器角色定义了遍历的接口Q但是没有规定由谁来控制q代。在Java collection的应用中Q是由客L序来控制遍历的进E,被称为外部P代器Q还有一U实现方式便是由q代器自w来控制q代Q被UCؓ内部q代器。外部P代器要比内部q代器灵zR强大,而且内部q代器在java语言环境中,可用性很弱?br />
  2Q在q代器模式中没有规定谁来实现遍历法。好像理所当然的要在P代器角色中实现。因为既便于一个容器上使用不同的遍历算法,也便于将一U遍历算法应用于不同的容器。但是这样就破坏掉了容器的封装——容器角色就要公开自己的私有属性,在java中便意味着向其他类公开了自qU有属性?br />
  那我们把它放到容器角色里来实现好了。这栯P代器角色p架空Z仅存放一个遍历当前位|的功能。但是遍历算法便和特定的容器紧紧l在一起了?br />
  而在Java Collection的应用中Q提供的具体q代器角色是定义在容器角色中的内部类。这样便保护了容器的装。但是同时容器也提供了遍历算法接口,你可以扩展自qq代器?br />
  好了Q我们来看下Java Collection中的q代器是怎么实现的吧?br />//q代器角Ԍ仅仅定义了遍历接?p>public interface Iterator {
 boolean hasNext();
 Object next();
 void remove();
}

//容器角色Q这里以ListZ。它也仅仅是一个接口,׃|列出来?br />//具体容器角色Q便是实CList接口的ArrayList{类。ؓ了突出重点这里指|列和P代器相关的内?br />//具体q代器角Ԍ它是以内部类的Ş式出来的。AbstractList是ؓ了将各个具体容器角色的公共部分提取出来而存在的?/p>

public abstract class AbstractList extends AbstractCollection implements List {
…?
//q个便是负责创徏具体q代器角色的工厂Ҏ
public Iterator iterator() {
 return new Itr();
}

//作ؓ内部cȝ具体q代器角?/p>

private class Itr implements Iterator {
 int cursor = 0;
 int lastRet = -1;
 int expectedModCount = modCount;

 public boolean hasNext() {
  return cursor != size();
 }

 public Object next() {
  checkForComodification();
  try {
   Object next = get(cursor);
   lastRet = cursor++;
   return next;
  } catch(IndexOutOfBoundsException e) {
   checkForComodification();
   throw new NoSuchElementException();
  }
 }

 public void remove() {
  if (lastRet == -1)
   throw new IllegalStateException();
   checkForComodification();

  try {
   AbstractList.this.remove(lastRet);
   if (lastRet < cursor)
    cursor--;
   lastRet = -1;
   expectedModCount = modCount;
  } catch(IndexOutOfBoundsException e) {
   throw new ConcurrentModificationException();
  }
 }

 final void checkForComodification() {
  if (modCount != expectedModCount)
   throw new ConcurrentModificationException();
 }
}
至于q代器模式的使用。正如引a中所列那P客户E序要先得到具体容器角色Q然后再通过具体容器角色得到具体q代器角艌Ӏ这样便可以使用具体q代器角色来遍历容器了…?br />
  四?实现自己的P代器

  在实现自qq代器的时候,一般要操作的容器有支持的接口才可以。而且我们q要注意以下问题Q?

  在P代器遍历的过E中Q通过该P代器q行容器元素的增减操作是否安全呢Q?br />
  在容器中存在复合对象的情况,q代器怎样才能支持深层遍历和多U遍历呢Q?br />
  以上两个问题对于不同l构的容器角Ԍ各不相同Q值得考虑?br />
  五?适用情况

  ׃面的讲述Q我们可以看P代器模式l容器的应用带来以下好处Q?br />
  1) 支持以不同的方式遍历一个容器角艌Ӏ根据实现方式的不同Q效果上会有差别?br />
  2) 化了容器的接口。但是在java Collection中ؓ了提高可扩展性,容器q是提供了遍历的接口?br />
  3) 对同一个容器对象,可以同时q行多个遍历。因为遍历状态是保存在每一个P代器对象中的?br />
  由此也能得出q代器模式的适用范围Q?br />
  1) 讉K一个容器对象的内容而无需暴露它的内部表示?br />
  2) 支持对容器对象的多种遍历?br />
  3) 为遍历不同的容器l构提供一个统一的接口(多态P代)?br />
实例Q?br />

public class IteratorDemo {
 private List<String> strList;

 public IteratorDemo() {
  strList = new ArrayList<String>();
 }

 public void add(String item) {
  strList.add(item);
 }

 public String remove(int index) {
  String item = strList.get(index);
  strList.remove(index);
  return item;
 }

 public Iterator<String> iterator() {
  return new Iterator<String>() {
   // 游标
   private int cursor = 0;

   public boolean hasNext() {
    return cursor < strList.size();
   }

   public String next() {
    return strList.get(cursor++);
   }

   public void remove() {

   }

  };
 }

 public static void main(String[] args) {
  IteratorDemo demo = new IteratorDemo();
  demo.add("1");
  demo.add("2");
  demo.add("3");
  demo.add("4");

  Iterator<String> iterator = demo.iterator();
  while (iterator.hasNext()) {
   System.out.println(iterator.next());
  }
 }
}



飞熊 2010-01-18 21:51 发表评论
]]>
Java设计模式使用率排行榜http://www.aygfsteel.com/kyleYang/archive/2010/01/17/309894.html飞熊飞熊Sun, 17 Jan 2010 14:28:00 GMThttp://www.aygfsteel.com/kyleYang/archive/2010/01/17/309894.htmlhttp://www.aygfsteel.com/kyleYang/comments/309894.htmlhttp://www.aygfsteel.com/kyleYang/archive/2010/01/17/309894.html#Feedback0http://www.aygfsteel.com/kyleYang/comments/commentRss/309894.htmlhttp://www.aygfsteel.com/kyleYang/services/trackbacks/309894.htmlJava设计模式使用率爬行榜

使用频率 所属类?/td> 模式名称 模式 单定?/td>
5 创徏?/td> Singleton 单例模式 保证一个类只有一个实例,q提供一个访问它的全局讉K炏V?/td>
5 l构?/td> Composite 复合模式 对象组合成树Şl构以表C部分整体的关系QComposite使得用户对单个对象和l合对象的用具有一致性?/td>
5 l构?/td> FASADE 面模?/td> 为子pȝ中的一l接口提供一致的界面Qfasade提供了一高层接口Q这个接口得子pȝ更容易用?/td>
5 l构?/td> Proxy 代理 为其他对象提供一U代理以控制对这个对象的讉K
5 行ؓ?/td> Iterator q代?/td> 提供一个方法顺序访问一个聚合对象的各个元素Q而又不需要暴露该对象的内部表C?/td>
5 行ؓ?/td> Observer 观察?/td> 定义对象间一对多的依赖关p,当一个对象的状态发生改变时Q所有依赖于它的对象都得到通知自动更新?/td>
5 行ؓ?/td> Template Method 模板Ҏ 定义一个操作中的算法的骨架Q而将一些步骤gq到子类中,TemplateMethod使得子类可以不改变一个算法的l构卛_以重定义该算法得某些特定步骤?/td>
4 创徏?/td> Abstract Factory 抽象工厂 提供一个创Zpd相关或相互依赖对象的接口Q而无L定它们的具体cR?/td>
4 创徏?/td> Factory Method 工厂Ҏ 定义一个用于创建对象的接口Q让子类军_实例化哪一个类QFactory Method使一个类的实例化延迟C子类?/td>
4 l构?/td> Adapter 适配?/td> 一cȝ接口转换成客户希望的另外一个接口,Adapter模式使得原本׃接口不兼容而不能一起工作那些类可以一起工作?/td>
4 l构?/td> Decrator 装饰模式 动态地l一个对象增加一些额外的职责Q就增加的功能来_Decorator模式相比生成子类更加灉|?/td>
4 行ؓ?/td> Command 指o模式 一个请求封装ؓ一个对象,从而你可以用不同的请求对客户q行参数化,对请求排队和记录h日志Q以及支持可撤销的操作?/td>
4 行ؓ?/td> State 状态模?/td> 允许对象在其内部状态改变时改变他的行ؓ。对象看hg改变了他的类?/td>
4 行ؓ?/td> Strategy {略模式 定义一pd的算法,把他们一个个装hQƈ使他们可以互相替换,本模式得算法可以独立于使用它们的客戗?/td>
3 创徏?/td> Builder 生成?/td> 一个复杂对象的构徏与他的表C相分离Q得同L构徏q程可以创徏不同的表C?/td>
3 l构?/td> Bridge 桥模?/td> 抽象部分与它的实现部分相分,使他们可以独立的变化?/td>
3 行ؓ?/td> Chain of Responsibility 职责?/td> 使多个对象都有机会处理请求,从而避免请求的送发者和接收者之间的耦合关系
2 创徏?/td> Prototype 原型 用原型实例指定创建对象的U类Qƈ且通过拯q些原型来创建新的对象?/td>
2 l构?/td> Flyweight 享元  
2 行ؓ?/td> Mediator 中介?/td> 用一个中介对象封装一些列的对象交互?/td>
2 行ؓ?/td> Visitor 讉K?/td> 表示一个作用于某对象结构中的各元素的操作,它你可以在不改变各元素cȝ前提下定义作用于q个元素的新操作?/td>
1 行ؓ?/td> Interpreter 解释?/td> l定一个语aQ定义他的文法的一个表C,q定义一个解释器Q这个解释器使用该表C来解释语言中的句子?/td>
1 行ؓ?/td> Memento 备忘?/td> 在不破坏对象的前提下Q捕获一个对象的内部状态,q在该对象之外保存这个状态?/td>

转自2004q?期《CSDN开发高手?/p>

飞熊 2010-01-17 22:28 发表评论
]]>
Java解读--桥接Bridgehttp://www.aygfsteel.com/kyleYang/archive/2010/01/17/309880.html飞熊飞熊Sun, 17 Jan 2010 12:39:00 GMThttp://www.aygfsteel.com/kyleYang/archive/2010/01/17/309880.htmlhttp://www.aygfsteel.com/kyleYang/comments/309880.htmlhttp://www.aygfsteel.com/kyleYang/archive/2010/01/17/309880.html#Feedback0http://www.aygfsteel.com/kyleYang/comments/commentRss/309880.htmlhttp://www.aygfsteel.com/kyleYang/services/trackbacks/309880.html阅读全文

飞熊 2010-01-17 20:39 发表评论
]]>
观察者模?Java自定义事?/title><link>http://www.aygfsteel.com/kyleYang/archive/2010/01/17/309871.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Sun, 17 Jan 2010 10:15:00 GMT</pubDate><guid>http://www.aygfsteel.com/kyleYang/archive/2010/01/17/309871.html</guid><wfw:comment>http://www.aygfsteel.com/kyleYang/comments/309871.html</wfw:comment><comments>http://www.aygfsteel.com/kyleYang/archive/2010/01/17/309871.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/kyleYang/comments/commentRss/309871.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/kyleYang/services/trackbacks/309871.html</trackback:ping><description><![CDATA[ <dd> <div id="wmqeeuq" class="Description">核心提示Q观察者模?Java自定义事?[正文]: MyEventTest.java: package wintys.event; import javax.swing.event.EventListenerList; import java.util.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; /** *Java的事件机?自定义事? q?<br /><a class="postTitle2" id="viewpost1_TitleUrl" href="/wintys/archive/2009/10/11/pattern_observer_event.html"><font color="#000000"><strong>观察者模?Java自定义事?/strong></font></a><strong> <br /><br /></strong>MyEventTest.java: <br /></div> </dd> <dd class="ArticleContent"> <div id="wmqeeuq" class="postTitle"> <ol class="dp-j"> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="keyword">package</span> <span> wintys.event;    </span> </span> </li> <li> <span>import</span> <span> javax.swing.event.EventListenerList;    </span> </li> <li id="wmqeeuq" class="alt"> <span>import</span> <span> java.util.Date;    </span> </li> <li> <span>import</span> <span> java.text.DateFormat;    </span> </li> <li id="wmqeeuq" class="alt"> <span>import</span> <span> java.text.SimpleDateFormat;    </span> </li> <li> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>/**  </span>  </li> <li> <span> <span id="wmqeeuq" class="comment">* Java的事件机?自定义事?  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment"> </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">q行l果:  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">do something interesting in source here.  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">listener detects [event]:wintys.event.MyEvent[source=wintys.event.MySource@18158  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">59] [occur at]:2009-10-11 16:27:49  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">listener detects [event]:wintys.event.MyEvent[source=wintys.event.MySource@18158  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">59] [occur at]:2009-10-11 16:27:49  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment"> </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">* @version 2009-10-11  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">* @author 天堂露珠 (wintys@gmail.com)  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">* @see http://www.aygfsteel.com/wintys  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">*/</span> <span>    </span> </span> </li> <li id="wmqeeuq" class="alt"> <span>class</span> <span> MyEventTest{    </span> </li> <li> <span>    </span> <span id="wmqeeuq" class="keyword">public</span> <span> </span> <span id="wmqeeuq" class="keyword">static</span> <span> </span> <span id="wmqeeuq" class="keyword">void</span> <span> main(String[] args){    </span> </li> <li id="wmqeeuq" class="alt"> <span>        MySource source = </span> <span id="wmqeeuq" class="keyword">new</span> <span> MySource();    </span> </li> <li> <span>        MyListener myListener = </span> <span id="wmqeeuq" class="keyword">new</span> <span> MyListener(){    </span> </li> <li id="wmqeeuq" class="alt"> <span>            </span> <span id="wmqeeuq" class="keyword">public</span> <span> </span> <span id="wmqeeuq" class="keyword">void</span> <span> doMyAction(MyEvent e){    </span> </li> <li> <span>                System.out.println(</span> <span id="wmqeeuq" class="string">"listener detects "</span> <span> + e);    </span> </li> <li id="wmqeeuq" class="alt"> <span>            }    </span> </li> <li> <span>        };    </span> </li> <li id="wmqeeuq" class="alt"> <span>        source.addMyListener(myListener);    </span> </li> <li> <span>        source.addMyListener(myListener);    </span> </li> <li id="wmqeeuq" class="alt"> <span>        source.addMyListener(myListener);    </span> </li> <li> <span>        source.removeMyListener(myListener);    </span> </li> <li id="wmqeeuq" class="alt"> <span>  </span> </li> <li> <span>        source.doSomething();    </span> </li> <li id="wmqeeuq" class="alt"> <span>    }    </span> </li> <li> <span>}    </span> </li> <li id="wmqeeuq" class="alt"> <span>  </span> </li> <li> <span>/**  </span>  </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">* 自定义的事g.  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">* @version 2009-10-11  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">* @author 天堂露珠(wintys@gmail.com)  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">* @see http://www.aygfsteel.com/wintys  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">*/</span> <span>    </span> </span> </li> <li> <span>class</span> <span> MyEvent </span> <span id="wmqeeuq" class="keyword">extends</span> <span> java.util.EventObject{    </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="keyword">private</span> <span> Date date;</span> <span id="wmqeeuq" class="comment">//记录事g发生的时闾b?</span> <span>  </span> </li> <li> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="keyword">public</span> <span> MyEvent(Object source , Date date){    </span> </li> <li> <span>        </span> <span id="wmqeeuq" class="keyword">super</span> <span>(source);    </span> </li> <li id="wmqeeuq" class="alt"> <span>  </span> </li> <li> <span>        </span> <span id="wmqeeuq" class="keyword">this</span> <span>.date = date;    </span> </li> <li id="wmqeeuq" class="alt"> <span>    }    </span> </li> <li> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="keyword">public</span> <span> String toString(){    </span> </li> <li> <span>        DateFormat df = </span> <span id="wmqeeuq" class="keyword">new</span> <span> SimpleDateFormat(</span> <span id="wmqeeuq" class="string">"yyyy-MM-dd HH:mm:ss"</span> <span>);    </span> </li> <li id="wmqeeuq" class="alt"> <span>        String dt = df.format(date);    </span> </li> <li> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>        </span> <span id="wmqeeuq" class="keyword">return</span> <span> </span> <span id="wmqeeuq" class="string">"[event]:"</span> <span> + </span> <span id="wmqeeuq" class="keyword">super</span> <span>.toString() + </span> <span id="wmqeeuq" class="string">" [occur at]:"</span> <span> + dt;    </span> </li> <li> <span>    }    </span> </li> <li id="wmqeeuq" class="alt"> <span>}    </span> </li> <li> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>/**  </span>  </li> <li> <span> <span id="wmqeeuq" class="comment">* 自定义事件监听器接口.  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">* @version 2009-10-11  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">* @author 天堂露珠(wintys@gmail.com)  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">* @see http://www.aygfsteel.com/wintys  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">*/</span> <span>    </span> </span> </li> <li id="wmqeeuq" class="alt"> <span>interface</span> <span> MyListener </span> <span id="wmqeeuq" class="keyword">extends</span> <span> java.util.EventListener{    </span> </li> <li> <span>    </span> <span id="wmqeeuq" class="keyword">void</span> <span> doMyAction(MyEvent e);    </span> </li> <li id="wmqeeuq" class="alt"> <span>}    </span> </li> <li> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>/**  </span>  </li> <li> <span> <span id="wmqeeuq" class="comment">* 自定义事件源.  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">* @version 2009-10-11  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">* @author 天堂露珠(wintys@gmail.com)  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">* @see http://www.aygfsteel.com/wintys  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">*/</span> <span>    </span> </span> </li> <li id="wmqeeuq" class="alt"> <span>class</span> <span> MySource{    </span> </li> <li> <span>    </span> <span id="wmqeeuq" class="comment">/**  </span>  </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">     * 保存注册的监听器列表.  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">     * 子类可以使用它保存自q事g监听?非MyListener监听?列表.  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">     */</span> <span>    </span> </span> </li> <li> <span>    </span> <span id="wmqeeuq" class="keyword">protected</span> <span> EventListenerList listenerList = </span> <span id="wmqeeuq" class="keyword">new</span> <span> EventListenerList();    </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="keyword">private</span> <span> MyEvent myEvent = </span> <span id="wmqeeuq" class="keyword">null</span> <span>;</span> <span id="wmqeeuq" class="comment">//fireDoMyAction()使用此变量?</span> <span>  </span> </li> <li> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="comment">/**  </span>  </li> <li> <span> <span id="wmqeeuq" class="comment">     * 没有做Q何事  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">     */</span> <span>    </span> </span> </li> <li> <span>    </span> <span id="wmqeeuq" class="keyword">public</span> <span> MySource(){    </span> </li> <li id="wmqeeuq" class="alt"> <span>    }    </span> </li> <li> <span>    </span> <span id="wmqeeuq" class="comment">/**  </span>  </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">     * d一个MyListener监听器?</span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">     */</span> <span>    </span> </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="keyword">public</span> <span> </span> <span id="wmqeeuq" class="keyword">void</span> <span> addMyListener(MyListener listener){    </span> </li> <li> <span>        listenerList.add(MyListener.</span> <span id="wmqeeuq" class="keyword">class</span> <span> , listener);    </span> </li> <li id="wmqeeuq" class="alt"> <span>    }    </span> </li> <li> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="comment">/**  </span>  </li> <li> <span> <span id="wmqeeuq" class="comment">     * U除一个已注册的MyListener监听?  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">     * 如果监听器列表中已有相同的监听器listener1、listener2,  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">     * q且listener1==listener2,  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">     * 那么只移除最q注册的一个监听器。?</span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">     */</span> <span>    </span> </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="keyword">public</span> <span> </span> <span id="wmqeeuq" class="keyword">void</span> <span> removeMyListener(MyListener listener){    </span> </li> <li> <span>        listenerList.remove(MyListener.</span> <span id="wmqeeuq" class="keyword">class</span> <span> , listener);    </span> </li> <li id="wmqeeuq" class="alt"> <span>    }    </span> </li> <li> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="comment">/**  </span>  </li> <li> <span> <span id="wmqeeuq" class="comment">     * @return 在此对象上监听的所有MyListenercd的监听器  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">     */</span> <span>    </span> </span> </li> <li> <span>    </span> <span id="wmqeeuq" class="keyword">public</span> <span> MyListener[] getMyListeners(){    </span> </li> <li id="wmqeeuq" class="alt"> <span>        </span> <span id="wmqeeuq" class="keyword">return</span> <span> (MyListener[])listenerList.getListeners(MyListener.</span> <span id="wmqeeuq" class="keyword">class</span> <span>);    </span> </li> <li> <span>    }    </span> </li> <li id="wmqeeuq" class="alt"> <span>  </span> </li> <li> <span>    </span> <span id="wmqeeuq" class="comment">//Winty:Copy directly from javax.swing.event.EventListenerList  </span> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="comment">/*Notify all listeners that have registered interest for  </span>  </li> <li> <span> <span id="wmqeeuq" class="comment">       notification on this event type.  The event instance  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">       is lazily created using the parameters passed into  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">       the fire method.  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">     */</span> <span>    </span> </span> </li> <li> <span>    </span> <span id="wmqeeuq" class="keyword">protected</span> <span> </span> <span id="wmqeeuq" class="keyword">void</span> <span> fireDoMyAction() {    </span> </li> <li id="wmqeeuq" class="alt"> <span>         </span> <span id="wmqeeuq" class="comment">// getListenerList() Guaranteed to return a non-null array  </span> <span>  </span> </li> <li> <span>         Object[] listeners = listenerList.getListenerList();    </span> </li> <li id="wmqeeuq" class="alt"> <span>         </span> <span id="wmqeeuq" class="comment">// Process the listeners last to first, notifying  </span> <span>  </span> </li> <li> <span>         </span> <span id="wmqeeuq" class="comment">// those that are interested in this event  </span> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>        </span> <span id="wmqeeuq" class="keyword">for</span> <span> (</span> <span id="wmqeeuq" class="keyword">int</span> <span> i = listeners.length-</span> <span id="wmqeeuq" class="number">2</span> <span>; i>=</span> <span id="wmqeeuq" class="number">0</span> <span>; i-=</span> <span id="wmqeeuq" class="number">2</span> <span>) {    </span> </li> <li> <span>            </span> <span id="wmqeeuq" class="keyword">if</span> <span> (listeners[i]==MyListener.</span> <span id="wmqeeuq" class="keyword">class</span> <span>) {    </span> </li> <li id="wmqeeuq" class="alt"> <span>                </span> <span id="wmqeeuq" class="comment">// Lazily create the event:  </span> <span>  </span> </li> <li> <span>                </span> <span id="wmqeeuq" class="keyword">if</span> <span> (myEvent == </span> <span id="wmqeeuq" class="keyword">null</span> <span>)    </span> </li> <li id="wmqeeuq" class="alt"> <span>                    myEvent = </span> <span id="wmqeeuq" class="keyword">new</span> <span> MyEvent(</span> <span id="wmqeeuq" class="keyword">this</span> <span> , </span> <span id="wmqeeuq" class="keyword">new</span> <span> Date());    </span> </li> <li> <span>                ((MyListener)listeners[i+</span> <span id="wmqeeuq" class="number">1</span> <span>]).doMyAction(myEvent);    </span> </li> <li id="wmqeeuq" class="alt"> <span>            }    </span> </li> <li> <span>        }    </span> </li> <li id="wmqeeuq" class="alt"> <span>    }    </span> </li> <li> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="comment">/**  </span>  </li> <li> <span> <span id="wmqeeuq" class="comment">     * 做一些事件源应该做的有意义的事,然后通知监听?  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">     * q里只是一个示例方?  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">     * 例如:MySource如果是一个按钮,则doSomething()可以命名ؓclick(),  </span> </span> </li> <li id="wmqeeuq" class="alt"> <span> <span id="wmqeeuq" class="comment">     * 当用LL钮时调用click()Ҏ.  </span> </span> </li> <li> <span> <span id="wmqeeuq" class="comment">     */</span> <span>    </span> </span> </li> <li id="wmqeeuq" class="alt"> <span>    </span> <span id="wmqeeuq" class="keyword">public</span> <span> </span> <span id="wmqeeuq" class="keyword">void</span> <span> doSomething() {    </span> </li> <li> <span>        System.out.println(</span> <span id="wmqeeuq" class="string">"do something interesting here."</span> <span>);    </span> </li> <li id="wmqeeuq" class="alt"> <span>  </span> </li> <li> <span>        fireDoMyAction();</span> <span id="wmqeeuq" class="comment">//通知监听器?</span> <span>  </span> </li> <li id="wmqeeuq" class="alt"> <span>    }    </span> </li> <li> <span>}   </span> </li> </ol> </div> <strong> <span> </span> </strong> <p> <br /> <strong>         EventListenerList是特别需要说明的Q它内部使用一个Object数组存放监听器。但是它q不是直接存放,而是先存监听器的classcdQ然后再存监听器本n。即存放(MyListener.class , myListener)。一个Object数组可以存放多种cd的ListenerQ如果还有一U监听器AnotherListenerQ那?AnotherListener.class , anotherListener)也可以存放。无论增删都是两个对象一同被d或删除。上qC码中的listenerList.add(MyListener.class , listener)或listenerList.remove(MyListener.class , listener)Q以及fireDoMyAction()中的"i-=2"Q就是这h作的?/strong> <br /> </p> </dd> <img src ="http://www.aygfsteel.com/kyleYang/aggbug/309871.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/kyleYang/" target="_blank">飞熊</a> 2010-01-17 18:15 <a href="http://www.aygfsteel.com/kyleYang/archive/2010/01/17/309871.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>适配器Adapterhttp://www.aygfsteel.com/kyleYang/archive/2010/01/17/309869.html飞熊飞熊Sun, 17 Jan 2010 09:54:00 GMThttp://www.aygfsteel.com/kyleYang/archive/2010/01/17/309869.htmlhttp://www.aygfsteel.com/kyleYang/comments/309869.htmlhttp://www.aygfsteel.com/kyleYang/archive/2010/01/17/309869.html#Feedback0http://www.aygfsteel.com/kyleYang/comments/commentRss/309869.htmlhttp://www.aygfsteel.com/kyleYang/services/trackbacks/309869.html 1.意图:
            一个类的接口{换成客户希望的另一个接口。Adapter模式使得原来׃版本不兼容而不能在一L够哦那个做的那些cd以在一起工作。有Ӟ为复用而设计的工具q不能够被复用的原因仅仅是因ؓ它的接口与专业应用领域所需要的接口不匹配?br />2.适配器模式有cȝ适配器模式和对象的适配器模式两U不同的形式?br />
一、类的适配器模?br />    cȝ适配器模式把适配的类的API转换成目标类的API?

  • 目标(Target)角色Q这是所期待得到的接口?
  • ?Adaptee)角色Q现有需要适配的接口?
  • 适配?Adapter)角色Q适配器类是本模式的核心。适配器把源接口{换成目标接口。显然这一角色不可以是接口Q而必L具体cR?

/**
 * 定义Client使用的与特定领域相关的接?br /> */
public interface Target {
    void sampleOperation1();
    void sampleOperation2();
}
/**
 * 定义一个已l存在的接口Q这个接口需要适配
 */
public class Adaptee {
    public void sampleOperation1() {
        // ......
    }
}
/**
 * 对Adaptee与Target接口q行适配
 */
public class Adapter extends Adaptee implements Target {
    public void sampleOperation2() {
        // ......
    }
}

二、对象适配?br />    与类的适配器模式一P对象适配器模式把适配的类的API转换成ؓ目标cȝAPIQ与cȝ适配器模式不同的是,对象的适配器模式不是用承关p连接到Adapteec,而是使用委派关系q接到AdapteecR示意代码如下:
/**
 * 定义Client使用的与特定领域相关的接?br /> */
public interface Target {
    void sampleOperation1();
    void sampleOperation2();
}
/**
 * 定义一个已l存在的接口Q这个接口需要适配
 */
public class Adaptee {
    public void sampleOperation1() {
        // ......
    }
}
/**
 * 对Adaptee与Target接口q行适配
 */
public class Adapter implements Target {
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee) {
        super();
        this.adaptee = adaptee;
    }
    public void sampleOperation1() {
        adaptee.sampleOperation1(); // 看点
    }
    public void sampleOperation2() {
        // ......
    }
}

c适配器模式和对象适配器模式的异同QTarget接口和Adapteec都相同Q不同的是类适配器的Adapterl承Adaptee实现TargetQ对象适配器的Adapter实现Target聚集Adaptee?br />
适配器模式的用意是将接口不同而功能相同或者相q的两个接口加以转换?br />



飞熊 2010-01-17 17:54 发表评论
]]>
q代器模?/title><link>http://www.aygfsteel.com/kyleYang/archive/2010/01/17/309868.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Sun, 17 Jan 2010 09:53:00 GMT</pubDate><guid>http://www.aygfsteel.com/kyleYang/archive/2010/01/17/309868.html</guid><wfw:comment>http://www.aygfsteel.com/kyleYang/comments/309868.html</wfw:comment><comments>http://www.aygfsteel.com/kyleYang/archive/2010/01/17/309868.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/kyleYang/comments/commentRss/309868.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/kyleYang/services/trackbacks/309868.html</trackback:ping><description><![CDATA[aa<img src ="http://www.aygfsteel.com/kyleYang/aggbug/309868.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/kyleYang/" target="_blank">飞熊</a> 2010-01-17 17:53 <a href="http://www.aygfsteel.com/kyleYang/archive/2010/01/17/309868.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java代理模式及动态代理类http://www.aygfsteel.com/kyleYang/archive/2010/01/17/309860.html飞熊飞熊Sun, 17 Jan 2010 08:52:00 GMThttp://www.aygfsteel.com/kyleYang/archive/2010/01/17/309860.htmlhttp://www.aygfsteel.com/kyleYang/comments/309860.htmlhttp://www.aygfsteel.com/kyleYang/archive/2010/01/17/309860.html#Feedback0http://www.aygfsteel.com/kyleYang/comments/commentRss/309860.htmlhttp://www.aygfsteel.com/kyleYang/services/trackbacks/309860.html 1.       代理模式

代理模式的作用是Qؓ其他对象提供一U代理以控制对这个对象的讉K。在某些情况下,一个客户不x者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用?/span>

代理模式一般涉及到的角色有Q?/span>

抽象角色 Q声明真实对象和代理对象的共同接口;

代理角色 Q代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在Q何时刻都能代替真实对象。同Ӟ代理对象可以在执行真实对象操作时Q附加其他的操作Q相当于对真实对象进行封装?/span>

真实角色 Q代理角色所代表的真实对象,是我们最l要引用的对象?/span> ( 参见文献 1)

以下以?/span> Java 与模式》中的示例ؓ例:

抽象角色Q?/span>

abstract public class Subject

{

    abstract public void request();

}

真实角色Q实C Subject ?/span> request() Ҏ?/span>

public class RealSubject extends Subject

{

       public RealSubject()

       {

       }

      

       public void request()

       {

              System.out.println("From real subject.");

       }

}

代理角色Q?/span>

public class ProxySubject extends Subject

{

    private RealSubject realSubject;  // 以真实角色作Z理角色的属?/span>

      

       public ProxySubject()

       {

       }

 

       public void request()  // 该方法封装了真实对象?/span> request Ҏ

       {

        preRequest(); 

              if( realSubject == null )

        {

                     realSubject = new RealSubject();

              }

        realSubject.request();  // 此处执行真实对象?/span> request Ҏ

        postRequest();

       }

 

    private void preRequest()

    {

        //something you want to do before requesting

    }

 

    private void postRequest()

    {

        //something you want to do after requesting

    }

}

客户端调用:

Subject sub=new ProxySubject();

Sub.request();

       ׃上代码可以看出,客户实际需要调用的?/span> RealSubject request() ҎQ现在用 ProxySubject 来代?/span> RealSubject c,同样辑ֈ目的Q同时还装了其他方?/span> (preRequest(),postRequest()) Q可以处理一些其他问题?/span>

       另外Q如果要按照上述的方法用代理模式,那么真实角色必须是事先已l存在的Qƈ其作ؓ代理对象的内部属性。但是实际用时Q一个真实角色必d应一个代理角Ԍ如果大量使用会导致类的急剧膨胀Q此外,如果事先q不知道真实角色Q该如何使用代理呢?q个问题可以通过 Java 的动态代理类来解冟?/span>

 

2. 动态代理类

       Java 动态代理类位于 Java.lang.reflect 包下Q一般主要涉及到以下两个c:

(1). Interface InvocationHandler Q该接口中仅定义了一个方?/span> Object Q?/span> invoke(Object obj,Method method, Object[] args) 。在实际使用ӞW一个参?/span> obj 一般是指代理类Q?/span> method 是被代理的方法,如上例中?/span> request() Q?/span> args Ҏ的参数数l。这个抽象方法在代理cM动态实现?/span>


(2).Proxy
Q该cd为动态代理类Q作用类g上例中的 ProxySubject Q其中主要包含以下内容:

Protected Proxy(InvocationHandler h) Q构造函敎ͼ估计用于l内部的 h 赋倹{?/span>

Static Class getProxyClass (ClassLoader loader, Class[] interfaces) Q获得一个代理类Q其?/span> loader 是类装蝲器, interfaces 是真实类所拥有的全部接口的数组?/span>

Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) Q返回代理类的一个实例,q回后的代理cd以当作被代理cM?/span> ( 可用被代理cȝ?/span> Subject 接口中声明过的方?/span> ) ?/span>


      
所?/span> Dynamic Proxy 是这样一U?/span> class Q它是在q行时生成的 class Q在生成它时你必L供一l?/span> interface l它Q然后该 class 宣U它实现了这?/span> interface 。你当然可以把该 class 的实例当作这?/span> interface 中的M一个来用。当然啦Q这?/span> Dynamic Proxy 其实是一?/span> Proxy Q它不会替你作实质性的工作Q在生成它的实例时你必须提供一?/span> handler Q由它接实际的工作?/span> ( 参见文献 3)

    在用动态代理类Ӟ我们必须实现 InvocationHandler 接口Q以W一节中的示例ؓ例:

抽象角色 ( 之前是抽象类Q此处应改ؓ接口 ) Q?/span>

public interface Subject

{

    abstract public void request();

}

具体角色 RealSubject Q同上;

 

代理角色Q?/span>

import java.lang.reflect.Method;

import java.lang.reflect.InvocationHandler;

 

public class DynamicSubject implements InvocationHandler {

  private Object sub;

 

  public DynamicSubject() {

  }

 

  public DynamicSubject(Object obj) {

    sub = obj;

  }

 

 

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    System.out.println("before calling " + method);

 

    method.invoke(sub,args);

 

    System.out.println("after calling " + method);

    return null;

  }

 

}

 

       该代理类的内部属性ؓ Object c,实际使用旉过该类的构造函?/span> DynamicSubject(Object obj) 对其赋|此外Q在该类q实C invoke ҎQ该Ҏ中的

method.invoke(sub,args);

其实是调用被代理对象的要被执行的ҎQ方法参?/span> sub 是实际的被代理对象, args 为执行被代理对象相应操作所需的参数。通过动态代理类Q我们可以在调用之前或之后执行一些相x作?/span>

客户?/span> Q?/span>

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Proxy;

import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

 

public class Client

{

 

    static public void main(String[] args) throws Throwable

       {

      RealSubject rs = new RealSubject();  // 在这里指定被代理c?/span>

      InvocationHandler ds = new DynamicSubject(rs);  // 初始化代理类

         Class cls = rs.getClass();

      // 以下是分解步?/span>

      /*

      Class c = Proxy.getProxyClass(cls.getClassLoader(),cls.getInterfaces()) ;

      Constructor ct=c.getConstructor(new Class[]{InvocationHandler.class});

      Subject subject =(Subject) ct.newInstance(new Object[]{ds});

     */

     // 以下是一ơ性生?/span>

      Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(),

                                 cls.getInterfaces(),ds );


      subject.request();

}

       通过q种方式Q被代理的对?/span> (RealSubject) 可以在运行时动态改变,需要控制的接口 (Subject 接口 ) 可以在运行时改变Q控制的方式 (DynamicSubject c?/span> ) 也可以动态改变,从而实C非常灉|的动态代理关p?/span> ( 参见文献 2) ?/span>



飞熊 2010-01-17 16:52 发表评论
]]>
单例模式http://www.aygfsteel.com/kyleYang/archive/2010/01/14/309585.html飞熊飞熊Thu, 14 Jan 2010 14:55:00 GMThttp://www.aygfsteel.com/kyleYang/archive/2010/01/14/309585.htmlhttp://www.aygfsteel.com/kyleYang/comments/309585.htmlhttp://www.aygfsteel.com/kyleYang/archive/2010/01/14/309585.html#Feedback0http://www.aygfsteel.com/kyleYang/comments/commentRss/309585.htmlhttp://www.aygfsteel.com/kyleYang/services/trackbacks/309585.html1.饿汉式单例类
public class Singleton {

  private Singleton(){}

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

  private static Singleton instance = new Singleton();

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

2.懒汉式单例类
public class Singleton2 {
    
//U有的默认构造子
    private Singleton2() {}
    
    
//注意Q这里没有final    
    private static Singleton2 single;
    
    
//只实例化一?/span>
    static{
        single 
= new Singleton2();
    }
    
    
//静态工厂方法?/span>
    public synchronized  static Singleton2 getInstance() {
         
if (single == null) {  
             single 
= new Singleton2();
         }  
        
return single;
    }
}
        上面l出懒汉式单例类实现里对静态工厂方法用了同步化,以处理多U程环境。有些设计师在这里徏议用所谓的"双重查成?.必须指出的是Q?双重查成?不可以在Java 语言中用。不十分熟悉的读者,可以看看后面l出的小节?同样Q由于构造子是私有的Q因此,此类不能被ѝ饿汉式单例cd自己被加载时将自己实例化。即便加载器是静态的Q在饿汉式单例类被加载时仍会自己实例化。单从资源利用效率角度来Ԍq个比懒汉式单例cȝ差些。从速度和反应时间角度来Ԍ则比懒汉式单例类E好些。然而,懒汉式单例类在实例化Ӟ必须处理好在多个U程同时首次引用此类时的讉K限制问题Q特别是当单例类作ؓ资源控制器,在实例化时必然涉及资源初始化Q而资源初始化很有可能耗费旉。这意味着出现多线E同旉ơ引用此cȝ机率变得较大?br />
3.单例模式 -- 双重查锁机制
public class DoubleLockSingleton {
    private static DoubleLockSingleton instance = null;
    private DoubleLockSingleton() {
    }

    public static DoubleLockSingleton getInstance()
   {
     if (instance == null)
     {
       synchronized(DoubleLockSingleton .class) {  //1
         if (instance == null)          //2
           instance = new DoubleLockSingleton ();  //3
       }
     }
     return instance;
   }
}
Singleton的好处还在于可以节省内存Q因为它限制?br />实例的个敎ͼ有利于Java垃圾回收Qgarbage collectionQ?br /> 
4.发明者是Google公司的Bob lee:
 public   class  Singleton   {  
 
   static   class  SingletonHolder   {  
     static  Singleton instance  =   new  Singleton();  
  }   
 
   public   static  Singleton getInstance()   {  
     return  SingletonHolder.instance;  
  }   
 
}



飞熊 2010-01-14 22:55 发表评论
]]>
վ֩ģ壺 ɽ| | | | ɽ| | | żҴ| | ʲ| ƽ| | | ³ľ| ˼é| | | ؼ| | ˮ| | | | | ƶ| ҵ| | ɽ| | Դ| ƽ| | | | | | | | º| | ʯ|