动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Java教程 ]的信息

本月文章推荐
.(转贴)Java的数据库应用.
.保护您的 J2ME/MIDP 应用程序.
.Java编程基础:EJB专用术语的详细.
.程序员学习Java的一剂良药:破坏.
.JAVA入门教程:数据类型.
.使用ANT协助高效开发java项目.
.关于继承内部类——java编程思想.
.图解JBuilderX安装与实践.
.虚拟现实之高级技巧(五).
.为什么很多Java开发人员都对JCP感.
.parse 方法.
.Java Q&A: 使用Factory Method模.
.软件最大的追求是什么?.
.用Java实现自动在数据库表中生成.
.JDK的环境配置.
.字符终端的管理.
.JBuilder开发Struts+Hibernate框.
.调试器--jdb.exe.
.Java核心代码例程之:ShowFileCo.
.是否有必要将Java程序写成.exe文.

在Java中应用设计模式之Factory Method

发表日期:2008-1-5 |



  在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛,EJB,RMI,COM,CORBA,Swing中都可以看到此模式的影子,它是最重要的模式之一。在很多地方我们都会看到xxxFactory这样命名的类,那么,什么是Factory Method,为什么要用这个模式,如何用Java语言来实现该模式,这就是本文想要带给大家的内容。
  
  基本概念
  
  Factory Method是一种创建性模式,它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类。当一个类无法预料要创建哪种类的对象或是一个类需要由子类来指定创建的对象时我们就需要用到Factory Method 模式了。
  
  简单说来,Factory Method可以根据不同的条件产生不同的实例,当然这些不同的实例通常是属于相同的类型,具有共同的父类。Factory Method把创建这些实例的具体过程封装起来了,简化了客户端的应用,也改善了程序的扩展性,使得将来可以做最小的改动就可以加入新的待创建的类。 通常我们将Factory Method作为一种标准的创建对象的方法,当发现需要更多的灵活性的时候,就开始考虑向其它创建型模式转化。
  
  简单分析
  
  图1是Factory Method 模式的结构图,这里提供了一些术语,让我们可以进行更方便的描述:
  
