??xml version="1.0" encoding="utf-8" standalone="yes"?>国内偷自视频区视频综合,亚洲一区二区三区色,久久99国产精品久久99果冻传媒http://www.aygfsteel.com/powerwind/category/18315.htmlJust for javazh-cnThu, 08 Mar 2007 02:28:24 GMTThu, 08 Mar 2007 02:28:24 GMT60设计模式之Interpreter(解释?http://www.aygfsteel.com/powerwind/articles/87031.htmlpowerwindpowerwindMon, 11 Dec 2006 11:54:00 GMThttp://www.aygfsteel.com/powerwind/articles/87031.htmlhttp://www.aygfsteel.com/powerwind/comments/87031.htmlhttp://www.aygfsteel.com/powerwind/articles/87031.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87031.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87031.html设计模式之Interpreter(解释?

板桥里h http://www.jdon.com 2002/05/05

模式实战书籍《Java实用pȝ开发指南?/font>

Interpreter解释器模式定?
定义语言的文?,q且建立一个解释器来解释该语言中的句子.

Interpreterg使用面不是很q?它描qC一个语a解释器是如何构成?在实际应用中,我们可能很少L造一个语a的文?我们q是来简单的了解一?

首先要徏立一个接?用来描述共同的操?

public interface AbstractExpression {
   void interpret( Context context );
}

再看看包含解释器之外的一些全局信息

public interface Context { }

AbstractExpression的具体实现分两种:l结W表辑ּ和非l结W表辑ּ:

public   class  TerminalExpression  implements  AbstractExpression { 
   
public   void  interpret( Context context ) { }

对于文法中没一条规?非终l符表达式都必须?

public   class  NonterminalExpression  implements  AbstractExpression 
   
private  AbstractExpression successor; 
  
   
public   void  setSuccessor( AbstractExpression successor ) 
     
this .successor  =  successor; 
   }
 

   
public  AbstractExpression getSuccessor() 
     
return  successor; 
   }


   
public   void  interpret( Context context )  { }  
}
 


powerwind 2006-12-11 19:54 发表评论
]]>
设计模式之Visitorhttp://www.aygfsteel.com/powerwind/articles/87032.htmlpowerwindpowerwindMon, 11 Dec 2006 11:54:00 GMThttp://www.aygfsteel.com/powerwind/articles/87032.htmlhttp://www.aygfsteel.com/powerwind/comments/87032.htmlhttp://www.aygfsteel.com/powerwind/articles/87032.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87032.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87032.html设计模式之Visitor

板桥里h http://www.jdon.com 2002/05/05Q{载请保留Q?/p>

模式实战书籍《Java实用pȝ开发指南?/font>

Visitor讉K者模式定?/b>
作用于某个对象群中各个对象的操作. 它可以你在不改变这些对象本w的情况?定义作用于这些对象的新操?

在Java?Visitor模式实际上是分离了collectionl构中的元素和对q些元素q行操作的行?

Z使用Visitor?
Java的Collection(包括Vector和Hashtable)是我们最l常使用的技?可是Collection好象是个黑色大染~?本来有各U鲜明类型特征的对象一旦放入后,再取出时,q些cd消׃.那么我们势必要用If来判??


Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
   Object o = iterator.next();
   if (o instanceof Collection)
      messyPrintCollection((Collection)o);
   else if (o instanceof String)
      System.out.println("'"+o.toString()+"'");
   else if (o instanceof Float)
      System.out.println(o.toString()+"f");
   else
      System.out.println(o.toString());
}
在上例中,我们使用?instanceof来判?o的类?

很显?q样做的~点代码If else if 很繁?我们可以用Visitor模式解决?

如何使用Visitor?
针对上例,定义接口叫Visitable,用来定义一个Accept操作,也就是说让Collection每个元素具备可访问?

被访问者是我们Collection的每个元素Element,我们要ؓq些Element定义一个可以接受访问的接口(讉K和被讉K是互动的,只有讉K?被访问者如果表CZƢ迎,讉K者就不能讉K),取名为VisitableQ也可取名ؓElement?/p>
public interface Visitable
{
   public void accept(Visitor visitor);
}

被访问的具体元素l承q个新的接口VisitableQ?/p>

public class StringElement implements Visitable
{
   private String value;
   public StringElement(String string) {
      value = string;
   }

   public String getValue(){
      return value;
   }


   //定义accept的具体内?q里是很单的一句调?br />   public void accept(Visitor visitor) {
      visitor.visitString(this);
   }
}


上面是被讉K者是字符串类型,下面再徏立一个Floatcd的:

public class FloatElement implements Visitable
{
   private Float value;
   public FloatElement(Float value) {
      this.value = value;
   }

   public Float getValue(){
      return value;
   }


   //定义accept的具体内?q里是很单的一句调?br />   public void accept(Visitor visitor) {
      visitor.visitFloat(this);
   }
}


我们设计一个接口visitor讉K者,在这个接口中,有一些访问操作,q些讉K操作是专门访问对象集合Collection中有可能的所有类Q目前我们假定有三个行ؓQ访问对象集合中的字W串cdQ访问对象集合中的FloatcdQ访问对象集合中的对象集合类型。注意最后一个类型是集合嵌套Q通过q个嵌套实现可以看出使用讉K模式的一个优炏V?/p>

接口visitor讉K者如下:

public interface Visitor
{

   public void visitString(StringElement stringE);
   public void visitFloat(FloatElement floatE);
   public void visitCollection(Collection collection);

}

讉K者的实现:

public class ConcreteVisitor implements Visitor
{
   //在本Ҏ?我们实现了对Collection的元素的成功讉K
   public void visitCollection(Collection collection) {
      Iterator iterator = collection.iterator()
      while (iterator.hasNext()) {
         Object o = iterator.next();
         if (o instanceof Visitable)
            ((Visitable)o).accept(this);
      }
   ?/p>

   public void visitString(StringElement stringE) {
      System.out.println("'"+stringE.getValue()+"'");
   }
   public void visitFloat(FloatElement floatE){
      System.out.println(floatE.getValue().toString()+"f");
   }

}

在上面的visitCollection我们实现了对Collection每个元素讉K,只用了一个判断语?只要判断其是否可以访?

StringElement只是一个实玎ͼ可以拓展为更多的实现Q整个核心奥妙在acceptҎ中,在遍历CollectionӞ通过相应的acceptҎ调用具体cd的被讉K者。这一步确定了被访问者类型,

如果是StringElementQ而StringElement则回调访问者的visiteStringҎQ这一步实C行ؓ操作Ҏ?/p>

客户端代码:

Visitor visitor = new ConcreteVisitor();

StringElement stringE = new StringElement("I am a String");
visitor.visitString(stringE);

Collection list = new ArrayList();
list.add(new StringElement("I am a String1"));
list.add(new StringElement("I am a String2"));
list.add(new FloatElement(new Float(12)));
list.add(new StringElement("I am a String3"));
visitor.visitCollection(list);

客户端代码中的list对象集合中放|了多种数据cdQ对对象集合中的讉K不必象一开始那P使用instance of逐个判断Q而是通过讉K者模式y妙实C?/p>

x,我们完成了Visitor模式基本l构.

使用Visitor模式的前?/b>
使用讉K者模式是对象结构中(Collection) 中的对象cd很少改变?/p>

在两个接口Visitor和Visitable?保Visitable很少变化,也就是说Q确保不能老有新的Element元素cd加进来,可以变化的是讉K者行为或操作Q也是Visitor的不同子cd以有多种,q样使用讉K者模式最方便.

如果对象集合中的对象集合l常有变? 那么不但Visitor实现要变化,Visistable也要增加相应行ؓQGOF?不如在这些对象类中直接逐个定义操作Q无需使用讉K者设计模式?/p>

但是在Java中,Java的Reflect技术解决了q个问题Q因此结合reflect反射机制Q可以得访问者模式适用范围更广了?/p>

Reflect技术是在运行期间动态获取对象类型和Ҏ的一U技?具体实现参考Javaworld?a target="_blank">英文原文.

 



powerwind 2006-12-11 19:54 发表评论
]]>
设计模式之Strategy({略)http://www.aygfsteel.com/powerwind/articles/87027.htmlpowerwindpowerwindMon, 11 Dec 2006 11:52:00 GMThttp://www.aygfsteel.com/powerwind/articles/87027.htmlhttp://www.aygfsteel.com/powerwind/comments/87027.htmlhttp://www.aygfsteel.com/powerwind/articles/87027.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87027.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87027.html设计模式之Strategy({略)

板桥里h http://www.jdon.com 2002/03/30

模式实战书籍《Java实用pȝ开发指南?/font>

Strategy{略模式是属于设计模式中 对象行ؓ型模?主要是定义一pd的算?把这些算法一个个装成单独的c?

Stratrgy应用比较q泛,比如, 公司l营业务变化? 可能有两U实现方?一个是U条曲线,一个是框图(bar),q是两种法,可以使用Strategy实现.

q里以字W串替代Z, 有一个文?我们需要读取后,希望替代其中相应的变?然后输出.关于替代其中变量的方法可能有多种Ҏ,q取决于用户的要?所以我们要准备几套变量字符替代Ҏ.

 

首先,我们建立一个抽象类RepTempRule 定义一些公用变量和Ҏ:

public abstract class RepTempRule{

protected String oldString="";
public void setOldString(String oldString){
  this.oldString=oldString;
}

protected String newString="";
public String getNewString(){
  return newString;
}



public abstract void replace() throws Exception;


}

在RepTempRule?有一个抽象方法abstract需要承明?q个replace里其实是替代的具体方?
我们现在有两个字W替代方?
1.文本中aaa替代成bbb;
2.文本中aaa替代成ccc;

对应的类分别是RepTempRuleOne RepTempRuleTwo

public class RepTempRuleOne extends RepTempRule{


public void replace() throws Exception{

  //replaceFirst是jdk1.4新特?
  newString=oldString.replaceFirst("aaa", "bbbb")
  System.out.println("this is replace one");
  
}


}

public class RepTempRuleTwo extends RepTempRule{


public void replace() throws Exception{

  newString=oldString.replaceFirst("aaa", "ccc")
  System.out.println("this is replace Two");
  
}


}

W二步:我们要徏立一个算法解决类Q用来提供客L可以自由选择法?/p>
public class RepTempRuleSolve {

  private RepTempRule strategy;

  public RepTempRuleSolve(RepTempRule rule){
    this.strategy=rule;
  }

  public String getNewContext(Site site,String oldString) {
    return strategy.replace(site,oldString);
  }

  public void changeAlgorithm(RepTempRule newAlgorithm) {
    strategy = newAlgorithm;
  }

}

 

 

调用如下:

public class test{

......

  public void testReplace(){

  //使用W一套替代方?br />  RepTempRuleSolve solver=new RepTempRuleSolve(new RepTempRuleSimple());
  solver.getNewContext(site,context);

  //使用W二?/p>

  solver=new RepTempRuleSolve(new RepTempRuleTwo());
  solver.getNewContext(site,context);

  }

.....

}

我们辑ֈ了在q行期间Q可以自由切换算法的目的?/p>

实际整个Strategy的核心部分就是抽象类的?使用Strategy模式可以在用户需要变化时,修改量很?而且快?

Strategy和Factory有一定的cM,Strategy相对单容易理?q且可以在运行时刻自由切换。Factory重点是用来创建对象?/p>

Strategy适合下列场合:

1.以不同的格式保存文g;

2.以不同的法压羃文g;

3.以不同的法截获图象;



powerwind 2006-12-11 19:52 发表评论
]]>
设计模式之Mediator(中介?http://www.aygfsteel.com/powerwind/articles/87028.htmlpowerwindpowerwindMon, 11 Dec 2006 11:52:00 GMThttp://www.aygfsteel.com/powerwind/articles/87028.htmlhttp://www.aygfsteel.com/powerwind/comments/87028.htmlhttp://www.aygfsteel.com/powerwind/articles/87028.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87028.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87028.html设计模式之Mediator(中介?

板桥里h http://www.jdon.com 2002/05/05

模式实战书籍《Java实用pȝ开发指南?/font>

Mediator中介者模式定?
用一个中介对象来装一pd关于对象交互行ؓ.

Z使用Mediator?
各个对象之间的交互操作非常多;每个对象的行为操作都依赖彼此Ҏ,修改一个对象的行ؓ,同时会涉及到修改很多其他对象的行?如果使用Mediator模式,可以使各个对象间的耦合松散,只需兛_?Mediator的关p?使多对多的关pd成了一对多的关p?可以降低pȝ的复杂?提高可修Ҏ展?

如何使用?

首先 有一个接?用来定义成员对象之间的交互联pL?

public interface Mediator { }

Meiator具体实现,真正实现交互操作的内?

public class ConcreteMediator implements Mediator {

   //假设当前有两个成?
   private ConcreteColleague1 colleague1 = new ConcreteColleague1();
   private ConcreteColleague2 colleague2 = new ConcreteColleague2();

   ...

}

再看看另外一个参与?成员,因ؓ是交互行?都需要双Ҏ供一些共同接?q种要求在Visitor Observer{模式中都是相同?

public class Colleague {
   private Mediator mediator;
   public Mediator getMediator() {
      return mediator;
   }

   public void setMediator( Mediator mediator ) {
      this.mediator = mediator;
   }
}

public class ConcreteColleague1 { }

public class ConcreteColleague2 { }

每个成员都必ȝ道Mediator,q且?Mediator联系,而不是和其他成员联系.

x,Mediator模式框架完成,可以发现Mediator模式规定不是很多,大体框架也比较简?但实际用v来就非常灉|.

Mediator模式在事仉动类应用中比较多,例如界面设计GUI.;聊天,消息传递等,在聊天应用中,需要有一个MessageMediator,专门负责request/reponse之间d的调?

MVC是J2EE的一个基本模?View Controller是一UMediator,它是Jsp和服务器上应用程序间的Mediator.

 



powerwind 2006-12-11 19:52 发表评论
]]>
设计模式之Chain of Responsibility(职责?http://www.aygfsteel.com/powerwind/articles/87024.htmlpowerwindpowerwindMon, 11 Dec 2006 11:51:00 GMThttp://www.aygfsteel.com/powerwind/articles/87024.htmlhttp://www.aygfsteel.com/powerwind/comments/87024.htmlhttp://www.aygfsteel.com/powerwind/articles/87024.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87024.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87024.html设计模式之Chain of Responsibility(职责?

板桥里h http://www.jdon.com 2002/04/21(转蝲请保?

Chain of Responsibility定义
Chain of Responsibility(CoR) 是用一pdc?classes)试图处理一个请求request,q些cM间是一个松散的耦合,唯一共同Ҏ在他们之间传递request. 也就是说Q来了一个请求,Acd处理Q如果没有处理,׃递到Bcd理,如果没有处理Q就传递到Ccd理,p栯一个链?chain)一样传递下厅R?/p>

如何使用?
虽然q一D|如何使用CoR,但是也是演示什么是CoR.

有一个Handler接口:

public interface Handler{
  public void handleRequest();
}

q是一个处理request的事例, 如果有多Urequest,比如 h帮助 h打印 或请求格式化Q?br />
最先想到的解决Ҏ是:在接口中增加多个hQ?br />public interface Handler{
  public void handleHelp();
  public void handlePrint();
  public void handleFormat();

}

具体是一D实现接口Handler代码Q?br />public class ConcreteHandler implements Handler{
  private Handler successor;

  public ConcreteHandler(Handler successor){
  this.successor=successor;
}

  public void handleHelp(){
    //具体处理hHelp的代?br />    ...
  }

  public void handlePrint(){
    //如果是print 转去处理Print
    successor.handlePrint();
  }
  public void handleFormat(){
    //如果是Format 转去处理format
    successor.handleFormat();
  }

}
一共有三个q样的具体实现类Q上面是处理help,q有处理Print 处理Formatq大概是我们最常用的编E思\?/p>

虽然思\单明了,但是有一个扩展问题,如果我们需要再增加一个请求requestU类,需要修Ҏ口及其每一个实现?/p>

W二Ҏ:每Urequest都变成一个接口,因此我们有以下代?Q?/p>

public interface HelpHandler{
  public void handleHelp();
}

public interface PrintHandler{
  public void handlePrint();
}

public interface FormatHandler{
  public void handleFormat();
}

public class ConcreteHandler
  implements HelpHandler,PrintHandler,FormatHandlet{
  private HelpHandler helpSuccessor;
  private PrintHandler printSuccessor;
  private FormatHandler formatSuccessor;

  public ConcreteHandler(HelpHandler helpSuccessor,PrintHandler printSuccessor,FormatHandler             formatSuccessor)
  {
    this.helpSuccessor=helpSuccessor;
    this.printSuccessor=printSuccessor;
    this.formatSuccessor=formatSuccessor;
  }

  public void handleHelp(){
    .......
  }

  public void handlePrint(){this.printSuccessor=printSuccessor;}

  public void handleFormat(){this.formatSuccessor=formatSuccessor;}

}

q个办法在增加新的请求request情况下,只是节省了接口的修改量,接口实现ConcreteHandlerq需要修攏V而且代码昄不简单美丽?/p>

解决Ҏ3: 在Handler接口中只使用一个参数化ҎQ?br />public interface Handler{
  public void handleRequest(String request);
}
那么Handler实现代码如下Q?br />public class ConcreteHandler implements Handler{
  private Handler successor;

  public ConcreteHandler(Handler successor){
    this.successor=successor;
  }

  public void handleRequest(String request){
    if (request.equals("Help")){
      //q里是处理Help的具体代?br />    }else
      //传递到下一?br />      successor.handle(request);

    }
  }

}

q里先假设request是StringcdQ如果不是怎么办?当然我们可以创徏一个专门类Request

最后解x?接口Handler的代码如下:
public interface Handler{
  public void handleRequest(Request request);
}
Requestcȝ定义:
public class Request{
  private String type;

  public Request(String type){this.type=type;}

  public String getType(){return type;}

  public void execute(){
    //request真正具体行ؓ代码
  }
}
那么Handler实现代码如下Q?br />public class ConcreteHandler implements Handler{
  private Handler successor;

  public ConcreteHandler(Handler successor){
    this.successor=successor;
  }

  public void handleRequest(Request request){
    if (request instanceof HelpRequest){
      //q里是处理Help的具体代?br />    }else if (request instanceof PrintRequst){
      request.execute();
    }else
      //传递到下一?br />      successor.handle(request);

    }
  }

}

q个解决Ҏ是CoR, 在一个链?都有相应职责的类,因此?b>Chain of Responsibility.

CoR的优点:
因ؓ无法预知来自外界Q客LQ的h是属于哪U类型,每个cd果碰到它不能处理的请求只要放弃就可以?/p>

~点是效率低Q因Z个请求的完成可能要遍历到最后才可能完成Q当然也可以用树的概念优化?在Java AWT1.0中,对于鼠标按键事情的处理就是用CoR,到Java.1.1以后Q就使用Observer代替CoR

扩展性差Q因为在CoR中,一定要有一个统一的接口Handler.局限性就在这里?/p>

与Command模式区别Q?/strong>

Command 模式需要事先协商客L和服务器端的调用关系Q比?1 代表 start 2 代表 move {,q些 都是装?request 中,到达服务器端再分解?/p>

CoR 模式无需q种事先U定Q服务器端可以?CoR 模式q行客户端请求的猜测Q一个个猜测 试验?




powerwind 2006-12-11 19:51 发表评论
]]>设计模式之Commandhttp://www.aygfsteel.com/powerwind/articles/87025.htmlpowerwindpowerwindMon, 11 Dec 2006 11:51:00 GMThttp://www.aygfsteel.com/powerwind/articles/87025.htmlhttp://www.aygfsteel.com/powerwind/comments/87025.htmlhttp://www.aygfsteel.com/powerwind/articles/87025.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87025.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87025.html设计模式之Command

板桥里h http://www.jdon.com 2002/4/23/Q{载请保留Q?/p>

模式实战书籍《Java实用pȝ开发指南?/font>

Command模式是最让我疑惑的一个模?我在阅读了很多代码后,才感觉隐U掌握其大概原理,我认为理解设计模式最主要是掌握v原理构?q样才对自己实际~程有指g?Command模式实际上不是个很具?规定很多的模?正是q个灉|?让h有些confuse.

Command定义
n 来自客L的请求传入一个对象,无需了解q个hȀzȝ 动作或有x受这个请求的处理l节?/p>

q是一U两台机器之间通讯联系性质的模式,cM传统q程?a?CallBack功能?

优点Q?br />解耦了发送者和接受者之间联pR?发送者调用一个操作,接受者接受请求执行相应的动作Q因Z用Command模式解耦,发送者无需知道接受者Q何接口?/p>

