自顶向下不是万能的
需求发生变化时,会很尴尬
变化是需求的本质特征
内部或外界的环境一旦发生小小的变化,就会造成很大的变动
个人---完全掌控-----》简单的软件逻辑《-----完全计划的模式
小组协作---掌控变化----》庞大的软件规模---产生--》自适应变化《-----解决-----主流解决方案:面向对象
面向对象正是采用自底向上的设计风格
实际开发中,使用混合风格,根据项目的要求而定
需求:不变,变
不变---》多种风格选择---》完成任务
变化---》估算变化---》确定风格---》完成任务
Excel是把每一个小格子确定为一个对象,仔细的去设计这个对象应当拥有的功能和其他对象的关系
自底向上的分析:
想象每一个小格子画出来以后进行组合就能完成要求。
构造这样的一个小对象,把它的功能调试完备,通过组合完成需求
设计一个小对象
用draw方法画出一个小单元格
利用外层循环画出整个表格
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ package topToBottom; //小单元类 class Cell{ private int x;//左上角位置 private int y; private int width; private int height; //构造方法 public Cell(int x,int y,int width,int height){ this.x = x; this.y = y; this.width = width; this.height = height; } //把自己描绘到cache[][]上去,我这里写的是a[][] public void draw(char[][] a){ for(int i=0;i<width;i++){//画水平线两条 a[y][x+i] = ‘$‘;//上面 a[y+height-1][x+i] = ‘$‘;//下面 } for(int i=0;i<height;i++){//画两条竖直线 a[y+i][x] = ‘$‘;//左边 a[y+i][x+width-1] = ‘$‘;//右边 } } } public class Print { public static void main(String[] args) { char[][] a = new char[20][50]; for(int i=0;i<3;i++){//3行 for(int j=0;j<8;j++){//8列 Cell x = new Cell(j*4, i*3, 5, 4); x.draw(a); } } print(a); } //打印 public static void print(char[][] a){ for(int i=0;i<a.length;i++){ for(int j=0;j<a[i].length;j++){ if(a[i][j]==0){ System.out.print(" "); }else{ System.out.print(a[i][j]); } } System.out.println(); } } }
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
自底向上的一个要点:在需求有变化的时候,小对象的重用能力很强。一个对象将来可以用于其他的项目
实际上具体的项目开发过程中,多种风格经常是混合着交叉使用的
模拟井字棋游戏
九个格子中双方轮流落子。
其中一方画x符号,另一方画o符号。
开始时,9个格子都是空的。
程序显示当前局面,提示某一方输入落子位置,然后显示局面,再提示另一方。
当某方棋子连成直线,该方获胜!
例如:
初始:
_ _ _
_ _ _
_ _ _
o 输入位置: 1,1
o _ _
_ _ _
_ _ _
x 输入位置: 2,2
o _ _
_ x _
_ _ _
当某一方出现了3个棋子连成直线或对角线,则该方获胜
/* * 模拟井字棋游戏 九个格子中双方轮流落子。 其中一方画x符号,另一方画o符号。 开始时,9个格子都是空的。 程序显示当前局面,提示某一方输入落子位置,然后显示局面,再提示另一方。 当某方棋子连成直线,该方获胜! 例如: 初始: _ _ _ _ _ _ _ _ _ o 输入位置: 1,1 o _ _ _ _ _ _ _ _ x 输入位置: 2,2 o _ _ _ x _ _ _ _ 当某一方出现了3个棋子连成直线或对角线,则该方获胜 */ package bottomToTop; import java.util.Scanner; public class GameJing { public static void main(String[] args) { System.out.println("初始:"); char[][] a = init();//初始化数组,棋盘 showMatrix(a);//展示棋盘 while(true){ turnOfO(a); if(judge(a)){ System.out.println("O胜!!!"); break; } if(peace(a)){ System.out.println("和棋!"); break; } turnOfX(a); if(judge(a)){ System.out.println("X胜!!!"); break; } if(peace(a)){ System.out.println("和棋!"); break; } } } //三个一样即赢 public static boolean judge(char[][] a){ boolean b = false; for(int i=0;i<3;i++){ if(a[i][0]!=‘-‘ && a[i][0]==a[i][1] && a[i][1]==a[i][2]){//横向3个相同 b=true; } if(a[0][i]!=‘-‘ && a[0][i]==a[1][i] && a[1][i]==a[2][i]){//纵向3个相同 b=true; } } if(a[0][0]!=‘-‘ && a[0][0]==a[1][1] && a[1][1]==a[2][2]){ b = true; } if(a[0][2]!=‘-‘ && a[0][2]==a[1][1] && a[1][1]==a[2][0]){ b = true; } return b; } //和棋 public static boolean peace(char[][] a){ int count = 0; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ if(a[i][j]!=‘-‘){//如果没有‘-‘,表示棋盘已经被占满,没有胜负,则和棋 count++; } } } return count==9; } //O下棋 public static void turnOfO(char [][] a){ Scanner scan = new Scanner(System.in); System.out.print("O输入位置:"); String s = scan.nextLine(); Cell co = new CellO(s); if(co.wrong_input){//输入格式范围不对 turnOfO(a);//调用自己,重新来 }else if(a[co.x][co.y]==‘X‘||a[co.x][co.y]==‘O‘){//已经被占了 System.out.println("该位置有棋子,请重新输入"); turnOfO(a);//调用自己,重新来 }else{ co.draw(a);//绘制下棋 showMatrix(a);//展示棋盘结果 } } //X下棋 public static void turnOfX(char [][] a){ Scanner scan = new Scanner(System.in); System.out.print("X输入位置:"); String s = scan.nextLine(); Cell cx = new CellX(s); if(cx.wrong_input){//输入格式范围不对,或者已经被占了 turnOfX(a);//调用自己,重新来 }else if(a[cx.x][cx.y]==‘X‘||a[cx.x][cx.y]==‘O‘){//已经被占了 System.out.println("该位置有棋子,请重新输入"); turnOfX(a);//调用自己,重新来 }else{ cx.draw(a);//绘制下棋 showMatrix(a);//展示棋盘结果 } } //显示二维数组 public static void showMatrix(char[][] a){ for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ System.out.print(" "+a[i][j]); } System.out.println(); } } //初始化 public static char[][] init(){ char[][] a =new char[3][3]; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ a[i][j] = ‘-‘; } } return a; } }
package bottomToTop; import java.util.regex.Matcher; import java.util.regex.Pattern; public abstract class Cell { public int x; public int y; public boolean wrong_input = false; public Cell(String s){ Pattern pt = Pattern.compile("([1-3]{1}),([1-3]{1})"); Matcher m = pt.matcher(s); if(m.find()){ this.x = Integer.valueOf(m.group(1))-1; this.y = Integer.valueOf(m.group(2))-1; }else{ System.out.println("输入格式有误,请重新输入"); wrong_input = true; } } public abstract void draw(char[][] a); }
package bottomToTop; public class CellO extends Cell { public CellO(String s) { super(s); // TODO Auto-generated constructor stub } @Override public void draw(char[][] a) { a[x][y]=‘O‘; } }
package bottomToTop; public class CellX extends Cell { public CellX(String s) { super(s); // TODO Auto-generated constructor stub } @Override public void draw(char[][] a) { a[x][y]=‘X‘; } }
初始: - - - - - - - - - O输入位置:1,1 O - - - - - - - - X输入位置:1,1 该位置有棋子,请重新输入 X输入位置:asdf 输入格式有误,请重新输入 X输入位置:1,2 O X - - - - - - - O输入位置:2,2 O X - - O - - - - X输入位置:2,3 O X - - O X - - - O输入位置:3,3 O X - - O X - - O O胜!!!
原文地址:http://blog.csdn.net/u011925500/article/details/24778139