State 引入一组表示对象状态的类,然后,把与状态相关的代码逻辑分配到这些类中
语境:
Door
1using System;
2
3namespace Gof.Test.State
4{
5 public delegate void ChangeHandler(Door door);
6 public class Door
7 {
8 public const int CLOSED = -1;
9 public const int OPENING = -2;
10 public const int OPEN = -3;
11 public const int CLOSING = -4;
12 public const int STAYOPEN = -5;
13
14 public event ChangeHandler Change;
15 private int _state = CLOSED;
16
17 public string Status()
18 {
19 switch(_state)
20 {
21 case OPENING:
22 {
23 return "Opening";
24 }
25 case OPEN:
26 {
27 return "Open";
28 }
29 case CLOSING:
30 {
31 return "Closing";
32 }
33 case STAYOPEN:
34 {
35 return "StayOpen";
36 }
37 default:
38 {
39 return "Closed";
40 }
41 }
42 }
43
44
45 public void Touch()
46 {
47 if(_state == CLOSED)
48 {
49 SetState(OPENING);
50 }
51 else if(_state == OPENING || _state == STAYOPEN)
52 {
53 SetState(CLOSING);
54 }
55 else
56 {
57 if(_state == OPEN)
58 {
59 SetState(STAYOPEN);
60 }
61 else if(_state == CLOSING)
62 {
63 SetState(OPENING);
64 }
65 }
66 }
67
68
69 private void SetState(int state)
70 {
71 this._state = state;
72 if(Change != null)
73 {
74 Change(this);
75 }
76 }
77
78
79 public void Complete()
80 {
81 if(_state == OPENING)
82 {
83 SetState(OPEN);
84 }
85 else if(_state == CLOSING)
86 {
87 SetState(CLOSED);
88 }
89 }
90
91
92 public void TimeOut()
93 {
94 if(_state == OPEN)
95 {
96 SetState(CLOSING);
97 }
98 }
99
100
101 public Door()
102 {
103 }
104 }
105}
1using System;
2
3namespace Gof.Test.State
4{
5 public delegate void ChangeHandler(Door door);
6 public class Door
7 {
8 public const int CLOSED = -1;
9 public const int OPENING = -2;
10 public const int OPEN = -3;
11 public const int CLOSING = -4;
12 public const int STAYOPEN = -5;
13
14 public event ChangeHandler Change;
15 private int _state = CLOSED;
16
17 public string Status()
18 {
19 switch(_state)
20 {
21 case OPENING:
22 {
23 return "Opening";
24 }
25 case OPEN:
26 {
27 return "Open";
28 }
29 case CLOSING:
30 {
31 return "Closing";
32 }
33 case STAYOPEN:
34 {
35 return "StayOpen";
36 }
37 default:
38 {
39 return "Closed";
40 }
41 }
42 }
43
44
45 public void Touch()
46 {
47 if(_state == CLOSED)
48 {
49 SetState(OPENING);
50 }
51 else if(_state == OPENING || _state == STAYOPEN)
52 {
53 SetState(CLOSING);
54 }
55 else
56 {
57 if(_state == OPEN)
58 {
59 SetState(STAYOPEN);
60 }
61 else if(_state == CLOSING)
62 {
63 SetState(OPENING);
64 }
65 }
66 }
67
68
69 private void SetState(int state)
70 {
71 this._state = state;
72 if(Change != null)
73 {
74 Change(this);
75 }
76 }
77
78
79 public void Complete()
80 {
81 if(_state == OPENING)
82 {
83 SetState(OPEN);
84 }
85 else if(_state == CLOSING)
86 {
87 SetState(CLOSED);
88 }
89 }
90
91
92 public void TimeOut()
93 {
94 if(_state == OPEN)
95 {
96 SetState(CLOSING);
97 }
98 }
99
100
101 public Door()
102 {
103 }
104 }
105}
客户代码
1 Door door = new Door();
2 door.Change +=new ChangeHandler(StateChange);
3 door.TimeOut();
4 door.Touch();
5 door.Touch();
6 door.Touch();
7 door.Touch();
8 door.Touch();
9 Console.ReadLine();
10private static void StateChange(Gof.Test.State.Door door)
11 {
12 Console.WriteLine("Door state had Changed to "+door.Status());
13 }
重构1,用状态模式简化Door类的状态相关代码。1 Door door = new Door();
2 door.Change +=new ChangeHandler(StateChange);
3 door.TimeOut();
4 door.Touch();
5 door.Touch();
6 door.Touch();
7 door.Touch();
8 door.Touch();
9 Console.ReadLine();
10private static void StateChange(Gof.Test.State.Door door)
11 {
12 Console.WriteLine("Door state had Changed to "+door.Status());
13 }
Door2
1using System;
2
3namespace Gof.Test.State
4{
5 public delegate void ChangeHandler2(Door2 door);
6 public class Door2
7 {
8 public readonly DoorState CLOSED;
9 public readonly DoorState OPENING;
10 public readonly DoorState OPEN;
11 public readonly DoorState CLOSING;
12 public readonly DoorState STAYOPEN;
13
14 public event ChangeHandler2 Change;
15 private DoorState _state;
16 public Door2()
17 {
18 OPEN = new DoorOpen(this);
19 CLOSING = new DoorClosing(this);
20 CLOSED = new DoorClosed(this);
21 OPENING = new DoorOpening(this);
22 STAYOPEN = new DoorClosing(this);
23 _state = CLOSED;
24 }
25 public string Status()
26 {
27 return _state.Status();
28 }
29
30
31 public void Touch()
32 {
33 _state.Touch();
34 }
35
36
37 internal void SetState(DoorState state)
38 {
39 this._state = state;
40 if(Change != null)
41 {
42 Change(this);
43 }
44 }
45
46
47 public void Complete()
48 {
49 _state.Touch();
50 }
51
52
53 public void TimeOut()
54 {
55 if(_state == OPEN)
56 {
57 SetState(CLOSING);
58 }
59 }
60 }
61}
1using System;
2
3namespace Gof.Test.State
4{
5 public delegate void ChangeHandler2(Door2 door);
6 public class Door2
7 {
8 public readonly DoorState CLOSED;
9 public readonly DoorState OPENING;
10 public readonly DoorState OPEN;
11 public readonly DoorState CLOSING;
12 public readonly DoorState STAYOPEN;
13
14 public event ChangeHandler2 Change;
15 private DoorState _state;
16 public Door2()
17 {
18 OPEN = new DoorOpen(this);
19 CLOSING = new DoorClosing(this);
20 CLOSED = new DoorClosed(this);
21 OPENING = new DoorOpening(this);
22 STAYOPEN = new DoorClosing(this);
23 _state = CLOSED;
24 }
25 public string Status()
26 {
27 return _state.Status();
28 }
29
30
31 public void Touch()
32 {
33 _state.Touch();
34 }
35
36
37 internal void SetState(DoorState state)
38 {
39 this._state = state;
40 if(Change != null)
41 {
42 Change(this);
43 }
44 }
45
46
47 public void Complete()
48 {
49 _state.Touch();
50 }
51
52
53 public void TimeOut()
54 {
55 if(_state == OPEN)
56 {
57 SetState(CLOSING);
58 }
59 }
60 }
61}
DoorState
1using System;
2
3namespace Gof.Test.State
4{
5 public abstract class DoorState
6 {
7 protected Door2 _door;
8
9 public DoorState(Door2 door)
10 {
11 _door = door;
12 }
13 public abstract void Touch();
14 public virtual void Complete(){}
15 public virtual void TimeOut(){}
16
17 public string Status()
18 {
19 return this.GetType().Name;
20 }
21 }
22}
1using System;
2
3namespace Gof.Test.State
4{
5 public abstract class DoorState
6 {
7 protected Door2 _door;
8
9 public DoorState(Door2 door)
10 {
11 _door = door;
12 }
13 public abstract void Touch();
14 public virtual void Complete(){}
15 public virtual void TimeOut(){}
16
17 public string Status()
18 {
19 return this.GetType().Name;
20 }
21 }
22}
DoorClosed
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosed : DoorState
6 {
7 public DoorClosed(Door2 door) : base(door)
8 {
9 }
10 public override void Touch()
11 {
12 _door.SetState(_door.OPENING);
13 }
14
15 }
16}
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosed : DoorState
6 {
7 public DoorClosed(Door2 door) : base(door)
8 {
9 }
10 public override void Touch()
11 {
12 _door.SetState(_door.OPENING);
13 }
14
15 }
16}
DoorClosing
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosing : DoorState
6 {
7 public DoorClosing(Door2 door) : base(door)
8 {
9 }
10 public override void Touch()
11 {
12 _door.SetState(_door.OPENING);
13 }
14 public override void Complete()
15 {
16 _door.SetState(_door.CLOSED);
17 }
18 }
19}
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosing : DoorState
6 {
7 public DoorClosing(Door2 door) : base(door)
8 {
9 }
10 public override void Touch()
11 {
12 _door.SetState(_door.OPENING);
13 }
14 public override void Complete()
15 {
16 _door.SetState(_door.CLOSED);
17 }
18 }
19}
DoorOpen
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpen:DoorState
6 {
7 public DoorOpen(Door2 door) : base(door)
8 {
9 }
10 public override void Touch()
11 {
12 _door.SetState(_door.STAYOPEN);
13 }
14 public override void TimeOut()
15 {
16 _door.SetState(_door.CLOSING);
17 }
18 }
19}
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpen:DoorState
6 {
7 public DoorOpen(Door2 door) : base(door)
8 {
9 }
10 public override void Touch()
11 {
12 _door.SetState(_door.STAYOPEN);
13 }
14 public override void TimeOut()
15 {
16 _door.SetState(_door.CLOSING);
17 }
18 }
19}
DoorOpening
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpening : DoorState
6 {
7 public DoorOpening(Door2 door) : base(door)
8 {
9 }
10 public override void Complete()
11 {
12 _door.SetState(_door.OPEN);
13 }
14 public override void Touch()
15 {
16 _door.SetState(_door.CLOSING);
17 }
18 }
19}
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpening : DoorState
6 {
7 public DoorOpening(Door2 door) : base(door)
8 {
9 }
10 public override void Complete()
11 {
12 _door.SetState(_door.OPEN);
13 }
14 public override void Touch()
15 {
16 _door.SetState(_door.CLOSING);
17 }
18 }
19}
DoorStayOpen
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorStayOpen : DoorState
6 {
7 public DoorStayOpen(Door2 door) : base(door)
8 {
9 }
10 public override void Touch()
11 {
12 _door.SetState(_door.CLOSING);
13 }
14 }
15}
重构2,把状态变成常量,每个状态只给出其下一个状态。1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorStayOpen : DoorState
6 {
7 public DoorStayOpen(Door2 door) : base(door)
8 {
9 }
10 public override void Touch()
11 {
12 _door.SetState(_door.CLOSING);
13 }
14 }
15}
Door2
1using System;
2
3namespace Gof.Test.State
4{
5 public delegate void ChangeHandler2(Door2 door);
6 public class Door2
7 {
8 public event ChangeHandler2 Change;
9 private DoorState _state;
10
11 public Door2()
12 {
13 _state = new DoorClosed();
14 }
15
16 public string Status()
17 {
18 return State.Status();
19 }
20
21 public void Touch()
22 {
23 State = _state.Touch();
24 }
25
26 public DoorState State
27 {
28 get
29 {
30 return _state;
31 }
32 set
33 {
34 _state = value;
35 if (Change != null)
36 {
37 Change(this);
38 }
39 }
40 }
41
42 public void Complete()
43 {
44 State = State.Complete();
45 }
46
47 public void TimeOut()
48 {
49 State = State.TimeOut();
50 }
51 }
52}
1using System;
2
3namespace Gof.Test.State
4{
5 public delegate void ChangeHandler2(Door2 door);
6 public class Door2
7 {
8 public event ChangeHandler2 Change;
9 private DoorState _state;
10
11 public Door2()
12 {
13 _state = new DoorClosed();
14 }
15
16 public string Status()
17 {
18 return State.Status();
19 }
20
21 public void Touch()
22 {
23 State = _state.Touch();
24 }
25
26 public DoorState State
27 {
28 get
29 {
30 return _state;
31 }
32 set
33 {
34 _state = value;
35 if (Change != null)
36 {
37 Change(this);
38 }
39 }
40 }
41
42 public void Complete()
43 {
44 State = State.Complete();
45 }
46
47 public void TimeOut()
48 {
49 State = State.TimeOut();
50 }
51 }
52}
DoorState
1using System;
2
3namespace Gof.Test.State
4{
5 public abstract class DoorState
6 {
7 static DoorState()
8 {
9 CLOSED = new DoorClosed();
10 OPENING = new DoorOpening();
11 OPEN = new DoorOpen();
12 STAYOPEN = new DoorStayOpen();
13 CLOSING = new DoorClosing();
14 }
15
16 public static DoorClosed CLOSED;
17 public static DoorOpening OPENING;
18 public static DoorOpen OPEN;
19 public static DoorStayOpen STAYOPEN;
20 public static DoorClosing CLOSING;
21
22 public abstract DoorState Touch();
23
24 public virtual DoorState Complete(){return this;}
25
26 public virtual DoorState TimeOut(){return this;}
27
28 public string Status()
29 {
30 return this.GetType().Name;
31 }
32 }
33}
1using System;
2
3namespace Gof.Test.State
4{
5 public abstract class DoorState
6 {
7 static DoorState()
8 {
9 CLOSED = new DoorClosed();
10 OPENING = new DoorOpening();
11 OPEN = new DoorOpen();
12 STAYOPEN = new DoorStayOpen();
13 CLOSING = new DoorClosing();
14 }
15
16 public static DoorClosed CLOSED;
17 public static DoorOpening OPENING;
18 public static DoorOpen OPEN;
19 public static DoorStayOpen STAYOPEN;
20 public static DoorClosing CLOSING;
21
22 public abstract DoorState Touch();
23
24 public virtual DoorState Complete(){return this;}
25
26 public virtual DoorState TimeOut(){return this;}
27
28 public string Status()
29 {
30 return this.GetType().Name;
31 }
32 }
33}
DoorClosed
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosed : DoorState
6 {
7 public override DoorState Touch()
8 {
9 return DoorState.OPENING;
10 }
11 }
12}
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosed : DoorState
6 {
7 public override DoorState Touch()
8 {
9 return DoorState.OPENING;
10 }
11 }
12}
DoorClosing
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosing : DoorState
6 {
7 public override DoorState Touch()
8 {
9 return DoorState.OPENING;
10 }
11 public override DoorState Complete()
12 {
13 return DoorState.CLOSED;
14 }
15 }
16}
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosing : DoorState
6 {
7 public override DoorState Touch()
8 {
9 return DoorState.OPENING;
10 }
11 public override DoorState Complete()
12 {
13 return DoorState.CLOSED;
14 }
15 }
16}
DoorOpen
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpen:DoorState
6 {
7 public override DoorState Touch()
8 {
9 return DoorState.STAYOPEN;
10 }
11 public override DoorState TimeOut()
12 {
13 return DoorState.CLOSING;
14 }
15 }
16}
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpen:DoorState
6 {
7 public override DoorState Touch()
8 {
9 return DoorState.STAYOPEN;
10 }
11 public override DoorState TimeOut()
12 {
13 return DoorState.CLOSING;
14 }
15 }
16}
DoorStayOpen
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorStayOpen : DoorState
6 {
7 public override DoorState Touch()
8 {
9 return DoorState.CLOSING;
10 }
11 }
12}
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorStayOpen : DoorState
6 {
7 public override DoorState Touch()
8 {
9 return DoorState.CLOSING;
10 }
11 }
12}
DoorOpening
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpening : DoorState
6 {
7 public override DoorState Complete()
8 {
9 return DoorState.OPEN;
10 }
11 public override DoorState Touch()
12 {
13 return DoorState.CLOSING;
14 }
15 }
16}
重构3,把状态变成常量,中间对象做为变量传递。1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpening : DoorState
6 {
7 public override DoorState Complete()
8 {
9 return DoorState.OPEN;
10 }
11 public override DoorState Touch()
12 {
13 return DoorState.CLOSING;
14 }
15 }
16}
Door2
1using System;
2
3namespace Gof.Test.State
4{
5 public delegate void ChangeHandler2(Door2 door);
6 public class Door2
7 {
8 public event ChangeHandler2 Change;
9 private DoorState _state;
10
11 public Door2()
12 {
13 _state = new DoorClosed();
14 }
15
16 public string Status()
17 {
18 return _state.Status();
19 }
20
21 public void Touch()
22 {
23 _state.Touch(this);
24 }
25
26 /**//// <summary>
27 /// 这个方法其自身不调用,是在状态类里当状态变化时调用,用来激活事件。
28 /// </summary>
29 /// <param name="state">状态基类</param>
30 public void SetState(DoorState state)
31 {
32 _state = state;
33 if (Change != null)
34 {
35 Change(this);
36 }
37 }
38
39 public void Complete()
40 {
41 _state.Complete(this);
42 }
43
44 public void TimeOut()
45 {
46 _state.TimeOut(this);
47 }
48 }
49}
1using System;
2
3namespace Gof.Test.State
4{
5 public delegate void ChangeHandler2(Door2 door);
6 public class Door2
7 {
8 public event ChangeHandler2 Change;
9 private DoorState _state;
10
11 public Door2()
12 {
13 _state = new DoorClosed();
14 }
15
16 public string Status()
17 {
18 return _state.Status();
19 }
20
21 public void Touch()
22 {
23 _state.Touch(this);
24 }
25
26 /**//// <summary>
27 /// 这个方法其自身不调用,是在状态类里当状态变化时调用,用来激活事件。
28 /// </summary>
29 /// <param name="state">状态基类</param>
30 public void SetState(DoorState state)
31 {
32 _state = state;
33 if (Change != null)
34 {
35 Change(this);
36 }
37 }
38
39 public void Complete()
40 {
41 _state.Complete(this);
42 }
43
44 public void TimeOut()
45 {
46 _state.TimeOut(this);
47 }
48 }
49}
DoorState
1using System;
2
3namespace Gof.Test.State
4{
5 public abstract class DoorState
6 {
7 static DoorState()
8 {
9 CLOSED = new DoorClosed();
10 OPENING = new DoorOpening();
11 OPEN = new DoorOpen();
12 STAYOPEN = new DoorStayOpen();
13 CLOSING = new DoorClosing();
14 }
15
16 public static DoorClosed CLOSED;
17 public static DoorOpening OPENING;
18 public static DoorOpen OPEN;
19 public static DoorStayOpen STAYOPEN;
20 public static DoorClosing CLOSING;
21
22 public abstract void Touch(Door2 door);
23
24 public virtual void Complete(Door2 door){}
25
26 public virtual void TimeOut(Door2 door){}
27
28 public string Status()
29 {
30 return this.GetType().Name;
31 }
32 }
33}
1using System;
2
3namespace Gof.Test.State
4{
5 public abstract class DoorState
6 {
7 static DoorState()
8 {
9 CLOSED = new DoorClosed();
10 OPENING = new DoorOpening();
11 OPEN = new DoorOpen();
12 STAYOPEN = new DoorStayOpen();
13 CLOSING = new DoorClosing();
14 }
15
16 public static DoorClosed CLOSED;
17 public static DoorOpening OPENING;
18 public static DoorOpen OPEN;
19 public static DoorStayOpen STAYOPEN;
20 public static DoorClosing CLOSING;
21
22 public abstract void Touch(Door2 door);
23
24 public virtual void Complete(Door2 door){}
25
26 public virtual void TimeOut(Door2 door){}
27
28 public string Status()
29 {
30 return this.GetType().Name;
31 }
32 }
33}
DoorClosed
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosed : DoorState
6 {
7 public override void Touch(Door2 door)
8 {
9 door.SetState(DoorState.OPENING);
10 }
11 }
12}
13
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosed : DoorState
6 {
7 public override void Touch(Door2 door)
8 {
9 door.SetState(DoorState.OPENING);
10 }
11 }
12}
13
DoorClosing
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosing : DoorState
6 {
7 public override void Touch(Door2 door)
8 {
9 door.SetState(DoorState.OPENING);
10 }
11 public override void Complete(Door2 door)
12 {
13 door.SetState(DoorState.CLOSED);
14 }
15 }
16}
17
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorClosing : DoorState
6 {
7 public override void Touch(Door2 door)
8 {
9 door.SetState(DoorState.OPENING);
10 }
11 public override void Complete(Door2 door)
12 {
13 door.SetState(DoorState.CLOSED);
14 }
15 }
16}
17
DoorOpen
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpen:DoorState
6 {
7 public override void Touch(Door2 door)
8 {
9 door.SetState(DoorState.STAYOPEN);
10 }
11 public override void TimeOut(Door2 door)
12 {
13 door.SetState(DoorState.CLOSING);
14 }
15 }
16}
17
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpen:DoorState
6 {
7 public override void Touch(Door2 door)
8 {
9 door.SetState(DoorState.STAYOPEN);
10 }
11 public override void TimeOut(Door2 door)
12 {
13 door.SetState(DoorState.CLOSING);
14 }
15 }
16}
17
DoorOpening
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpening : DoorState
6 {
7 public override void Complete(Door2 door)
8 {
9 door.SetState(DoorState.OPEN);
10 }
11 public override void Touch(Door2 door)
12 {
13 door.SetState(DoorState.CLOSING);
14 }
15 }
16}
17
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorOpening : DoorState
6 {
7 public override void Complete(Door2 door)
8 {
9 door.SetState(DoorState.OPEN);
10 }
11 public override void Touch(Door2 door)
12 {
13 door.SetState(DoorState.CLOSING);
14 }
15 }
16}
17
DoorStayOpen
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorStayOpen : DoorState
6 {
7 public override void Touch(Door2 door)
8 {
9 door.SetState(DoorState.CLOSING);
10 }
11 }
12}
13
1using System;
2
3namespace Gof.Test.State
4{
5 public class DoorStayOpen : DoorState
6 {
7 public override void Touch(Door2 door)
8 {
9 door.SetState(DoorState.CLOSING);
10 }
11 }
12}
13