使用表驱动编程方式编写打印万年历
表驱动编程设计只是编程的一个技巧,对于复杂的决策,可以将其包装为决策表,然后使用驱动编程的方法解决。这样可以使程序变得清晰简洁,又提高了代码的可修改性。
决策表设计如下:
条件和行动 | 规则 | |||
月份类型 | 大月 | 小月 | 平月(2月) | |
年份类型 | 无限制 | 无限制 | 平年 | 闰年 |
月份天数 | 31 | 30 | 28 | 29 |
年份天数 | 365 | 366 | ||
打印月份天数为31 | √ |
|
|
|
打印月份天数为30 |
| √ |
|
|
打印月份天数为29 |
|
| √ |
|
打印月份天数为28 |
|
|
| √ |
Java编程实现
package test;
import java.util.Scanner;
public class Test {
// 决策表,无限制单元格补上任意符号,保持数组大小为4
private static String[] monthType = { "big", "small", "flat", "flat" };
private static String[] yearType = { "any", "any", "flat", "leap" };
private static int[] monthDay = { 31, 30, 28, 29 };
private static int[] yearDay = { 365, 365, 365, 366 };
// 获取相应的月份天数和年份天数,字符串表示,"_"隔开
// 按照决策,年份的判断依据2月判断,所以下面计算总天数时传2月
public static String getYearAndMonthDay(int year, int month) {
for (int i = 0; i < 4; i++) {
if (monthType[i].equals(judgeMonthType(month))
&& (yearType[i].equals("any") || yearType[i]
.equals(judgeYearType(year)))) {
return yearDay[i] + "_" + monthDay[i];
}
}
return null;
}
public static void printDate(int y, int m) {
int monthDay = 0;
int yearDay_sum = 0;
// 计算从1900年到当前年份的总天数,用于计算星期几
for (int i = 1900; i < y; i++) {
//一定要传2月才能得到正确的当年天数
yearDay_sum += Integer
.parseInt(getYearAndMonthDay(i, 2).split("_")[0]);
}
for (int i = 1; i < m; i++) {
yearDay_sum += Integer
.parseInt(getYearAndMonthDay(y, i).split("_")[1]);
}
yearDay_sum = yearDay_sum + 1;
monthDay = Integer.parseInt(getYearAndMonthDay(y, m).split("_")[1]);
System.out.println("日\t一\t二\t三\t四\t五\t六");
// 除以7便是从那天开始
int length = yearDay_sum % 7;
// 之前用空格 打印
for (int i = 0; i <= length - 1; i++) {
System.out.print(" \t");
}
// 遍历月份 取出多加的monthDay
for (int i = 1; i <= monthDay; i++) {
if (yearDay_sum % 7 == 6) {
System.out.print(i + "\n");
} else {
System.out.print(i + "\t");
}
// 总天数自增
yearDay_sum++;
}
}
// 判断平年闰年的方法
public static String judgeYearType(int year) {
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
return "leap";
}
return "flat";
}
// 判断月份类型
public static String judgeMonthType(int month) {
if (month == 4 || month == 6 || month == 9 || month == 11) {
return "small";
} else if (month == 2) {
return "flat";
}
return "big";
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入年份:");
// int year = sc.nextInt();
System.out.println("请输入月份:");
// int month = sc.nextInt();
printDate(2017, 10);
}
}