在Java中应用设计模式之Factory Method

  
图1: Factory Method 模式结构

  
  1.ProdUCt: 需要创建的产品的抽象类。
  
  2.ConcreteProduct: Product的子类,一系列具体的产品。
  
  3.Creator: 抽象创建器接口,声明返回Product类型对象的Factory Method。
  
  4.ConcreteCreator: 具体的创建器,重写Creator中的Factory Method,返回ConcreteProduct类型的实例。
  
  由此可以清楚的看出这样的平行对应关系:
  
  Product <====> Creator ;
  ConreteProduct <====> ConreteCreator
  
  抽象产品对应抽象创建器,具体产品对应具体创建器。这样做的好处是什么呢?为什么我们不直接用具体的产品和具体的创建器完成需求呢?实际上我们也可以这样做。但通过Factory Method模式来完成,客户(client)只需引用抽象的Product和Creater,对具体的ConcreteProduct和ConcreteCreator可以毫不关心,这样做我们可以获得额外的好处。
  
  首先客户端可以统一从抽象创建器获取产生的实例,Creator的作用将client和产品创建过程分离开来,客户不用操心返回的是那一个具体的产品,也不用关心这些产品是如何创建的。
  
  同时,ConcreteProduct也被隐藏在Product后面,ConreteProduct继续了Product的所有属性,并实现了Product中定义的抽象方法,按照Java中的对象造型(cast)原则,通过ConcreteCreator产生的ConcreteProduct可以自动的上溯造型成Product。这样一来,实质内容不同的ConcreteProduct就可以在形式上统一为Product,通过Creator提供给client来访问。
  
  其次,当我们添加一个新的ConcreteCreator时,由于Creator所提供的接口不变,客户端程序不会有丝毫的改动,不会带来动一发而牵全身的灾难, 这就是良好封装性的体现。但假如直接用ConcreteProduct和ConcreteCreator两个类是无论如何也做不到这点的。
  
  优良的面向对象设计鼓励使用封装(encapsulation)和委托(delegation),而Factory Method模式就是使用了封装和委托的典型例子,这里封装是通过抽象创建器Creator来体现的,而委托则是通过抽象创建器把创建对象的责任完全交给具体创建器ConcreteCreator来体现的。
  
  现在,请再回头看看基本概念中的那段话,开始也许觉得生涩难懂,现在是不是已经明朗化了很多。
  
  下面让我们看看在 Java 中如何实现Factory Method模式,进一步加深对它的熟悉。
  
  具体实施
  
  先说明一点,用Factory Method模式创建对象并不一定会让我们的代码更短,实事上往往更长,我们也使用了更多的类,真正的目的在于这样可以灵活的,有弹性的创建不确定的对象。而且,代码的可重用性提高了,客户端的应用简化了,客户程序的代码会大大减少,变的更具可读性。
  
  标准实现: 这里我采用Bruce Eckel 用来描述OO思想的经典例子 Shape。这样大家会比较熟悉一些。我完全按照图1中所定义的结构写了下面的一段演示代码。这段代码的作用是创建不同的Shape实例,每个实例完成两个操作:draw和erase。具体的创建过程委托?ShapeFactory来完成。
  
  1.a 首先定义一个抽象类Shape,定义两个抽象的方法。
  
  abstract class Shape
  {
  // 勾画shape
  public abstract void draw();
  // 擦去 shape
  public abstract void erase();
  
  public String name;
  public Shape(String aName)
  {
  name = aName;
  }
  }
  
  1.b 定义 Shape的两个子类: Circle, Square,实现Shape中定义的抽象方法
  
  // 圆形子类
  class Circle extends Shape
  {
  public void draw()
  {
  System.out.println("It will draw a circle.");
  }
  public void erase()
  {
  System.out.println("It will erase a circle.");
  }
  // 构造函数
  public Circle(String aName)
  {
  super(aName);
  }
  }
  
  // 方形子类
  class Square extends Shape
  {
  public void draw()
  {
  System.out.println("It will draw a square.");
  }
  public void erase() {
  System.out.println("It will erase a square.");
  }
  // 构造函数
  public Square(String aName)
  {
  super(aName);
  }
  }
  
  1.c 定义抽象的创建器,anOperation调用factoryMethod创建一个对象,并对该对象进行一系列操作。
  
  abstract class ShapeFactory
  {
  protected abstract Shape
  factoryMethod(String aName);
  // 在anOperation中定义Shape的一系列行为
  public void anOperation(String aName)
  {
  Shape s = factoryMethod(aName);
  System.out.println
  ("The current shape is: " + s.name);
  s.draw();
  s.erase();
  }
  }
  
  1.d 定义与circle和square相对应的两个具体创建器CircleFactory,SquareFactory,实现父类的methodFactory方法
  
  // 定义返回 circle 实例的 CircleFactory
  class CircleFactory extends ShapeFactory
  {
  // 重载factoryMethod方法,返回Circle对象
  protected Shape factoryMethod(String aName)
  {
  return new Circle(aName + "
  (created by CircleFactory)");
  }
  }
  
  // 定义返回 Square
  实例的 SquareFactory
  class SquareFactory extends ShapeFactory
  {
  // 重载factoryMethod方法,返回Square对象
  protected Shape factoryMethod(String aName)
  {
  return new Square
  (aName + " (created by SquareFactory)");
  }
  }
  
  1.e 测试类:请注重这个客户端程序多么简洁,既没有罗嗦的条件判定语句,也无需关心ConcreteProduct和ConcreteCreator的细节(因为这里我用anOperation封装了Product里的两个方法,所以连Product的影子也没看见,当然把Product里方法的具体调用放到客户程序中也是不错的)。
  
  class Main
  {
  public static void main(String[] args)
  {
  ShapeFactory sf1 = new SquareFactory();
  ShapeFactory sf2 = new CircleFactory();
  sf1.anOperation("Shape one");
  sf2.anOperation("Shape two");
  }
  }
  
  运行结果如下:
  
  The current shape is: Shape one
  (created by SquareFactory)
  It will draw a square.
  It will erase a square.
  The current shape is: Shape two
  (created by CircleFactory)
  It will draw a circle.
  It will erase a circle.
  
  参数化的Factory Method: 这种方式依靠指定的参数作为标志来创建对应的实例,这是很常见的一种办法。比如JFC中的BorderFactory就是个很不错的例子。
  
  以下的这个例子是用字符串作为标记来进行判定的,假如参数的类型也不一样,那就可以用到过载函数来解决这个问题,定义一系列参数和方法体不同的同名函数,这里java.util.Calendar.getInstance()又是个极好的例子。
  
  参数化的创建方式克服了Factory Method模式一个最显著的缺陷,就是当具体产品比较多时,我们不得不也建立一系列与之对应的具体构造器。 但是在客户端我们必须指定参数来决定要创建哪一个类。
  
  2.a 我们在第一种方法的基础上进行修改,首先自定义一个的异常,这样当传入不正确的参数时可以得到更明显的报错信息。
  
  class NoThisShape extends Exception
  {
  public NoThisShape(String aName)
  {
  super(aName);
  }
  }
  
  2.b 去掉了ShapeFactory的两个子类,改为由ShapeFactory直接负责实例的创建。 ShapeFactory自己变成一个具体的创建器,直接用参数化的方法实现factoryMethod返回多种对象。<
上一篇:技术解析:什么是模式?什么是框架? 人气:542
下一篇:在Java中应用设计模式之Singleton 人气:525
浏览全部Java的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-10-10 企业网站智能管理系统(TZIMS) v6
2008-10-10 拓文asp.net网站内容管理系统 v6
2008-10-10 动网论坛PHP版 v2.0++ Build 081
2008-10-10 免费时代CMS v5.0
2008-10-10 wodig第四季中文DIGG社区 v4.1 b
2008-10-10 老Y文章管理系统 v2.2 bulid 081
2008-10-10 魔法盒动感相册 ASP+SQL版 v2.0
2008-10-10 Asoft签到管理系统 v3.0 Pack1
2008-10-10 哥特人音乐网潮流留言本 v1.1
2008-10-11 联系人分组工具 v1.1 中文破解版
2008-10-11 FaceMelter变脸 v2.0 汉化破解版
2008-10-11 PathTracker道路跟踪仪 v1.2 破解
2008-10-11 Rooms手机聊天室 v0.6.7 破解版
2008-10-11 RemoteDesktop远程桌面 v1.0 破解
2008-10-11 ProRemote远程调音台 v1.0.1 破解
2008-10-11 PicShare照片共享 v1.0.0 破解版
2008-10-11 Photogene照片编辑器 v1.5 汉化破
2008-10-11 WriteRoom共享文档 v1.0 破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | js/vbs加密 | md5加密 | 进制转换 | UTF-8 转换工具 | Html转换js | Html转换asp | Html转换php | Html转换perl
实用工具:汉字翻译拼音 | 拼音字典 | 符号对照表 | 个税计算 | 实时汇率查询换算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 | 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵
SEO対策 中国語教室 ホームページ作成