不少Command模式的代码都是针对图形界面的,它实际就是菜单命?我们在一个下拉菜单选择一个命令时,然后会执行一些动?

这些命令封装成在一个类?然后用户(调用?再对q个c进行操?q就是Command模式,换句话说,本来用户(调用?是直接调用这些命令的,如菜单上打开文档(调用?,q接指向打开文档的代?使用Command模式,是在这两者之间增加一个中间?这U直接关pL?同时两者之间都隔离,基本没有关系?

昄q样做的好处是符合封装的Ҏ?降低耦合?Command是将对行行封装的典型模式,Factory是将创徏q行装的模?
从Command模式,我也发现设计模式一?通病":好象喜欢简单的问题复杂? 喜欢在不同类中增加第三?当然q样做有利于代码的健壮?可维护?q有复用?

如何使用?
具体的Command模式代码各式各样,因ؓ如何装命o,不同pȝ,有不同的做法.下面事例是将命o装在一个Collection的List?M对象一旦加入List?实际上装入了一个封闭的黑盒?对象的特性消׃,只有取出?才有可能模糊的分辨出:

典型的Command模式需要有一个接?接口中有一个统一的方?q就?命?h装为对?:
public interface Command {
  public abstract void execute ( );
}

具体不同命o/h代码是实现接口Command,下面有三个具体命?br />
public class Engineer implements Command {

  public void execute( ) {
    //do Engineer's command
  }
}

public class Programmer implements Command {

  public void execute( ) {
    //do programmer's command
  }
}

public class Politician implements Command {

  public void execute( ) {
    //do Politician's command
  }
}


按照通常做法,我们可以直接调用这三个Command,但是使用Command模式,我们要将他们装h,扔到黑盒子List里去:

public class producer{
  public static List produceRequests() {
    List queue = new ArrayList();
    queue.add( new DomesticEngineer() );
    queue.add( new Politician() );
    queue.add( new Programmer() );
    return queue;
  }

}

q三个命令进入List中后,已经失去了其外表特征,以后再取?也可能无法分辨出谁是Engineer 谁是Programmer?看下面客L如何调用Command模式:

public class TestCommand {
  public static void main(String[] args) {
    
    List queue = Producer.produceRequests();
    for (Iterator it = queue.iterator(); it.hasNext(); )
      
 //客户端直接调用executeҎQ无需知道被调用者的其它更多cȝҎ名?br />        ((Command)it.next()).execute();
  

  }
}

由此可见,调用者基本只和接口打交道,不合具体实现交互,q也体现了一个原?面向接口~程,q样,以后增加W四个具体命令时,׃必修改调用者TestCommand中的代码?

理解了上面的代码的核心原?在用中,应该各人有自己Ҏ?特别是在如何分离调用者和具体命o?有很多实现方?上面的代码是使用"从Listq一?的做?q种做法只是Z演示.

使用Command模式的一个好理由q因为它能实现Undo功能.每个具体命o都可以记住它刚刚执行的动?q且在需要时恢复.

Command模式在界面设计中应用q泛.Java的Swing中菜单命令都是用Command模式,׃Java在界面设计的性能上还有欠~?因此界面设计具体代码我们׃讨论,|络上有很多q样的示?

参?
http://www.patterndepot.com/put/8/command.pdf

http://www.javaworld.com/javaworld/javatips/jw-javatip68.html

设计模式如何在具体项目中应用?a target="_blank">《Java实用pȝ开发指南?/font>

 



powerwind 2006-12-11 19:51 发表评论
]]>
设计模式之Statehttp://www.aygfsteel.com/powerwind/articles/87026.htmlpowerwindpowerwindMon, 11 Dec 2006 11:51:00 GMThttp://www.aygfsteel.com/powerwind/articles/87026.htmlhttp://www.aygfsteel.com/powerwind/comments/87026.htmlhttp://www.aygfsteel.com/powerwind/articles/87026.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87026.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87026.html设计模式之State

板桥里h http://www.jdon.com 2002/4/6/

模式实战书籍《Java实用pȝ开发指南?/font>

State模式的定?/b> : 不同的状?不同的行?或者说,每个状态有着相应的行?

何时使用 ?
State模式在实际用中比较?适合"状态的切换".因ؓ我们l常会用If elseif else q行状态切? 如果针对状态的q样判断切换反复出现,我们p联想到是否可以采取State模式?

不只是根据状?也有Ҏ属?如果某个对象的属性不?对象的行为就不一?q点在数据库pȝ中出现频率比较高,我们l常会在一个数据表的尾?加上property属性含义的字段,用以标识记录中一些特D性质的记?q种属性的改变(切换)又是随时可能发生?有可能要用State.

是否使用?
在实际?cM开关一L状态切换是很多?但有时ƈ不是那么明显,取决于你的经验和对系l的理解深度.

q里要阐q的?开兛_换状? ? 一般的状态判?是有一些区别的, " 一般的状态判?也是?if..elseifl构,例如:

    if (which==1) state="hello";
    else if (which==2) state="hi";
    else if (which==3) state="bye";

q是一?" 一般的状态判?,state值的不同是根据which变量来决定的,which和state没有关系.如果Ҏ:

    if (state.euqals("bye")) state="hello";
    else if (state.euqals("hello")) state="hi";
    else if (state.euqals("hi")) state="bye";

q就?"开兛_换状?,是将state的状态从"hello"切换?hi",再切换到""bye";在切换到"hello",好象一个旋转开?q种状态改变就可以使用State模式?

如果单纯有上面一U将"hello"-->"hi"-->"bye"-->"hello"q一个方向切?也不一定需要用State模式,因ؓState模式会徏立很多子c?复杂?但是如果又发生另外一个行?上面的切换方向反过来切?或者需要Q意切?需要State?

L下例:

public class Context{

  private Color state=null;

  public void push(){

    //如果当前red状?切换到blue
    if (state==Color.red) state=Color.blue;

    //如果当前blue状?切换到green
    else if (state==Color.blue) state=Color.green;

    //如果当前black状?切换到red
    else if (state==Color.black) state=Color.red;

    //如果当前green状?切换到black
    else if (state==Color.green) state=Color.black;
    
    Sample sample=new Sample(state);
    sample.operate();
  }

  public void pull(){

    //与push状态切换正好相?/p>

    if (state==Color.green) state=Color.blue;
    else if (state==Color.black) state=Color.green;
    else if (state==Color.blue) state=Color.red;
    else if (state==Color.red) state=Color.black;

    Sample2 sample2=new Sample2(state);
    sample2.operate();
  }

}

在上例中,我们有两个动作push推和pull?q两个开兛_?改变了Context颜色,x,我们需要用State模式优化?

另外注意:但就上例,state的变?只是单的颜色赋?q个具体行ؓ是很单的,State适合巨大的具体行?因此?本?实际使用中也不一定非要用State模式,q会增加子类的数?单的变复?

例如: 银行帐户, l常会在Open 状态和Close状态间转换.

例如: l典的TcpConnection, Tcp的状态有创徏 侦听 关闭三个,q且反复转换,其创?侦听 关闭的具体行Z是简单一两句p完成?适合使用State

例如:信箱POP帐号, 会有四种状? start HaveUsername Authorized quit,每个状态对应的行ؓ应该是比较大?适合使用State

例如:在工L挑选不同工?可以看成在不同工具中切换,适合使用State.?具体l图E序,用户可以选择不同工具l制Ҏ 直线 曲线,q种状态切换可以用State.

如何使用
State需要两U类型实体参?

1.state manager 状态管理器 ,是开?,如上面例子的Context实际是一个state manager, 在state manager中有对状态的切换动作.
2.用抽象类或接口实现的父类,,不同状态就是承这个父cȝ不同子类.

以上面的ContextZ.我们要修改它,建立两个cd的实?
W一? 首先建立一个父c?

public abstract class State{

  public abstract void handlepush(Context c);
  public abstract void handlepull(Context c);
  public abstract void getcolor();

}

父类中的Ҏ要对应state manager中的开兌?在state manager?本例是Context?有两个开兛_作push推和pull?那么在状态父cMp有具体处理这两个动作:handlepush() handlepull(); 同时q需要一个获取push或pulll果的方法getcolor()

下面是具体子cȝ实现:

public class BlueState extends State{

  public void handlepush(Context c){
     //ҎpushҎ"如果是blue状态的切换到green" ;
     c.setState(new GreenState());

  }
  public void handlepull(Context c){

     //ҎpullҎ"如果是blue状态的切换到red" ;
    c.setState(new RedState());

  }

  public abstract void getcolor(){ return (Color.blue)}

}

 

同样 其他状态的子类实现如blue一?

W二? 要重新改写State manager 也就是本例的Context:

public class Context{

  private Sate state=null; //我们原来的 Color state Ҏ了新建的State state;

  //setState是用来改变state的状?使用setState实现状态的切换
  pulic void setState(State state){

    this.state=state;

  }

  public void push(){

    //状态的切换的细节部?在本例中是颜色的变化,已经装在子cȝhandlepush中实?q里无需兛_
    state.handlepush(this);
    
    //因ؓsample要用state中的一个切换结?使用getColor()
    Sample sample=new Sample(state.getColor());
    sample.operate();

  }

 

  public void pull(){

    state.handlepull(this);
    
    Sample2 sample2=new Sample2(state.getColor());
    sample2.operate();

  }

}

 

x,我们也就实现了State的refactoryingq程.

以上只是相当单的一个实?在实际应用中,handlepush或handelpull的处理是复杂?

状态模式优点:
Q?Q?装转换q程Q也是转换规则
Q?Q?枚D可能的状态,因此Q需要事先确定状态种cR?br />

状态模式可以允许客L改变状态的转换行ؓQ而状态机则是能够自动改变状态,状态机是一个比较独立的而且复杂的机Ӟ具体可参考一个状态机开源项目:http://sourceforge.net/projects/smframework/

状态模式在工作或游戏{各U系l中有大量用,甚至是这些系l的核心功能设计Q例如政府OA中,一个批文的状态有多种Q未办;正在办理Q正在批C;正在审核Q已l完成等各种状态,使用状态机可以装q个状态的变化规则Q从而达到扩充状态时Q不必涉及到状态的使用者?/p>

在网l游戏中Q一个游戏活动存在开始;开玩;正在玩;输赢{各U状态,使用状态模式就可以实现游戏状态的LQ而游戏状态决定了游戏的各个方面,使用状态模式可以对整个游戏架构功能实现起到军_的主g用?/p>

状态模式实?/strong>Q?br />使用状态模式前Q客L外界需要介入改变状态,而状态改变的实现是琐或复杂的?/p>

使用状态模式后Q客L外界可以直接使用事gEvent实现Q根本不必关心该事gD如何状态变化,q些是由状态机{内部实现?/p>

q是一UEvent-condition-StateQ状态模式封装了condition-State部分?/p>

每个状态Ş成一个子c,每个状态只兛_它的下一个可能状态,从而无形中形成了状态{换的规则。如果新的状态加入,只涉及它的前一个状态修改和定义?/p>

状态{换有几个Ҏ实现Q一个在每个状态实现next()Q指定下一个状态;q有一U方法,讑֮一个StateOwnerQ在StateOwner讑֮stateEnter状态进入和stateExit状态退为?/p>

状态从一个方面说明了程Q流E是随时间而改变,状态是截取程某个旉片?/p>


相关文章Q?/p>

从工作流状态机实践中ȝ状态模式用心?/font>

参考资?
the State and Stategy
How to implement state-dependent behavior
The state patterns

 



powerwind 2006-12-11 19:51 发表评论
]]>
设计模式之Observerhttp://www.aygfsteel.com/powerwind/articles/87022.htmlpowerwindpowerwindMon, 11 Dec 2006 11:50:00 GMThttp://www.aygfsteel.com/powerwind/articles/87022.htmlhttp://www.aygfsteel.com/powerwind/comments/87022.htmlhttp://www.aygfsteel.com/powerwind/articles/87022.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87022.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87022.html设计模式之Observer

板桥里h http://www.jdon.com 2002/3/16

Java深入C定程?׃可避免的到设计模式(design pattern)q一概念,了解设计模式,自己对java中的接口或抽象类应用有更q理解.设计模式在java的中型系l中应用q泛,遵@一定的~程模式,才能使自q代码便于理解,易于交流,Observer(观察?模式是比较常用的一个模?其在界面设计中应用q泛,而本站所x的是Java在电子商务系l中应用,因此想从电子商务实例中分析Observer的应?

虽然|上商店形式多样,每个站点有自q特色,但也有其一般的共?单就"商品的变?以便及时通知订户"q一?是很多网上商店共有的模式,q一模式cMObserver patern观察者模?

具体的说,如果|上商店中商品在名称 h{方面有变化,如果pȝ能自动通知会员,是|上商店区别传统商店的一大特?q就需要在商品product中加入Observerq样角色,以便productl节发生变化?Observer能自动观察到q种变化,q能q行及时的update或notify动作.

Java的APIqؓ为我们提供现成的Observer接口Java.util.Observer.我们只要直接使用它就可以.

我们必须extends Java.util.Observer才能真正使用?
1.提供Add/Delete observer的方?
2.提供通知(notisfy) 所有observer的方?

//产品c?可供Jsp直接使用UseBean调用 该类主要执行产品数据库插?更新
public class product extends Observable{

  private String name;
  private float price;

  public String getName(){ return name;}
  public void setName(String name){
   this.name=name;
  //讄变化?
   setChanged();
   notifyObservers(name);

  }   

  public float getPrice(){ return price;}
  public void setPrice(float price){
   this.price=price;
  //讄变化?br />   setChanged();
   notifyObservers(new Float(price));

  }

  //以下可以是数据库更新 插入命o.
  public void saveToDb(){
  .....................

}


我们注意?在productcM 的setXXXҎ?我们讄?notify(通知)Ҏ, 当Jsp表单调用setXXX(如何调用见我?a target="_blank">另外一文?/font>),实际上就触发了notisfyObserversҎ,q将通知相应观察者应该采取行动了.

下面看看q些观察者的代码,他们I竟采取了什么行?

//观察者NameObserver主要用来对品名U?name)q行观察?br />public class NameObserver implements Observer{

  private String name=null;

  public void update(Observable obj,Object arg){

    if (arg instanceof String){

     name=(String)arg;
     //产品名称改变值在name?br />     System.out.println("NameObserver :name changet to "+name);

    }

  }

}

//观察者PriceObserver主要用来对品h?price)q行观察?br />public class PriceObserver implements Observer{

  private float price=0;

  public void update(Observable obj,Object arg){

    if (arg instanceof Float){

     price=((Float)arg).floatValue();
  
     System.out.println("PriceObserver :price changet to "+price);

    }

  }

}


Jsp中我们可以来正式执行q段观察者程?

<jsp:useBean id="product" scope="session" class="Product" />
<jsp:setProperty name="product" property="*" />

<jsp:useBean id="nameobs" scope="session" class="NameObserver" />
<jsp:setProperty name="product" property="*" />

<jsp:useBean id="priceobs" scope="session" class="PriceObserver" />
<jsp:setProperty name="product" property="*" />

<%

if (request.getParameter("save")!=null)
{
  product.saveToDb();


  out.println("产品数据变动 保存! q已l自动通知客户");

}else{

  //加入观察?br />  product.addObserver(nameobs);

  product.addObserver(priceobs);

%>

  //request.getRequestURI()是生本jsp的程序名,是自己调用自己
  <form action="<%=request.getRequestURI()%>" method=post>

  <input type=hidden name="save" value="1">
  产品名称:<input type=text name="name" >
  产品h:<input type=text name="price">
  <input type=submit>

  </form>

<%

}

%>

 

 

 

执行改JspE序,会出C个表单录入界? 需要输入品名U?产品h, ҎSubmit?q是执行该jsp?br />if (request.getParameter("save")!=null)之间的代?


׃q里使用了数据javabeans的自动赋值概?实际E序自动执行了setName setPrice语句.你会在服务器控制C发现下面信息::

NameObserver :name changet to ?????(Jsp表单中输入的产品名称)

PriceObserver :price changet to ???(Jsp表单中输入的产品h);

q说明观察者已l在行动?!!
同时你会在执行jsp的浏览器端得C?

产品数据变动 保存! q已l自动通知客户

上文׃使用jsp概念,隐含很多自动动作,现将调用观察者的Java代码写如?

 

public class Test {

  public static void main(String args[]){

Product product=new Product();

NameObserver nameobs=new NameObserver();
PriceObserver priceobs=new PriceObserver();

//加入观察?br />product.addObserver(nameobs);
product.addObserver(priceobs);

product.setName("子U了");
product.setPrice(9.22f);

  }

}

 

 

 

你会在发C面信?:

NameObserver :name changet to 子U了

PriceObserver :price changet to 9.22

q说明观察者在行动?!!

设计模式如何在具体项目中应用?a target="_blank">《Java实用pȝ开发指南?/font>



powerwind 2006-12-11 19:50 发表评论
]]>
设计模式之Templatehttp://www.aygfsteel.com/powerwind/articles/87020.htmlpowerwindpowerwindMon, 11 Dec 2006 11:49:00 GMThttp://www.aygfsteel.com/powerwind/articles/87020.htmlhttp://www.aygfsteel.com/powerwind/comments/87020.htmlhttp://www.aygfsteel.com/powerwind/articles/87020.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87020.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87020.html设计模式之Template

板桥里h http://www.jdon.com 2002/05/05

Template模板模式定义:
定义一个操作中法的骨?一些步骤的执行延迟到其子类?

使用Java的抽象类Ӟq怼使用到Template模式,因此Template模式使用很普?而且很容易理解和使用?/p>

 

public abstract class Benchmark
{
  /**
  * 下面操作是我们希望在子类中完?br />  */
  public abstract void benchmark();

  /**
  * 重复执行benchmarkơ数
  */
  public final long repeat (int count) {
    if (count <= 0)
      return 0;
    else {
      long startTime = System.currentTimeMillis();

    for (int i = 0; i < count; i++)
      benchmark();

    long stopTime = System.currentTimeMillis();
    return stopTime - startTime;
  }
}
}

在上例中,我们希望重复执行benchmark()操作,但是对benchmark()的具体内Ҏ有说?而是延迟到其子类中描q?

public class MethodBenchmark extends Benchmark
{
  /**
  * 真正定义benchmark内容
  */
  public void benchmark() {

    for (int i = 0; i < Integer.MAX_VALUE; i++){
      System.out.printtln("i="+i);    
    }
  }
}

x,Template模式已经完成,是不是很?

我们UrepeatҎ为模板方法, 它其中的benchmark()实现被gq到子类MethodBenchmark中实CQ?/p>

看看如何使用:

Benchmark operation = new MethodBenchmark();
long duration = operation.repeat(Integer.parseInt(args[0].trim()));
System.out.println("The operation took " + duration + " milliseconds");

 

也许你以前还疑惑抽象cL什么用,现在你应该彻底明白了? 至于q样做的好处,很显然啊,扩展性强,以后Benchmark内容变化,我只要再做一个承子cd可以,不必修改其他应用代码.



powerwind 2006-12-11 19:49 发表评论
]]>
设计模式之Memento(备忘机制)http://www.aygfsteel.com/powerwind/articles/87021.htmlpowerwindpowerwindMon, 11 Dec 2006 11:49:00 GMThttp://www.aygfsteel.com/powerwind/articles/87021.htmlhttp://www.aygfsteel.com/powerwind/comments/87021.htmlhttp://www.aygfsteel.com/powerwind/articles/87021.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87021.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87021.html设计模式之Memento(备忘机制)

板桥里h http://www.jdon.com 2002/05/05

Memento备望录模式定?
memento是一个保存另外一个对象内部状态拷贝的对象.q样以后可以将该对象恢复到原先保存的状?

Memento模式相对也比较好理解,我们看下列代?

public class Originator {

   private int number;

  private File file = null;

  public Originator(){}

  // 创徏一个Memento
  public Memento getMemento(){
    return new Memento(this);
  }

  // 恢复到原始?br />  public void setMemento(Memento m){
     number = m.number;
     file = m.file;
  }

}

 

我们再看看Mementoc?

private class Memento implements java.io.Serializable{

  private int number;

  private File file = null;

  public Memento( Originator o){

    number = o.number;
    file = o.file;

  }

}


可见 Memento中保存了Originator中的number和file的? 通过调用Originator中number和file值改变的?通过调用setMemento()Ҏ可以恢复.

Memento模式的缺Ҏ耗费?如果内部状态很?再保存一?无意要浪费大量内?

Memento模式在Jsp+Javabean中的应用
在Jsp应用?我们通常有很多表单要求用戯?比如用户注册,需要输入姓名和Email{? 如果一些表用h有填写或者填写错?我们希望在用h"提交Submit"?通过JspE序?发现实有未填写目,则在该项目下U字昄警告或错?同时,q要昄用户刚才已经输入的表?

如下图中 First Name是用户已l输?Last Name没有输入,我们则提C红字警?:

q种技术的实现,是利用了Javabean的scope="request"或scope="session"Ҏ?也就是Memento模式.

具体CZ和代码见 JavaWorld的英文原?/font> , Javabean表单输入Ҏ参见我的另?a target="_blank">一文?

 



powerwind 2006-12-11 19:49 发表评论
]]>
设计模式之Bridgehttp://www.aygfsteel.com/powerwind/articles/87018.htmlpowerwindpowerwindMon, 11 Dec 2006 11:48:00 GMThttp://www.aygfsteel.com/powerwind/articles/87018.htmlhttp://www.aygfsteel.com/powerwind/comments/87018.htmlhttp://www.aygfsteel.com/powerwind/articles/87018.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87018.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87018.html设计模式之Bridge

