问题:
有一个函数:
y={ x x<1
| 2x-1 1<=x<10
\ 3x-11 x>=10写一段程序,输入x,输出y
代码实现:
有两种实现方式:
第一种:最简单的办法,使用条ifelse件判断语句来实现:
1 import java.util.Scanner;
2
3 public class Demo {
4
5 public static void main(String[] args) {
6 // TODO Auto-generated method stub
7 System.out.println("请输入一个数:");
8 Scanner scanner=new Scanner(System.in);
9 int x=scanner.nextInt();
10 if(x<1){
11 System.out.println(x);
12 }else if (1<=x&&x<10) {
13 System.out.println(2*x-1);
14 }else {
15 System.out.println(3*x-11);
16 }
17 }
18
19 }
这个方法简单易懂,但是在实际中,这种方法并不是效率最高的,尤其是当面对多个选择判断时。而且在后期维护中也不方便,往往是一处改,处处改,带来不必要的麻烦。
所以建议采用第二种方法
第二种:使用状态模式来实现该问题(当选择条件大于等于三个时,建议使用该方法)
关于状态模式,详情看:
首先,先写抽象状态类(status):
1 public interface Status {
2
3 //定义不同状态需要实现的方法
4 public boolean s();
5
6
7 }
其次,再写具体状态类(S1,S2,S3):
1 //第一个具体状态类(S1)
2 public class S1 implements Status{
3 Context context;
4
5 //初始化
6 public S1(Context context) {
7 // TODO Auto-generated constructor stub
8 this.context=context;
9 }
10
11 //实现具体状态,符合该状态则输出,不符合则返回false,并将状态传递给下一个状态
12 @Override
13 public boolean s() {
14 // TODO Auto-generated method stub
15 if(context.x<1){
16 System.out.println("**************");
17 System.out.println(context.x);
18 System.out.println("**************");
19 }else{
20 context.setStatus(context.getStatus2());
21 return false;
22 }
23 return true;
24 }
25 }
26
27
28
29 //第二个具体状态类(S2)
30 public class S2 implements Status{
31 Context context;
32
33 //初始化
34 public S2(Context context) {
35 // TODO Auto-generated constructor stub
36 this.context=context;
37 }
38
39 //实现具体状态,符合该状态则输出,不符合则返回false,并将状态传递给下一个状态
40 @Override
41 public boolean s() {
42 // TODO Auto-generated method stub
43 if (context.x<10&&context.x>=1) {
44 System.out.println("**************");
45 System.out.println(2*context.x-1);
46 System.out.println("**************");
47 } else {
48 context.setStatus(context.getStatus3());
49 return false;
50 }
51 return true;
52 }
53 }
54
55
56 //第三个具体状态类(S3)
57 public class S3 implements Status{
58 Context context;
59
60 //初始化
61 public S3(Context context) {
62 // TODO Auto-generated constructor stub
63 this.context=context;
64 }
65
66 //实现具体状态,符合该状态则输出,不符合则返回false,并且输出错误
67 @Override
68 public boolean s() {
69 // TODO Auto-generated method stub
70 if (context.x>=10) {
71 System.out.println("**************");
72 System.out.println(3*context.x-11);
73 System.out.println("**************");
74 } else {
75 System.out.println("输入有误!请输入大于等于10的数!");
76 return false;
77 }
78 return true;
79 }
80 }
然后,是环境类(Context),负责管理具体状态:
1 public class Context {
2 int x;
3 Status status;
4 Status status1;
5 Status status2;
6 Status status3;
7
8 //初始化
9 public Context(int x) {
10 // TODO Auto-generated constructor stub
11 status1=new S1(this);
12 status2=new S2(this);
13 status3=new S3(this);
14 status =status1;
15 this.x =x;
16 }
17
18 //显示状态
19 public boolean show() {
20 return status.s();
21 }
22
23 //get和set方法
24 public Status getStatus() {
25 return status;
26 }
27 public void setStatus(Status status){
28 this.status=status;
29 }
30 public Status getStatus1() {
31 return status1;
32 }
33 public void setStatus1(Status status1) {
34 this.status1 = status1;
35 }
36 public Status getStatus2() {
37 return status2;
38 }
39 public void setStatus2(Status status2) {
40 this.status2 = status2;
41 }
42 public Status getStatus3() {
43 return status3;
44 }
45 public void setStatus3(Status status3) {
46 this.status3 = status3;
47 }
最后,是测试类(Test):
1 public class Test {
2 public static void main(String[] args) {
3
4 //获取用户输入的数字
5 System.out.println("请输入一个数:");
6 Scanner scanner=new Scanner(System.in);
7 int x=scanner.nextInt();
8
9 //将数字传递给环境类,并获取相应的状态
10 Context context=new Context(x);
11 Status status =new S1(context);
12
13 //将获取到的状态传递给环境类
14 context.setStatus(status);
15
16 //环境类根据所传递过来的状态找到相应的具体状态,并输出
17 while (true) {
18 if(context.show()==true){
19 System.out.println("结束");
20 break;
21 }
22 }
23 }
24 }
这样,就使用状态类,解决了分段函数的问题,虽然看上去相比第一种方法麻烦复杂了许多,但是这方便日后对该程序进行升级和维护,而且就算是修改代码,也不会出现一处改,处处改的局面。