zoukankan      html  css  js  c++  java
  • Java中的简单工厂模式

    举两个例子以快速明白Java中的简单 工厂模式:

    女娲抟土造人
    话说:“天地开辟,未有人民,女娲抟土为人。”女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的思想里面。
    女娲造人,这就是简单工厂模式的应用。 

      首先,在这个造人的思想里面,有几个重要的角色:女娲本身、抽象的人的概念和女娲所造出的一个个具体的人。
      1.)女娲是一个工厂类,也就是简单工厂模式的核心角色。

            2.)具休的一个个的人,包括张三,李四等。这些人便是简单工厂模式里面的具体产品角色
      3.)抽象的人是最早只存在于女娲的头脑里的一个想法,女娲按照这个想法造出的一个个具体的人,便都符合这个抽象的人的定义。换言之,这个抽象的想法规定了所有具体的人必须都有的接口(特征或者功能)
       其UML类图出下所示:
         
    理解了上面的这些东西,再来理解下面的例子,对照理解,相信看完这篇文章,便对java简单工厂模式有一个很好的理解:


    有一个农场公司,专门向市场销售各类水果,在这个系统里需要描述下列水果:
         葡萄 Grape
         草莓 Stuawberry
         苹果 Apple
    水果与其他植物不同,最终可以采摘食用,那么一个自然的做法是建立一个各种水果都适用的接口,以便与其他农场里的植物区分开来,
     
    此时,则是为水果类声明了一个接口,表现在代码上:

     1  public   interface  Fruit {
     2       // 生长 
     3        void  grow();
     4        // 收获 
     5        void  harvest();
     6        // 种植 
     7        void  plant();
     8  } 

     9  
    10 


    水果接口规定出所有的水果必须实现的接口,包括任何水果类必须具备的方法plant(),grow(),和harvest();

    Apple类是水果类的一种,因此它实现了水果接口所声明的所有方法。另处,由于苹果是多年生植物,因此多出一个treeAge性质,描述苹果的树龄。代码如下所示:

     package  fac;
     
     public   class  Apple  implements  Fruit // 通过implements实现接口Fruit 
     
         private   int  treeAge;
         
          public   void  grow() {
             log( " Apple is growing " );
         } 

         
          public   void  harvest() {
             log( " Apple has been harvested " );
         } 

         
          public   void  plant() {
             log( " Apple ha been planted " );
         } 

         
          public   static   void  log(String msg) {
             System.out.println(msg);
         } 

         
          public   int  getTreeAge() {
              return  treeAge;
         } 

         
          public   void  setTreeAge( int  treeAge) {
              this .treeAge = treeAge;
         } 

     } 


    同理,葡萄 Grape:

     package  fac;
     
     public   class  Grape  implements  Fruit {
          private   boolean  seedless;
          public   void  grow() {
             log( " Grape is growing . " );
         } 

         
          public   void  harvest() {
             log( " Grape has been harvested " );
         } 

         
          public   void  plant() {
             log( " Grape ha been planted " );
         } 

         
          public   static   void  log(String msg) {
             System.out.println(msg);
         } 

     
          public   boolean  isSeedless()  {
              return  seedless;
         } 

     
          public   void  setSeedless( boolean  seedless)  {
              this .seedless  =  seedless;
         } 

         
     
     }


    草莓 Stuawberry:

     package  fac;
     
     public   class  Strawberry  implements  Fruit {
          public   void  grow() {
             log( " Strawberry is growing " );
         } 

         
          public   void  harvest() {
             log( " Strawberry has been harvested " );
         } 

         
          public   void  plant() {
             log( " Strawberry has been planted " );
         } 

         
          public   static   void  log(String msg) {
             System.out.println(msg);
         } 

     }



    农场园丁也是系统的一部分,由一个类来代表,FruitGardener类,代码如下:

     package  fac;
     
     public   class  FruitGardener {
          public   static  Fruit factory(String which) throws  Exception {
              if (which.equalsIgnoreCase( " apple " )) {
                  return   new  Apple();
             } 
    else   if (which.equalsIgnoreCase( " strawberry " )) {
                  return   new  Strawberry();
             } 
    else   if  (which.equalsIgnoreCase( " grape " )) {
                  return   new  Grape();
             } 
    else {
                  throw   new  Exception( " Bad fruit request " );
             } 

         } 

     }

    这时有人来果园玩,和园丁说,给我们介绍下你的水果吧。于是园丁:

     package  fac;
     
     public   class  People  {
     
          public   static   void  main(String[] args)  throws  Exception  {
             FruitGardener fg = new  FruitGardener();
             Fruit ap = fg.factory( " Apple " );
             ap.grow();
             Fruit gp = fg.factory( " Grape " );
             gp.plant();
             
             Fruit dd = fg.factory( " ddd " ); // 抛出Bad fruit request异常 
     
        } 
        
     
     } 


    (注:以上代码在JDK5.0,Myeclise3.2下编译通过)

     

     类比两个例子,园丁就相当于女娲,而水果就相当于具体的人,接口水果类就相当于存在于类女娲思想里的人的抽象概念。

    由以上两个例子可得出,简单工厂模式需要由以下角色组成:
          接口
                            接口的实现类(简单工厂模式里面的具体产品角色)
                            工厂

    理解了以下两个例子,再来看第三个例子:
    注意对比以下三个实例的不同
    实例1:

     package  org.jzkangta.factorydemo01;
     // 定义接口 
     
    interface  Car {
          public   void  run();
          public   void  stop();
     } 

     // 具体实现类 
     
    class  Benz  implements  Car {
          public   void  run() {
             System.out.println( " Benz开始启动了。。。。。 " );
         } 

          public   void  stop() {
             System.out.println( " Benz停车了。。。。。 " );
         } 

     } 

     // 具体实现类 
     
    class  Ford  implements  Car {
          public   void  run() {
             System.out.println( " Ford开始启动了。。。 " );
         } 

          public   void  stop() {
             System.out.println( " Ford停车了。。。。 " );
         } 

     } 

     // 工厂 
     
    class  Factory {
          public   static  Car getCarInstance() {
              return   new  Ford();
         } 

     } 

     public   class  FactoryDemo01  {
     
          public   static   void  main(String[] args)  {
             Car c = Factory.getCarInstance();
             c.run();
             c.stop();
     
         } 

     
     } 


    实例二:

     package  fac;
     
     
     // 定义接口 
     
    interface  Car {
          public   void  run();
          public   void  stop();
     } 

     // 具体实现类 
     
    class  Benz  implements  Car {
          public   void  run() {
             System.out.println( " Benz开始启动了。。。。。 " );
         } 

          public   void  stop() {
             System.out.println( " Benz停车了。。。。。 " );
         } 

     } 

     
     class  Ford  implements  Car {
          public   void  run() {
             System.out.println( " Ford开始启动了。。。 " );
         } 

          public   void  stop() {
             System.out.println( " Ford停车了。。。。 " );
         } 

     } 

     // 工厂 
     
    class  Factory {
          public   static  Car getCarInstance(String type) {
             Car c = null ;
              if ( " Benz " .equals(type)) {
                 c = new  Benz();
             } 

              if ( " Ford " .equals(type)) {
                 c = new  Ford();
             } 

              return  c;
         } 

     } 

     
     
     public   class  FactoryDemo02  {
     
          public   static   void  main(String[] args)  {
             Car c = Factory.getCarInstance( " Benz " );
              if (c != null ) {
                 c.run();
                 c.stop();
             } 
    else {
                 System.out.println( " 造不了这种汽车。。。 " );
             } 

             
     
         } 

     
     } 

     


    实例三:

     interface  Car {
          public   void  run();
          public   void  stop();
     } 

     
     class  Benz  implements  Car {
          public   void  run() {
             System.out.println( " Benz开始启动了。。。。。 " );
         } 

          public   void  stop() {
             System.out.println( " Benz停车了。。。。。 " );
         } 

     } 

     
     class  Ford  implements  Car {
          public   void  run() {
             System.out.println( " Ford开始启动了。。。 " );
         } 

          public   void  stop() {
             System.out.println( " Ford停车了。。。。 " );
         } 

     } 

     
     class  Toyota  implements  Car {
          public   void  run() {
             System.out.println( " Toyota开始启动了。。。 " );
         } 

          public   void  stop() {
             System.out.println( " Toyota停车了。。。。 " );
         } 

     } 

     
     class  Factory {
          public   static  Car getCarInstance(String type) {
             Car c = null ;
              try   {
                 c = (Car)Class.forName( " org.jzkangta.factorydemo03. " + type).newInstance();//利用反射得到汽车类型  
             } 
      catch  (InstantiationException e)  {
                  //  TODO Auto-generated catch block 
     
                e.printStackTrace();
             } 
      catch  (IllegalAccessException e)  {
                  //  TODO Auto-generated catch block 
     
                e.printStackTrace();
             } 
      catch  (ClassNotFoundException e)  {
                  //  TODO Auto-generated catch block 
     
                e.printStackTrace();
             } 

         
              return  c;
         } 

     } 

     public   class  FactoryDemo03  {
     
          public   static   void  main(String[] args)  {
             Car c = Factory.getCarInstance( " Toyota " );
              if (c != null ) {
                 c.run();
                 c.stop();
             } 
    else {
                 System.out.println( " 造不了这种汽车。。。 " );
             } 

             
     
         } 

     
     } 

     

    对比三个实例:
    实 例一,虽然实现了简单工厂,但每次只能得到一种汽车,如果我们想换一种,就得修改工厂,太不方便,而实例二则改变了这种情况,便得我们可以按照我们的需要 更换汽车,但我们所更换的汽车必须是实现类中有的,如果我们想要增加一种汽车的时候,我们还是得更改工厂,通过改进,实例三利用反射机制,得到汽车类型, 这样当我们需要增加一种新的汽车时,就无需要再修改工厂,而只需要增加要实现的类即可。也就是说要增加什么样的汽车直接增加这个汽车的类即可,而无需改变 工厂。从而达到了工厂分离的效果。 

    (本文参考《java与模式》及〈浪曦〉视频教程,并引用了相关实例)

  • 相关阅读:
    Balanced Binary Tree
    Convert Sorted List to Binary Search Tree
    Convert Sorted Array to Binary Search Tree
    Binary Tree Zigzag Level Order Traversal
    Validate Binary Search Tree
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Maximum Depth of Binary Tree
    如何把U盘的两个盘或者多个盘合成一个
    bugku 想蹭网先解开密码
  • 原文地址:https://www.cnblogs.com/lxsky/p/3629643.html
Copyright © 2011-2022 走看看