板桥里h http://www.jdon.com 2002/05/01

Bridge模式定义 :
抽象和行ؓ划分开?各自独立,但能动态的l合?/p>

M事物对象都有抽象和行Z分,例如人,人是一U抽象,人分男h和女人等Qh有行为,行ؓ也有各种具体表现Q所以,“h”与“h的行为”两个概念也反映了抽象和行ؓ之分?/p>

在面向对象设计的基本概念中,对象q个概念实际是由属性和行ؓ两个部分l成的,属性我们可以认为是一U静止的Q是一U抽象,一般情况下Q行为是包含在一个对象中Q但是,在有的情况下Q我们需要将q些行ؓ也进行归c,形成一个ȝ行ؓ接口Q这是桥模式的用处?/p>

Z么?
不希望抽象部分和行ؓ有一U固定的l定关系Q而是应该可以动态联pȝ?/p>

如果一个抽象类或接口有多个具体实现(子类、concrete subclass),q些子类之间关系可能有以下两U情?
1. q多个子cM间概忉|q列?如前面D?打桩,有两个concrete class:方Ş桩和圆Ş?q两个Ş状上的桩是ƈ列的,没有概念上的重复?br />
2.q多个子cM中有内容概念上重?那么需要我们把抽象共同部分和行为共同部分各自独立开?原来是准备放在一个接口里,现在需要设计两个接口:抽象接口和行为接口,分别攄抽象和行?

例如,一杯咖啡ؓ?子类实现cMؓ四个Q中杯加奶、大杯加奶?中杯不加奶、大杯不加奶?/p>

但是Q我们注意到Q上面四个子cM有概念重叠,可从另外一个角度进行考虑Q这四个cd际是两个角色的组合:抽象 和行为,其中抽象为:中杯和大杯;行ؓ为:加奶 不加Ӟ如加汁 加苹果汁Q?

实现四个子类在抽象和行ؓ之间发生了固定的l定关系Q如果以后动态增加加葡萄汁的行ؓQ就必须再增加两个类Q中杯加葡萄汁和大杯加葡萄汁。显然؜?扩展性极差?/p>

那我们从分离抽象和行为的角度Q用Bridge模式来实现?/p>

如何实现?
以上面提到的咖啡 Z. 我们原来打算只设计一个接?抽象c?,使用Bridge模式?我们需要将抽象和行为分开,加奶和不加奶属于行ؓ,我们它们抽象成一个专门的行ؓ接口.

先看看抽象部分的接口代码:

public abstract class Coffee
{
  CoffeeImp coffeeImp;

  public void setCoffeeImp() {
    this.CoffeeImp = CoffeeImpSingleton.getTheCoffeImp();
  }

  public CoffeeImp getCoffeeImp() {return this.CoffeeImp;}

  public abstract void pourCoffee();
}

其中CoffeeImp 是加不加奶的行ؓ接口,看其代码如下:

public abstract class CoffeeImp
{
  public abstract void pourCoffeeImp();
}

现在我们有了两个抽象c?下面我们分别对其q行l承,实现concrete class:

//中杯
public class MediumCoffee extends Coffee
{
  public MediumCoffee() {setCoffeeImp();}

  public void pourCoffee()
  {
    CoffeeImp coffeeImp = this.getCoffeeImp();
    //我们以重复次数来说明是冲中杯q是大杯 ,重复2ơ是中杯
    for (int i = 0; i < 2; i++)
    {

      coffeeImp.pourCoffeeImp();
    }
  
  }
}

//大杯
public class SuperSizeCoffee extends Coffee
{
  public SuperSizeCoffee() {setCoffeeImp();}

  public void pourCoffee()
  {
    CoffeeImp coffeeImp = this.getCoffeeImp();
    //我们以重复次数来说明是冲中杯q是大杯 ,重复5ơ是大杯
    for (int i = 0; i < 5; i++)
    {

      coffeeImp.pourCoffeeImp();
    }
  
  }
}

上面分别是中杯和大杯的具体实?下面再对行ؓCoffeeImpq行l承:

//加奶
public class MilkCoffeeImp extends CoffeeImp
{
  MilkCoffeeImp() {}

  public void pourCoffeeImp()
  {
    System.out.println("加了味的牛?);
  }
}

//不加?br />public class FragrantCoffeeImp extends CoffeeImp
{
  FragrantCoffeeImp() {}

  public void pourCoffeeImp()
  {
    System.out.println("什么也没加,清香");
  }
}

Bridge模式的基本框架我们已l搭好了,别忘记定义中q有一?动态结?我们现在可以喝到臛_四种咖啡:
1.中杯加奶
2.中杯不加?br />3.大杯加奶
4.大杯不加?/p>

看看是如何动态结合的,在用之?我们做个准备工作,设计一个单态类(Singleton)用来hold当前的CoffeeImp:

public class CoffeeImpSingleton
{
  private static CoffeeImp coffeeImp;

  public CoffeeImpSingleton(CoffeeImp coffeeImpIn)
   {this.coffeeImp = coffeeImpIn;}

  public static CoffeeImp getTheCoffeeImp()
  {
    return coffeeImp;
  }
}

看看中杯加奶 和大杯加?是怎么出来?

//拿出牛奶
CoffeeImpSingleton coffeeImpSingleton = new CoffeeImpSingleton(new MilkCoffeeImp());

//中杯加奶
MediumCoffee mediumCoffee = new MediumCoffee();
mediumCoffee.pourCoffee();

//大杯加奶
SuperSizeCoffee superSizeCoffee = new SuperSizeCoffee();
superSizeCoffee.pourCoffee();

注意: Bridge模式的执行类如CoffeeImp和Coffee是一对一的关p? 正确创徏CoffeeImp是该模式的关?

Bridge模式在EJB中的应用
EJB中有一个Data Access Object (DAO)模式,q是商业逻辑和具体数据资源分开?因ؓ不同的数据库有不同的数据库操?操作不同数据库的行为独立抽象成一个行为接口DAO.如下:

1.Business Object (cMCoffee)

实现一些抽象的商业操作:如寻找一个用户下所有的订单

涉及数据库操作都使用DAOImplementor.

2.Data Access Object (cMCoffeeImp)

一些抽象的Ҏ据库资源操作

3.DAOImplementor 如OrderDAOCS, OrderDAOOracle, OrderDAOSybase(cMMilkCoffeeImp FragrantCoffeeImp)

具体的数据库操作,?INSERT INTO "{语?OrderDAOOracle是Oracle OrderDAOSybase是Sybase数据?

4.数据?(Cloudscape, Oracle, or Sybase database via JDBC API)




powerwind 2006-12-11 19:48 发表评论
]]>
设计模式之Flyweight(享元) FlyWeight模式http://www.aygfsteel.com/powerwind/articles/87019.htmlpowerwindpowerwindMon, 11 Dec 2006 11:48:00 GMThttp://www.aygfsteel.com/powerwind/articles/87019.htmlhttp://www.aygfsteel.com/powerwind/comments/87019.htmlhttp://www.aygfsteel.com/powerwind/articles/87019.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87019.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87019.html设计模式之Flyweight(享元) FlyWeight模式

板桥里h http://www.jdon.com 2002/05/02

Flyweight模式定义:
避免大量拥有相同内容的小cȝ开销(如耗费内存),使大家共享一个类(元类).

Z么?
面向对象语言的原则就是一切都是对?但是如果真正使用h,有时对象数可能显得很庞大,比如,字处理Y?如果以每个文字都作ؓ一个对?几千个字,对象数就是几?无疑耗费内存,那么我们q是?求同存异",扑ևq些对象的共同?设计一个元c?装可以被共享的c?另外,q有一些特性是取决于应?context),是不可共享的,q也Flyweight中两个重要概念内部状态intrinsic和外部状态extrinsic之分.

说白?是先捏一个的原始模型,然后随着不同场合和环?再生各L征的具体模型,很显?在这里需要生不同的新对?所以Flyweight模式中常出现Factory模式.Flyweight的内部状态是用来׃n?Flyweight factory负责l护一个Flyweight pool(模式?来存攑ֆ部状态的对象.

Flyweight模式是一个提高程序效率和性能的模?会大大加快程序的q行速度.应用场合很多:比如你要从一个数据库中读取一pd字符?q些字符串中有许多是重复?那么我们可以这些字W串储存在Flyweight?pool)?

如何使用?

我们先从Flyweight抽象接口开?

public interface Flyweight
{
  public void operation( ExtrinsicState state );
}

//用于本模式的抽象数据cd(自行设计)
public interface ExtrinsicState { }

下面是接口的具体实现(ConcreteFlyweight) ,qؓ内部状态增加内存空? ConcreteFlyweight必须是可׃n?它保存的M状态都必须是内?intrinsic),也就是说,ConcreteFlyweight必须和它的应用环境场合无?

public class ConcreteFlyweight implements Flyweight {
  private IntrinsicState state;
  
  public void operation( ExtrinsicState state )
  {
      //具体操作
  }

}

当然,q不是所有的Flyweight具体实现子类都需要被׃n?所以还有另外一U不׃n的ConcreteFlyweight:

public class UnsharedConcreteFlyweight implements Flyweight {

  public void operation( ExtrinsicState state ) { }

}

Flyweight factory负责l护一个Flyweight?存放内部状?,当客Lh一个共享Flyweight?q个factory首先搜烦池中是否已经有可适用?如果?factory只是单返回送出q个对象,否则,创徏一个新的对?加入到池?再返回送出q个对象.?/p>

