好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

OO思想解

OO思想解

OO思想解决农场养牛问题

最近在自学设计,碰到一题目,我相信网上很多地方也能找到这个题目,题目内容如下:

农场一头小母牛

每年生头小母牛

母牛五岁产母牛

二十年上多少牛

请使用OO思想来解决这个问题。

这题目很有意思,为什么呢?因为读起来朗朗上口,很顺溜,哈哈,开个玩笑。

OK,下面我将结合所学的知识和技巧来描述下自己解决这个问题的过程。

名词

   

     从题目内容中,我们可以抽取出多个名词,如农场、母牛等,为什么我们要把名词抽取出来?因为在OO思想中,就是要有类或者对象,而抽取出来的名词就有可能是我们需要的类或者对象,当然也有可能是类的属性,这个我们就需要结合具体的情况来分析。通过名词抽取,我确定我需要两个类,分别是农场和母牛,我命名为Farm和Cow。

  

 1   /** 
 2    * 
  3    *   @author   LingJian
  4    *
  5    */ 
 6   public   class   Farm {
  7      
 8  }

 1   /** 
 2    * 
  3    *   @author   LingJian
  4    *
  5    */ 
 6   public   class   Cow {
  7  
 8  }    

    属性

   

    确定了类,接下来就需要确定类的属性。有些时候我们可以从给的材料或者需求中直接就定义到相关类的属性,但是在这个题目里面我们是需要慢慢的理解隐含的关系才能确定的。首先由“母牛五岁产母牛”可以确定的属性是母牛的年龄(age),当然在这个地方是不是还有一个生育年龄呢?还有是不是有一个生育数呢?而农场呢,咋一看,貌似只有牛,那么它的属性是牛(Cow),还是牛群(List<Cow>)呢?在我的设计里面,牛是有年龄、生育年龄、生育数三个属性的,只不过我把生育年龄和生育数定义为常量,而农场则有牛群和经营时间两个属性。

   

  1   /** 
  2    * 
   3    *   @author   LingJian
   4    *
   5    */ 
  6   public   class   Farm {
   7  
  8       //  农场经营时间 
  9       private   int   year;
  10       //  牛群 
 11       private  List<Cow>  cows;
  12  
 13       public   int   getYear() {
  14           return   year;
  15       }
  16       public   void  setYear( int   year) {
  17           this .year =  year;
  18       }
  19       public  List<Cow>  getCows() {
  20           return   cows;
  21       }
  22       public   void  setCows(List<Cow>  cows) {
  23           this .cows =  cows;
  24       }
  25  }

  1   /** 
  2    * 
   3    *   @author   LingJian
   4    *
   5    */ 
  6   public   class   Cow {
   7  
  8       //  生育年龄 
  9       private   static   final   int  BEARAGE = 5 ;
  10       //  生育数 
 11       private   static   final   int  BORNCOUNT = 1 ;
  12      
 13       //  年龄 
 14       private   int   age;
  15      
 16      
 17       public   int   getAge() {
  18           return   age;
  19       }
  20       public   void  setAge( int   age) {
  21           this .age =  age;
  22       }
  23      
 24  }

类之间的关系 、 方法

    有了类,有了属性,那么接下来我们就要去确定这些个类的方法,而类的方法往往都是由类之间的关系确定的,举个例子,工厂模式中Factory的create方法,假如工厂生产玩具,正是因为工厂(Factory)会生产玩具(Toy),有这样一层关系,所以Factory会有一个create方法,这个方法就返回Toy的实例。在我们的题目环境中,Farm与Cow,随着经营时间变化,农场的牛不断长大,长大到了5岁会生出小牛,这些小牛又不断长大,而农场的牛群就因此在壮大,所以牛会有一个长大(growUp)方法,农场会有一个随时间变化的方法,我把它命名为past。

隐藏(封装)

    在确定了方法之后,我们很自然的就会去想方法体里面该写些什么?很多时候,我们会对方法的细节特别关注,牛到了五岁时,生出来的牛是不是应该分一下是最先的母牛生的,还是后面生出来的母牛生的。至少当时我就一直在抠这个细节,而后来我发现面向对象的一大特性就是封装,隐藏一些无须关注细节,因为我们不是在计算二十年后,最先的母牛生了多少崽,而是关注农场二十年后有多少牛,当然如果问题是问你二十年后生了崽的母牛都有多少崽或孙崽等或许就需要抠这个细节了,封装的好处就是降低耦合,避免方法不得不需要修改时而造成的牵一发而动全身,增强可扩展性。

   

    到此,OO思想解决这个问题就基本完成了,最后写一个main方法来测试。

   

  1   /** 
  2    * 
   3    *   @author   LingJian
   4    *
   5    */ 
  6   public   class   Farm {
   7  
  8       //  农场经营时间 
  9       private   int   year;
  10       //  牛群 
 11       private  List<Cow>  cows;
  12  
 13       public   int   getYear() {
  14           return   year;
  15       }
  16       public   void  setYear( int   year) {
  17           this .year =  year;
  18       }
  19       public  List<Cow>  getCows() {
  20           return   cows;
  21       }
  22       public   void  setCows(List<Cow>  cows) {
  23           this .cows =  cows;
  24       }
  25  
 26       public   void  past( int   time) {
  27           while ( this .year <  time) {
  28               this .year ++ ;
  29              
 30               int  j =  cows.size();
  31               for ( int  i=0; i<j; i++ ) {
  32                   System.out.println(i);
  33                  Cow c =  cows.get(i);
  34                  c.growUp( this  );
  35               }
  36              System.out.println("第" + year + "年,农场有" + cows.size() + "头牛" );
  37           }
  38  
 39       }
  40  }

  1   /** 
  2    * 
   3    *   @author   LingJian
   4    *
   5    */ 
  6   public   class   Cow {
   7  
  8       //  生育年龄 
  9       private   static   final   int  BEARAGE = 5 ;
  10       //  生育数 
 11       private   static   final   int  BORNCOUNT = 1 ;
  12      
 13       //  年龄 
 14       private   int   age;
  15      
 16      
 17       public   int   getAge() {
  18           return   age;
  19       }
  20       public   void  setAge( int   age) {
  21           this .age =  age;
  22       }
  23      
 24       public  Cow( int   age) {
  25           super  ();
  26           this .age =  age;
  27       }
  28      
 29       public   void   growUp(Farm f) {
  30           this .age ++ ;
  31           //  母牛五岁生母牛 
 32           if (age >=  BEARAGE) {
  33               //  每年生头小母牛 
 34               for ( int  i=0; i<BORNCOUNT; i++ ) {
  35                  f.getCows().add( new  Cow(0 ));
  36               }
  37           }
  38       }
  39  }

  1   /** 
  2    * 测试类
   3    *   @author   LingJian
   4    *
   5    */ 
  6   public   class   Test {
   7  
  8       /** 
  9        * 测试方法
  10        *   @param   args
  11        */ 
 12       public   static   void   main(String[] args) {
  13          
 14          List<Cow> cows =  new  ArrayList<Cow> ();
  15          Farm f =  new   Farm();
  16           //  农场一头小母牛 
 17          cows.add( new  Cow(0 ));
  18           f.setCows(cows);
  19          
 20           //  二十年上多少牛 
 21          f.past(20 );
  22          
 23       }
  24  
 25  }

