使用状态模式来解决分段函数的问题

问题:

有一个函数:

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 }

  这个方法简单易懂,但是在实际中,这种方法并不是效率最高的,尤其是当面对多个选择判断时。而且在后期维护中也不方便,往往是一处改,处处改,带来不必要的麻烦。

  所以建议采用第二种方法

  第二种:使用状态模式来实现该问题(当选择条件大于等于三个时,建议使用该方法)

  关于状态模式,详情看:https://www.cnblogs.com/wangjiong/p/11249380.html

  首先,先写抽象状态类(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  }

   这样,就使用状态类,解决了分段函数的问题,虽然看上去相比第一种方法麻烦复杂了许多,但是这方便日后对该程序进行升级和维护,而且就算是修改代码,也不会出现一处改,处处改的局面。

 

posted @ 2019-07-26 11:36  Tinero  阅读(288)  评论(0编辑  收藏  举报