public class FlyweightFactory {
  //Flyweight pool
  private Hashtable flyweights = new Hashtable();

  public Flyweight getFlyweight( Object key ) {

    Flyweight flyweight = (Flyweight) flyweights.get(key);

    if( flyweight == null ) {
      //产生新的ConcreteFlyweight
      flyweight = new ConcreteFlyweight();
      flyweights.put( key, flyweight );
    }

    return flyweight;
  }
}

x,Flyweight模式的基本框架已l就l?我们看看如何调用:

FlyweightFactory factory = new FlyweightFactory();
Flyweight fly1 = factory.getFlyweight( "Fred" );
Flyweight fly2 = factory.getFlyweight( "Wilma" );
......

从调用上?好象是个Ua的Factory使用,但奥妙就在于Factory的内部设计上.

Flyweight模式在XML{数据源中应?/b>
我们上面已经提到,当大量从数据源中d字符?其中肯定有重复的,那么我们使用Flyweight模式可以提高效率,以唱片CDZ,在一个XML文g?存放了多个CD的资?

每个CD有三个字D?
1.出片日期(year)
2.歌唱者姓名等信息(artist)
3.q曲目 (title)

其中,歌唱者姓名有可能重复,也就是说,可能有同一个演p的多个不同时期 不同曲目的CD.我们?歌唱者姓?作ؓ可共享的ConcreteFlyweight.其他两个字段作ؓUnsharedConcreteFlyweight.

首先看看数据源XML文g的内?


<?xml version="1.0"?>
<collection>

<cd>
<title>Another Green World</title>
<year>1978</year>
<artist>Eno, Brian</artist>
</cd>

<cd>
<title>Greatest Hits</title>
<year>1950</year>
<artist>Holiday, Billie</artist>
</cd>

<cd>
<title>Taking Tiger Mountain (by strategy)</title>
<year>1977</year>
<artist>Eno, Brian</artist>
</cd>

.......

</collection>


虽然上面举例CD只有3?CD可看成是大量重复的小c?因ؓ其中成分只有三个字段,而且有重复的(歌唱者姓?.

CD是cM上面接口 Flyweight:


public class CD {

  private String title;
  private int year;
  private Artist artist;

  public String getTitle() {  return title; }
  public int getYear() {    return year;  }
  public Artist getArtist() {    return artist;  }

  public void setTitle(String t){    title = t;}
  public void setYear(int y){year = y;}
  public void setArtist(Artist a){artist = a;}

}

?歌唱者姓?作ؓ可共享的ConcreteFlyweight:

public class Artist {

  //内部状?br />  private String name;

  // note that Artist is immutable.
  String getName(){return name;}

  Artist(String n){
    name = n;
  }

}

再看看Flyweight factory,专门用来刉上面的可共享的ConcreteFlyweight:Artist

public class ArtistFactory {

  Hashtable pool = new Hashtable();

  Artist getArtist(String key){

    Artist result;
    result = (Artist)pool.get(key);
    ////产生新的Artist
    if(result == null) {
      result = new Artist(key);
      pool.put(key,result);
      
    }
    return result;
  }

}

当你有几千张甚至更多CD?Flyweight模式节省更多空?׃n的flyweight多,I间节省也就大.

 



powerwind 2006-12-11 19:48 发表评论
]]>
设计模式之Composite(l合)http://www.aygfsteel.com/powerwind/articles/87015.htmlpowerwindpowerwindMon, 11 Dec 2006 11:47:00 GMThttp://www.aygfsteel.com/powerwind/articles/87015.htmlhttp://www.aygfsteel.com/powerwind/comments/87015.htmlhttp://www.aygfsteel.com/powerwind/articles/87015.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87015.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87015.html设计模式之Composite(l合)

板桥里h http://www.jdon.com 2002/04/27Q{载请保留Q?/p>

Composite模式定义:
对象以树Şl构l织h,以达成“部分-整体?的层ơ结构,使得客户端对单个对象和组合对象的使用h一致?

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

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

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

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

下面的代码是以抽象类定义Q一般尽量用接口interface,

public abstract class Equipment
{
  private String name;
  //实h
  public abstract double netPrice();
  //折扣h
  public abstract double discountPrice();
  //增加部gҎ  
  public boolean add(Equipment equipment) { return false; }
  //删除部gҎ
  public boolean remove(Equipment equipment) { return false; }
  //注意q里Q这里就提供一U用于访问组合体cȝ部gҎ?br />  public Iterator iter() { return null; }
  
  public Equipment(final String name) { this.name=name; }
}

抽象cEquipment是Component定义Q代表着l合体类的对象们,Equipment中定义几个共同的Ҏ?/p>

public class Disk extends Equipment
{
  public Disk(String name) { super(name); }
  //定义Disk实h?
  public double netPrice() { return 1.; }
  //定义了disk折扣h?.5 Ҏ?br />  public double discountPrice() { return .5; }
}

Disk是组合体内的一个对象,或称一个部Ӟq个部g是个单独元素( Primitive)?br />q有一U可能是Q一个部件也是一个组合体Q就是说q个部g下面q有'儿子'Q这是树形结构中通常的情况,应该比较Ҏ理解。现在我们先要定义这个组合体Q?/p>

abstract class CompositeEquipment extends Equipment
{
  private int i=0;
  //定义一个Vector 用来存放'儿子'
  private Lsit equipment=new ArrayList();

  public CompositeEquipment(String name) { super(name); }

  public boolean add(Equipment equipment) {
     this.equipment.add(equipment);
     return true;
   }

  public double netPrice()
  {
    double netPrice=0.;
    Iterator iter=equipment.iterator();
    for(iter.hasNext())
      netPrice+=((Equipment)iter.next()).netPrice();
    return netPrice;
  }

  public double discountPrice()
  {
    double discountPrice=0.;
    Iterator iter=equipment.iterator();
    for(iter.hasNext())
      discountPrice+=((Equipment)iter.next()).discountPrice();
    return discountPrice;
  }
  