继承和多态

     若干年后,农场主发现养牛不挣钱啦,而且小牛要等到5岁的时候才生小牛,每次才生1头,这样生产力和生产效率都不行啊,这个时候他想养猪,养猪挣钱呐,繁殖能力也强,于是咱们又写了个Pig类,然后把main方法改改,又过了一段时间,农场主嫌养猪也烦,想养鸡养鸭,然后就会发现我们不停的改main方法,在很多项目中就是我们不停的根据需求的变动改以前的写好的代码,而且做得都是牵一发动全身的事情,但是如果我们能写出可扩展性非常不错的设计,或许客户的需求一变动,我们只要改一个地方就完事了那该多爽,OK,回到刚刚养猪的问题,这个地方我们如果使用OO的继承(实现)和多态的话,即可在main方法做小小的改动,就可计算出结果。最后说一个有关生育年龄和生育数的设计,这里我都是在类的属性里面赋以常量,如果我们要提高扩展性,可增加一个配置文件,通过反射取得配置文件中的key和value,这样每次不管是养牛也好,养猪也好,生育年龄和生育数改变只需在main方法和配置文件中稍作变动,就可以得到驯养不同动物的结果。

  1   /** 
  2    * 可驯养的动物接口
   3    * 关于抽象类和接口
   4    * 脑子里有这个概念,但是没有具体的东西可以设计为抽象类 如交通工具
   5    * 一类或几类事物的共同特征,如可驯养的 就设计为接口 
   6    *   @author   LingJian
   7    *
   8    */ 
  9   public   interface   Tamableness {
  10      
 11       public   void   growUp(Farm f);
  12  
 13  }

  1   /** 
  2    * 
   3    *   @author   LingJian
   4    *
   5    */ 
  6   public   class   Farm {
   7  
  8       //  农场经营时间 
  9       private   int   year;
  10       //  可驯养动物 
 11       private  List<Tamableness>  t;
  12  
 13       public   int   getYear() {
  14           return   year;
  15       }
  16       public   void  setYear( int   year) {
  17           this .year =  year;
  18       }
  19       public  List<Tamableness>  getT() {
  20           return   t;
  21       }
  22       public   void  setT(List<Tamableness>  t) {
  23           this .t =  t;
  24       }
  25       public   void  past( int   time) {
  26           while ( this .year <  time) {
  27               this .year ++ ;
  28              
 29               int  j =  t.size();
  30               for ( int  i=0; i<j; i++ ) {
  31                   System.out.println(i);
  32                  Tamableness c =  t.get(i);
  33                  c.growUp( this  );
  34               }
  35              System.out.println("第" + year + "年,农场有" + t.size() + "头可驯养的能挣钱的动物" );
  36           }
  37  
 38       }
  39  }

  1   /** 
  2    * 不养牛
   3    *   @author   LingJian
   4    *
   5    */ 
  6   public   class  Cow  implements   Tamableness {
   7  
  8       //  生育年龄 
  9       private   static   final   int  BEARAGE = 5 ;
  10       //  生育数 
 11       private   static   final   int  BORNCOUNT = 1 ;
  12      
 13       //  年龄 
 14       private   int   age;
  15      
 16      
 17       public   int   getAge() {
  18           return   age;
  19       }
  20       public   void  setAge( int   age) {
  21           this .age =  age;
  22       }
  23      
 24       public  Cow( int   age) {
  25           super  ();
  26           this .age =  age;
  27       }
  28      
 29       @Override
  30       public   void   growUp(Farm f) {
  31           this .age ++ ;
  32           //  母牛五岁生母牛 
 33           if (age >=  BEARAGE) {
  34               //  每年生头小母牛 
 35               for ( int  i=0; i<BORNCOUNT; i++ ) {
  36                  f.getT().add( new  Cow(0 ));
  37               }
  38           }
  39       }
  40  }

  1   /** 
  2    * 改养猪
   3    *   @author   LingJian
   4    *
   5    */ 
  6   public   class  Pig  implements   Tamableness {
   7  
  8       //  生育年龄 
  9       private   static   final   int  BEARAGE = 8 ;
  10       //  生育数 
 11       private   static   final   int  BORNCOUNT = 8 ;
  12      
 13       //  年龄 
 14       private   int   age;
  15      
 16      
 17       public   int   getAge() {
  18           return   age;
  19       }
  20       public   void  setAge( int   age) {
  21           this .age =  age;
  22       }
  23      
 24       public  Pig( int   age) {
  25           super  ();
  26           this .age =  age;
  27       }
  28      
 29      
 30       @Override
  31       public   void   growUp(Farm f) {
  32           this .age ++ ;
  33           if (age >=  BEARAGE) {
  34               for ( int  i=0; i<BORNCOUNT; i++ ) {
  35                  f.getT().add( new  Pig(0 ));
  36               }
  37           }
  38       }
  39  
 40  }

  1   /** 
  2    * 测试类
   3    *   @author   LingJian
   4    *
   5    */ 
  6   public   class   Test {
   7  
  8       /** 
  9        * 测试方法
  10        *   @param   args
  11        */ 
 12       public   static   void   main(String[] args) {
  13          
 14          List<Tamableness> list =  new  ArrayList<Tamableness> ();
  15          Farm f =  new   Farm();
  16           //  养什么 就new什么 
 17          list.add( new  Pig(0 ));
  18           f.setT(list);
  19          
 20          
 21          f.past(20 );
  22          
 23       }
  24  
 25  }

 

 

分类:  design pattern of java

标签:  JAVA 面向对象 设计模式

作者: Leo_wl

    

出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于OO思想解的详细内容...

  阅读:54次