本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7591080
建立时间:2006年5月29日




[设计模式]Java中的模式 --工厂模式
软件技术

lhwork 发表于 2006/12/19 9:36:28

工厂模式主要负责将大量有共通接口的类实例化,工场模式有以下几种形态简单工厂(Simple Factory)   又称 静态工厂方法(Static Factory Method)工厂方法(Factory Method)   又称 多态性工厂(Polymorphic Factory)抽象工厂(Abstract Factory) 又称 工具箱(Kit or Toolkit) 先说简单工厂模式:需求:一个水果工厂,为任何来的客人提供水果,现有水果Apple ,Banana,Orange实现:定义三个类Apple,Banana,Orange 让他们都实现Fruit接口 500)this.width=500'> ----------------------- list  1 -------------------------------- 500)this.width=500'> 500)this.width=500'> public   class  FruitFactory 500)this.width=500'> {500)this.width=500'>500)this.width=500'>  public   static  Fruit factory(String which) 500)this.width=500'> {500)this.width=500'>500)this.width=500'>   if (which.equalsIgnoreCase( " apple " ) 500)this.width=500'> {500)this.width=500'>                return new Apple();500)this.width=500'>500)this.width=500'>  } else   if (which equalsIgnoreCase( " banana " )) 500)this.width=500'> {500)this.width=500'>                return new Banana();500)this.width=500'>500)this.width=500'>  } else   if (which equalsIgnoreCase( " orange " )) 500)this.width=500'> {500)this.width=500'>                return new Orange();500)this.width=500'>500)this.width=500'>  } else 500)this.width=500'> {500)this.width=500'>                throw  RuntimeException( " no this fruit " );500)this.width=500'>  } 500)this.width=500'> } 500)this.width=500'>} 500)this.width=500'> ----------------------- list  1 -------------------------------- 500)this.width=500'> 客人的需求实现 1 500)this.width=500'> 500)this.width=500'> try 500)this.width=500'> { 2 500)this.width=500'> FruitFactory.factory( " apple " ); 3 500)this.width=500'> FruitFactory.factory( " banana " ); 4 500)this.width=500'> FruitFactory.factory( " orange " ); 5 500)this.width=500'> 500)this.width=500'>} catch (Exception e) 500)this.width=500'> { 6 500)this.width=500'> 500)this.width=500'>500)this.width=500'> 7 500)this.width=500'>} 8 500)this.width=500'> 优点:分开了生产者和消费者的责任缺点:所有的产品都出自一个工厂造成问题:1,当这个工厂出现问题时,损失惨重,不利于分散风险2,当出现不同种类的水果(有不同接口的水果),工场内部既须要判断种类,又须要判断具体的产品。比如这种结构:1,水果接口Fruit2,两个种类水果实现了Fruit接口   有籽水果 /无籽水果3,所有有籽水果继承自有籽水果类   ,所有无籽水果继承自无籽水果类 这事如果客户要有籽西瓜,无籽西瓜 工厂类的实现  1 500)this.width=500'> ----------------------- list  2 --------------------------------  2 500)this.width=500'> 500)this.width=500'> public   class  FruitFactory 500)this.width=500'> {  3 500)this.width=500'> 500)this.width=500'>  public   static  Fruit factory(String which, boolean  hasSeed ) 500)this.width=500'> {  4 500)this.width=500'> 500)this.width=500'>   if (hasSeed) 500)this.width=500'> {  5 500)this.width=500'> 500)this.width=500'>    if (which.equalsIgnoreCase( " watermelon  " ) 500)this.width=500'> {  6 500)this.width=500'>     return   new  WatermelonOne();  7 500)this.width=500'> 500)this.width=500'>   } else   if (which equalsIgnoreCase( " orange " )) 500)this.width=500'> {  8 500)this.width=500'>     return   new  OrangeOne();  9 500)this.width=500'> 500)this.width=500'>    else 500)this.width=500'> { 10 500)this.width=500'>     throw  RuntimeException( " no this fruit " ); 11 500)this.width=500'>   } 12 500)this.width=500'> 500)this.width=500'>  } else 500)this.width=500'> { 13 500)this.width=500'> 500)this.width=500'>    if (which.equalsIgnoreCase( " watermelon  " ) 500)this.width=500'> { 14 500)this.width=500'>     return   new  WatermelonTwo(); 15 500)this.width=500'> 500)this.width=500'>   } else   if (which equalsIgnoreCase( " orange " )) 500)this.width=500'> { 16 500)this.width=500'>     return   new  OrangeTwo(); 17 500)this.width=500'> 500)this.width=500'>    else 500)this.width=500'> { 18 500)this.width=500'>     throw  RuntimeException( " no this fruit " ); 19 500)this.width=500'>   } 20 500)this.width=500'>  } 21 500)this.width=500'> } 22 500)this.width=500'>} 23 500)this.width=500'> ----------------------- list  2 -------------------------------- 24 500)this.width=500'> 接着试想一下,我有20个大分类,复杂的层次结构,那么这个工厂模式怎么维护。总结一下:简单工厂方法,在一定程度上支持了开闭原则,当增加一种水果的时候符合开闭原则  但当增加一类水果(多种有共通特点的水果)时候,出现维护困难的问题。  这个时候引入工厂方法,工厂方法利用继承,解决了上边的问题。看看它是如何解决的。简单来说:工厂方法就是为没一大类水果实现一个"简单工厂",这些"简单工厂"都实现一个共通的接口。这样当然就解决了问题,添加一个大类的话,就添加一个简单工厂 在我们的日常生活中经常会遇到这样的情况,如要生产IBM-PC或者Apple ,每一台计算计又有Cpu和内存IBM-PC Apple,Cpu 内存Ram 不是一类东西,这个时候如果简单的建立四个工厂类是不对的。解决办法:  1 500)this.width=500'> ----------------------- list  3 --------------------------------  2 500)this.width=500'> 500)this.width=500'> public  IbmPcFactory 500)this.width=500'> {  3 500)this.width=500'> 500)this.width=500'>  public  Cpu CpuFactory(String cpuType) 500)this.width=500'> {  4 500)this.width=500'>   return   new  IbmPcCpu(cpuType);  5 500)this.width=500'> }  6 500)this.width=500'> 500)this.width=500'>  public  Ram RamFactory(String ramType) 500)this.width=500'> {  7 500)this.width=500'>   return   new  IbmPcRam(ramType);  8 500)this.width=500'> }  9 500)this.width=500'>} 10 500)this.width=500'> 500)this.width=500'> public  AppleFactory() 500)this.width=500'> { 11 500)this.width=500'> 500)this.width=500'>  public  Cpu CpuFactory(String cpuType) 500)this.width=500'> { 12 500)this.width=500'>   return   new  AppleCpu(cpuType); 13 500)this.width=500'> } 14 500)this.width=500'> 500)this.width=500'>  public  Ram RamFactory(String ramType) 500)this.width=500'> { 15 500)this.width=500'>   return   new  AppleRam(ramType); 16 500)this.width=500'> } 17 500)this.width=500'>} 18 500)this.width=500'> ----------------------- list  3 -------------------------------- 19 500)this.width=500'> 这个就使抽象工厂了,不过抽象工厂对开闭原则的支持不够好,只在机型的增加上支持开闭,在配件上就不行了。 对比三个工厂模式,<<Java与模式>>的作者的比喻更能让人明白问题。 1,话说女娲造人,开始用手捏,感觉太慢2,所以女娲想出了办法,用一条绳子(简单工厂,告诉绳子怎么造人),放到泥堆里边,然後一抖,就出来一批人(简单工厂须要一个接口,interface 人)3,接着女娲想要男人和女人之分,所以造了两条绳子,阳绳和阴绳(工厂方法,两个工厂,告诉阳绳怎么造男人,女绳怎么造女人),然後一下出来一批男人,一批女人(工厂方法须要多个接口,interface 人  interface 绳  阳绳-阴绳实现绳 男人-女人实现人)4,可女娲还想造点动物,而且动物也想分男女(其实应改是雌雄),那怎么办,改造两条绳子,让绳子也学会怎么造动物(抽象工厂),这个时候抖一下绳子,阳绳出来的东西,长的像人的是男人,长的像动物的是雄动物,(抽象工厂须要再多的接口 interface 人 interface 兽 interface 绳阳绳-阴绳实现绳 男人-女人实现人 雌动物-雄动物实现兽)阴绳出来的东西,长的像人的是女人,长的像动物的是雌动物 最后再回到实现上,看到在list 1中,出现了大量的if(which.equalsIgnoreCase("xxx"){   return new Xxx();}试想如果产品上千,上万呢。那这个将是不可想想的。Java的动态load正好解决了这个问题看看实现  1 500)this.width=500'> 500)this.width=500'> public   class  FruitFactory 500)this.width=500'> {  2 500)this.width=500'> 500)this.width=500'>  public   static  Fruit factory(String which) 500)this.width=500'> {  3 500)this.width=500'> 500)this.width=500'>   try 500)this.width=500'> {  4 500)this.width=500'>   Class clazz  =  Class.forName(which);  5 500)this.width=500'>    return  (Fruit)clazz.newInstance();  6 500)this.width=500'> 500)this.width=500'>  } catch (Exception e) 500)this.width=500'> {  7 500)this.width=500'>   500)this.width=500'>500)this.width=500'>  8 500)this.width=500'>  }  9 500)this.width=500'> } 10 500)this.width=500'>} 11 500)this.width=500'> 好了,这个时候无论增加多少类的产品都不是问题了,你只要让所有的产品实现Fruit接口,同时为每个产品编写自己的类。完全符合开闭原则。


阅读全文(1390) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.066 second(s), page refreshed 144766654 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号