  //注意q里Q这里就提供用于讉K自己l合体内的部件方法?br />  //上面dIsk 之所以没有,是因为Disk是个单独(Primitive)的元?
  public Iterator iter()
  {
    return equipment.iterator() ;
  {
  //重蝲IteratorҎ
   public boolean hasNext() { return i<equipment.size(); }
  //重蝲IteratorҎ
   public Object next()
   {
    if(hasNext())
       return equipment.elementAt(i++);
    else
        throw new NoSuchElementException();
   }
  

}

上面CompositeEquipmentl承了Equipment,同时己里面的对象们提供了外部讉K的方?重蝲了Iterator,Iterator是Java的Collection的一个接口,是Iterator模式的实?

我们再看看CompositeEquipment的两个具体类:盘盒Chassis和箱子CabinetQ箱子里面可以放很多东西Q如底板Q电源盒Q硬盘盒{;盘盒里面可以放一些小讑֤Q如盘 软驱{。无疑这两个都是属于l合体性质的?/p>

public class Chassis extends CompositeEquipment
{
   public Chassis(String name) { super(name); }
   public double netPrice() { return 1.+super.netPrice(); }
   public double discountPrice() { return .5+super.discountPrice(); }
}

public class Cabinet extends CompositeEquipment
{
   public Cabinet(String name) { super(name); }
   public double netPrice() { return 1.+super.netPrice(); }
   public double discountPrice() { return .5+super.discountPrice(); }
}

x我们完成了整个Composite模式的架构?/p>

我们可以看看客户端调用Composote代码:

Cabinet cabinet=new Cabinet("Tower");

Chassis chassis=new Chassis("PC Chassis");
//PC Chassis装到Tower?(盘盒装到箱子里)
cabinet.add(chassis);
//一?0GB的硬盘装?PC Chassis (硬盘装到盘盒里)
chassis.add(new Disk("10 GB"));

//调用 netPrice()Ҏ;
System.out.println("netPrice="+cabinet.netPrice());
System.out.println("discountPrice="+cabinet.discountPrice());

上面调用的方法netPrice()或discountPrice()Q实际上Composite使用Iterator遍历了整个树形结?L同样包含q个Ҏ的对象ƈ实现调用执行.

Composite是个很y妙体现智慧的模式Q在实际应用中,如果到树Şl构Q我们就可以试是否可以使用q个模式?/p>

以论坛ؓ例,一个版(forum)中有很多帖子(message),q些帖子有原始脓Q有对原始脓的回应脓Q是个典型的树Şl构Q那么当然可以用Composite模式Q那么我们进入Jive中看看,是如何实现的.

Jive解剖
在Jive?ForumThread是ForumMessages的容器container(l合?.也就是说QForumThreadcM我们上例中的 CompositeEquipment.它和messages的关pd图:
[thread]
   |- [message]
   |- [message]
      |- [message]
      |- [message]
         |- [message]

我们在ForumThread看到如下代码Q?br />

public interface ForumThread {
   ....
   public void addMessage(ForumMessage parentMessage, ForumMessage newMessage)
         throws UnauthorizedException;

   public void deleteMessage(ForumMessage message)
         throws UnauthorizedException;

  
   public Iterator messages();
      ....

}

cMCompositeEquipment, 提供用于讉K自己l合体内的部件方? 增加 删除 遍历.

l合我的其他模式中对Jive的分析,我们已经基本大体理解了Jive论坛体系的框Ӟ如果你之前不理解设计模式Q而直接去看Jive源代码,你肯定无法看懂?/p>

参考文章:

Composite模式和树形结构的讨论



powerwind 2006-12-11 19:47 发表评论
]]>
设计模式之Decorator(Ҏ?http://www.aygfsteel.com/powerwind/articles/87017.htmlpowerwindpowerwindMon, 11 Dec 2006 11:47:00 GMThttp://www.aygfsteel.com/powerwind/articles/87017.htmlhttp://www.aygfsteel.com/powerwind/comments/87017.htmlhttp://www.aygfsteel.com/powerwind/articles/87017.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87017.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87017.html设计模式之Decorator(Ҏ?

板桥里h http://www.jdon.com 2002/04/28

装饰模式:Decorator常被译?装饰",我觉得翻译成"Ҏ?更Ş象点,Ҏ?decorator)是用来刷Ҏ?那么被刷Ҏ的对象我们称decoratee.q两U实体在Decorator模式中是必须?

Decorator定义:
动态给一个对象添加一些额外的职责,p在墙上刷Ҏ.使用Decorator模式相比用生成子cL式达到功能的扩充昑־更ؓ灉|.

Z么用Decorator?
我们通常可以使用l承来实现功能的拓展,如果q些需要拓展的功能的种cdJ多,那么势必生成很多子类,增加pȝ的复杂?同时,使用l承实现功能拓展,我们必须可预见这些拓展功?q些功能是编译时q定了,是静态的.

使用Decorator的理由是:q些功能需要由用户动态决定加入的方式和时?Decorator提供?x即用"的方?在运行期间决定何时增加何U功?

如何使用?
举Adapter中的打桩CZ,在Adapter中有两种c?方Ş?圆Ş?Adapter模式展示如何l合使用q两个类,在Decorator模式?我们是要在打桩时增加一些额外功?比如,挖坑 在桩上钉木板{?不关心如何用两个不相关的类.

我们先徏立一个接?

public interface Work
{
  public void insert();

}

接口Work有一个具体实?插入方Ş桩或圆Ş?q两个区别对Decorator是无所?我们以插入方形桩Z:

public class SquarePeg implements Work{
  public void insert(){
    System.out.println("方Ş桩插?);
  }

}

现在有一个应?需要在桩打入前,挖坑,在打入后,在桩上钉木板,q些额外的功能是动?可能随意增加调整修改,比如,可能又需要在打桩之后钉架?只是比喻).

那么我们使用Decorator模式,q里方Ş桩SquarePeg是decoratee(被刷Ҏ?,我们需要在decoratee上刷?Ҏ",q些Ҏ是那些额外的功?

public class Decorator implements Work{

  private Work work;
  //额外增加的功能被打包在这个List?br />  private ArrayList others = new ArrayList();

  //在构造器中用组合new方式,引入Work对象;
  public Decorator(Work work)
  {
    this.work=work;
  
    others.add("挖坑");

    others.add("钉木?);
  }

  public void insert(){

    newMethod();
  }


  
  //在新Ҏ?我们在insert之前增加其他Ҏ,q里ơ序先后是用LzL定的   
  public void newMethod()
  {
    otherMethod();
    work.insert();


  }

  public void otherMethod()
  {
    ListIterator listIterator = others.listIterator();
    while (listIterator.hasNext())
    {
      System.out.println(((String)(listIterator.next())) + " 正在q行");
    }

  }

}

在上例中,我们把挖坑和钉木杉K排在了打桩insert前面,q里只是举例说明额外功能ơ序可以L安排.

好了,Decorator模式出来?我们看如何调?

Work squarePeg = new SquarePeg();
Work decorator = new Decorator(squarePeg);
decorator.insert();

Decorator模式x完成.

如果你细?会发?上面调用cM我们d文g时的调用:

FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);

实际上Java 的I/O API是使用Decorator实现?/font>,I/O变种很多,如果都采取承方?会产生很多子类,昄相当J琐.

Jive中的Decorator实现
在论坛系l中,有些特别的字是不能出现在论坛中如"打倒XXX",我们需要过滤这?反动"的字?不让他们出现或者高亮度昄.

在IBM Java专栏中专?a target="_blank">谈Jive的文?/font>?有谈及Jive中ForumMessageFilter.java使用了Decorator模式,其实,该程序ƈ没有真正使用Decorator,而是提示?针对特别论坛可以设计额外增加的过滤功?那么可以重lForumMessageFilter作ؓDecorator模式?

所?我们在分辨是否真正是Decorator模式,以及会真正用Decorator模式,一定要把握好Decorator模式的定?以及其中参与的角?Decoratee 和Decorator).

 



powerwind 2006-12-11 19:47 发表评论
]]>
设计模式之Adapter(适配?http://www.aygfsteel.com/powerwind/articles/87014.htmlpowerwindpowerwindMon, 11 Dec 2006 11:46:00 GMThttp://www.aygfsteel.com/powerwind/articles/87014.htmlhttp://www.aygfsteel.com/powerwind/comments/87014.htmlhttp://www.aygfsteel.com/powerwind/articles/87014.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87014.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87014.html设计模式之Adapter(适配?

板桥里h http://www.jdon.com 2002/04/21

适配器模式定?
两个不兼容的类U合在一起用,属于l构型模?需要有Adaptee(被适配?和Adaptor(适配?两个w䆾.

Z使用?
我们l常到要将两个没有关系的类l合在一起?W一解决Ҏ是:修改各自cȝ接口Q但是如果我们没有源代码Q或者,我们不愿意ؓ了一个应用而修改各自的接口?怎么?

使用AdapterQ在q两U接口之间创Z个؜合接?淯?.

如何使用?
实现Adapter方式,其实"think in Java"?cd?一节中已经提到,有两U方式:l合(composition)和?inheritance).


假设我们要打桩,有两U类Q方形桩 圆Ş?
public class SquarePeg{
  public void insert(String str){
    System.out.println("SquarePeg insert():"+str);
  }

}

public class RoundPeg{
  public void insertIntohole(String msg){
    System.out.println("RoundPeg insertIntoHole():"+msg);
}
}

现在有一个应?需要既打方形桩,又打圆Ş?那么我们需要将q两个没有关pȝcȝ合应?假设RoundPeg我们没有源代?或源代码我们不想修改,那么我们使用Adapter来实现这个应?

public class PegAdapter extends SquarePeg{

  private RoundPeg roundPeg;

  public PegAdapter(RoundPeg peg)(this.roundPeg=peg;)

  public void insert(String str){ roundPeg.insertIntoHole(str);}

}

在上面代码中,RoundPeg属于Adaptee,是被适配?PegAdapter是Adapter,Adaptee(被适配者RoundPeg)和Target(目标SquarePeg)q行适配.实际上这是将l合Ҏ(composition)和?inheritance)Ҏl合q用.

PegAdapter首先l承SquarePegQ然后用new的组合生成对象方式,生成RoundPeg的对象roundPegQ再重蝲父类insert()Ҏ。从q里,你也了解使用new生成对象和用extendsl承生成对象的不?前者无需对原来的cM?甚至无需要知道其内部l构和源代码.

如果你有些Java使用的经验,已经发现Q这U模式经怋用?/p>

q一步?/b>
上面的PegAdapter是承了SquarePeg,如果我们需要两边承,即承SquarePeg 又承RoundPeg,因ؓJava中不允许多承,但是我们可以实现(implements)两个接口(interface)

public interface IRoundPeg{
  public void insertIntoHole(String msg);

}

public interface ISquarePeg{
  public void insert(String str);

}

下面是新的RoundPeg 和SquarePeg, 除了实现接口q一区别Q和上面的没什么区别?br />public class SquarePeg implements ISquarePeg{
  public void insert(String str){
    System.out.println("SquarePeg insert():"+str);
  }

}

public class RoundPeg implements IRoundPeg{
  public void insertIntohole(String msg){
    System.out.println("RoundPeg insertIntoHole():"+msg);
  }
}

下面是新的PegAdapter,叫做two-way adapter:

public class PegAdapter implements IRoundPeg,ISquarePeg{

  private RoundPeg roundPeg;
  private SquarePeg squarePeg;

  // 构造方?br />  public PegAdapter(RoundPeg peg){this.roundPeg=peg;}
  // 构造方?br />  public PegAdapter(SquarePeg peg)(this.squarePeg=peg;)

  public void insert(String str){ roundPeg.insertIntoHole(str);}

}

q有一U叫Pluggable Adapters,可以动态的获取几个adapters中一个。用Reflection技术,可以动态的发现cM的PublicҎ?br />



powerwind 2006-12-11 19:46 发表评论
]]>
设计模式之Proxy(代理)http://www.aygfsteel.com/powerwind/articles/87013.htmlpowerwindpowerwindMon, 11 Dec 2006 11:45:00 GMThttp://www.aygfsteel.com/powerwind/articles/87013.htmlhttp://www.aygfsteel.com/powerwind/comments/87013.htmlhttp://www.aygfsteel.com/powerwind/articles/87013.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87013.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87013.html设计模式之Proxy(代理)

板桥里hbanq http://www.jdon.com 2002/04/21/

理解q用设计模?能够培养我们良好的面向对象编E习?同时在实际应用中,可以如鱼得水,享受游刃有余的乐?

代理模式是比较有用途的一U模?而且变种较多,应用场合覆盖从小l构到整个系l的大结?Proxy是代理的意?我们也许有代理服务器{概?代理概念可以解释?在出发点到目的地之间有一道中间层,意ؓ代理.

设计模式中定?/b>: 为其他对象提供一U代理以控制对这个对象的讉K.

Z么要使用Proxy?
1.授权机制 不同U别的用户对同一对象拥有不同的访问权?如Jive论坛pȝ?׃用Proxyq行授权机制控制,讉K论坛有两Uh:注册用户和游?未注册用?,Jive中就通过cMForumProxyq样的代理来控制q两U用户对论坛的访问权?

2.某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动.
举例两个具体情况:
(1)如果那个对象是一个是很大的图?需要花费很长时间才能显C出?那么当这个图片包含在文档中时,使用~辑器或览器打开q个文档,打开文档必须很迅?不能{待大图片处理完?q时需要做个图片Proxy来代替真正的囄.

(2)如果那个对象在Internet的某个远端服务器?直接操作q个对象因ؓ|络速度原因可能比较?那我们可以先用Proxy来代曉K个对?

M原则?对于开销很大的对?只有在用它时才创徏,q个原则可以为我们节省很多宝늚Java内存. 所?有些为Java耗费资源内存,我以和程序编制思\也有一定的关系.

如何使用Proxy?
?a >Jive论坛pȝZ,讉K论坛pȝ的用h多种cd:注册普通用?论坛理?pȝ理?游客,注册普通用h能发a;论坛理者可以管理他被授权的论坛;pȝ理者可以管理所有事务等,q些权限划分和管理是使用Proxy完成?

Forum是Jive的核心接?在Forum中陈列了有关论坛操作的主要行?如论坛名U?论坛描述的获取和修改,帖子发表删除~辑{?

在ForumPermissions中定义了各种U别权限的用?

public class ForumPermissions implements Cacheable {

/**
* Permission to read object.
*/
public static final int READ = 0;

/**
* Permission to administer the entire sytem.
*/
public static final int SYSTEM_ADMIN = 1;

/**
* Permission to administer a particular forum.
*/
public static final int FORUM_ADMIN = 2;

/**
* Permission to administer a particular user.
*/
public static final int USER_ADMIN = 3;

/**
* Permission to administer a particular group.
*/
public static final int GROUP_ADMIN = 4;

/**
* Permission to moderate threads.
*/
public static final int MODERATE_THREADS = 5;

/**
* Permission to create a new thread.
*/
public static final int CREATE_THREAD = 6;

/**
* Permission to create a new message.
*/
public static final int CREATE_MESSAGE = 7;

/**
* Permission to moderate messages.
*/
public static final int MODERATE_MESSAGES = 8;

.....

public boolean isSystemOrForumAdmin() {
  return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]);
}

.....

}

因此,Forum中各U操作权限是和ForumPermissions定义的用L别有关系?作ؓ接口Forum的实?ForumProxy正是这U对应关p联pv?比如,修改Forum的名U?只有论坛理者或pȝ理者可以修?代码如下:

public class ForumProxy implements Forum {

private ForumPermissions permissions;
private Forum forum;
this.authorization = authorization;

public ForumProxy(Forum forum, Authorization authorization,
ForumPermissions permissions)
{
this.forum = forum;
this.authorization = authorization;
this.permissions = permissions;
}

.....

public void setName(String name) throws UnauthorizedException,
ForumAlreadyExistsException
{
  //只有是系l或论坛理者才可以修改名称
  if (permissions.isSystemOrForumAdmin()) {
    forum.setName(name);
  }
  else {
    throw new UnauthorizedException();
  }
}

...

}

而DbForum才是接口Forum的真正实?以修改论坛名UCؓ?

public class DbForum implements Forum, Cacheable {
...

public void setName(String name) throws ForumAlreadyExistsException {

  ....

  this.name = name;
  //q里真正新名称保存到数据库?
  saveToDb();

  ....
}


...

}

凡是涉及到对论坛名称修改q一事g,其他E序都首先得和ForumProxy打交?由ForumProxy军_是否有权限做某一样事?ForumProxy是个名副其实?|关","安全代理pȝ".

在^时应用中,无可避免总要涉及到系l的授权或安全体p?不管你有无意识的使用Proxy,实际你已l在使用Proxy?

我们l箋l合Jive谈入׃?下面要涉及到工厂模式?如果你不了解工厂模式,L我的另外一文?设计模式之Factory

我们已经知道,使用Forum需要通过ForumProxy,Jive中创Z个Forum是用Factory模式,有一个ȝ抽象cForumFactory,在这个抽象类?调用ForumFactory是通过getInstance()Ҏ实现,q里使用了Singleton(也是设计模式之一,׃介绍文章很多,我就不写?看这?/a>),getInstance()q回的是ForumFactoryProxy.

Z么不q回ForumFactory,而返回ForumFactory的实现ForumFactoryProxy?
原因是明昄,需要通过代理定是否有权限创建forum.

在ForumFactoryProxy中我们看C码如?

public class ForumFactoryProxy extends ForumFactory {

  protected ForumFactory factory;
  protected Authorization authorization;
  protected ForumPermissions permissions;

  public ForumFactoryProxy(Authorization authorization, ForumFactory factory,
  ForumPermissions permissions)
  {
    this.factory = factory;
    this.authorization = authorization;
    this.permissions = permissions;
  }

  public Forum createForum(String name, String description)
      throws UnauthorizedException, ForumAlreadyExistsException
  {
    //只有pȝ理者才可以创徏forum
    if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) {
      Forum newForum = factory.createForum(name, description);
      return new ForumProxy(newForum, authorization, permissions);
    }
    else {
      throw new UnauthorizedException();
  }
}

ҎcreateForumq回的也是ForumProxy, Proxyp一道墙,其他E序只能和Proxy交互操作.

注意到这里有两个Proxy:ForumProxy和ForumFactoryProxy. 代表两个不同的职?使用Forum和创建Forum;
至于Z么将使用对象和创建对象分开,q也是ؓ什么用Factory模式的原因所?是ؓ?装" "分派";换句话说,可能功能单一?方便l护修改.

Jive论坛pȝ中其他如帖子的创建和使用,都是按照Forumq个思\而来?

以上我们讨论了如何用Proxyq行授权机制的访?Proxyq可以对用户隐藏另外一U称为copy-on-write的优化方?拯一个庞大而复杂的对象是一个开销很大的操?如果拯q程?没有对原来的对象有所修改,那么q样的拷贝开销没有必?用代理gq这一拯q程.

比如:我们有一个很大的Collection,具体如hashtable,有很多客L会ƈ发同时访问它.其中一个特别的客户端要q行q箋的数据获?此时要求其他客户端不能再向hashtable中增加或删除 东东.

最直接的解x案是:使用collection的lock,让这特别的客L获得q个lock,q行q箋的数据获?然后再释放lock.
public void foFetches(Hashtable ht){
  synchronized(ht){
    //具体的连l数据获取动?.
  }

}

但是q一办法可能锁住Collection会很长时?q段旉,其他客户端就不能讉K该Collection?

W二个解x案是cloneq个Collection,然后让连l的数据获取针对clone出来的那个Collection操作.q个Ҏ前提?q个Collection是可clone?而且必须有提供深度clone的方?Hashtable提供了对自qcloneҎ,但不是Key和value对象的clone,关于Clone含义可以参?a target="_blank">专门文章.
public void foFetches(Hashtable ht){

  Hashttable newht=(Hashtable)ht.clone();

}

问题又来?׃是针对clone出来的对象操?如果原来的母体被其他客户端操作修改了, 那么对clone出来的对象操作就没有意义?

最后解x?我们可以{其他客L修改完成后再q行clone,也就是说,q个特别的客L先通过调用一个叫clone的方法来q行一pd数据获取操作.但实际上没有真正的进行对象拷?直至有其他客L修改了这个对象Collection.

使用Proxy实现q个Ҏ.q就是copy-on-write操作.

Proxy应用范围很广,现在行的分布计方式RMI和Corba{都是Proxy模式的应?

更多Proxy应用,?a target="_blank">http://www.research.umbc.edu/~tarr/cs491/lectures/Proxy.pdf

Sun公司?Explore the Dynamic Proxy APIDynamic Proxy Classes

 



powerwind 2006-12-11 19:45 发表评论
]]>
设计模式之Facade(外观 ȝ Manager)http://www.aygfsteel.com/powerwind/articles/87011.htmlpowerwindpowerwindMon, 11 Dec 2006 11:44:00 GMThttp://www.aygfsteel.com/powerwind/articles/87011.htmlhttp://www.aygfsteel.com/powerwind/comments/87011.htmlhttp://www.aygfsteel.com/powerwind/articles/87011.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87011.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87011.html设计模式之Facade(外观 ȝ Manager)

板桥里h http://www.jdon.com 2002/4/6/Q{载请保留Q?/p>

Facade模式的定?/b> : 为子pȝ中的一l接口提供一个一致的界面.

Facade一个典型应用就是数据库JDBC的应?如下例对数据库的操作:

public class DBCompare {

  Connection conn = null;
  PreparedStatement prep = null;
  ResultSet rset = null;
  try {
     Class.forName( "<driver>" ).newInstance();
     conn = DriverManager.getConnection( "<database>" );
    
     String sql = "SELECT * FROM <table> WHERE <column name> = ?";
     prep = conn.prepareStatement( sql );
     prep.setString( 1, "<column value>" );
     rset = prep.executeQuery();
     if( rset.next() ) {
        System.out.println( rset.getString( "<column name" ) );
     }
  } catch( SException e ) {
     e.printStackTrace();
  } finally {
     rset.close();
     prep.close();
     conn.close();
  }
}

上例是Jsp中最通常的对数据库操作办?

在应用中,l常需要对数据库操?每次都写上述一D代码肯定比较麻?需要将其中不变的部分提炼出?做成一个接?q就引入了facade外观对象.如果以后我们更换Class.forName中的<driver>也非常方?比如从Mysql数据库换到Oracle数据?只要更换facade接口中的driver可?

我们做成了一?a target="_blank">Facade接口,使用该接?上例中的E序可以更改如?

public class DBCompare {

  String sql = "SELECT * FROM <table> WHERE <column name> = ?";  

  try {
     Mysql msql=new mysql(sql);
     prep.setString( 1, "<column value>" );
     rset = prep.executeQuery();
     if( rset.next() ) {
        System.out.println( rset.getString( "<column name" ) );
     }
  } catch( SException e ) {
     e.printStackTrace();
  } finally {
     mysql.close();
     mysql=null;
  }
}

可见非常?所有程序对数据库访问都是用改接口,降低pȝ的复杂?增加了灵zL?

如果我们要用连接池,也只要针对facade接口修改可?

 

׃囑֏以看? facade实际上是个理系l间关系,降低pȝ间耦合度的一个常用的办法,也许你已l不知不觉在使用,管不知道它是facade.



powerwind 2006-12-11 19:44 发表评论
]]>
设计模式之Singleton(单?http://www.aygfsteel.com/powerwind/articles/87010.htmlpowerwindpowerwindMon, 11 Dec 2006 11:43:00 GMThttp://www.aygfsteel.com/powerwind/articles/87010.htmlhttp://www.aygfsteel.com/powerwind/comments/87010.htmlhttp://www.aygfsteel.com/powerwind/articles/87010.html#Feedback0http://www.aygfsteel.com/powerwind/comments/commentRss/87010.htmlhttp://www.aygfsteel.com/powerwind/services/trackbacks/87010.html设计模式之Singleton(单?

板桥里h http://www.jdon.com 2002/05/07

单态定?/strong>:
Singleton模式主要作用是保证在Java应用E序中,一个类Class只有一个实例存在?

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

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

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

Singleton模式׃ؓ我们提供了这样实现的可能。用Singleton的好处还在于可以节省内存Q因为它限制了实例的个数Q有利于Java垃圾回收Qgarbage collectionQ?br />
我们常常看到工厂模式中类装入?class loader)中也用Singleton模式实现?因ؓ被装入的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个Ҏ比上面有所改进Q不用每ơ都q行生成对象Q只是第一ơ     
  //使用时生成实例,提高了效率!
  if (instance==null)
    instanceQnew Singleton();
  return instance;   }

}

 

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

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

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

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

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

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

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

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

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

q一步深入可参考:

Double-checked locking and the Singleton pattern

When is a singleton not a singleton?



powerwind 2006-12-11 19:43 发表评论
]]>
վ֩ģ壺 | | | | ԫ| | ¡| | | | ػ| ɫ| | | ͬ| | ̴| | | | | | ͨ| ʲ| | | | | | | | ³| | | | | | | ľ| | |