??xml version="1.0" encoding="utf-8" standalone="yes"?>国产亚洲精品线观看动态图,亚洲午夜久久久久久尤物,亚洲天堂一区二区http://www.tkk7.com/hengheng123456789/category/20692.htmlzh-cnTue, 20 Mar 2007 14:37:49 GMTTue, 20 Mar 2007 14:37:49 GMT60设计模式之Composite(l合)http://www.tkk7.com/hengheng123456789/articles/104911.html哼哼哼哼Tue, 20 Mar 2007 03:26:00 GMThttp://www.tkk7.com/hengheng123456789/articles/104911.htmlhttp://www.tkk7.com/hengheng123456789/comments/104911.htmlhttp://www.tkk7.com/hengheng123456789/articles/104911.html#Feedback0http://www.tkk7.com/hengheng123456789/comments/commentRss/104911.htmlhttp://www.tkk7.com/hengheng123456789/services/trackbacks/104911.html 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>

哼哼 2007-03-20 11:26 发表评论
]]>
设计模式之Decorator(Ҏ?http://www.tkk7.com/hengheng123456789/articles/104322.html哼哼哼哼Fri, 16 Mar 2007 09:57:00 GMThttp://www.tkk7.com/hengheng123456789/articles/104322.htmlhttp://www.tkk7.com/hengheng123456789/comments/104322.htmlhttp://www.tkk7.com/hengheng123456789/articles/104322.html#Feedback0http://www.tkk7.com/hengheng123456789/comments/commentRss/104322.htmlhttp://www.tkk7.com/hengheng123456789/services/trackbacks/104322.html装饰模式: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实现?/a>,I/O变种很多,如果都采取承方?会产生很多子类,昄相当J琐.

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

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

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



哼哼 2007-03-16 17:57 发表评论
]]>
设计模式之Facade(外观 ȝ Manager)http://www.tkk7.com/hengheng123456789/articles/104318.html哼哼哼哼Fri, 16 Mar 2007 09:42:00 GMThttp://www.tkk7.com/hengheng123456789/articles/104318.htmlhttp://www.tkk7.com/hengheng123456789/comments/104318.htmlhttp://www.tkk7.com/hengheng123456789/articles/104318.html#Feedback0http://www.tkk7.com/hengheng123456789/comments/commentRss/104318.htmlhttp://www.tkk7.com/hengheng123456789/services/trackbacks/104318.html 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.



哼哼 2007-03-16 17:42 发表评论
]]>
设计模式之Adapter(适配?http://www.tkk7.com/hengheng123456789/articles/104295.html哼哼哼哼Fri, 16 Mar 2007 08:36:00 GMThttp://www.tkk7.com/hengheng123456789/articles/104295.htmlhttp://www.tkk7.com/hengheng123456789/comments/104295.htmlhttp://www.tkk7.com/hengheng123456789/articles/104295.html#Feedback0http://www.tkk7.com/hengheng123456789/comments/commentRss/104295.htmlhttp://www.tkk7.com/hengheng123456789/services/trackbacks/104295.html 适配器模式定?
两个不兼容的类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Ҏ?/p>

哼哼 2007-03-16 16:36 发表评论
]]>
设计模式之Proxy(代理)http://www.tkk7.com/hengheng123456789/articles/104281.html哼哼哼哼Fri, 16 Mar 2007 07:48:00 GMThttp://www.tkk7.com/hengheng123456789/articles/104281.htmlhttp://www.tkk7.com/hengheng123456789/comments/104281.htmlhttp://www.tkk7.com/hengheng123456789/articles/104281.html#Feedback0http://www.tkk7.com/hengheng123456789/comments/commentRss/104281.htmlhttp://www.tkk7.com/hengheng123456789/services/trackbacks/104281.html理解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



哼哼 2007-03-16 15:48 发表评论
]]>
设计模式之Factoryhttp://www.tkk7.com/hengheng123456789/articles/104269.html哼哼哼哼Fri, 16 Mar 2007 07:28:00 GMThttp://www.tkk7.com/hengheng123456789/articles/104269.htmlhttp://www.tkk7.com/hengheng123456789/comments/104269.htmlhttp://www.tkk7.com/hengheng123456789/articles/104269.html#Feedback0http://www.tkk7.com/hengheng123456789/comments/commentRss/104269.htmlhttp://www.tkk7.com/hengheng123456789/services/trackbacks/104269.html 工厂模式定义:提供创徏对象的接?

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

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

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

Sample sample=new Sample();

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

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

Sample sample=new Sample(参数);

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

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

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

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

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

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

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

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

public class Factory{

  public static Sample creator(int which){

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

  }

}

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

Sample sampleA=Factory.creator(1);

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

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

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

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

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

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

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

public abstract class Factory{

  public abstract Sample creator();

  public abstract Sample2 creator(String name);

}

public class SimpleFactory extends Factory{

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

  }

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

  }

}

public class BombFactory extends Factory{

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

  }

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

}

 

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

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

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

举例

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

public abstract class ForumFactory {

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

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

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

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

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

  ....

}

 

 

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

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

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

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

看看Java宠物店中的CatalogDAOFactory:

public class CatalogDAOFactory {

  /**

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

  public static CatalogDAO getDAO() throws CatalogDAOSysException {

    CatalogDAO catDao = null;

    try {

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

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

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

    } catch (NamingException ne) {

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

    } catch (Exception se) {

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

    }

    return catDao;

  }

}


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

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

哼哼 2007-03-16 15:28 发表评论
]]>
设计模式之Singleton(单?http://www.tkk7.com/hengheng123456789/articles/104253.html哼哼哼哼Fri, 16 Mar 2007 06:59:00 GMThttp://www.tkk7.com/hengheng123456789/articles/104253.htmlhttp://www.tkk7.com/hengheng123456789/comments/104253.htmlhttp://www.tkk7.com/hengheng123456789/articles/104253.html#Feedback0http://www.tkk7.com/hengheng123456789/comments/commentRss/104253.htmlhttp://www.tkk7.com/hengheng123456789/services/trackbacks/104253.html 单态定?/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这?font color="#ff1493">synchronized很重?/font>Q如果没有synchronizedQ那么用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴者进一步研I?/p>

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

使用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?font color="#0000ff">如果你的应用Z容器Q那么Singleton模式用或者不用,可以使用相关替代技术?/font>

q一步深入可参考:

Double-checked locking and the Singleton pattern

When is a singleton not a singleton?

Singleton是邪恶的



哼哼 2007-03-16 14:59 发表评论
]]>
设计模式之Builderhttp://www.tkk7.com/hengheng123456789/articles/104240.html哼哼哼哼Fri, 16 Mar 2007 05:52:00 GMThttp://www.tkk7.com/hengheng123456789/articles/104240.htmlhttp://www.tkk7.com/hengheng123456789/comments/104240.htmlhttp://www.tkk7.com/hengheng123456789/articles/104240.html#Feedback0http://www.tkk7.com/hengheng123456789/comments/commentRss/104240.htmlhttp://www.tkk7.com/hengheng123456789/services/trackbacks/104240.html Builder模式定义:
一个复杂对象的构徏与它的表C分?使得同样的构E可以创Z同的表示.

Builder模式是一步一步创Z个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容可以构建它?用户不知道内部的具体构徏l节.Builder模式是非常类似抽象工厂模?l微的区别大概只有在反复使用中才能体会到.

Z使用?
是ؓ了将构徏复杂对象?b>q程
和它?i>部g解?注意: 是解?b>q程?i>部g.

因ؓ一个复杂的对象,不但有很多大量组成部?如汽?有很多部?车轮 方向?发动有各U小零g{等,部g很多,但远不止q些,如何这些部件装配成一辆汽?q个装配q程也很复杂(需要很好的l装技?,Builder模式是Z部件和l装q程分开.

如何使用?
首先假设一个复杂对象是由多个部件组成的,Builder模式是把复杂对象的创建和部g的创建分别开?分别用BuildercdDirectorcL表示.

首先,需要一个接?它定义如何创建复杂对象的各个部g:

public interface Builder {

  //创徏部gA  比如创徏汽R车轮
  void buildPartA();
  //创徏部gB 比如创徏汽R方向?br />  void buildPartB();
  //创徏部gC 比如创徏汽R发动?br />  void buildPartC();

  //q回最后组装成品结?(q回最后装配好的汽?
  //成品的组装过E不在这里进?而是转移C面的DirectorcMq行.
  //从而实C解?b>q程?i>部g
  Product getResult();

}

用Director构徏最后的复杂对象,而在上面Builder接口中封装的是如何创Z个个部g(复杂对象是由q些部gl成?,也就是说Director的内Ҏ如何部件最后组装成成品:

public class Director {

  private Builder builder;

  public Director( Builder builder ) {
    this.builder = builder;
  }
  // 部件partA partB partC最后组成复杂对?br />  //q里是将车轮 方向盘和发动机组装成汽R的过E?br />  public void construct() {
    builder.buildPartA();
    builder.buildPartB();
    builder.buildPartC();

  }

}

Builder的具体实现ConcreteBuilder:
通过具体完成接口Builder来构建或装配产品的部?
定义q明它所要创建的是什么具体东?
提供一个可以重新获取品的接口:

public class ConcreteBuilder implements Builder {

  Part partA, partB, partC;
  public void buildPartA() {
    //q里是具体如何构建partA的代?br />
  };
  public void buildPartB() {
    //q里是具体如何构建partB的代?br />  };
   public void buildPartC() {
    //q里是具体如何构建partB的代?br />  };
   public Product getResult() {
    //q回最后组装成品结?br />  };

}

复杂对象:产品Product:

public interface Product { }

复杂对象的部?

public interface Part { }


我们看看如何调用Builder模式:
ConcreteBuilder builder = new ConcreteBuilder();
Director director = new Director( builder );

director.construct();    //部g的创?/font>
Product product = builder.getResult();  //对象Q品)的创?/font>

Builder模式的应?br />在Java实际使用?我们l常用到"?(Pool)的概?当资源提供者无法提供够的资源,q且q些资源需要被很多用户反复׃n?需要用池.

"?实际是一D内?当池中有一些复杂的资源?断肢"(比如数据库的q接?也许有时一个连接会中断),如果循环再利用这?断肢",提高内存用效?提高池的性能.修改Builder模式中DirectorcM之能诊断"断肢"断在哪个部g?再修复这个部?



哼哼 2007-03-16 13:52 发表评论
]]>设计模式之Prototype(原型)http://www.tkk7.com/hengheng123456789/articles/104222.html哼哼哼哼Fri, 16 Mar 2007 05:18:00 GMThttp://www.tkk7.com/hengheng123456789/articles/104222.htmlhttp://www.tkk7.com/hengheng123456789/comments/104222.htmlhttp://www.tkk7.com/hengheng123456789/articles/104222.html#Feedback0http://www.tkk7.com/hengheng123456789/comments/commentRss/104222.htmlhttp://www.tkk7.com/hengheng123456789/services/trackbacks/104222.html原型模式定义:
用原型实例指定创建对象的U类,q且通过拯q些原型创徏新的对象.

Prototype模式允许一个对象再创徏另外一个可定制的对象,Ҏ无需知道M如何创徏的细?工作原理?通过一个原型对象传l那个要发动创徏的对象,q个要发动创建的对象通过h原型对象拯它们自己来实施创建?/p>

如何使用?
因ؓJava中的提供clone()Ҏ来实现对象的克隆,所以Prototype模式实现一下子变得很简?

以勺子ؓ例:

public abstract class AbstractSpoon implements Cloneable
{
  String spoonName;

  public void setSpoonName(String spoonName) {this.spoonName = spoonName;}
  public String getSpoonName() {return this.spoonName;}

  public Object clone()
  {
    Object object = null;
    try {
      object = super.clone();
    } catch (CloneNotSupportedException exception) {
      System.err.println("AbstractSpoon is not Cloneable");
    }
    return object;
  }
}

有个具体实现(ConcretePrototype):

public class SoupSpoon extends AbstractSpoon
{
  public SoupSpoon()
  {
    setSpoonName("Soup Spoon");
  }
}

调用Prototype模式很简?

AbstractSpoon spoon = new SoupSpoon();
AbstractSpoon spoon2 = spoon.clone();

当然也可以结合工厂模式来创徏AbstractSpoon实例?/p>

在Java中Prototype模式变成clone()Ҏ的用,׃Java的纯z的面向对象Ҏ,使得在Java中用设计模式变得很自然Q两者已l几乎是然一体了。这反映在很多模式上Q如Interator遍历模式?/p>

哼哼 2007-03-16 13:18 发表评论
]]>
վ֩ģ壺 ޹ۺϾƷĵһ | þþþþþþþþѾƷ| ޾Ʒ| ˵һaվ| Ƶۿ| ޵Ӱ߹ۿ| 91avƵ| Ʒר| 㽶߹ۿ| ޹ۺרߵӰ| ԺԺҳ| ޾Ʒ| ŮëƬѲ| Ƶһ| 8x8Ƶ| һƵۿwww | պһëƬ| պav| 9277ֻƵۿ| պѵƵ߹ۿ㽶| ĻĻ| ȫ߲ëƬ| ŮվɫƵ| ޱٸ뼤| 123| Ļ| AVһ| һɪ| ޹һ߹ۿ| ޹˾þ77| þþþþƷAV| һ| www77777| ޹ŷһ | ѹۿƵ| ŮƷƵѹۿ| պѿ| www.޾Ʒ.com| ˿ۺ| ŷƷһ| AV벻߲|