3.2自底向上风格
自顶向下不是万能的
需求发生变化时,会很尴尬
变化是需求的本质特征
内部或外界的环境一旦发生小小的变化,就会造成很大的变动
个人---完全掌控-----》简单的软件逻辑《-----完全计划的模式
小组协作---掌控变化----》庞大的软件规模---产生--》自适应变化《-----解决-----主流解决方案:面向对象
面向对象正是采用自底向上的设计风格
打印控制台表格2
实际开发中,使用混合风格,根据项目的要求而定
需求:不变,变
不变---》多种风格选择---》完成任务
变化---》估算变化---》确定风格---》完成任务
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胜!!!