论坛首页 Java企业应用论坛

OO 还是 procedural 小程序的设计

浏览 13213 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2011-07-18   最后修改:2011-07-19
OO
背景: 面试写个小程序计算保龄球的总分。
保龄球基本规则: 每一盘可以有10 个frame ,从1-9 个 frame 是有两次击球机会,第10个 有可能有3次机会。
                 如果一个frame第一个球全中(strike) 那就 进入 下一个frame, 并把下两次击球的得分算为这次的bonus。
                 如果一个frame 没有全中,就打这个frame的第二个球, 如果补了个全中(Spare),那就把下一次击球的得分算为bonus。
                 如果一个frame既没有全中,也没有补全中,那就击倒几个瓶算积分。
                 第10个frame,如果是全中,或者补中 就有3次击球机会,并把三次击球总共打倒的瓶数算为这个frame的分数。
于是我就很快写了以下代码,可是却被说不是OO,大家以为这样的小程序如果要写成OO 就有点为OO而增加复杂度了。
如果用OO,如何才能很简洁地实现



public class BowlingTotalScoreCalculator {
	private int frames[][] = null;
public BowlingTotalScoreCalculator(int frames[][]){
	this.frames = frames; 
}
	
 public int	getScore(){
	 int score =0;
	 for(int i =0 ; i< frames.length-1 ; i++){
		 if(isStrike(frames[i])){
			 if(isStrike(frames[i+1])){// if the next frame also strike then need to check the frame after next
				 if(i==8){// at frame 8 take frame 9's  ball one and ball two as bonus
					 score = score +  20 + frames[9][1];
				 }else{
					 score = score +  20 + frames[i+2][0]; 
				 }
				
			}else{
				score = score + 10 + frames[i+1][0]+frames[i+1][1]; 
			}
		 }else if(isSpare(frames[i])){
			 score= score + 10 + frames[i+1][0]; 
		 }else{
			 score= score +  frames[i][0]+frames[i][1]; 
		 }
	 }
	  score = score  + getLastFrameScroe();
	 return score;
	}
	
	private int getLastFrameScroe() {
		int sc;
		 if(isStrike(frames[9])){
			 sc= 10 + frames[9][1]+frames[9][2] ; 
		 }else if(isSpare(frames[9])){
			 sc= 10 + frames[9][2]; 
		 }else{
			 sc= frames[9][0]+frames[9][1]; 
		 }
		 
		return sc ;
}


