??xml version="1.0" encoding="utf-8" standalone="yes"?>精品久久久中文字幕,99国产精品久久久久,国产一区二区三区亚洲http://www.aygfsteel.com/fish001118/展现自我Q放飞理惻Izh-cnTue, 17 Jun 2025 17:21:25 GMTTue, 17 Jun 2025 17:21:25 GMT60设计模式之Factoryhttp://www.aygfsteel.com/fish001118/archive/2006/02/19/31561.html飞翔天空飞翔天空Sun, 19 Feb 2006 14:23:00 GMThttp://www.aygfsteel.com/fish001118/archive/2006/02/19/31561.htmlhttp://www.aygfsteel.com/fish001118/comments/31561.htmlhttp://www.aygfsteel.com/fish001118/archive/2006/02/19/31561.html#Feedback0http://www.aygfsteel.com/fish001118/comments/commentRss/31561.htmlhttp://www.aygfsteel.com/fish001118/services/trackbacks/31561.html板桥里h Q{载请保留Q?/P>

工厂模式定义:提供创徏对象的接?

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首先,我们需要将创徏实例的工作与使用实例的工作分开, 也就是说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>

飞翔天空 2006-02-19 22:23 发表评论
]]>
新的博客Q从q里开始!http://www.aygfsteel.com/fish001118/archive/2006/02/19/31559.html飞翔天空飞翔天空Sun, 19 Feb 2006 14:19:00 GMThttp://www.aygfsteel.com/fish001118/archive/2006/02/19/31559.htmlhttp://www.aygfsteel.com/fish001118/comments/31559.htmlhttp://www.aygfsteel.com/fish001118/archive/2006/02/19/31559.html#Feedback0http://www.aygfsteel.com/fish001118/comments/commentRss/31559.htmlhttp://www.aygfsteel.com/fish001118/services/trackbacks/31559.html我懒得去写什么h生感悟、生z趣事。说实在的,也没I去惟뀂我的博客无非是Z记录一些^素在|上搜到的技术资料,以便自己查阅Q也和大家一起分享。之前在CSDN上有一个自q博客。没什么理由,想换到q边来。。。。。。也可能是想找个阅读量大的地儿,呵呵Q就从今天开始吧Q?/P>

飞翔天空 2006-02-19 22:19 发表评论
]]>
վ֩ģ壺 | | | | ɽ| | | | | ɽ| | | | | ǿ| ƶ| ̷| | | | | ְ| | | ɽ| | ¡| ƽ| | | ɽ| ƺ| | غ| | | ̩| մ| | ʱ| |