|
Home >
Real-time Mantra > Object Oriented Design
> The Open Closed Principle
|
| Resource Allocator (Violates Open Closed Principle) |
|
The problems with the above design is that it violates the Open Closed Principle. The following code presents a new design where the resource allocator is completely transparent to the actual resource types being supported. This is accomplished by adding a new abstraction, resource pool. The resource allocator directly interacts with the abstract class resource pool.
This has several advantages:
| Resource Allocator (Follows Open Closed Principle) |
|
The above design follows the open and closed principle. The Resource Pool is open for extension as new resource pools can be added without much impact on the rest of the system. The Resource Allocator is closed for change, as no changes need to be made to it for enhancing the system.
As you can see the above has been achieved by using two techniques:
If this principle is followed during the design, most changes to the system would be in terms of adding new classes/methods. Changes to existing classes/methods would be minimized.
Consider another example of a Call_Manager object. The Call_Manager manages a Call abstract class. The Call_Manager design is open for extension but closed for modification. Addition of a new call type requires writing a new class that inherits from Call. No changes are needed in the Call_Manager.

C# code for the example is presented below:
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace Open_Closed_Principle
6 {
7 public class Call_Manager
8 {
9 protected Call[] _calls;
10
11 // Creates a call. Returns the assigned call_id. Returns -1 if the call
12 // could not be created.
13 public int Create_Call(Call call)
14 {
15 int found_call_id = -1;
16 for (int call_id = 0; call_id < _calls.Length; call_id++)
17 {
18 if (_calls[call_id] == null)
19 {
20 found_call_id = call_id;
21 _calls[call_id] = call;
22 _calls[call_id].Handle_Create();
23 break;
24 }
25 }
26
27 return found_call_id;
28 }
29
30 // Deletes the call specified with the call_id.
31 // Returns true if a call is deleted
32 public bool Delete_Call(int call_Id)
33 {
34 Call found_call = null;
35
36 if (_calls[call_Id] != null)
37 {
38 found_call = _calls[call_Id];
39 found_call.Handle_Delete();
40 _calls[call_Id] = null;
41 }
42
43 return (found_call != null);
44 }
45
46 public void Dump()
47 {
48 foreach (Call call in _calls)
49 {
50 if (call != null)
51 {
52 call.Dump();
53 }
54 }
55 }
56 }
57
58 abstract public class Call
59 {
60 public abstract void Handle_Create();
61 public abstract void Handle_Delete();
62 public abstract void Dump();
63 }
64
65 public class ISUP_Call : Call
66 {
67 public override void Handle_Create()
68 {
69 // Create an ISUP call
70 }
71 public override void Handle_Delete()
72 {
73 // Delete an ISUP Call
74 }
75 public override void Dump()
76 {
77 // Dump the contents on an ISUP call
78 }
79 }
80
81 public class ISDN_Call : Call
82 {
83 public override void Handle_Create()
84 {
85 // Create an ISDN call
86 }
87 public override void Handle_Delete()
88 {
89 // Delete an ISDN Call
90 }
91 public override void Dump()
92 {
93 // Dump the contents on an ISDN call
94 }
95 }
96
97 public class GSM_Call : Call
98 {
99 public override void Handle_Create()
100 {
101 // Create an GSM call
102 }
103 public override void Handle_Delete()
104 {
105 // Delete an GSM Call
106 }
107 public override void Dump()
108 {
109 // Dump the contents on an GSM call
110 }
111 }
112 }
| Related Links |
|