	private boolean isStrike(int[] frame ){
		if(frame[0] == 10 ) return true;
		else return false;
		
	}
	private boolean isSpare(int[] frame ){
		if(frame[0] < 10 && frame[0]+ frame[1] ==10  ) return true;
		else return false;
		
	}
	public static void main(String[] args) {
		BowlingTotalScoreCalculator bs = new BowlingTotalScoreCalculator(
                new int[][]{{10,0},{7,2},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}
                );
		
		System.out.println(bs.getScore() );  // print 28
		BowlingTotalScoreCalculator bs2 = new BowlingTotalScoreCalculator(
                 new int[][]{{8,2},{1,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}
                 );
		System.out.println(bs2.getScore() );//12
		BowlingTotalScoreCalculator bs3 = new BowlingTotalScoreCalculator(
                new int[][]{{10,10},{10,10},{10,10},{10,10},{10,10},{10,10},{10,10},{10,10},{10,10},{10,10,10}}
                );
		
		System.out.println(bs3.getScore() ); //300
		BowlingTotalScoreCalculator bs4 = new BowlingTotalScoreCalculator(
                new int[][]{{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5,5}}
                );
		
		System.out.println(bs4.getScore() );//150
		BowlingTotalScoreCalculator bs5 = new BowlingTotalScoreCalculator(
                new int[][]{{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{10,0},{0,0}}
                );
		
		System.out.println(bs4.getScore() );//150
	}

}

   发表时间:2011-07-19   最后修改:2011-07-19
操蛋的面试题年年有。。。。。

你要是不玩那东西
死你也想不出OO的写法的。
同被BS过的飘过。

0 请登录后投票
   发表时间:2011-07-19   最后修改:2011-07-19
我后来自己又去建立一个Frame 对象 重写了一遍,可是真正计算分数的还是那一样的if..else 计算还是一样可是代码却多了不少。
这只是一小段代码,不需要与其他程序交互。我们写一个类的内部代码到底是该简洁达到目的呢还是要为了面向对象而面向对象?
抛砖引玉,希望大家来讨论一下。
0 请登录后投票
   发表时间:2011-07-19  
试着重写了一下:

package my;

public class Frame {

	public static final int BALLS = 10;

	protected Frame nextFrame;

	protected int[] hitCounts;

	public Frame(int[] hitCounts) {
		this.hitCounts = hitCounts;
	}

	/** 当前Frame以及之后的总分 */
	public int totalScore() {
		int total = 0;
		for (Frame f = this; f != null; f = f.nextFrame) {
			total += f.frameScore();
		}
		return total;
	}

	/** 一局得分 */
	public int frameScore() {
		int total = 0;
		for (int hit : hitCounts)
			total += hit;

		if (nextFrame != null) {
			if (isStrikeFrame()) total += nextFrame.getStrikeBonus();
			if (isSpareFrame()) total += nextFrame.getSpareBonus();
		}
		return total;
	}

	/** 当前Frame可贡献的Spare奖励 */
	public int getSpareBonus() {
		return hitCounts[0];
	}

	/** 当前Frame可贡献的Strike奖励 */
	public int getStrikeBonus() {
		return hitCounts[0] + (nextFrame != null && isStrikeFrame() ? nextFrame.hitCounts[0] : hitCounts[1]);
	}

	public boolean isSpareFrame() {
		return !isStrikeFrame() && hitCounts[0] + hitCounts[1] == BALLS;
	}

	public boolean isStrikeFrame() {
		return hitCounts[0] == BALLS;
	}

	public void setNextFrame(Frame frame) {
		nextFrame = frame;
	}

}

package my;

public class FrameFactory {

	public static Frame buildFrames(int[][] hitCounts) {

		Frame last = new Frame(hitCounts[hitCounts.length - 1]);
		for (int i = hitCounts.length - 2; i >= 0; i--) {
			Frame frame = new Frame(hitCounts[i]);
			frame.setNextFrame(last);
			last = frame;
		}
		return last;
	}
}

package my;

public class Main {

	public static void main(String[] args) {
		int[][] hitCounts = new int[][] { { 10, 0 }, { 7, 2 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
				{ 0, 0 }, { 0, 0 }, { 0, 0 } };
		Frame head = FrameFactory.buildFrames(hitCounts);
		System.out.println(head.totalScore());
	}
}
0 请登录后投票
   发表时间:2011-07-19  
用OO 重写了,可是我觉得对于解决问题来说比不用oo复杂。
0 请登录后投票
   发表时间:2011-07-21  
抛出异常的爱 写道
操蛋的面试题年年有。。。。。

你要是不玩那东西
死你也想不出OO的写法的。
同被BS过的飘过。




0 请登录后投票
   发表时间:2011-07-21  
算分那一块,可以用到设计模式,好像是策略模式
0 请登录后投票
   发表时间:2011-07-21  
规则看的头晕!!
0 请登录后投票
   发表时间:2011-07-22  
用chain of responsibility, 把frame和hit封装为两个对象。然后传递进一个chain,把你的每种情况作为一个node挂在这个chain上。用一个这个chain中提供提相应的修改和提取frames和hits的方法给这个chain中的node。

0 请登录后投票
   发表时间:2011-07-22   最后修改:2011-07-23
用类继承的方式实现了一下。除工厂类以外,可以完全去掉if else的判断。



上面朋友提到的  策略模式、责任链模式 谁来实现一下吗?
  • my.rar (3.1 KB)
  • 下载次数: 10
  • 大小: 58.8 KB
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics