Design Patterns
Design Patterns
Contents
1 Overview 1
1.1 Design pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.1 Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.2 History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.3 Practice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.4 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.5 Classification and list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.6 Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.7 Criticism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.8 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.9 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.10 Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Creational Patterns 6
2.1 Creational pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.1 Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.2 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.3 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.4 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.5 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.6 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 Abstract factory pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.1 Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.2 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.3 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.4 Pseudocode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.5 C# example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.6 Java example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.7 PHP example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.8 Crystal example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.9 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.10 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.11 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
i
ii CONTENTS
2.8.1 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.8.2 Rules of thumb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.8.3 Pseudocode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.8.4 C# Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.8.5 Java Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.8.6 PHP Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.8.7 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.8.8 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.8.9 Sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.9 Resource Acquisition Is Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.9.1 C++11 example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.9.2 Benefits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.9.3 Typical uses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.9.4 Clang and GCC “cleanup” extension for C . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.9.5 Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.9.6 Reference counting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.9.7 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.9.8 Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.9.9 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.10 Singleton pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.10.1 Common uses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.10.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.10.3 Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.10.4 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.10.5 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3 Structural patterns 29
3.1 Structural pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.1.1 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.1.2 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.2 Adapter pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.2.1 Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.2.2 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.2.3 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.2.4 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.2.5 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.3 Bridge pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.3.1 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.3.2 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.3.3 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.3.4 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.3.5 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
iv CONTENTS
4 Behavioral patterns 51
4.1 Behavioral pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.1.1 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.1.2 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.2 Chain-of-responsibility pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.2.1 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.2.2 Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.2.3 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.2.4 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.3 Command pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.3.1 Uses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.3.2 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.3.3 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
4.3.4 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.3.5 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.3.6 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.4 Interpreter pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.4.1 Uses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.4.2 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.4.3 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.4.4 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.4.5 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.4.6 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.5 Iterator pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.5.1 Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.5.2 Language-specific implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.5.3 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.5.4 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.5.5 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
vi CONTENTS
5 Concurrency patterns 88
5.1 Concurrency pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
5.1.1 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
5.1.2 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
5.1.3 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
5.2 Active object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
5.2.1 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.2.2 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.2.3 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.2.4 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.3 Balking pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.3.1 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.3.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.3.3 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.3.4 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.4 Messaging pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.4.1 SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.4.2 ØMQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.4.3 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.4.4 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
5.4.5 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
5.5 Double-checked locking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
5.5.1 Usage in C++11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
5.5.2 Usage in Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
5.5.3 Usage in Microsoft .NET (Visual Basic, C#) . . . . . . . . . . . . . . . . . . . . . . . . . 92
5.5.4 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
5.5.5 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
5.5.6 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
5.6 Asynchronous method invocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.6.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.6.2 Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.6.3 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.6.4 Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
5.7 Guarded suspension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
5.7.1 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
5.7.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
5.7.3 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
5.7.4 Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
CONTENTS ix
5.7.5 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
5.8 Lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
5.8.1 Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
5.8.2 Granularity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
5.8.3 Database locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
5.8.4 Disadvantages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
5.8.5 Language support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
5.8.6 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
5.8.7 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
5.8.8 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
5.9 Monitor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
5.9.1 Mutual exclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
5.9.2 Condition variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
5.9.3 History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
5.9.4 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
5.9.5 Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
5.9.6 Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
5.9.7 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
5.10 Reactor pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
5.10.1 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
5.10.2 Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
5.10.3 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
5.10.4 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
5.10.5 External links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
5.11 Readers-writer lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
5.11.1 Upgradable RW lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
5.11.2 Priority policies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
5.11.3 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
5.11.4 Programming language support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
5.11.5 Alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
5.11.6 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
5.11.7 Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
5.11.8 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
5.12 Scheduler pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
5.12.1 Types of operating system schedulers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
5.12.2 Scheduling disciplines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
5.12.3 Operating system process scheduler implementations . . . . . . . . . . . . . . . . . . . . . 118
5.12.4 See also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
5.12.5 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
5.12.6 Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
5.13 Thread pool pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
x CONTENTS
Overview
1.1 Design pattern the definition of building blocks to support task syn-
chronization.
In software engineering, a software design pattern is a
Implementation strategy patterns Addressing con-
general reusable solution to a commonly occurring prob-
cerns related to implementing source code to
lem within a given context in software design. It is not
support
a finished design that can be transformed directly into
source or machine code. It is a description or template for 1. program organization, and
how to solve a problem that can be used in many different
situations. Design patterns are formalized best practices 2. the common data structures specific to parallel
that the programmer can use to solve common problems programming.
when designing an application or system.
Structural design patterns Addressing concerns re-
Object-oriented design patterns typically show relation- lated to global structures of applications being de-
ships and interactions between classes or objects, without veloped.
specifying the final application classes or objects that are
involved. Patterns that imply mutable state may be un-
suited for functional programming languages, some pat- 1.1.2 History
terns can be rendered unnecessary in languages that have
built-in support for solving the problem they are trying Patterns originated as an architectural concept by
to solve, and object-oriented patterns are not necessarily Christopher Alexander (1977/79). In 1987, Kent Beck
suitable for non-object-oriented languages. and Ward Cunningham began experimenting with the
Design patterns may be viewed as a structured approach idea of applying patterns to programming – specifi-
to computer programming intermediate between the lev- cally pattern languages – and presented their results at
[6][7]
els of a programming paradigm and a concrete algorithm. the OOPSLA conference that year. In the following
years, Beck, Cunningham and others followed up on this
work.
1.1.1 Types
Design patterns gained popularity in computer science
after the book Design Patterns: Elements of Reusable
Design patterns reside in the domain of modules and in-
Object-Oriented Software was published in 1994 by the so-
terconnections. At a higher level there are architectural
called “Gang of Four” (Gamma et al.), which is frequently
patterns which are larger in scope, usually describing an
abbreviated as “GoF”. That same year, the first Pattern
overall pattern followed by an entire system.[1]
Languages of Programming Conference was held and the
There are many types of design patterns, for instance [2] following year, the Portland Pattern Repository was set up
[3]
for documentation of design patterns. The scope of the
term remains a matter of dispute. Notable books in the
Algorithm strategy patterns Addressing concerns re- design pattern genre include:
lated to high-level strategies describing how to ex-
ploit application characteristics on a computing plat- • Gamma, Erich; Helm, Richard; Johnson, Ralph;
form. Vlissides, John (1995). Design Patterns: Elements
Computational design patterns Addressing concerns of Reusable Object-Oriented Software. Addison-
related to key computation identification.[4][5] Wesley. ISBN 0-201-63361-2.
Execution patterns Which address issues related to • Brinch Hansen, Per (1995). Studies in Computa-
lower-level support of application execution, includ- tional Science: Parallel Programming Paradigms.
ing strategies for executing streams of tasks and for Prentice Hall. ISBN 0-13-439324-4.
1
2 CHAPTER 1. OVERVIEW
• Buschmann, Frank; Meunier, Regine; Rohnert, the Structure, Participants, and Collaboration sections.
Hans; Sommerlad, Peter (1996). Pattern-Oriented These sections describe a design motif: a prototypi-
Software Architecture, Volume 1: A System of Pat- cal micro-architecture that developers copy and adapt to
terns. John Wiley & Sons. ISBN 0-471-95869-7. their particular designs to solve the recurrent problem de-
scribed by the design pattern. A micro-architecture is
• Schmidt, Douglas C.; Stal, Michael; Rohnert, Hans;
a set of program constituents (e.g., classes, methods...)
Buschmann, Frank (2000). Pattern-Oriented Soft-
and their relationships. Developers use the design pattern
ware Architecture, Volume 2: Patterns for Concur-
by introducing in their designs this prototypical micro-
rent and Networked Objects. John Wiley & Sons.
architecture, which means that micro-architectures in
ISBN 0-471-60695-2.
their designs will have structure and organization similar
• Fowler, Martin (2002). Patterns of Enterprise Appli- to the chosen design motif.
cation Architecture. Addison-Wesley. ISBN 978-0-
321-12742-6.
Domain-specific patterns
• Hohpe, Gregor; Woolf, Bobby (2003). Enterprise
Integration Patterns: Designing, Building, and De- Efforts have also been made to codify design patterns in
ploying Messaging Solutions. Addison-Wesley. particular domains, including use of existing design pat-
ISBN 0-321-20068-3. terns as well as domain specific design patterns. Exam-
• Freeman, Eric T; Robson, Elisabeth; Bates, Bert; ples include user interface design patterns,[11] information
[12] [13]
Sierra, Kathy (2004). Head First Design Patterns. visualization,[15] secure design, “secure usability”,[14]
O'Reilly Media. ISBN 0-596-00712-4. Web design and business model design.[16]
The annual Pattern Languages of Programming Confer-
Although design patterns have been applied practically ence proceedings [17] include many examples of domain-
for a long time, formalization of the concept of design specific patterns.
patterns languished for several years.[8]
new pattern-writing efforts.[29] One example of a com- and showed that code-level dependencies were removed
monly used documentation format is the one used by from the implementations of 17 of the 23 design patterns
Erich Gamma, Richard Helm, Ralph Johnson and John and that aspect-oriented programming could simplify the
Vlissides (collectively known as the “Gang of Four”, or implementations of design patterns.[31] See also Paul Gra-
GoF for short) in their book Design Patterns. It contains ham’s essay “Revenge of the Nerds”.[32]
the following sections: Moreover, inappropriate use of patterns may unnecessar-
ily increase complexity.[33]
• Pattern Name and Classification: A descriptive
and unique name that helps in identifying and refer-
ring to the pattern. 1.1.8 See also
• Intent: A description of the goal behind the pattern • Abstraction principle
and the reason for using it.
• Algorithmic skeleton
• Also Known As: Other names for the pattern.
• Anti-pattern
• Motivation (Forces): A scenario consisting of a
problem and a context in which this pattern can be • Architectural pattern
used.
• Debugging patterns
• Applicability: Situations in which this pattern is us-
able; the context for the pattern. • Design pattern
• Structure: A graphical representation of the pat- • Distributed design patterns
tern. Class diagrams and Interaction diagrams may
be used for this purpose. • Double-chance function
• Material Design
1.1.7 Criticism
The concept of design patterns has been criticized in sev- 1.1.9 References
eral ways.
[1] Martin, Robert C. (2000). “Design Principles and Design
The design patterns may just be a sign of some miss-
Patterns” (PDF).
ing features of a given programming language (Java or
C++ for instance). Peter Norvig demonstrates that 16 out [2] https://sourcemaking.com/design_patterns
of the 23 patterns in the Design Patterns book (which is
primarily focused on C++) are simplified or eliminated [3] https://pmsware.wordpress.com/tag/
computational-design-patterns/
(via direct language support) in Lisp or Dylan.[30] Re-
lated observations were made by Hannemann and Kicza- [4] "Category:Computational Thinking Patterns – Scalable
les who implemented several of the 23 design patterns us- Game Design wiki”. sgd.cs.colorado.edu. Retrieved
ing an aspect-oriented programming language (AspectJ) 2015-12-26.
4 CHAPTER 1. OVERVIEW
[5] “Introduction to Software Engineer- [18] McConnell, Steve (June 2004). “Design in Construction”.
ing/Architecture/Design Patterns – Wikibooks, open Code Complete (2nd ed.). Microsoft Press. p. 104. ISBN
books for an open world”. en.wikibooks.org. Retrieved 978-0-7356-1967-8. Table 5.1 Popular Design Patterns
2015-12-26.
[19] “Design Patterns: Dependency injection”. Retrieved
[6] Smith, Reid (October 1987). Panel on design method- 2011-04-13. The use of a factory class is one common
ology. OOPSLA '87 Addendum to the Proceedings. way to implement DI.
doi:10.1145/62138.62151., “Ward cautioned against re-
[20] Fowler, Martin (2002). Patterns of Enterprise Application
quiring too much programming at, what he termed, 'the
Architecture. Addison-Wesley. ISBN 978-0-321-12742-
high level of wizards.' He pointed out that a written 'pat-
6.
tern language' can significantly improve the selection and
application of abstractions. He proposed a 'radical shift in [21] C. Martin, Robert (2002). “28. Extension object”. Agile
the burden of design and implementation' basing the new Software Development, Principles, Patterns, and Practices.
methodology on an adaptation of Christopher Alexander’s p. 408. ISBN 978-0135974445.
work in pattern languages and that programming-oriented
pattern languages developed at Tektronix has significantly [22] Bloch, Joshua (2008). “Item 37: Use marker interfaces to
aided their software development efforts.” define types”. Effective Java (Second edition). Addison-
Wesley. p. 179. ISBN 978-0-321-35668-0.
[7] Beck, Kent; Cunningham, Ward (September 1987).
[23] “Twin – A Design Pattern for Modeling Multiple Inheri-
Using Pattern Languages for Object-Oriented Program.
tance” (PDF).
OOPSLA '87 workshop on Specification and Design for
Object-Oriented Programming. Retrieved 2006-05-26. [24] Schmidt, Douglas C.; Stal, Michael; Rohnert, Hans;
Buschmann, Frank (2000). Pattern-Oriented Software Ar-
[8] Baroni, Aline Lúcia; Guéhéneuc, Yann-Gaël; Albin- chitecture, Volume 2: Patterns for Concurrent and Net-
Amiot, Hervé (June 2003). “Design Patterns Formal- worked Objects. John Wiley & Sons. ISBN 0-471-60695-
ization”. Nantes: École Nationale Supérieure des Tech- 2.
niques Industrielles et des Mines de Nantes. CiteSeerX
10.1.1.62.6466 . [25] Binding Properties
[9] Bishop, Judith. “C# 3.0 Design Patterns: Use the Power [26] Nagel, Christian; Evjen, Bill; Glynn, Jay; Watson, Karli;
of C# 3.0 to Solve Real-World Problems”. C# Books Skinner, Morgan (2008). “Event-based Asynchronous
from O'Reilly Media. Retrieved 2012-05-15. If you want Pattern”. Professional C# 2008. Wiley. pp. 570–571.
to speed up the development of your .NET applications, ISBN 0-470-19137-6.
you're ready for C# design patterns -- elegant, accepted [27] Lock Pattern
and proven ways to tackle common programming prob-
lems. [28] Gabriel, Dick. “A Pattern Definition”. Archived from the
original on 2007-02-09. Retrieved 2007-03-06.
[10] Meyer, Bertrand; Arnout, Karine (July 2006).
“Componentization: The Visitor Example” [29] Fowler, Martin (2006-08-01). “Writing Software Pat-
(PDF). IEEE Computer. IEEE. 39 (7): 23–30. terns”. Retrieved 2007-03-06.
doi:10.1109/MC.2006.227. [30] Norvig, Peter (1998). Design Patterns in Dynamic Lan-
guages.
[11] Laakso, Sari A. (2003-09-16). “Collection of User Inter-
face Design Patterns”. University of Helsinki, Dept. of [31] Hannemann, Jan (2002). Design pattern implementation
Computer Science. Retrieved 2008-01-31. in Java and AspectJ.
[12] Heer, J.; Agrawala, M. (2006). “Software Design Pat- [32] Graham, Paul (2002). Revenge of the Nerds. Retrieved
terns for Information Visualization”. IEEE Transactions 2012-08-11.
on Visualization and Computer Graphics. 12 (5): 853–60.
doi:10.1109/TVCG.2006.178. PMID 17080809. [33] McConnell, Steve (2004). Code Complete: A Practical
Handbook of Software Construction, 2nd Edition. p. 105.
[13] Dougherty, Chad; Sayre, Kirk; Seacord, Robert C.; Svo-
boda, David; Togashi, Kazuya (2009). Secure Design Pat-
terns (PDF). Software Engineering Institute. 1.1.10 Further reading
[14] Garfinkel, Simson L. (2005). Design Principles and Pat- • Alexander, Christopher; Ishikawa, Sara; Silverstein,
terns for Computer Systems That Are Simultaneously Se- Murray; Jacobson, Max; Fiksdahl-King, Ingrid; An-
cure and Usable (Ph.D. thesis). gel, Shlomo (1977). A Pattern Language: Towns,
Buildings, Construction. New York: Oxford Univer-
[15] “Yahoo! Design Pattern Library”. Retrieved 2008-01-31.
sity Press. ISBN 978-0-19-501919-3.
[16] “How to design your Business Model as a Lean Startup?".
• Alur, Deepak; Crupi, John; Malks, Dan (May
Retrieved 2010-01-06.
2003). Core J2EE Patterns: Best Practices and De-
[17] Pattern Languages of Programming, Conference proceed- sign Strategies (2nd Edition). Prentice Hall. ISBN
ings (annual, 1994—) 0-13-142246-4.
1.1. DESIGN PATTERN 5
• Beck, Kent (October 2007). Implementation Pat- • Larman, Craig (2005). Applying UML and Patterns.
terns. Addison-Wesley. ISBN 978-0-321-41309-3. Prentice Hall. ISBN 0-13-148906-2.
• Beck, Kent; Crocker, R.; Meszaros, G.; Coplien, J. • Liskov, Barbara; Guttag, John (2000). Program De-
O.; Dominick, L.; Paulisch, F.; Vlissides, J. (March velopment in Java: Abstraction, Specification, and
1996). Proceedings of the 18th International Con- Object-Oriented Design. Addison-Wesley. ISBN 0-
ference on Software Engineering. pp. 25–30. 201-65768-6.
• Borchers, Jan (2001). A Pattern Approach to Inter- • Manolescu, Dragos; Voelter, Markus; Noble, James
action Design. John Wiley & Sons. ISBN 0-471- (2006). Pattern Languages of Program Design 5.
49828-9. Addison-Wesley. ISBN 0-321-32194-4.
• Coplien, James O.; Schmidt, Douglas C. (1995). • Marinescu, Floyd (2002). EJB Design Patterns: Ad-
Pattern Languages of Program Design. Addison- vanced Patterns, Processes and Idioms. John Wiley
Wesley. ISBN 0-201-60734-4. & Sons. ISBN 0-471-20831-0.
• Coplien, James O.; Vlissides, John M.; Kerth, Nor- • Martin, Robert Cecil; Riehle, Dirk; Buschmann,
man L. (1996). Pattern Languages of Program De- Frank (1997). Pattern Languages of Program De-
sign 2. Addison-Wesley. ISBN 0-201-89527-7. sign 3. Addison-Wesley. ISBN 0-201-31011-2.
• Eloranta, Veli-Pekka; Koskinen, Johannes; Leppä- • Mattson, Timothy G; Sanders, Beverly A.;
nen, Marko; Reijonen, Ville (2014). Designing Dis- Massingill, Berna L. (2005). Patterns for Par-
tributed Control Systems: A Pattern Language Ap- allel Programming. Addison-Wesley. ISBN
proach. Wiley. ISBN 1118694155. 0-321-22811-1.
• Fowler, Martin (1997). Analysis Patterns: Reusable • Shalloway, Alan; Trott, James R. (2001). Design
Object Models. Addison-Wesley. ISBN 0-201- Patterns Explained, Second Edition: A New Perspec-
89542-0. tive on Object-Oriented Design. Addison-Wesley.
• Fowler, Martin (2003). Patterns of Enterprise Appli- ISBN 0-321-24714-0.
cation Architecture. Addison-Wesley. ISBN 978-0- • Vlissides, John M. (1998). Pattern Hatching: De-
321-12742-6. sign Patterns Applied. Addison-Wesley. ISBN 0-
• Freeman, Eric; Freeman, Elisabeth; Sierra, Kathy; 201-43293-5.
Bates, Bert (2004). Head First Design Patterns.
• Weir, Charles; Noble, James (2000). Small Memory
O'Reilly Media. ISBN 0-596-00712-4.
Software: Patterns for systems with limited memory.
• Hohmann, Luke; Fowler, Martin; Kawasaki, Guy Addison-Wesley. ISBN 0-201-59607-5. Archived
(2003). Beyond Software Architecture. Addison- from the original on 2007-06-17.
Wesley. ISBN 0-201-77594-8.
• Gabriel, Richard (1996). Patterns of Software: Tales
From The Software Community (PDF). Oxford Uni-
versity Press. p. 235. ISBN 0-19-512123-6.
Archived from the original (PDF) on 2003-08-01.
• Gamma, Erich; Helm, Richard; Johnson, Ralph;
Vlissides, John (1995). Design Patterns: Elements
of Reusable Object-Oriented Software. Addison-
Wesley. ISBN 0-201-63361-2.
• Hohpe, Gregor; Woolf, Bobby (2003). Enterprise
Integration Patterns: Designing, Building, and De-
ploying Messaging Solutions. Addison-Wesley.
ISBN 0-321-20068-3.
• Holub, Allen (2004). Holub on Patterns. Apress.
ISBN 1-59059-388-X.
• Kircher, Michael; Völter, Markus; Zdun, Uwe
(2005). Remoting Patterns: Foundations of Enter-
prise, Internet and Realtime Distributed Object Mid-
dleware. John Wiley & Sons. ISBN 0-470-85662-
9.
Chapter 2
Creational Patterns
In software engineering, creational design patterns are The creational patterns aim to separate a system from how
design patterns that deal with object creation mecha- its objects are created, composed, and represented. They
nisms, trying to create objects in a manner suitable to the increase the system’s flexibility in terms of the what, who,
situation. The basic form of object creation could result how, and when of object creation..[6]
in design problems or in added complexity to the design.
Creational design patterns solve this problem by somehow 2.1.2 Usage
controlling this object creation.
Creational design patterns are composed of two domi- As modern software engineering depends more on object
nant ideas. One is encapsulating knowledge about which composition than class inheritance, emphasis shifts away
concrete classes the system uses. Another is hiding from hard-coding behaviors toward defining a smaller
how instances of these concrete classes are created and set of basic behaviors that can be composed into more
combined.[1] complex ones.[7] Hard-coding behaviors are inflexible
because they require overriding or re-implementing the
Creational design patterns are further categorized into
whole thing in order to change parts of the design. Addi-
Object-creational patterns and Class-creational patterns,
tionally, hard-coding does not promote reuse and is hard
where Object-creational patterns deal with Object cre-
to keep track of errors. For these reasons, creational pat-
ation and Class-creational patterns deal with Class-
terns are more useful than hard-coding behaviors. Cre-
instantiation. In greater details, Object-creational pat-
ational patterns make design become more flexible. They
terns defer part of its object creation to another object,
provide different ways to remove explicit references in
while Class-creational patterns defer its object creation to
the concrete classes from the code that needs to instanti-
subclasses.[2]
ate them.[8] In other words, they create independency for
Five well-known design patterns that are parts of cre- objects and classes.
ational patterns are the
Consider applying creational patterns when:
• Abstract factory pattern, which provides an inter- • A system should be independent of how its objects
face for creating related or dependent objects with- and products are created.
out specifying the objects’ concrete classes.[3]
• A set of related objects is designed to be used to-
• Builder pattern, which separates the construction of gether.
a complex object from its representation so that the • Hiding the implementations of a class library or
same construction process can create different rep- product, revealing only their interfaces.
resentations.
• Constructing different representation of indepen-
• Factory method pattern, which allows a class to de- dent complex objects.
fer instantiation to subclasses.[4] • A class wants its subclass to implement the object it
creates.
• Prototype pattern, which specifies the kind of object
to create using a prototypical instance, and creates • The class instantiations are specified at run-time.
new objects by cloning this prototype. • There must be a single instance and client can access
this instance at all times.
• Singleton pattern, which ensures that a class only has
one instance, and provides a global point of access • Instance should be extensible without being modi-
to it.[5] fied.
6
2.1. CREATIONAL PATTERN 7
2.1.6 References
[1] Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlis-
sides, John (1995). Design Patterns. Massachusetts:
Addison-Wesley. p. 81. ISBN 978-0-201-63361-0. Re-
Creational Pattern class diagram. trieved 2015-05-22.
Below is a simple class diagram that most creational pat- [2] Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlis-
terns have in common. Note that different creational pat- sides, John (1995). Design Patterns. Massachusetts:
terns require additional and different participated classes. Addison-Wesley. ISBN 978-0-201-63361-0. Retrieved
2015-05-22.
Participants:
[3] Freeman, Eric; Freeman, Elisabeth; Sierra, Kathy; Bates,
Bert (2004). Hendrickson, Mike; Loukides, Mike, eds.
• Creator: Declares object interface. Returns object.
Head First Design Patterns. California: O'Reilly Media.
• ConcreteCreator: Implements object’s interface. p. 156. ISBN 978-0-596-00712-6. Retrieved 2015-05-
22.
• Builder pattern: separate the construction of a com- [6] Judith, Bishop (2007). C# 3.0 Design Patterns. Califor-
plex object from its representation so that the same nia: O'Reilly Media. p. 336. ISBN 978-0-596-52773-0.
Retrieved 2015-05-22.
construction process can create different represen-
tations [7] Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlis-
sides, John (1995). Design Patterns. Massachusetts:
• Dependency Injection pattern: separate object cre- Addison-Wesley. p. 84. ISBN 978-0-201-63361-0. Re-
ation from an application trieved 2015-05-22.
• Lazy initialization pattern: tactic of delaying the [8] Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlis-
creation of an object, the calculation of a value, or sides, John (1995). Design Patterns. Massachusetts:
some other expensive process until the first time it is Addison-Wesley. p. 85. ISBN 978-0-201-63361-0. Re-
needed trieved 2015-05-22.
8 CHAPTER 2. CREATIONAL PATTERNS
The abstract factory pattern provides a way to encap- The factory determines the actual concrete type of object
sulate a group of individual factories that have a common to be created, and it is here that the object is actually cre-
theme without specifying their concrete classes.[1] In nor- ated (in C++, for instance, by the new operator). How-
mal usage, the client software creates a concrete imple- ever, the factory only returns an abstract pointer to the
mentation of the abstract factory and then uses the generic created concrete object.
interface of the factory to create the concrete objects that This insulates client code from object creation by having
are part of the theme. The client doesn't know (or care) clients ask a factory object to create an object of the de-
which concrete objects it gets from each of these inter- sired abstract type and to return an abstract pointer to the
nal factories, since it uses only the generic interfaces of object.[4]
their products.[1] This pattern separates the details of im-
As the factory only returns an abstract pointer, the client
plementation of a set of objects from their general usage
code (that requested the object from the factory) does not
and relies on object composition, as object creation is im-
know — and is not burdened by — the actual concrete
plemented in methods exposed in the factory interface.[2]
type of the object that was just created. However, the
An example of this would be an abstract factory class type of a concrete object (and hence a concrete factory)
DocumentCreator that provides interfaces to create a is known by the abstract factory; for instance, the factory
number of products (e.g. createLetter() and createRe- may read it from a configuration file. The client has no
sume()). The system would have any number of derived need to specify the type, since it has already been speci-
concrete versions of the DocumentCreator class like Fan- fied in the configuration file. In particular, this means:
cyDocumentCreator or ModernDocumentCreator, each
with a different implementation of createLetter() and cre-
ateResume() that would create a corresponding object • The client code has no knowledge whatsoever of the
like FancyLetter or ModernResume. Each of these prod- concrete type, not needing to include any header
ucts is derived from a simple abstract class like Letter files or class declarations related to it. The client
or Resume of which the client is aware. The client code code deals only with the abstract type. Objects of a
would get an appropriate instance of the DocumentCre- concrete type are indeed created by the factory, but
ator and call its factory methods. Each of the resulting the client code accesses such objects only through
objects would be created from the same DocumentCre- their abstract interface.[5]
ator implementation and would share a common theme
(they would all be fancy or modern objects). The client • Adding new concrete types is done by modifying the
would only need to know how to handle the abstract Let- client code to use a different factory, a modification
ter or Resume class, not the specific version that it got that is typically one line in one file. The different
from the concrete factory. factory then creates objects of a different concrete
type, but still returns a pointer of the same abstract
A factory is the location of a concrete class in the code
type as before — thus insulating the client code from
at which objects are constructed. The intent in employing
change. This is significantly easier than modify-
the pattern is to insulate the creation of objects from their
ing the client code to instantiate a new type, which
usage and to create families of related objects without
would require changing every location in the code
having to depend on their concrete classes.[2] This allows
where a new object is created (as well as making sure
for new derived types to be introduced with no change to
that all such code locations also have knowledge of
the code that uses the base class.
the new concrete type, by including for instance a
Use of this pattern makes it possible to interchange con- concrete class header file). If all factory objects are
crete implementations without changing the code that stored globally in a singleton object, and all client
uses them, even at runtime. However, employment of code goes through the singleton to access the proper
this pattern, as with similar design patterns, may result in factory for object creation, then changing factories
unnecessary complexity and extra work in the initial writ- is as easy as changing the singleton object.[5]
ing of code. Additionally, higher levels of separation and
abstraction can result in systems that are more difficult to
debug and maintain.
2.2.3 Structure
Class diagram
2.2.1 Definition
The method createButton on the GUIFactory interface
The essence of the Abstract Factory Pattern is to “Provide returns objects of type Button. What implementation of
an interface for creating families of related or dependent Button is returned depends on which implementation of
objects without specifying their concrete classes.”.[3] GUIFactory is handling the method call.
2.2. ABSTRACT FACTORY PATTERN 9
CreateProductA()
{ IButton CreateButton(); } class WinFactory : IGU-
CreateProductB()
IFactory { public IButton CreateButton() { return new
«interface»
WinButton(); } } class OSXFactory : IGUIFactory {
«import»
ConcreteFactory2 ConcreteFactory1
AbstractProductA
«import»
public IButton CreateButton() { return new OSXBut-
CreateProductA()
CreateProductB()
CreateProductA()
CreateProductB()
ton(); } } class WinButton : IButton { public void
«instantiate»
ProductA1 ProductA2
Paint() { //Render a button in a Windows style } } class
«instantiate» OSXButton : IButton { public void Paint() { //Render
«instantiate»
«interface»
AbstractProductB a button in a Mac OS X style } } class Program { static
void Main() { var appearance = Settings.Appearance;
ProductB1 ProductB2
IGUIFactory factory; switch (appearance) { case Ap-
«instantiate»
pearance.Win: factory = new WinFactory(); break; case
Appearance.OSX: factory = new OSXFactory(); break;
default: throw new System.NotImplementedException();
} var button = factory.CreateButton(); button.Paint(); }
}
Lepus3 chart (legend)
edited. This type of data can't be edited step by step and 2.3.5 Pseudocode
must be edited at once.
We have a Car class. The problem is that a car has many
Builder often builds a Composite. Often, designs start out
options. The combination of each option would lead to a
using Factory Method (less complicated, more customiz-
huge list of constructors for this class. So we will create a
able, subclasses proliferate) and evolve toward Abstract
builder class, CarBuilder. We will send to the CarBuilder
Factory, Prototype, or Builder (more flexible, more com-
each car option step by step and then construct the final
plex) as the designer discovers where more flexibility is
car with the right options:
needed. Sometimes creational patterns are complemen-
tary: Builder can use one of the other patterns to imple- class Car is Can have GPS, trip computer and various
ment which components are built. Builders are good can- numbers of seats. Can be a city car, a sports car, or a
didates for a fluent interface.[1] cabriolet. class CarBuilder is method getResult() is out-
put: a Car with the right options Construct and return
the car. method setSeats(number) is input: the number
2.3.1 Definition of seats the car may have. Tell the builder the number
of seats. method setCityCar() is Make the builder re-
The intent of the Builder design pattern is to separate the member that the car is a city car. method setCabriolet()
construction of a complex object from its representation. is Make the builder remember that the car is a cabrio-
By doing so the same construction process can create dif- let. method setSportsCar() is Make the builder remem-
ferent representations. [2] ber that the car is a sports car. method setTripCom-
puter() is Make the builder remember that the car has
a trip computer. method unsetTripComputer() is Make
2.3.2 Advantages [3] the builder remember that the car does not have a trip
computer. method setGPS() is Make the builder remem-
ber that the car has a global positioning system. method
• Allows you to vary a product’s internal representa-
unsetGPS() is Make the builder remember that the car
tion.
does not have a global positioning system. Construct
a CarBuilder called carBuilder carBuilder.setSeats(2)
• Encapsulates code for construction and representa-
carBuilder.setSportsCar() carBuilder.setTripComputer()
tion.
carBuilder.unsetGPS() car := carBuilder.getResult()
• Provides control over steps of construction process. Of course one could dispense with Builder and just do
this:
car = new Car(); car.seats = 2; car.type =
2.3.3 Disadvantages[3] CarType.SportsCar; car.setTripComputer();
car.unsetGPS(); car.isValid();
• Requires creating a separate ConcreteBuilder for
So this indicates that the Builder pattern is more than
each different type of Product.
just a means to limit constructor proliferation. It removes
what could be a complex building process from being the
responsibility of the user of the object that is built. It
2.3.4 Structure also allows for inserting new implementations of how an
object is built without disturbing the client code.
Director Builder ConcreteBuilder
builder : Builder
buildPart() buildPart()
construct() getResult() : Product 2.3.6 Examples
<< create >>
this.builder.buildPart();
Product
C#
: ICarBuilder { private Car _car; public CarBuilder() b; b.setProductP(); Product p2 = b.build(); // get Product
{ this._car = new Car(); } public void SetColour(string P object b.setC('!'); // customize Product P Product p3
colour) { this._car.Colour = colour; } public void = b.build(); p2.print(); // test p2 p3.print(); // test p3 }
SetWheels(int count) { this._car.Wheels = count; }
public Car GetResult() { return this._car; } } /// <sum-
mary> /// The director /// </summary> public class
CarBuildDirector { public Car Construct() { CarBuilder Java
builder = new CarBuilder(); builder.SetColour(“Red”);
builder.SetWheels(4); return builder.GetResult(); } } /** * Represents the product created by the builder.
*/ class Car { private int wheels; private String color;
public Car() { } @Override public String toString()
The Director assembles a car instance in the example { return “Car [wheels = " + wheels + ", color = " +
above, delegating the construction to a separate builder color + "]"; } public int getWheels() { return wheels;
object. } public void setWheels(final int wheels) { this.wheels
= wheels; } public String getColor() { return color; }
public void setColor(final String color) { this.color =
C++ color; } } /** * The builder abstraction. */ interface
CarBuilder { CarBuilder setWheels(final int wheels);
////// Product declarations and inline impl. (possibly CarBuilder setColor(final String color); Car build();
Product.h) ////// class Product{ public: // use this class } class CarBuilderImpl implements CarBuilder { pri-
to construct Product class Builder; private: // variables vate Car car; public CarBuilderImpl() { car = new
in need of initialization to make valid object const int i; Car(); } @Override public CarBuilder setWheels(final
const float f; const char c; // Only one simple constructor int wheels) { car.setWheels(wheels); return this; }
- rest is handled by Builder Product( const int i, const @Override public CarBuilder setColor(final String
float f, const char c ) : i(i), f(f), c(c){} public: // Product color) { car.setColor(color); return this; } @Over-
specific functionality void print(); void doSomething(); ride public Car build() { return car; } } public
void doSomethingElse(); }; class Product::Builder{ class CarBuildDirector { private CarBuilder builder;
private: // variables needed for construction of object public CarBuildDirector(final CarBuilder builder) {
of Product class int i; float f; char c; public: // default this.builder = builder; } public Car construct() { return
values for variables static const constexpr int defaultI = builder.setWheels(4).setColor(“Red”).build(); } public
1; static const constexpr float defaultF = 3.1415f; static static void main(final String[] arguments) { CarBuilder
const constexpr char defaultC = 'a'; // create Builder builder = new CarBuilderImpl(); CarBuildDirector
with default values assigned // (in C++11 they can be carBuildDirector = new CarBuildDirector(builder);
simply assigned above on declaration instead) Builder() System.out.println(carBuildDirector.construct()); } }
: i( defaultI ), f( defaultF ), c( defaultC ){ } // sets
custom values for Product creation // returns Builder for
shorthand inline usage (same way as cout <<) Builder&
setI( const int i ){ this->i = i; return *this; } Builder& PHP
setF( const float f ){ this->f = f; return *this; } Builder&
setC( const char c ){ this->c = c; return *this; } // abstract class GetterSetter { public function
prepare specific frequently desired Product // returns __get($name) { $method = sprintf('get%s’, uc-
Builder for shorthand inline usage (same way as cout first($name)); if (!method_exists($this, $method))
<<) Builder& setProductP(){ this->i = 42; this->f = { throw new Exception(); } return $this-
−1.0f/12.0f; this->c = '@'; return *this; } // produce >$method(); } public function __set($name, $v)
desired Product Product build(){ // here optionaly check { $method = sprintf('set%s’, ucfirst($name)); if
variable consistency // and also if Product is buildable (!method_exists($this, $method)) { throw new Excep-
from given information return Product( this->i, this->f, tion(); } $this->$method($v); } } //Represents a product
this->c ); } }; created by the builder class Car extends GetterSetter {
///// Product implementation (possibly Product.cpp) private $wheels; private $colour; function __construct()
///// #include <iostream> void Product::print(){ using { } public function setWheels($wheels) { $this->wheels
namespace std; cout << “Product internals dump:" = $wheels; } public function getWheels() { return
<< endl; cout << “i: " << this->i << endl; cout << $this->wheels; } public function setColour($colour)
“f: " << this->f << endl; cout << “c: " << this->c { $this->colour = $colour; } public function get-
<< endl; } void Product::doSomething(){} void Prod- Colour() { return $this->colour; } } //The builder
uct::doSomethingElse(){} abstraction interface ICarBuilder { public function
//////////////////// Usage of Builder (replaces Director SetColour($colour); public function SetWheels($count);
from diagram) int main(){ // simple usage Product p1 public function GetResult(); } //Concrete builder im-
= Product::Builder().setI(2).setF(0.5f).setC('x').build(); plementation class CarBuilder implements ICarBuilder
p1.print(); // test p1 // advanced usage Product::Builder { private $_car; function __construct() { $this->_car
2.4. FACTORY METHOD PATTERN 13
class Car property wheels : Int32 property seats : Int32 “Define an interface for creating an object, but let sub-
property color : String def initialize(@wheels = 4, @seats classes decide which class to instantiate. The Factory
= 4, @color = “Black”) end end abstract class Builder method lets a class defer instantiation it uses to sub-
abstract def set_wheels(number : Int32) abstract def classes.” (Gang Of Four)
set_seats(number : Int32) abstract def set_color(color Creating an object often requires complex processes not
: String) abstract def get_result end class CarBuilder < appropriate to include within a composing object. The
Builder private getter car : Car def initialize @car = object’s creation may lead to a significant duplication of
Car.new end def set_wheels(value : Int32) @car.wheels code, may require information not accessible to the com-
= value end def set_seats(value : Int32) @car.seats = posing object, may not provide a sufficient level of ab-
value end def set_color(value : String) @car.color = straction, or may otherwise not be part of the compos-
value end def get_result return @car end end class Car- ing object’s concerns. The factory method design pattern
BuilderDirector def self.construct : Car builder = Car- handles these problems by defining a separate method for
Builder.new builder.set_wheels(8) builder.set_seats(4) creating the objects, which subclasses can then override
builder.set_color(“Red”) builder.get_result end end car to specify the derived type of product that will be created.
= CarBuilderDirector.construct p car
The factory method pattern relies on inheritance, as ob-
ject creation is delegated to subclasses that implement the
factory method to create objects.[1]
2.3.7 See also
2.4.2 Example
• Currying
Structure
2.3.8 References
(MazeGame) from the implementation of the concrete C# Factory pattern deals with the instantiation of ob-
classes. This makes the “new” Operator redundant, al- jects without exposing the instantiation logic. In other
lows adherence to the Open/closed principle and makes words, a Factory is actually a creator of objects which
the final product more flexible in the event of change. have a common interface.
//Empty vocabulary of actual object public interface
IPerson { string GetName(); } public class Villager :
Example implementations IPerson { public string GetName() { return “Village
Person"; } } public class CityPerson : IPerson { public
Java A maze game may be played in two modes, one string GetName() { return “City Person"; } } public
with regular rooms that are only connected with adjacent enum PersonType { Rural, Urban } /// <summary>
rooms, and one with magic rooms that allow players to /// Implementation of Factory - Used to create objects
be transported at random (this Java example is similar to /// </summary> public class Factory { public IPerson
one in the book Design Patterns). The MazeGame uses GetPerson(PersonType type) { switch (type) { case
Rooms but it puts the responsibility of creating Rooms PersonType.Rural: return new Villager(); case Person-
to its subclasses which create the concrete classes. The Type.Urban: return new CityPerson(); default: throw
regular game mode could use this template method: new NotSupportedException(); } } }
public abstract class MazeGame { private final
List<Room> rooms = new ArrayList<>(); public In the above code you can see the creation of one interface
MazeGame() { Room room1 = makeRoom(); Room called IPerson and two implementations called Villager
room2 = makeRoom(); room1.connect(room2); and CityPerson. Based on the type passed into the Fac-
rooms.add(room1); rooms.add(room2); } abstract pro- tory object, we are returning the original concrete object
tected Room makeRoom(); } as the interface IPerson.
A factory method is just an addition to Factory class. It
In the above snippet, the MazeGame constructor is a creates the object of the class through interfaces but on
template method that makes some common logic. It the other hand, it also lets the subclass decide which class
refers to the makeRoom factory method that encapsulates is instantiated.
the creation of rooms such that other rooms can be used public interface IProduct { string GetName(); string
in a subclass. To implement the other game mode that SetPrice(double price); } public class Phone : IProduct {
has magic rooms, it suffices to override the makeRoom private double _price; public string GetName() { return
method: “Apple TouchPad"; } public string SetPrice(double
public class MagicMazeGame extends MazeGame { price) { this._price = price; return “success"; } } /*
@Override protected Room makeRoom() { return new Almost same as Factory, just an additional exposure
MagicRoom(); } } public class OrdinaryMazeGame to do something with the created method */ public
extends MazeGame { @Override protected Room make- abstract class ProductAbstractFactory { protected
Room() { return new OrdinaryRoom(); } } MazeGame abstract IProduct DoSomething(); public IProduct
ordinaryGame = new OrdinaryMazeGame(); MazeGame GetObject() // Implementation of Factory Method. {
magicGame = new MagicMazeGame(); return this.DoSomething(); } } public class PhoneCon-
creteFactory : ProductAbstractFactory { protected
override IProduct DoSomething() { IProduct product =
new Phone(); //Do something with the object after you
get the object. product.SetPrice(20.30); return product;
PHP Another example in PHP follows, this time us-
}}
ing interface implementations as opposed to subclassing
(however the same can be achieved through subclassing).
It is important to note that the factory method can also be You can see we have used GetObject in concreteFactory.
defined as public and called directly by the client code (in As a result, you can easily call DoSomething() from it to
contrast with the Java example above). get the IProduct. You might also write your custom logic
after getting the object in the concrete Factory Method.
/* Factory and car interfaces */ interface CarFactory
The GetObject is made abstract in the Factory interface.
{ public function makeCar(); } interface Car { public
function getType(); } /* Concrete implementations of
the factory and car */ class SedanFactory implements 2.4.3 Uses
CarFactory { public function makeCar() { return new
Sedan(); } } class Sedan implements Car { public func- • In ADO.NET, IDbCommand.CreateParameter is
tion getType() { return 'Sedan'; } } /* Client */ $factory an example of the use of factory method to connect
= new SedanFactory(); $car = $factory->makeCar(); parallel class hierarchies.
print $car->getType();
• In Qt, QMainWindow::createPopupMenu is a fac-
2.5. LAZY INITIALIZATION 15
A fairly straightforward 'fill-in-the-blanks’ example of a type, e.g. “apple” * postcondition: The Fruit instance
Lazy Initialization design pattern, except that this uses an associated with that type. */ Fruit* Fruit::getFruit(const
enumeration for the type string& type) { map<string,Fruit*>::iterator it =
namespace DesignPatterns.LazyInitialization { pub- types.find(type); // try to find an existing instance; if
lic class LazyFactoryObject { //internal collection not found std::map will return types.end() Fruit *f; if
of items //IDictionaery makes sure they are unique (it == types.end()) { // if no instance with the proper
private IDictionary<LazyObjectType, LazyObject> type was found, make one f = new Fruit(type); // lazy
_LazyObjectList = new Dictionary<LazyObjectType, initialization part types[type] = f; // adding the newly
created Fruit to the types map for later lookup } else
LazyObject>(); //enum for passing name of type
required //avoids passing strings and is part of type { //if already had an instance f = it->second; //The
return value will be the found fruit } return f; } /* *
ahead public enum LazyObjectType { None, Small,
Big, Bigger, Huge } //standard type of object that For example purposes to see pattern in action */ void
Fruit::printCurrentTypes() { if (!types.empty()) { cout
will be constructed public struct LazyObject { public
LazyObjectType Name; public IList<int> Result; } << “Number of instances made = " << types.size()
<< endl; for (map<string,Fruit*>::iterator iter =
//takes type and create 'expensive' list private IList<int>
Result(LazyObjectType name) { IList<int> result = null; types.begin(); iter != types.end(); ++iter) { cout <<
switch (name) { case LazyObjectType.Small: result = (*iter).first << endl; } cout << endl; } } int main(void)
CreateSomeExpensiveList(1, 100); break; case Lazy- { Fruit::getFruit(“Banana”); Fruit::printCurrentTypes();
ObjectType.Big: result = CreateSomeExpensiveList(1, Fruit::getFruit(“Apple”); Fruit::printCurrentTypes();
1000); break; case LazyObjectType.Bigger: result // returns pre-existing instance from first // time Fruit
= CreateSomeExpensiveList(1, 10000); break; case with “Banana” was created Fruit::getFruit(“Banana”);
LazyObjectType.Huge: result = CreateSomeExpen- Fruit::printCurrentTypes(); return 0; } /* OUTPUT:
siveList(1, 100000); break; case LazyObjectType.None: Number of instances made = 1 Banana Number of
result = null; break; default: result = null; break; } return instances made = 2 Apple Banana Number of instances
result; } //not an expensive item to create, but you get the made = 2 Apple Banana */
point //delays creation of some expensive object until
needed private IList<int> CreateSomeExpensiveList(int
start, int end) { IList<int> result = new List<int>(); for
(int counter = 0; counter < (end - start); counter++) Java
{ result.Add(start + counter); } return result; } public
LazyFactoryObject() { //empty constructor } public Here is an example in Java.
LazyObject GetLazyFactoryObject(LazyObjectType import java.util.HashMap; import java.util.Map; im-
name) { //yes, i know it is illiterate and inaccurate port java.util.Map.Entry; public class Program { /**
LazyObject noGoodSomeOne; //retrieves LazyOb- * @param args */ public static void main(String[]
jectType from list via out, else creates one and adds args) { Fruit.getFruitByTypeName(FruitType.banana);
it to list if (!_LazyObjectList.TryGetValue(name, Fruit.showAll(); Fruit.getFruitByTypeName(FruitType.apple);
out noGoodSomeOne)) { noGoodSomeOne = new Fruit.showAll(); Fruit.getFruitByTypeName(FruitType.banana);
LazyObject(); noGoodSomeOne.Name = name; Fruit.showAll(); } } enum FruitType { none, apple, ba-
noGoodSomeOne.Result = this.Result(name); _Lazy- nana, } class Fruit { private static Map<FruitType,
ObjectList.Add(name, noGoodSomeOne); } return Fruit> types = new HashMap<>(); /** * Using a private
noGoodSomeOne; } } } constructor to force the use of the factory method. *
@param type */ private Fruit(FruitType type) { } /** *
Lazy Factory method, gets the Fruit instance associated
with a certain * type. Instantiates new ones as needed.
C++ * @param type Any allowed fruit type, e.g. APPLE *
@return The Fruit instance associated with that type.
Here is an example in C++. */ public static Fruit getFruitByTypeName(FruitType
#include <iostream> #include <string> #include <map> type) { Fruit fruit; // This has concurrency issues. Here
using namespace std; class Fruit { public: static Fruit* the read to types is not synchronized, // so types.put
getFruit(const string& type); static void printCurrent- and types.containsKey might be called at the same
Types(); private: static map<string,Fruit*> types; string time. // Don't be surprised if the data is corrupted.
type; // note: constructor private forcing one to use if (!types.containsKey(type)) { // Lazy initialisation
static getFruit() Fruit(const string& t) : type( t ) {} fruit = new Fruit(type); types.put(type, fruit); } else {
}; //definition needed for using any static member // OK, it’s available currently fruit = types.get(type);
variable map<string,Fruit*> Fruit::types; /* * Lazy } return fruit; } /** * Lazy Factory method, gets
Factory method, gets the Fruit instance associated with the Fruit instance associated with a certain * type.
a * certain type. Instantiates new ones as needed. * Instantiates new ones as needed. Uses double-checked
precondition: type. Any string that describes a fruit locking * pattern for using in highly concurrent en-
18 CHAPTER 2. CREATIONAL PATTERNS
vironments. * @param type Any allowed fruit type, = new Fruit($type); } return self::$types[$type]; }
e.g. APPLE * @return The Fruit instance associated public static function printCurrentTypes() { echo
with that type. */ public static Fruit getFruitByType- 'Number of instances made: ' . count(self::$types)
NameHighConcurrentVersion(FruitType type) { if . "\n"; foreach (array_keys(self::$types) as $key) {
(!types.containsKey(type)) { synchronized (types) echo "$key\n"; } echo "\n"; } } Fruit::getFruit('Apple');
{ // Check again, after having acquired the lock to Fruit::printCurrentTypes(); Fruit::getFruit('Banana');
make sure // the instance was not created meanwhile Fruit::printCurrentTypes(); Fruit::getFruit('Apple');
by another thread if (!types.containsKey(type)) { // Fruit::printCurrentTypes(); /* OUTPUT: Number of
Lazy initialisation types.put(type, new Fruit(type)); instances made: 1 Apple Number of instances made:
} } } return types.get(type); } /** * Displays all 2 Apple Banana Number of instances made: 2 Apple
entered fruits. */ public static void showAll() { Banana */ ?>
if (types.size() > 0) { System.out.println(“Number
of instances made = " + types.size()); for (En-
try<FruitType, Fruit> entry : types.entrySet()) {
String fruit = entry.getKey().toString(); fruit = Char- Python
acter.toUpperCase(fruit.charAt(0)) + fruit.substring(1);
System.out.println(fruit); } System.out.println(); } } } Here is an example in Python.
class Fruit: def __init__(self, item): self.item =
Output item class Fruits: def __init__(self): self.items
= {} def get_fruit(self, item): if item not in
self.items: self.items[item] = Fruit(item) return
Number of instances made = 1 Banana Number of in- self.items[item] if __name__ == '__main__':
stances made = 2 Banana Apple Number of instances fruits = Fruits() print(fruits.get_fruit('Apple'))
made = 2 Banana Apple print(fruits.get_fruit('Lime'))
JavaScript
Ruby
Here is an example in JavaScript.
var Fruit = (function() { var types = {}; function Fruit() Here is an example in Ruby, of lazily initializing an au-
{}; // count own properties in object function count(obj) thentication token from a remote service like Google.
{ return Object.keys(obj).length; } var _static = { The way that @auth_token is cached is also an example
getFruit: function(type) { if (typeof types[type] == 'un- of memoization.
defined') { types[type] = new Fruit; } return types[type]; require 'net/http' class Blogger def auth_token
}, printCurrentTypes: function () { console.log('Number @auth_token ||= (res = Net::HTTP.post_form(uri,
of instances made: ' + count(types)); for (var type params)) && get_token_from_http_response(res)
in types) { console.log(type); } } }; return _static; end # get_token_from_http_response, uri and
})(); Fruit.getFruit('Apple'); Fruit.printCurrentTypes(); params are defined later in the class end b = Blog-
Fruit.getFruit('Banana'); Fruit.printCurrentTypes(); ger.new b.instance_variable_get(:@auth_token)
Fruit.getFruit('Apple'); Fruit.printCurrentTypes(); # returns nil b.auth_token # returns token
b.instance_variable_get(:@auth_token) # returns to-
Output ken
Here is an example of lazy initialization in PHP 5: height ^height ifNil: [height := 2.0].
Note that lazy initialization can also be used in non- • Description from the Portland Pattern Repository
object-oriented languages.
• Lazy Initialization of Application Server Services
• Lazy Inheritance in C#
Scala has built-in support for lazy variable initiation.[1]
scala> val x = { println(“Hello”); 99 } Hello x: Int = 99
scala> lazy val y = { println(“Hello!!"); 31 } y: Int = 2.6 Multiton pattern
<lazy> scala> y Hello!! res2: Int = 31 scala> y res3: Int
= 31
Multiton
Crystal -instances: Map<Key, Multiton>
class Fruit private getter type : String @@types =
-Multiton()
{} of String => Fruit def initialize(@type) end def
self.get_fruit_by_type(type : String) @@types[type] +getInstance(): Multiton
||= Fruit.new(type) end def self.show_all puts
“Number of instances made: #{@@types.size}"
UML diagram of the multiton
@@types.each do |type, fruit| puts "#{type}"
end puts end def self.size @@types.size end end
In software engineering, the multiton pattern is a design
Fruit.get_fruit_by_type(“Banana”) Fruit.show_all
pattern similar to the singleton, which allows only one in-
Fruit.get_fruit_by_type(“Apple”) Fruit.show_all
stance of a class to be created. The multiton pattern ex-
Fruit.get_fruit_by_type(“Banana”) Fruit.show_all
pands on the singleton concept to manage a map of named
instances as key-value pairs.
Output:
Rather than having a single instance per application (e.g.
Number of instances made: 1 Banana Number of in- the java.lang.Runtime object in the Java programming
stances made: 2 Banana Apple Number of instances language) the multiton pattern instead ensures a single in-
made: 2 Banana Apple stance per key.
Most people and textbooks consider this a singleton pat-
2.5.3 See also tern. For example, multiton does not explicitly appear
in the highly regarded object-oriented programming text-
• Double-checked locking book Design Patterns (it appears as a more flexible ap-
proach named registry of singletons).
• Lazy loading
• Proxy pattern 2.6.1 Description
• Singleton pattern
While it may appear that the multiton is no more than a
simple hash table with synchronized access there are two
2.5.4 References important distinctions. First, the multiton does not allow
clients to add mappings. Secondly, the multiton never re-
[1] https://books.google.com/books?id=Qt-bRFetWw0C& turns a null or empty reference; instead, it creates and
lpg=PA30&ots=hW9ax5LeHb&dq=scala%20lazy% stores a multiton instance on the first request with the as-
20variables&pg=PA30#v=onepage&q=scala%20lazy% sociated key. Subsequent requests with the same key re-
20variables&f=false turn the original instance. A hash table is merely an im-
plementation detail and not the only possible approach.
The pattern simplifies retrieval of shared objects in an
2.5.5 External links application.
• Article "Java Tip 67: Lazy instantiation - Balancing Since the object pool is created only once, being a mem-
performance and resource usage” by Philip Bishop ber associated with the class (instead of the instance), the
and Nigel Warren multiton retains its flat behavior rather than evolving into
a tree structure.
• Java code examples
The multiton is unique in that it provides centralized ac-
• Use Lazy Initialization to Conserve Resources cess to a single directory (i.e. all keys are in the same
20 CHAPTER 2. CREATIONAL PATTERNS
namespace, per se) of multitons, where each multiton in- Object pools are primarily used for performance: in some
stance in the pool may exist having its own state. In this circumstances, object pools significantly improve perfor-
manner, the pattern advocates indexed storage of essen- mance. Object pools complicate object lifetime, as ob-
tial objects for the system (such as would be provided by jects obtained from and returned to a pool are not actually
an LDAP system, for example). However, a multiton is created or destroyed at this time, and thus require care in
limited to wide use by a single system rather than a myr- implementation.
iad of distributed systems.
2.7.1 Description
2.6.2 Drawbacks
When it is necessary to work with a large number of
This pattern, like the Singleton pattern, makes unit testing objects that are particularly expensive to instantiate and
far more difficult,[1] as it introduces global state into an each object is only needed for a short period of time, the
application. performance of an entire application may be adversely
affected. An object pool design pattern may be deemed
With garbage collected languages it may become a source
desirable in cases such as these.
of memory leaks as it introduces global strong references
to the objects. The object pool design pattern creates a set of objects
that may be reused. When a new object is needed, it is re-
quested from the pool. If a previously prepared object is
2.6.3 Implementations available it is returned immediately, avoiding the instan-
tiation cost. If no objects are present in the pool, a new
In Java, the multiton pattern can be implemented using an item is created and returned. When the object has been
enumerated type, with the values of the type correspond- used and is no longer needed, it is returned to the pool,
ing to the instances. In the case of an enumerated type allowing it to be used again in the future without repeat-
with a single value, this gives the singleton pattern. ing the computationally expensive instantiation process.
It is important to note that once an object has been used
and returned, existing references will become invalid.
2.6.4 References In some object pools the resources are limited so a max-
imum number of objects is specified. If this number is
[1] http://googletesting.blogspot.com/2008/11/ reached and a new item is requested, an exception may
clean-code-talks-global-state-and.html be thrown, or the thread will be blocked until an object
is released back into the pool.
2.6.5 External links The object pool design pattern is used in several places
in the standard classes of the .NET framework. One ex-
• Multiton implementation in Ruby language ample is the .NET Framework Data Provider for SQL
Server. As SQL Server database connections can be slow
• Multiton usage in PureMVC Framework for Action- to create, a pool of connections is maintained. When you
Script 3 close a connection it does not actually relinquish the link
to SQL Server. Instead, the connection is held in a pool
• Article with a C# Multiton implementation, example from which it can be retrieved when requesting a new con-
of use, and discussion of memory issues nection. This substantially increases the speed of making
connections.
For the article about a general pool, see Pool (computer Object pooling can offer a significant performance boost
science). in situations where the cost of initializing a class instance
is high and the rate of instantiation and destruction of
The object pool pattern is a software creational design a class is high – in this case objects can frequently be
pattern that uses a set of initialized objects kept ready reused, and each reuse saves a significant amount of time.
to use – a "pool" – rather than allocating and destroy- Object pooling requires resources – memory and possi-
ing them on demand. A client of the pool will request bly other resources, such as network sockets, and thus it
an object from the pool and perform operations on the is preferable that the number of instances in use at any
returned object. When the client has finished, it returns one time is low, but this is not required.
the object to the pool rather than destroying it; this can The pooled object is obtained in predictable time when
be done manually or automatically. creation of the new objects (especially over network) may
2.7. OBJECT POOL PATTERN 21
take variable time. These benefits are mostly true for be in some state that was unexpected by the client pro-
objects that are expensive with respect to time, such as gram and may cause the client program to fail. The pool
database connections, socket connections, threads and is responsible for resetting the objects, not the clients.
large graphic objects like fonts or bitmaps. Object pools full of objects with dangerously stale state
In other situations, simple object pooling (that hold no are sometimes called object cesspools and regarded as an
external resources, but only occupy memory) may not be anti-pattern.
efficient and could decrease performance.[1] In case of The presence of stale state is not always an issue; it be-
simple memory pooling, the slab allocation memory man- comes dangerous when the presence of stale state causes
agement technique is more suited, as the only goal is to the object to behave differently. For example, an ob-
minimize the cost of memory allocation and deallocation ject that represents authentication details may break if the
by reducing fragmentation. “successfully authenticated” flag is not reset before it is
passed out, since it will indicate that a user is correctly au-
thenticated (possibly as someone else) when they haven't
2.7.3 Implementation yet attempted to authenticate. However, it will work just
fine if you fail to reset some value only used for debug-
Object pools can be implemented in an automated fash- ging, such as the identity of the last authentication server
ion in languages like C++ via smart pointers. In the used.
constructor of the smart pointer, an object can be re-
quested from the pool, and in the destructor of the smart Inadequate resetting of objects may also cause an infor-
pointer, the object can be released back to the pool. In mation leak. If an object contains confidential data (e.g.
garbage-collected languages, where there are no destruc- a user’s credit card numbers) that isn't cleared before the
tors (which are guaranteed to be called as part of a stack object is passed to a new client, a malicious or buggy
unwind), object pools must be implemented manually, by client may disclose the data to an unauthorized party.
explicitly requesting an object from the factory and re- If the pool is used by multiple threads, it may need the
turning the object by calling a dispose method (as in the means to prevent parallel threads from grabbing and try-
dispose pattern). Using a finalizer to do this is not a good ing to reuse the same object in parallel. This is not nec-
idea, as there are usually no guarantees on when (or if) essary if the pooled objects are immutable or otherwise
the finalizer will be run. Instead, “try ... finally” should thread-safe.
be used to ensure that getting and releasing the object is
exception-neutral.
Manual object pools are simple to implement, but harder 2.7.6 Criticism
to use, as they require manual memory management of
pool objects. Some publications do not recommend using object pool-
ing with certain languages, such as Java, especially for
objects that only use memory and hold no external
2.7.4 Handling of empty pools resources.[2] Opponents usually say that object allocation
is relatively fast in modern languages with garbage col-
Object pools employ one of three strategies to handle a lectors; while the operator new needs only ten instruc-
request when there are no spare objects in the pool. tions, the classic new - delete pair found in pooling de-
signs requires hundreds of them as it does more complex
1. Fail to provide an object (and return an error to the work. Also, most garbage collectors scan “live” object
client). references, and not the memory that these objects use for
their content. This means that any number of “dead” ob-
2. Allocate a new object, thus increasing the size of the jects without references can be discarded with little cost.
pool. Pools that do this usually allow you to set the In contrast, keeping a large number of “live” but unused
high water mark (the maximum number of objects objects increases the duration of garbage collection.[1]
ever used).
3. In a multithreaded environment, a pool may block
the client until another thread returns an object to 2.7.7 Examples
the pool.
C#
the cost of creation and disposal of threads. the tasks can be placed in the queue. Finally, if this
The following shows the basic code of the object pool queue may get too long, it can be configured to suspend
design pattern implemented using C#. For brevity the the requesting thread.
properties of the classes are declared using C# 3.0 au- public class PooledObject { public String temp1; public
tomatically implemented property syntax. These could String temp2; public String temp3; public String get-
be replaced with full property definitions for earlier ver- Temp1() { return temp1; } public void setTemp1(String
sions of the language. Pool is shown as a static class, as temp1) { this.temp1 = temp1; } public String getTemp2()
it’s unusual for multiple pools to be required. However, { return temp2; } public void setTemp2(String temp2)
it’s equally acceptable to use instance classes for object { this.temp2 = temp2; } public String getTemp3() {
pools. return temp3; } public void setTemp3(String temp3) {
namespace DesignPattern.Objectpool { // The Poole- this.temp3 = temp3; } }
dObject class is the type that is expensive or slow to public class PooledObjectPool { private static
instantiate, // or that has limited availability, so is to be long expTime = 60000;//6 seconds public static
held in the object pool. public class PooledObject { HashMap<PooledObject, Long> available = new
DateTime _createdAt = DateTime.Now; public Date- HashMap<PooledObject, Long>(); public static
Time CreatedAt { get { return _createdAt; } } public HashMap<PooledObject, Long> inUse = new
string TempData { get; set; } } // The Pool class is the HashMap<PooledObject, Long>(); public synchro-
most important class in the object pool design pattern. nized static PooledObject getObject() { long now =
It controls access to the // pooled objects, maintaining System.currentTimeMillis(); if (available.isEmpty()) {
a list of available objects and a collection of objects PooledObject po = new PooledObject(); push(inUse, po,
that have already been // requested from the pool and now); return po; } else { for (Map.Entry<PooledObject,
are still in use. The pool also ensures that objects that Long> entry : available.entrySet()) { if (now -
have been released // are returned to a suitable state, entry.getValue() > expTime) { //object has ex-
ready for the next time they are requested. public pired popElement(available); } else { PooledOb-
static class Pool { private static List<PooledObject> ject po = popElement(available, entry.getKey());
_available = new List<PooledObject>(); pri- cleanUp(po); push(inUse, po, now); return po; }
vate static List<PooledObject> _inUse = new } } return null; } private synchronized static void
List<PooledObject>(); public static PooledObject push(HashMap<PooledObject, Long> map, PooledOb-
GetObject() { lock(_available) { if (_available.Count != ject po, long now) { map.put(po, now); } public static
void releaseObject(PooledObject po) { cleanUp(po);
0) { PooledObject po = _available[0]; _inUse.Add(po);
_available.RemoveAt(0); return po; } else { PooledOb- available.put(po, System.currentTimeMillis());
inUse.remove(po); } public static PooledOb-
ject po = new PooledObject(); _inUse.Add(po);
return po; } } } public static void ReleaseOb- ject popElement(HashMap<PooledObject, Long>
map) { Map.Entry<PooledObject, Long> entry
ject(PooledObject po) { CleanUp(po); lock (_available)
{ _available.Add(po); _inUse.Remove(po); } } private = map.entrySet().iterator().next(); PooledObject
key= entry.getKey(); //Long value=entry.getValue();
static void CleanUp(PooledObject po) { po.TempData =
null; } } } map.remove(entry.getKey()); return key; } public static
PooledObject popElement(HashMap<PooledObject,
Long> map, PooledObject key) { map.remove(key);
In the code above, the PooledObject includes two prop- return key; } public static void cleanUp(PooledObject
erties that are not shown in the UML diagram. One holds po) { po.setTemp1(null); po.setTemp2(null);
the time at which the object was first created. The other po.setTemp3(null); } }
holds a string that can be modified by the client but that is
reset when the PooledObject is released back to the pool.
This shows the clean-up process on release of an object
that ensures it is in a valid state before it can be requested 2.7.8 See also
from the pool again.
• Connection pool
• Free list
Java
• Slab allocation
Java supports thread pooling via
java.util.concurrent.ExecutorService and other re-
2.7.9 References
lated classes. The executor service has a certain number
of “basic” threads that are never discarded. If all threads [1] Goetz, Brian (2005-09-27). “Java theory and practice:
are busy, the service allocates the allowed number of Urban performance legends, revisited”. IBM developer-
extra threads that are later discarded if not used for the Works. Archived from the original on 2005-09-27. Re-
certain expiration time. If no more threads are allowed, trieved 2012-08-28.
2.8. PROTOTYPE PATTERN 23
[2] Goetz, Brian (2005-09-27). “Java theory and practice: The mitotic division of a cell — resulting in two identical
Garbage collection in the HotSpot JVM”. IBM devel- cells — is an example of a prototype that plays an active
operWorks. Archived from the original on 2003-11-25. role in copying itself and thus, demonstrates the Proto-
Retrieved 2012-08-28. type pattern. When a cell splits, two cells of identical
genotype result. In other words, the cell clones itself.[1]
• Kircher, Michael; Prashant Jain (2002-07-04).
“Pooling Pattern” (PDF). EuroPLoP 2002. Ger-
many. Retrieved 2007-06-09. 2.8.1 Structure
• Goldshtein, Sasha; Zurbalev, Dima; Flatow, Ido
(2012). Pro .NET Performance: Optimize Your C# I
«interface»
Prototype «import»
Client
Object p = prototype.clone();
clone() clone()
• Developer.com article
• Portland Pattern Repository entry
2.8.2 Rules of thumb
• Apache Commons Pool: A mini-framework to cor-
rectly implement object pooling in Java Sometimes creational patterns overlap — there are cases
when either prototype or abstract factory would be appro-
• Game Programming Patterns: Object Pool
priate. At other times they complement each other: ab-
stract factory might store a set of prototypes from which
to clone and return product objects (GoF, p126). Ab-
2.8 Prototype pattern stract factory, builder, and prototype can use singleton in
their implementations. (GoF, p81, 134). Abstract fac-
For other uses, see Software prototyping. tory classes are often implemented with factory meth-
Not to be confused with Prototype-based programming ods (creation through inheritance), but they can be im-
or Function prototype. plemented using prototype (creation through delegation).
(GoF, p95)
The prototype pattern is a creational design pattern in Often, designs start out using Factory Method (less com-
software development. It is used when the type of objects plicated, more customizable, subclasses proliferate) and
to create is determined by a prototypical instance, which evolve toward abstract factory, prototype, or builder
is cloned to produce new objects. This pattern is used to: (more flexible, more complex) as the designer discovers
where more flexibility is needed. (GoF, p136)
• avoid subclasses of an object creator in the client ap- Prototype does not require subclassing, but it does require
plication, like the abstract factory pattern does. an “initialize” operation. Factory method requires sub-
• avoid the inherent cost of creating a new object in the classing, but does not require initialization. (GoF, p116)
standard way (e.g., using the 'new' keyword) when it Designs that make heavy use of the composite and
is prohibitively expensive for a given application. decorator patterns often can benefit from Prototype as
well. (GoF, p126)
To implement the pattern, declare an abstract base class The rule of thumb could be that you would need to clone()
that specifies a pure virtual clone() method. Any class an Object when you want to create another Object at run-
that needs a "polymorphic constructor" capability derives time that is a true copy of the Object you are cloning. True
itself from the abstract base class, and implements the copy means all the attributes of the newly created Object
clone() operation. should be the same as the Object you are cloning. If you
The client, instead of writing code that invokes the “new” could have instantiated the class by using new instead, you
operator on a hard-coded class name, calls the clone() would get an Object with all attributes as their initial val-
method on the prototype, calls a factory method with ues. For example, if you are designing a system for per-
a parameter designating the particular concrete derived forming bank account transactions, then you would want
class desired, or invokes the clone() method through some to make a copy of the Object that holds your account in-
mechanism provided by another design pattern. formation, perform transactions on it, and then replace
24 CHAPTER 2. CREATIONAL PATTERNS
the original Object with the modified one. In such cases, 2.8.5 Java Example
you would want to use clone() instead of new.
This pattern creates the kind of object using its prototype.
In other words, while creating the object of Prototype ob-
ject, the class actually creates a clone of it and returns it as
2.8.3 Pseudocode prototype. You can see here, we have used Clone method
to clone the prototype when required.
Let’s write an occurrence browser class for a text. This // Prototype pattern public abstract class Prototype
class lists the occurrences of a word in a text. Such an implements Cloneable { public Prototype clone() throws
object is expensive to create as the locations of the occur-CloneNotSupportedException{ return (Prototype) su-
rences need an expensive process to find. So, to duplicate per.clone(); } } public class ConcretePrototype1 extends
such an object, we use the prototype pattern: Prototype { @Override public Prototype clone() throws
CloneNotSupportedException { return super.clone(); }
class WordOccurrences is field occurrences is The list } public class ConcretePrototype2 extends Prototype {
of the index of each occurrence of the word in the text. @Override public Prototype clone() throws CloneNot-
constructor WordOccurrences(text, word) is input: the SupportedException { return super.clone(); } }
text in which the occurrences have to be found input:
the word that should appear in the text Empty the oc-
currences list for each textIndex in text isMatching :=
true for each wordIndex in word if the current word 2.8.6 PHP Example
character does not match the current text character then
isMatching := false if isMatching is true then Add the // The Prototype pattern in PHP is done with the
current textIndex into the occurrences list method getO- use of built-in PHP function __clone() abstract class
neOccurrenceIndex(n) is input: a number to point on Prototype { public $a; public $b; public function
the nth occurrence. output: the index of the nth occur- displayCONS() { echo “CONS: {$this->a}\n"; echo
rence. Return the nth item of the occurrences field if any. “CONS: {$this->b}\n"; } public function display-
method clone() is output: a WordOccurrences object CLON() { echo “CLON: {$this->a}\n"; echo “CLON:
containing the same data. Call clone() on the super class. {$this->b}\n"; } abstract function __clone(); } class
On the returned object, set the occurrences field with the ConcretePrototype1 extends Prototype { public function
value of the local occurrences field. Return the cloned ob- __construct() { $this->a = “A1"; $this->b = “B1";
ject. text := “The prototype pattern is a creational design $this->displayCONS(); } function __clone() { $this-
pattern in software development first described in design >displayCLON(); } } class ConcretePrototype2 extends
patterns, the book.” word := “pattern"d searchEngine := Prototype { public function __construct() { $this->a
new WordOccurrences(text, word) anotherSearchEngine = “A2"; $this->b = “B2"; $this->displayCONS(); }
:= searchEngine.clone() function __clone() { $this->a = $this->a ."-C"; $this->b
(the search algorithm is not optimized; it is a basic algo- = $this->b ."-C"; $this->displayCLON(); } } $cP1 =
rithm to illustrate the pattern implementation) new ConcretePrototype1(); $cP2 = new ConcreteProto-
type2(); $cP2C = clone $cP2; // RESULT: #quanton81
// CONS: A1 // CONS: B1 // CONS: A2 // CONS: B2 //
CLON: A2-C // CLON: B2-C
2.8.4 C# Example
This pattern creates the kind of object using its prototype. 2.8.7 See also
In other words, while creating the object of Prototype ob-
ject, the class actually creates a clone of it and returns it • Function prototype
as prototype.You can see here, we have used Member-
wiseClone method to clone the prototype when required.
2.8.8 References
public abstract class Prototype { // normal imple-
mentation public abstract Prototype Clone(); } [1] Duell, Michael (July 1997). “Non-Software Examples of
public class ConcretePrototype1 : Prototype { Design Patterns”. Object Magazine. 7 (5): 54. ISSN 1055-
public override Prototype Clone() { return (Proto- 3614.
type)this.MemberwiseClone(); // Clones the concrete
class. } } public class ConcretePrototype2 : Prototype
{ public override Prototype Clone() { return (Proto- 2.8.9 Sources
type)this.MemberwiseClone(); // Clones the concrete
class. } } • Gamma, Erich; Helm, Richard; Johnson, Ralph;
Vlissides, John (1994). Design Patterns: Elements
2.9. RESOURCE ACQUISITION IS INITIALIZATION 25
of Reusable Object-Oriented Software. Addison- all stack objects are destroyed at the end of the enclos-
Wesley. ISBN 0-201-63361-2. ing scope, known as stack unwinding. The destructors of
both the lock and file objects are therefore guaranteed to
be called when returning from the function, whether an
2.9 Resource Acquisition Is Initial- exception has been thrown or not.[9]
ization Local variables allow easy management of multiple re-
sources within a single function: they are destroyed in the
reverse order of their construction, and an object is de-
Resource acquisition is initialization (RAII)[1] is a stroyed only if fully constructed—that is, if no exception
programming idiom[2] used in several object-oriented propagates from its constructor.[10]
languages, most prominently C++, where it originated,
but also D, Ada, Vala, and Rust. The technique was Using RAII greatly simplifies resource management, re-
developed for exception-safe resource management in duces overall code size and helps ensure program correct-
C++[3] during 1984–89, primarily by Bjarne Stroustrup ness. RAII is therefore highly recommended in C++, and
[11]
and Andrew Koenig,[4] and the term itself was coined most of the C++ standard library follows the idiom.
by Stroustrup.[5] RAII is generally pronounced as an
initialism, sometimes pronounced as “R, A, double I”.[6]
2.9.2 Benefits
In RAII, holding a resource is a class invariant, and is tied
to object lifetime: resource allocation (or acquisition) is The advantages of RAII as a resource management tech-
done during object creation (specifically initialization), by nique are that it provides encapsulation, exception safety
the constructor, while resource deallocation (release) is (for stack resources), and locality (it allows acquisition
done during object destruction (specifically finalization), and release logic to be written next to each other).
by the destructor. Thus the resource is guaranteed to be
Encapsulation is provided because resource management
held between when initialization finishes and finalization
logic is defined once in the class, not at each call site. Ex-
starts (holding the resources is a class invariant), and to
ception safety is provided for stack resources (resources
be held only when the object is alive. Thus if there are no
that are released in the same scope as they are acquired)
object leaks, there are no resource leaks.
by tying the resource to the lifetime of a stack variable (a
Other names for this idiom include Constructor Ac- local variable declared in a given scope): if an exception
quires, Destructor Releases (CADRe) [7] and one partic- is thrown, and proper exception handling is in place, the
ular style of use is called Scope-based Resource Manage- only code that will be executed when exiting the cur-
ment (SBRM).[8] This latter term is for the special case rent scope are the destructors of objects declared in that
of automatic variables. RAII ties resources to object life- scope. Finally, locality of definition is provided by writ-
time, which may not coincide with entry and exit of a ing the constructor and destructor definitions next to each
scope. (Notably variables allocated on the free store have other in the class definition.
lifetimes unrelated to any given scope.) However, using
Resource management therefore needs to be tied to the
RAII for automatic variables (SBRM) is the most com-
lifespan of suitable objects in order to gain automatic al-
mon use case.
location and reclamation. Resources are acquired during
initialization, when there is no chance of them being used
2.9.1 C++11 example before they are available, and released with the destruc-
tion of the same objects, which is guaranteed to take place
The following C++11 example demonstrates usage of even in case of errors.
RAII for file access and mutex locking: Comparing RAII with the finally construct used in Java,
#include <mutex> #include <iostream> #include Stroustrup wrote that “In realistic systems, there are far
<string> #include <fstream> #include <stdexcept> more resource acquisitions than kinds of resources, so the
void write_to_file (const std::string & message) { // “resource acquisition is initialization” technique leads to
mutex to protect file access (shared across threads) static less code than use of a “finally” construct.”[1]
std::mutex mutex; // lock mutex before accessing file
std::lock_guard<std::mutex> lock(mutex); // try to open
2.9.3 Typical uses
file std::ofstream file(“example.txt”); if (!file.is_open())
throw std::runtime_error(“unable to open file”); // writeThe RAII design is often used for controlling mutex locks
message to file file << message << std::endl; // file will be
in multi-threaded applications. In that use, the object re-
closed 1st when leaving scope (regardless of exception) leases the lock when destroyed. Without RAII in this sce-
// mutex will be unlocked 2nd (from lock destructor) nario the potential for deadlock would be high and the
when leaving // scope (regardless of exception) } logic to lock the mutex would be far from the logic to
unlock it. With RAII, the code that locks the mutex es-
This code is exception-safe because C++ guarantees that sentially includes the logic that the lock will be released
26 CHAPTER 2. CREATIONAL PATTERNS
when execution leaves the scope of the RAII object. In C++, stack unwinding is only guaranteed to occur if
Another typical example is interacting with files: We the exception is caught somewhere. This is because “If
could have an object that represents a file that is open no matching handler is found in a program, the function
for writing, wherein the file is opened in the constructor terminate() is called; whether or not the stack is unwound
and closed when execution leaves the object’s scope. In before this call to terminate() is implementation-defined
both cases, RAII ensures only that the resource in ques- (15.5.1).” (C++03 standard, §15.3/9).[14] This behavior
tion is released appropriately; care must still be taken to is usually acceptable, since the operating system releases
maintain exception safety. If the code modifying the data remaining resources like memory, files, sockets, etc. at
program termination.
structure or file is not exception-safe, the mutex could be
unlocked or the file closed with the data structure or file
corrupted.
2.9.6 Reference counting
Ownership of dynamically allocated objects (memory
allocated with new in C++) can also be controlled Perl, Python (in the CPython implementation),[15] and
with RAII, such that the object is released when the PHP[16] manage object lifetime by reference counting,
RAII (stack-based) object is destroyed. For this pur- which makes it possible to use RAII. Objects that are
pose, the C++11 standard library defines the smart no longer referenced are immediately destroyed or final-
pointer classes std::unique_ptr for single-owned objects ized and released, so a destructor or finalizer can release
and std::shared_ptr for objects with shared ownership. the resource at that time. However, it is not always id-
Similar classes are also available through std::auto_ptr in iomatic in such languages, and is specifically discouraged
C++98, and boost::shared_ptr in the Boost libraries. in Python (in favor of context managers and finalizers
from the weakref package).
2.9.4 Clang and GCC “cleanup” extension However, object lifetimes are not necessarily bound
to any scope, and objects may be destroyed non-
for C
deterministically or not at all. This makes it possible
to accidentally leak resources that should have been re-
Both Clang and GNU Compiler Collection implement
leased at the end of some scope. Objects stored in a
a non-standard extension to the C language to support
static variable (notably a global variable) may not be fi-
RAII: the “cleanup” variable attribute.[12] The following
nalized when the program terminates, so their resources
macro annotates a variable with a given destructor func-
are not released; CPython makes no guarantee of fi-
tion that it will call when the variable goes out of scope:
nalizing such objects, for instance. Further, objects
static inline void fclosep(FILE **fp) { if (*fp) with circular references will not be collected by a sim-
fclose(*fp); } #define _cleanup_fclose_ __at- ple reference counter, and will live indeterminately long;
tribute__((cleanup(fclosep))) even if collected (by more sophisticated garbage collec-
tion), destruction time and destruction order will be non-
This macro can then be used as follows: deterministic. In CPython there is a cycle detector which
detects cycles and finalizes the objects in the cycle, though
void example_usage() { _cleanup_fclose_ FILE *logfile prior to CPython 3.4, cycles are not collected if any ob-
= fopen(“logfile.txt”, “w+"); fputs(“hello logfile!", log- ject in the cycle has a finalizer.[17] Also, in the case of
file); } Python, the garbage collection strategy is an implementa-
tion detail, so running with an alternative interpreter (such
In this example, the compiler arranges for the fclosep as IronPython or Jython) could result in the RAII imple-
function to be called before example_usage returns. mentation not working.
[10] “What’s the order that local objects are destructed?". Re- Class diagram exemplifying the singleton pattern.
trieved 12 February 2013.
• RAII in Delphi "One-liner RAII in Delphi" by Barry • ensure that only one instance of the singleton class
Kelly ever exists; and
28 CHAPTER 2. CREATIONAL PATTERNS
• declaring all constructors of the class to be private; • Four different ways to implement singleton in Java
and "Ways to implement singleton in Java"
• providing a static method that returns a reference to • Book extract: Implementing the Singleton Pattern
the instance. in C# by Jon Skeet
2.10.3 Notes
[1] In Java, to avoid the synchronization overhead while keep-
ing lazy initialization with thread safety, the preferred ap-
proach is to use the initialization-on-demand holder idiom.
2.10.4 References
[1] Scott Densmore. Why singletons are evil, May 2004
Structural patterns
29
30 CHAPTER 3. STRUCTURAL PATTERNS
An adapter helps two incompatible interfaces to work to- This adapter pattern uses multiple polymorphic interfaces
gether. This is the real world definition for an adapter. implementing or inheriting both the interface that is ex-
Interfaces may be incompatible, but the inner function- pected and the interface that is pre-existing. It is typical
ality should suit the need. The Adapter design pattern for the expected interface to be created as a pure interface
allows otherwise incompatible classes to work together class, especially in languages such as Java (before jdk 1.8)
by converting the interface of one class into an interface that do not support multiple inheritance of classes.[1]
expected by the clients.
3.2.2 Usage
3.2.3 Structure
There are two adapter patterns:[1] The class adapter pattern expressed in UML.
The object adapter pattern expressed in UML. The adapter hides However, suppose that the format of the string data must
the adaptee’s interface from the client. be varied. A compile time solution is to use inheritance:
public class Format1ClassA extends ClassA { @Override
public String getStringData() { return format(toString());
}}
the source of the data, ClassA in this example, and out- (vii) In this way, the use of adapters and providers al-
puts the data formatted as appropriate: lows multiple “views” by ClassB and ClassC into ClassA
public interface StringProvider { public String getString- without having to alter the class hierarchy. In general,
Data(); } public class ClassAFormat1 implements String- it permits a mechanism for arbitrary data flows between
Provider { private ClassA classA = null; public Clas- objects that can be retrofitted to an existing object hier-
sAFormat1(final ClassA a) { classA = a; } public String archy.
getStringData() { return format(classA.getStringData());
} private String format(final String sourceValue) { //
Implementation of the Adapter pattern
Manipulate the source string into a format required //
by the object needing the source object’s data return
When implementing the adapter pattern, for
sourceValue.trim(); } }
clarity one can apply the class name [Class-
Name]To[Interface]Adapter to the provider implemen-
(ii) Write an Adapter class that returns the specific imple- tation, for example DAOToProviderAdapter. It should
mentation of the Provider: have a constructor method with an adaptee class variable
public class ClassAFormat1Adapter extends Adapter { as a parameter. This parameter will be passed to an
public Object adapt(final Object anObject) { return new instance member of [ClassName]To[Interface]Adapter.
ClassAFormat1((ClassA) anObject); } } When the clientMethod is called, it will have access
to the adaptee instance that allows for accessing the
required data of the adaptee and performing operations
(iii) Register the Adapter with a global registry, so that on that data that generates the desired output.
the Adapter can be looked up at runtime:
AdapterFactory.getInstance().registerAdapter(ClassA.class,
ClassAFormat1Adapter.class, “format1”); Crystal abstract class FormatIphone getter connector
abstract def recharge abstract def use_lightning end
abstract class FormatAndroid getter connector abstract
(iv) In code, when wishing to transfer data from ClassA def recharge abstract def use_micro_usb end class
to ClassB, write: Iphone < FormatIphone def initialize @connector = false
Adapter adapter = AdapterFactory.getInstance() end def use_lightning @connector = true puts “Light-
.getAdapterFromTo(ClassA.class, StringProvider.class, ning connected” end def recharge if @connector puts
“format1”); StringProvider provider = (String- “Recharge started” puts “Recharge finished” else puts
Provider) adapter.adapt(classA); String string = “Connect Lightning first” end end end class Android <
provider.getStringData(); classB.setStringData(string); FormatAndroid def initialize @connector = false end def
use_micro_usb @connector = true puts “MicroUsb con-
nected” end def recharge if @connector puts “Recharge
or more concisely: started” puts “Recharge finished” else puts “Connect
classB.setStringData( ((StringProvider) AdapterFac- MicroUsb first” end end end class IphoneAdapter < For-
tory.getInstance() .getAdapterFromTo(ClassA.class, matAndroid private getter mobile : FormatIphone def
StringProvider.class, “format1”) .adapt(classA)) .get- initialize(@mobile) end def recharge @mobile.recharge
StringData()); end def use_micro_usb puts “MicroUsb connected”
@mobile.use_lightning end end class AndroidRecharger
def initialize phone = Android.new phone.use_micro_usb
(v) The advantage can be seen in that, if it is desired to
phone.recharge end end class IphoneMicroUs-
transfer the data in a second format, then look up the dif-
bRecharger def initialize phone = Iphone.new
ferent adapter/provider:
phone_adapter = IphoneAdapter.new(phone)
Adapter adapter = AdapterFactory.getInstance() phone_adapter.use_micro_usb phone_adapter.recharge
.getAdapterFromTo(ClassA.class, StringProvider.class, end end class IphoneRecharger def initialize phone =
“format2”); Iphone.new phone.use_lightning phone.recharge end end
puts “Recharging android with MicroUsb Recharger”
(vi) And if it is desired to output the data from ClassA as, AndroidRecharger.new puts puts “Recharging iPhone
say, image data in Class C: with MicroUsb using Adapter pattern” IphoneMicroUs-
bRecharger.new puts puts “Recharging iPhone with
Adapter adapter = AdapterFactory.getInstance() iPhone Recharger” IphoneRecharger.new
.getAdapterFromTo(ClassA.class, Image-
Provider.class, “format2”); ImageProvider
provider = (ImageProvider) adapter.adapt(classA); Output
classC.setImage(provider.getImage()); Recharging android with MicroUsb Recharger Mi-
croUsb connected Recharge started Recharge finished
Recharging iPhone with MicroUsb using Adapter pat-
32 CHAPTER 3. STRUCTURAL PATTERNS
tern MicroUsb connected Lightning connected Recharge "---Phone Ready for use---\n\n"; } } $androidRecharger
started Recharge finished Recharging iPhone with = new AndroidRecharger(); // Result: #quanton81
iPhone Recharger Lightning connected Recharge started //---Recharging iPhone with Generic Recharger--- //Mi-
Recharge finished croUsb connected -> Lightning connected -$ //Recharge
Started //Recharge 20% //Recharge 50% //Recharge
70% //Recharge Finished //---iPhone Ready for use---
Java public class AdapteeToClientAdapter imple- // //---Recharging iPhone with iPhone Recharger---
ments Adapter { private final Adaptee instance; public //Lightning connected -$ //Recharge Started //Recharge
AdapteeToClientAdapter(final Adaptee instance) { 20% //Recharge 50% //Recharge 70% //Recharge
this.instance = instance; } @Override public void client- Finished //---iPhone Ready for use--- // //---Recharging
Method() { // call Adaptee’s method(s) to implement Android Phone with Generic Recharger--- //MicroUsb
Client’s clientMethod } } connected -> //Recharge Started //Recharge 20%
//Recharge 50% //Recharge 70% //Recharge Finished
//---Phone Ready for use---
PHP // Adapter Pattern example interface IFormatI-
Phone { public function recharge(); public function
useLightning(); } interface IFormatAndroid { public Scala implicit def adaptee2Adapter(adaptee:
function recharge(); public function useMicroUsb(); Adaptee): Adapter = { new Adapter { override def
} // Adaptee class IPhone implements IFormatIPhone clientMethod: Unit = { // call Adaptee’s method(s) to
{ private $connectorOk = FALSE; public function implement Client’s clientMethod */ } } }
useLightning() { $this->connectorOk = TRUE; echo
“Lightning connected -$\n"; } public function recharge()
{ if($this->connectorOk) { echo “Recharge Started\n";
echo “Recharge 20%\n"; echo “Recharge 50%\n"; echo 3.2.4 See also
“Recharge 70%\n"; echo “Recharge Finished\n"; } else
{ echo “Connect Lightning first\n"; } } } // Adapter class • Delegation, strongly relevant to the object adapter
IPhoneAdapter implements IFormatAndroid { private pattern.
$mobile; public function __construct(IFormatIPhone
$mobile) { $this->mobile = $mobile; } public func- • Dependency inversion principle, which can be
tion recharge() { $this->mobile->recharge(); } public thought of as applying the Adapter pattern, when
function useMicroUsb() { echo “MicroUsb con- the high-level class defines their own (adapter) in-
nected -> "; $this->mobile->useLightning(); } } class terface to the low-level module (implemented by an
Android implements IFormatAndroid { private $con- Adaptee class).
nectorOk = FALSE; public function useMicroUsb() • Shim
{ $this->connectorOk = TRUE; echo “MicroUsb
connected ->\n"; } public function recharge() { if($this- • Wrapper function
>connectorOk) { echo “Recharge Started\n"; echo
“Recharge 20%\n"; echo “Recharge 50%\n"; echo • Wrapper library
“Recharge 70%\n"; echo “Recharge Finished\n"; }
else { echo “Connect MicroUsb first\n"; } } } // client
class MicroUsbRecharger { private $phone; private
3.2.5 References
$phoneAdapter; public function __construct() { echo "-- [1] Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bates,
-Recharging iPhone with Generic Recharger---\n"; $this- Bert (2004). “Head First Design Patterns” (paperback).
>phone = new IPhone(); $this->phoneAdapter = new O'Reilly Media: 244. ISBN 978-0-596-00712-6. OCLC
IPhoneAdapter($this->phone); $this->phoneAdapter- 809772256. Retrieved April 30, 2013.
>useMicroUsb(); $this->phoneAdapter->recharge();
echo "---iPhone Ready for use---\n\n"; } } $mi- [2] Freeman, Eric; Freeman, Elisabeth; Sierra, Kathy; Bates,
croUsbRecharger = new MicroUsbRecharger(); class Bert (2004). Hendrickson, Mike; Loukides, Mike, eds.
“Head First Design Patterns” (paperback). 1. O'Reilly:
IPhoneRecharger { private $phone; public func-
243, 252, 258, 260. ISBN 978-0-596-00712-6. Re-
tion __construct() { echo "---Recharging iPhone
trieved 2012-07-02.
with iPhone Recharger---\n"; $this->phone = new
IPhone(); $this->phone->useLightning(); $this->phone-
>recharge(); echo "---iPhone Ready for use---\n\n"; } }
$iPhoneRecharger = new IPhoneRecharger(); class An- 3.3 Bridge pattern
droidRecharger { public function __construct() { echo
"---Recharging Android Phone with Generic Recharger- The bridge pattern is a design pattern used in software
--\n"; $this->phone = new Android(); $this->phone- engineering that is meant to “decouple an abstraction from
>useMicroUsb(); $this->phone->recharge(); echo its implementation so that the two can vary independently”,
3.3. BRIDGE PATTERN 33
• Template method pattern good choice; it is less complex in this situation to treat
primitives and composites as homogeneous.
3.3.4 References
3.4.3 Structure
[1] Gamma, E, Helm, R, Johnson, R, Vlissides, J: Design Pat-
terns, page 151. Addison-Wesley, 1995
Component
0..*
3.3.5 External links + operation()
child
+ remove()
84453-2. + getChild()
Composite should be used when clients ignore the dif- As it is described in Design Patterns, the pattern also in-
ference between compositions of objects and individual volves including the child-manipulation methods in the
objects.[1] If programmers find that they are using multi- main Component interface, not just the Composite sub-
ple objects in the same way, and often have nearly iden- class. More recent descriptions sometimes omit these
tical code to handle each of them, then composite is a methods.[3]
36 CHAPTER 3. STRUCTURAL PATTERNS
graphic1.add(ellipse3); graphic2.add(ellipse4);
graphic.add(graphic1); graphic.add(graphic2); //Prints
the complete graphic (four times the string “Ellipse”).
graphic.print(); } }
C#
abstract class Graphic abstract def print end # Composite [3] Geary, David (13 Sep 2002). “A look at the Composite
design pattern”.
class CompositeGraphic < Graphic private getter graph-
ics def initialize @graphics = [] of Graphic end def print
@graphics.each do |graphic| graphic.print end end def
add(graphic : Graphic) @graphics.push(graphic) end def 3.5 Decorator pattern
remove(graphic : Graphic) @graphics.delete(graphic)
end end # Leaf class Ellipse < Graphic private getter Not to be confused with the concept of “decorators” in
name : String def initialize(@name) end def print puts Python.
“Ellipse #{name}" end end class Program def initialize
ellipse1 = Ellipse.new(“1”) ellipse2 = Ellipse.new(“2”)
In object-oriented programming, the decorator pattern
ellipse3 = Ellipse.new(“3”) ellipse4 = Ellipse.new(“4”)
(also known as Wrapper, an alternative naming shared
graphic = CompositeGraphic.new graphic1 = Compos-
with the Adapter pattern) is a design pattern that allows
iteGraphic.new graphic2 = CompositeGraphic.new #
behavior to be added to an individual object, either stat-
graphic 1 contains 3 ellipses graphic1.add(ellipse1)
ically or dynamically, without affecting the behavior of
graphic1.add(ellipse2) graphic1.add(ellipse3) #
other objects from the same class.[1] The decorator pat-
graphic 2 contains 1 ellipse graphic2.add(ellipse4)
tern is often useful for adhering to the Single Responsi-
# graphic contains both graphic 1 and graphic 2
bility Principle, as it allows functionality to be divided
graphic.add(graphic1) graphic.add(graphic2) # now
between classes with unique areas of concern.[2]
print the graphic graphic.print end end Program.new
3.5.1 Intent
3.4.6 See also
• Perl Design Patterns Book Component
• Mixin + operation()
• Law of Demeter
ConcreteComponent Decorator
3.4.7 External links - component
+ operation()
+ operation()
• Composite pattern description from the Portland
Pattern Repository
• Composite pattern in UML and in LePUS3, a for- ConcreteDecorator
• Class::Delegation on CPAN
• “The End of Inheritance: Automatic Run-time In- Decorator UML class diagram
terface Building for Aggregated Objects” by Paul
Baranowski The decorator pattern can be used to extend (decorate)
the functionality of a certain object statically, or in some
• PerfectJPattern Open Source Project, Provides cases at run-time, independently of other instances of the
componentized implementation of the Composite same class, provided some groundwork is done at design
Pattern in Java time. This is achieved by designing a new Decorator class
• A persistent Java-based implementation that wraps the original class. This wrapping could be
achieved by the following sequence of steps:
• Composite Design Pattern
• Composite Design Pattern implementation example 1. Subclass the original Component class into a Deco-
rator class (see UML diagram);
4. In the Decorator class, forward all Component meth- no functionality for adding scrollbars. One could create
ods to the Component pointer; and a subclass ScrollingWindow that provides them, or create
a ScrollingWindowDecorator that adds this functionality
5. In the ConcreteDecorator class, override any Com- to existing Window objects. At this point, either solution
ponent method(s) whose behavior needs to be mod- would be fine.
ified.
Now, assume one also desires the ability to add borders to
This pattern is designed so that multiple decorators can windows. Again, the original Window class has no sup-
be stacked on top of each other, each time adding a new port. The ScrollingWindow subclass now poses a prob-
functionality to the overridden method(s). lem, because it has effectively created a new kind of win-
dow. If one wishes to add border support to many but not
Note that decorators and the original class object share all windows, one must create subclasses WindowWith-
a common set of features. In the previous diagram, the Border and ScrollingWindowWithBorder etc. This prob-
operation() method was available in both the decorated lem gets worse with every new feature or window subtype
and undecorated versions. to be added. For the decorator solution, we simply create
The decoration features (e.g., methods, properties, or a new BorderedWindowDecorator—at runtime, we can
other members) are usually defined by an interface, mixin decorate existing windows with the ScrollingWindowDec-
(a.k.a. trait) or class inheritance which is shared by the orator or the BorderedWindowDecorator or both, as we
decorators and the decorated object. In the previous ex- see fit. Notice that if the functionality needs to be added
ample the class Component is inherited by both the Con- to all Windows, you could modify the base class and that
creteComponent and the subclasses that descend from will do. On the other hand, sometimes (e.g., using exter-
Decorator. nal frameworks) it is not possible, legal, or convenient to
modify the base class.
The decorator pattern is an alternative to subclassing.
Subclassing adds behavior at compile time, and the Note, in the previous example, that the “SimpleWindow”
change affects all instances of the original class; deco- and “WindowDecorator” classes implement the “Win-
rating can provide new behavior at run-time for selective dow” interface, which defines the “draw()" method and
objects. the “getDescription()" method, that are required in this
scenario, in order to decorate a window control.
This difference becomes most important when there are
several independent ways of extending functionality. In
some object-oriented programming languages, classes 3.5.3 Usage
cannot be created at runtime, and it is typically not possi-
ble to predict, at design time, what combinations of exten- A decorator makes it possible to add or alter behavior of
sions will be needed. This would mean that a new class an interface at run-time. Alternatively, the adapter can be
would have to be made for every possible combination. used when the wrapper must respect a particular interface
By contrast, decorators are objects, created at runtime, and must support polymorphic behavior, and the Facade
and can be combined on a per-use basis. The I/O Streams when an easier or simpler interface to an underlying ob-
implementations of both Java and the .NET Framework ject is desired.[3]
incorporate the decorator pattern.
3.5.4 Examples
3.5.2 Motivation
C++
Static Decorator (Mixin Inheritance) struct Cir- Here’s a test program that creates a Window instance
cle { float radius; void resize(float factor) { radius which is fully decorated (i.e., with vertical and horizontal
*= factor; } string str() { return string(“A circle of scrollbars), and prints its description:
radius”) + to_string(radius); } }; template <typename public class DecoratedWindowTest { public static
T> struct ColoredShape : T { string color; string str() void main(String[] args) { // Create a decorated Win-
{ return T::str() + " which is colored " + color; } }; dow with horizontal and vertical scrollbars Window
// usage: ColoredShape<Circle> red_circle{"red"}; decoratedWindow = new HorizontalScrollBarDec-
cout << red_circle.str() << endl; // and this is legal orator ( new VerticalScrollBarDecorator (new Sim-
red_circle.resize(1.2); pleWindow())); // Print the Window’s description
System.out.println(decoratedWindow.getDescription());
}}
Java
Below is the JUnit test class for the Test Driven Develop-
First example (window/scrolling scenario) The fol- ment
lowing Java example illustrates the use of decorators us- import static org.junit.Assert.assertEquals; import
ing the window/scrolling scenario. org.junit.Test; public class WindowDecoratorTest {
// The Window interface class public interface Window @Test public void testWindowDecoratorTest() { Win-
{ void draw(); // Draws the Window String getDe- dow decoratedWindow = new HorizontalScrollBarDec-
scription(); // Returns a description of the Window } orator(new VerticalScrollbarDecorator(new SimpleWin-
// Implementation of a simple Window without any dow())); // assert that the description indeed includes
scrollbars class SimpleWindow implements Window { horizontal + vertical scrollbars assertEquals(“simple
public void draw() { // Draw window } public String window, including vertical scrollbars, including horizon-
getDescription() { return “simple window"; } } tal scrollbars”, decoratedWindow.getDescription()) } }
The following classes contain the decorators for all Win- The output of this program is “simple window, including
dow classes, including the decorator classes themselves. vertical scrollbars, including horizontal scrollbars”. No-
tice how the getDescription method of the two decorators
// abstract decorator class - note that it implements
first retrieve the decorated Window’s description and dec-
Window abstract class WindowDecorator implements
orates it with a suffix.
Window { protected Window windowToBeDeco-
rated; // the Window being decorated public Win-
dowDecorator (Window windowToBeDecorated) {
this.windowToBeDecorated = windowToBeDecorated; Second example (coffee making scenario) The next
} public void draw() { windowToBeDecorated.draw(); Java example illustrates the use of decorators using cof-
//Delegation } public String getDescription() { return fee making scenario. In this example, the scenario only
windowToBeDecorated.getDescription(); //Delegation includes cost and ingredients.
} } // The first concrete decorator which adds vertical // The interface Coffee defines the functionality of
scrollbar functionality class VerticalScrollBarDecorator Coffee implemented by decorator public interface
extends WindowDecorator { public VerticalScroll- Coffee { public double getCost(); // Returns the cost of
BarDecorator (Window windowToBeDecorated) { the coffee public String getIngredients(); // Returns the
super(windowToBeDecorated); } @Override public ingredients of the coffee } // Extension of a simple coffee
void draw() { super.draw(); drawVerticalScrollBar(); without any extra ingredients public class SimpleCoffee
} private void drawVerticalScrollBar() { // Draw the implements Coffee { @Override public double getCost()
vertical scrollbar } @Override public String getDescrip- { return 1; } @Override public String getIngredients() {
tion() { return super.getDescription() + ", including return “Coffee"; } }
vertical scrollbars"; } } // The second concrete decorator
which adds horizontal scrollbar functionality class Hor-
izontalScrollBarDecorator extends WindowDecorator The following classes contain the decorators for all Coffee
{ public HorizontalScrollBarDecorator (Window win- classes, including the decorator classes themselves..
dowToBeDecorated) { super(windowToBeDecorated); // Abstract decorator class - note that it implements
} @Override public void draw() { super.draw(); Coffee interface public abstract class CoffeeDec-
drawHorizontalScrollBar(); } private void drawHor- orator implements Coffee { protected final Coffee
izontalScrollBar() { // Draw the horizontal scrollbar decoratedCoffee; public CoffeeDecorator(Coffee c) {
} @Override public String getDescription() { return this.decoratedCoffee = c; } public double getCost() { //
40 CHAPTER 3. STRUCTURAL PATTERNS
Crystal
PHP
abstract class Coffee abstract def cost abstract def
abstract class Component { protected $data; protected ingredients end # Extension of a simple coffee class
$value; abstract public function getData(); abstract SimpleCoffee < Coffee def cost 1.0 end def ingredients
public function getValue(); } class ConcreteComponent “Coffee” end end # Abstract decorator class CoffeeDec-
extends Component { public function __construct() orator < Coffee protected getter decorated_coffee
{ $this->value = 1000; $this->data = “Concrete : Coffee def initialize(@decorated_coffee) end def
Component:\t{$this->value}\n"; } public function get- cost decorated_coffee.cost end def ingredients dec-
Data() { return $this->data; } public function getValue() orated_coffee.ingredients end end class WithMilk <
{ return $this->value; } } abstract class Decorator ex- CoffeeDecorator def cost super + 0.5 end def ingre-
tends Component { } class ConcreteDecorator1 extends dients super + ", Milk” end end class WithSprinkles
Decorator { public function __construct(Component < CoffeeDecorator def cost super + 0.2 end def in-
$data) { $this->value = 500; $this->data = $data; } pub- gredients super + ", Sprinkles” end end class Program
lic function getData() { return $this->data->getData() def print(coffee : Coffee) puts “Cost: #{coffee.cost};
. “Concrete Decorator 1:\t{$this->value}\n"; } public Ingredients: #{coffee.ingredients}" end def initialize
function getValue() { return $this->value + $this->data- coffee = SimpleCoffee.new print(coffee) coffee =
>getValue(); } } class ConcreteDecorator2 extends WithMilk.new(coffee) print(coffee) coffee = WithSprin-
Decorator { public function __construct(Component kles.new(coffee) print(coffee) end end Program.new
$data) { $this->value = 500; $this->data = $data; } pub-
lic function getData() { return $this->data->getData()
. “Concrete Decorator 2:\t{$this->value}\n"; } public Output:
function getValue() { return $this->value + $this->data- Cost: 1.0; Ingredients: Coffee Cost: 1.5; Ingredients:
>getValue(); } } class Client { private $component; Coffee, Milk Cost: 1.7; Ingredients: Coffee, Milk,
public function __construct() { $this->component Sprinkles
3.6. FACADE PATTERN 41
3.5.5 See also The Facade design pattern is often used when a system is
very complex or difficult to understand because the sys-
• Composite pattern tem has a large number of interdependent classes or its
source code is unavailable. This pattern hides the com-
• Adapter pattern plexities of the larger system and provides a simpler in-
• Abstract class terface to the client. It typically involves a single wrapper
class that contains a set of members required by client.
• Abstract factory These members access the system on behalf of the facade
client and hide the implementation details.
• Aspect-oriented programming
Facade The facade class abstracts Packages 1, 2, and 3 body.SetBody(); accessories.SetAccessories(); Con-
from the rest of the application. sole.WriteLine("******** Car creation is completed.
**********"); } } // Facade pattern demo class Pro-
Clients The objects are using the Facade Pattern to ac- gram { static void Main(string[] args) { var facade =
cess resources from the Packages. new CarFacade(); facade.CreateCompleteCar(); Con-
sole.ReadKey(); } } }
3.6.3 Example
• Spring Framework[2]
3.7.1 Instruction • Yesod Web application framework written in
Haskell.
Handler «abstract»
Command 3.7.3 Implementation
doGet()
doPost() process()
To better understand front controller pattern, there is an
example to implement front controller in Java.[3] It can be
defined in 3 components:
Several Web-tier application frameworks implement the 3.7.4 Benefits and liabilities
front controller pattern, among them:
There are three benefits for using front controller
• Apache Struts. pattern.[5]
44 CHAPTER 3. STRUCTURAL PATTERNS
According to the textbook Design Patterns: Elements of using System.Collections.Concurrent; using Sys-
Reusable Object-Oriented Software,[1] the flyweight pat- tem.Collections.Generic; using System.Threading;
tern was first coined and extensively explored by Paul public interface ICoffeeFlavourFactory { CoffeeFlavour
Calder and Mark Linton in 1990 to efficiently handle GetFlavour(string flavour); } public class Reduced-
glyph information in a WYSIWYG document editor,[2] MemoryFootprint : ICoffeeFlavourFactory { private
although similar techniques were already used in other readonly object _cacheLock = new object(); pri-
systems, e.g., an application framework by Weinand et vate readonly IDictionary<string, CoffeeFlavour>
al. (1988).[3] _cache = new Dictionary<string, CoffeeFlavour>();
public CoffeeFlavour GetFlavour(string flavour) { if
(_cache.ContainsKey(flavour)) return _cache[flavour];
var coffeeFlavour = new CoffeeFlavour(flavour);
3.8.2 Immutability and equality ThreadPool.QueueUserWorkItem(AddFlavourToCache,
coffeeFlavour); return coffeeFlavour; } pri-
To enable safe sharing, between clients and threads, Fly- vate void AddFlavourToCache(object state) {
weight objects must be immutable. Flyweight objects are var coffeeFlavour = (CoffeeFlavour)state; if
by definition value objects. The identity of the object in- (!_cache.ContainsKey(coffeeFlavour.Flavour))
stance is of no consequence therefore two Flyweight in- { lock (_cacheLock) { if
stances of the same value are considered equal. (!_cache.ContainsKey(coffeeFlavour.Flavour))
Example in C# (note Equals and GetHashCode overrides _cache.Add(coffeeFlavour.Flavour, coffeeFlavour);
as well as == and != operator overloads): } } } } public class MinimumMemoryFootprint :
ICoffeeFlavourFactory { private readonly Concur-
public class CoffeeFlavour { private readonly string rentDictionary<string, CoffeeFlavour> _cache =
_flavour; public CoffeeFlavour(string flavour) { _flavour new ConcurrentDictionary<string, CoffeeFlavour>();
= flavour; } public string Flavour { get { return public CoffeeFlavour GetFlavour(string flavour) {
_flavour; } } public override bool Equals(object obj) return _cache.GetOrAdd(flavour, flv => new Cof-
{ if (ReferenceEquals(null, obj)) return false; return feeFlavour(flv)); } }
obj is CoffeeFlavour && Equals((CoffeeFlavour)obj);
} public bool Equals(CoffeeFlavour other) { return
string.Equals(_flavour, other._flavour); } public over-
ride int GetHashCode() { return (_flavour != null Simple implementation
? _flavour.GetHashCode() : 0); } public static bool
operator ==(CoffeeFlavour a, CoffeeFlavour b) { Flyweight allows you to share bulky data that are common
return Equals(a, b); } public static bool operator !=(Cof- to each object. In other words, if you think that same data
feeFlavour a, CoffeeFlavour b) { return !Equals(a, b); } } is repeating for every object, you can use this pattern to
point to the single object and hence can easily save space.
Here the FlyweightPointer creates a static member Com-
pany, which is used for every object of MyObject.
3.8.3 Concurrency // Defines Flyweight object that repeats itself. public
class FlyWeight { public string CompanyName { get;
Special consideration must be made in scenarios where set; } public string CompanyLocation { get; set; }
Flyweight objects are created on multiple threads. If the public string CompanyWebSite { get; set; } //Bulky
list of values is finite and known in advance the Flyweights Data public byte[] CompanyLogo { get; set; } } public
can be instantiated ahead of time and retrieved from a static class FlyWeightPointer { public static readonly
container on multiple threads with no contention. If Fly- FlyWeight Company = new FlyWeight { CompanyName
weights are instantiated on multiple threads there are two = “Abc”, CompanyLocation = “XYZ”, CompanyWeb-
options: Site = "www.abc.com" // Load CompanyLogo here };
} public class MyObject { public string Name { get;
set; } public string Company { get { return FlyWeight-
1. Make Flyweight instantiation single threaded thus Pointer.Company.CompanyName; } } }
introducing contention and ensuring one instance
per value.
= CoffeeShop.new shop.take_order(“Cappuchino”,
2) shop.take_order(“Frappe”, 1)
shop.take_order(“Espresso”, 1)
shop.take_order(“Frappe”, 897)
delegate
Proxy RealSubject
shop.take_order(“Cappuccino”,
97) shop.take_order(“Frappe”, 3)
DoAction() DoAction()
shop.take_order(“Espresso”, 3)
shop.take_order(“Cappuccino”, 3)
shop.take_order(“Espresso”, 96) Proxy in UML
shop.take_order(“Frappe”, 552)
shop.take_order(“Cappuccino”, 121)
shop.take_order(“Espresso”, 121) shop.service puts
shop.report
Output
Serving Cappuchino to table 2 Serving Frappe to table 1
Serving Espresso to table 1 Serving Frappe to table 897
Serving Cappuccino to table 97 Serving Frappe to table 3
Serving Espresso to table 3 Serving Cappuccino to table
3 Serving Espresso to table 96 Serving Frappe to table Proxy in LePUS3 (legend)
552 Serving Cappuccino to table 121 Serving Espresso
In computer programming, the proxy pattern is a
to table 121 Total CoffeeFlavor made: 4
software design pattern.
A proxy, in its most general form, is a class functioning
3.8.11 See also as an interface to something else. The proxy could inter-
face to anything: a network connection, a large object in
• Copy-on-write memory, a file, or some other resource that is expensive
• Memoization or impossible to duplicate. In short, a proxy is a wrapper
or agent object that is being called by the client to ac-
• Multiton cess the real serving object behind the scenes. Use of the
proxy can simply be forwarding to the real object, or can
provide additional logic. In the proxy extra functionality
3.8.12 References can be provided, for example caching when operations on
[1] Gamma, Erich; Richard Helm; Ralph Johnson; John Vlis-
the real object are resource intensive, or checking precon-
sides (1995). Design Patterns: Elements of Reusable ditions before operations on the real object are invoked.
Object-Oriented Software. Addison-Wesley. pp. 205– For the client, usage of a proxy object is similar to using
206. ISBN 0-201-63361-2. the real object, because both implement the same inter-
face.
[2] Calder, Paul R.; Linton, Mark A. (October 1990). Glyphs:
Flyweight Objects for User Interfaces. The 3rd Annual
ACM SIGGRAPH Symposium on User Interface Soft- 3.9.1 Possible Usage Scenarios
ware and Technology. Snowbird, Utah, United States. pp.
92–101. doi:10.1145/97924.97935. ISBN 0-89791-410-
Remote Proxy
4.
[3] Weinand, Andre; Gamma, Erich; Marty, Rudolf In distributed object communication, a local object rep-
(1988). ET++—an object oriented application frame- resents a remote object (one that belongs to a different
work in C++. OOPSLA (Object-Oriented Program- address space). The local object is a proxy for the remote
ming Systems, Languages and Applications). San object, and method invocation on the local object results
Diego, California, United States. pp. 46–57. in remote method invocation on the remote object. An
doi:10.1145/62083.62089. ISBN 0-89791-284-5.
example would be an ATM implementation, where the
[4] “Date Model §". The (online) Python Language Reference. ATM might hold proxy objects for bank information that
Python Software Foundation. Retrieved 7 March 2017. exists in the remote server.
3.9. PROXY PATTERN 49
Protection Proxy
Crystal
A protection proxy might be used to control access to a
resource based on access rights. abstract class AbstractCar abstract def drive end class
Car < AbstractCar def drive puts “Car has been
driven!" end end class Driver getter age : Int32 def
3.9.2 Example initialize(@age) end end class ProxyCar < AbstractCar
private getter driver : Driver private getter real_car
C#
: AbstractCar def initialize(@driver) @real_car =
Car.new end def drive if driver.age <= 16 puts “Sorry,
interface ICar { void DriveCar(); } // Real Object
the driver is too young to drive.” else @real_car.drive
public class Car : ICar { public void DriveCar() {
end end end # Program driver = Driver.new(16) car =
Console.WriteLine(“Car has been driven!"); } } //Proxy
ProxyCar.new(driver) car.drive driver = Driver.new(25)
Object public class ProxyCar : ICar { private Driver
car = ProxyCar.new(driver) car.drive
driver; private ICar realCar; public ProxyCar(Driver
driver) { this.driver = driver; this.realCar = new Car();
} public void DriveCar() { if (driver.Age <= 16) Output
Console.WriteLine(“Sorry, the driver is too young to Sorry, the driver is too young to drive. Car has been
drive.”); else this.realCar.DriveCar(); } } public class driven!
Driver { private int Age { get; set; } public Driver(int
age) { this.Age = age; } } // How to use above Proxy
class? private void btnProxy_Click(object sender, Even- Delphi / Object Pascal
tArgs e) { ICar car = new ProxyCar(new Driver(16));
car.DriveCar(); car = new ProxyCar(new Driver(25)); // Proxy Design pattern unit DesignPattern.Proxy;
car.DriveCar(); } interface type // Car Interface ICar = interface pro-
cedure DriveCar; end; // TCar class, implementing
Output ICar TCar = Class(TInterfacedObject, ICar) class
function New: ICar; procedure DriveCar; End; // Driver
Sorry, the driver is too young to drive. Car has been Interface IDriver = interface function Age: Integer;
driven! end; // TDriver Class, implementing IDriver TDriver =
Notes: Class(TInterfacedObject, IDriver) private FAge: Inte-
ger; public constructor Create(Age: Integer); Overload;
• A proxy may hide information about the real object class function New(Age: Integer): IDriver; function
to the client. Age: Integer; End; // Proxy Object TProxyCar =
Class(TInterfacedObject, ICar) private FDriver: IDriver;
• A proxy may perform optimization like on demand FRealCar: ICar; public constructor Create(Driver:
loading. IDriver); Overload; class function New(Driver: IDriver):
ICar; procedure DriveCar; End; implementation { TCar
• A proxy may do additional house-keeping job like Implementation } class function TCar.New: ICar; begin
audit tasks. Result := Create; end; procedure TCar.DriveCar; begin
• Proxy design pattern is also known as surrogate de- WriteLn('Car has been driven!'); end; { TDriver Imple-
sign pattern. mentation } constructor TDriver.Create(Age: Integer);
begin inherited Create; FAge := Age; end; class function
TDriver.New(Age: Integer): IDriver; begin Result :=
C++ Create(Age); end; function TDriver.Age: Integer; begin
Result := FAge; end; { TProxyCar Implementation }
class ICar { public: virtual void DriveCar() = 0; }; constructor TProxyCar.Create(Driver: IDriver); begin
class Car : public ICar { void DriveCar() override { inherited Create; Self.FDriver := Driver; Self.FRealCar
std::cout << “Car has been driven!"; } }; class ProxyCar := TCar.Create AS ICar; end; class function TProx-
: public ICar { private: ICar* realCar = new Car(); int yCar.New(Driver: IDriver): ICar; begin Result :=
50 CHAPTER 3. STRUCTURAL PATTERNS
Behavioral patterns
• Weak reference pattern: De-couple an ob- [2] Nakashian, Ashod (2004-04-11). “Weak Reference Pat-
server from an observable[2] tern”. c2.com. Archived from the original on 2004-04-
11. Retrieved 2012-05-21.
• Protocol stack: Communications are handled
by multiple layers, which form an encapsulation [3] “Protocol Stack”. c2.com. 2006-09-05. Archived from
hierarchy[3] the original on 2006-09-05. Retrieved 2012-05-21.
51
52 CHAPTER 4. BEHAVIORAL PATTERNS
} public class ConsoleLogger : Logger { public @log_levels << level end end def set_next(next_logger
ConsoleLogger(LogLevel mask) : base(mask) { } : Logger) @next = next_logger end def message(msg
protected override void WriteMessage(string msg) { : String, severity : LogLevel) write_message(msg)
Console.WriteLine(“Writing to console: " + msg); } } if @log_levels.includes?(LogLevel::All)
public class EmailLogger : Logger { public EmailLog- || @log_levels.includes?(severity)
ger(LogLevel mask) : base(mask) { } protected override @next.try(&.message(msg, severity)) if @next end
void WriteMessage(string msg) { // Placeholder for mail abstract def write_message(msg : String) end class
send logic, usually the email configurations are saved in ConsoleLogger < Logger def write_message(msg :
config file. Console.WriteLine(“Sending via email: " + String) puts “Writing to console: #{msg}" end end
msg); } } class FileLogger : Logger { public FileLog- class EmailLogger < Logger def write_message(msg
ger(LogLevel mask) : base(mask) { } protected override : String) puts “Sending via email: #{msg}" end end
void WriteMessage(string msg) { // Placeholder for File class FileLogger < Logger def write_message(msg :
writing logic Console.WriteLine(“Writing to Log File: String) puts “Writing to Log File: #{msg}" end end
" + msg); } } public class Program { public static void # Program # Build the chain of responsibility logger
Main(string[] args) { // Build the chain of responsibility = ConsoleLogger.new(LogLevel::All) logger1 = log-
Logger logger, logger1, logger2; logger = new ConsoleL- ger.set_next(EmailLogger.new(LogLevel::FunctionalMessage,
ogger(LogLevel.All); logger1 = logger.SetNext(new LogLevel::FunctionalError)) logger2 = log-
EmailLogger(LogLevel.FunctionalMessage | ger1.set_next(FileLogger.new(LogLevel::Warning,
LogLevel.FunctionalError)); logger2 = log- LogLevel::Error)) # Handled by ConsoleLog-
ger1.SetNext(new FileLogger(LogLevel.Warning ger since the console has a loglevel of all log-
| LogLevel.Error)); // Handled by ConsoleLog- ger.message(“Entering function ProcessOrder().”,
ger since the console has a loglevel of all log- LogLevel::Debug) logger.message(“Order record re-
ger.Message(“Entering function ProcessOrder().”, trieved.”, LogLevel::Info) # Handled by ConsoleLogger
LogLevel.Debug); logger.Message(“Order record re- and FileLogger since filelogger implements Warning
trieved.”, LogLevel.Info); // Handled by ConsoleLogger & Error logger.message(“Customer Address details
and FileLogger since filelogger implements Warning missing in Branch DataBase.”, LogLevel::Warning)
& Error logger.Message(“Customer Address details logger.message(“Customer Address details miss-
missing in Branch DataBase.”, LogLevel.Warning); ing in Organization DataBase.”, LogLevel::Error) #
logger.Message(“Customer Address details miss- Handled by ConsoleLogger and EmailLogger as it
ing in Organization DataBase.”, LogLevel.Error); // implements functional error logger.message(“Unable
Handled by ConsoleLogger and EmailLogger as it to Process Order ORD1 Dated D1 For Customer
implements functional error logger.Message(“Unable C1.”, LogLevel::FunctionalError) # Handled by Con-
to Process Order ORD1 Dated D1 For Customer soleLogger and EmailLogger logger.message(“Order
C1.”, LogLevel.FunctionalError); // Handled by Con- Dispatched.”, LogLevel::FunctionalMessage)
soleLogger and EmailLogger logger.Message(“Order
Dispatched.”, LogLevel.FunctionalMessage); } } } /* Output
Output Writing to console: Entering function Proces-
sOrder(). Writing to console: Order record retrieved. Writing to console: Entering function ProcessOrder().
Writing to console: Customer Address details missing Writing to console: Order record retrieved. Writing to
in Branch DataBase. Writing to Log File: Customer console: Customer Address details missing in Branch
Address details missing in Branch DataBase. Writing to DataBase. Writing to Log File: Customer Address details
console: Customer Address details missing in Organiza- missing in Branch DataBase. Writing to console: Cus-
tion DataBase. Writing to Log File: Customer Address tomer Address details missing in Organization DataBase.
details missing in Organization DataBase. Writing to Writing to Log File: Customer Address details missing
console: Unable to Process Order ORD1 Dated D1 For in Organization DataBase. Writing to console: Unable to
Customer C1. Sending via email: Unable to Process Process Order ORD1 Dated D1 For Customer C1. Send-
Order ORD1 Dated D1 For Customer C1. Writing to ing via email: Unable to Process Order ORD1 Dated D1
console: Order Dispatched. Sending via email: Order For Customer C1. Writing to console: Order Dispatched.
Dispatched. */ Sending via email: Order Dispatched.
4.2.2 Implementations
Crystal example
Cocoa and Cocoa Touch
enum LogLevel None, Info, Debug, Warning, Er-
ror, FunctionalMessage, FunctionalError, All end The Cocoa and Cocoa Touch frameworks, used for
abstract class Logger protected getter log_levels pro- OS X and iOS applications respectively, actively use
tected getter next : Logger | Nil def initialize(*levels) the chain-of-responsibility pattern for handling events.
@log_levels = [] of LogLevel levels.each do |level| Objects that participate in the chain are called re-
54 CHAPTER 4. BEHAVIORAL PATTERNS
sponder objects, inheriting from the NSResponder about a concrete command, it knows only about com-
(OS X)/UIResponder (iOS) class. All view objects mand interface. Both an invoker object and several com-
(NSView/UIView), view controller objects (NSView- mand objects are held by a client object. The client de-
Controller/UIViewController), window objects (NSWin- cides which commands to execute at which points. To
dow/UIWindow), and the application object (NSAppli- execute a command, it passes the command object to the
cation/UIApplication) are responder objects. invoker object.
Typically, when a view receives an event which it can't Using command objects makes it easier to construct gen-
handle, it dispatches it to its superview until it reaches the
eral components that need to delegate, sequence or ex-
view controller or window object. If the window can't ecute method calls at a time of their choosing without
handle the event, the event is dispatched to the applicationthe need to know the class of the method or the method
object, which is the last object in the chain. For example: parameters. Using an invoker object allows bookkeep-
ing about command executions to be conveniently per-
• On OS X, moving a textured window with the mouse formed, as well as implementing different modes for
can be done from any location (not just the title bar), commands, which are managed by the invoker object,
unless on that location there’s a view which handles without the need for the client to be aware of the exis-
dragging events, like slider controls. If no such view tence of bookkeeping or modes.
(or superview) is there, dragging events are sent up
the chain to the window which does handle the drag- 4.3.1 Uses
ging event.
• On iOS, it’s typical to handle view events in the view Notation: UML
Caller Command
execute() receiver.action()
the program simply pops the most recent command synonyms, and implementations that may obscure the
object and executes its undo() method. original pattern by going well beyond it.
Networking It is possible to send whole command ob-
jects across the network to be executed on the other 1. Ambiguity.
machines, for example player actions in computer
(a) The term command is ambiguous. For exam-
games.
ple, move up, move up may refer to a single
Parallel Processing Where the commands are written (move up) command that should be executed
as tasks to a shared resource and executed by many twice, or it may refer to two commands, each
threads in parallel (possibly on remote machines - of which happens to do the same thing (move
this variant is often referred to as the Master/Worker up). If the former command is added twice
pattern) to an undo stack, both items on the stack re-
fer to the same command instance. This may
Progress bars Suppose a program has a sequence of be appropriate when a command can always
commands that it executes in order. If each com- be undone the same way (e.g. move down).
mand object has a getEstimatedDuration() method, Both the Gang of Four and the Java example
the program can easily estimate the total duration. below use this interpretation of the term com-
It can show a progress bar that meaningfully reflects mand. On the other hand, if the latter com-
how close the program is to completing all the tasks. mands are added to an undo stack, the stack
Thread pools A typical, general-purpose thread pool refers to two separate objects. This may be ap-
class might have a public addTask() method that propriate when each object on the stack must
adds a work item to an internal queue of tasks wait- contain information that allows the command
ing to be done. It maintains a pool of threads that to be undone. For example, to undo a delete
execute commands from the queue. The items in selection command, the object may contain a
the queue are command objects. Typically these copy of the deleted text so that it can be re-
objects implement a common interface such as inserted, if the delete selection command must
java.lang.Runnable that allows the thread pool to be undone. Note that using a separate object
execute the command even though the thread pool for each invocation of a command is also an
class itself was written without any knowledge of the example of the chain of responsibility pattern.
specific tasks for which it would be used. (b) The term execute is also ambiguous. It may
refer to running the code identified by the
Transactional behavior Similar to undo, a database command object’s execute method. However,
engine or software installer may keep a list of oper- in Microsoft’s Windows Presentation Founda-
ations that have been or will be performed. Should tion a command is considered to have been ex-
one of them fail, all others can be reversed or dis- ecuted when the command’s execute method
carded (usually called rollback). For example, if two has been invoked, but that does not necessarily
database tables that refer to each other must be up- mean that the application code has run. That
dated, and the second update fails, the transaction occurs only after some further event process-
can be rolled back, so that the first table does not ing.
now contain an invalid reference.
2. Synonyms and homonyms.
Wizards Often a wizard presents several pages of con-
figuration for a single action that happens only when (a) Client, Source, Invoker: the button, toolbar
the user clicks the “Finish” button on the last page. button, or menu item clicked, the shortcut key
In these cases, a natural way to separate user in- pressed by the user.
terface code from application code is to implement
the wizard using a command object. The command (b) Command Object, Routed Command Ob-
object is created when the wizard is first displayed. ject, Action Object: a singleton object (e.g.
Each wizard page stores its GUI changes in the com- there is only one CopyCommand object),
mand object, so the object is populated as the user which knows about shortcut keys, button im-
progresses. “Finish” simply triggers a call to exe- ages, command text, etc. related to the com-
cute(). This way, the command class will work. mand. A source/invoker object calls the Com-
mand/Action object’s execute/performAction
method. The Command/Action object no-
4.3.2 Terminology tifies the appropriate source/invoker objects
when the availability of a command/action has
The terminology used to describe command pattern im- changed. This allows buttons and menu items
plementations is not consistent and can therefore be con- to become inactive (grayed out) when a com-
fusing. This is the result of ambiguity, the use of mand/action cannot be executed/performed.
56 CHAPTER 4. BEHAVIORAL PATTERNS
(c) Receiver, Target Object: the object that is object that identifies the target and the appli-
about to be copied, pasted, moved, etc. The cation code, which is executed at that point.
receiver object owns the method that is called
by the command’s execute method. The re-
ceiver is typically also the target object. For 4.3.3 Example
example, if the receiver object is a cursor
and the method is called moveUp, then one Consider a “simple” switch. In this example we configure
would expect that the cursor is the target of the Switch with two commands: to turn the light on and
the moveUp action. On the other hand, if the to turn the light off.
code is defined by the command object itself, A benefit of this particular implementation of the com-
the target object will be a different object en- mand pattern is that the switch can be used with any de-
tirely. vice, not just a light - the Switch in the following exam-
(d) Command Object, routed event argu- ple turns a light on and off, but the Switch’s constructor
ments, event object: the object that is passed is able to accept any subclasses of Command for its two
from the source to the Command/Action ob- parameters. For example, you could configure the Switch
ject, to the Target object to the code that does to start an engine.
the work. Each button click or shortcut key
results in a new command/event object. Some
implementations add more information to the C#
command/event object as it is being passed
from one object (e.g. CopyCommand) to an- The following code is an implementation of Command
other (e.g. document section). Other im- pattern in C#.
plementations put command/event objects in namespace CommandPattern { using System; pub-
other event objects (like a box inside a bigger lic interface ICommand { void Execute(); } /* The
box) as they move along the line, to avoid nam- Invoker class */ public class Switch { ICommand
ing conflicts. (See also chain of responsibility _closedCommand; ICommand _openedCommand;
pattern). public Switch(ICommand closedCommand, ICom-
(e) Handler, ExecutedRoutedEventHandler, mand openedCommand) { this._closedCommand =
method, function: the actual code that closedCommand; this._openedCommand = opened-
does the copying, pasting, moving, etc. In Command; } //close the circuit/power on public
some implementations the handler code void Close() { this._closedCommand.Execute(); }
is part of the command/action object. In //open the circuit/power off public void Open() {
other implementations the code is part of this._openedCommand.Execute(); } } /* An interface
the Receiver/Target Object, and in yet other that defines actions that the receiver can perform
implementations the handler code is kept */ public interface ISwitchable { void PowerOn();
separate from the other objects. void PowerOff(); } /* The Receiver class */ public
class Light : ISwitchable { public void PowerOn() {
(f) Command Manager, Undo Manager,
Console.WriteLine(“The light is on”); } public void
Scheduler, Queue, Dispatcher, Invoker: an
PowerOff() { Console.WriteLine(“The light is off”);
object that puts command/event objects on
} } /* The Command for turning on the device -
an undo stack or redo stack, or that holds on
ConcreteCommand #1 */ public class CloseSwitchCom-
to command/event objects until other objects
mand : ICommand { private ISwitchable _switchable;
are ready to act on them, or that routes the
public CloseSwitchCommand(ISwitchable switchable)
command/event objects to the appropriate
{ _switchable = switchable; } public void Execute()
receiver/target object or handler code.
{ _switchable.PowerOn(); } } /* The Command for
3. Implementations that go well beyond the original turning off the device - ConcreteCommand #2 */
command pattern. public class OpenSwitchCommand : ICommand {
private ISwitchable _switchable; public OpenSwitch-
(a) Microsoft’s Windows Presentation Foundation Command(ISwitchable switchable) { _switchable
(WPF), introduces routed commands, which = switchable; } public void Execute() { _switch-
combine the command pattern with event pro- able.PowerOff(); } } /* The test class or client */
cessing. As a result, the command object no internal class Program { public static void Main(string[]
longer contains a reference to the target ob- arguments) { string argument = arguments.Length > 0
ject nor a reference to the application code. ? arguments[0].ToUpper() : null; ISwitchable lamp =
Instead, invoking the command object’s exe- new Light(); //Pass reference to the lamp instance to
cute command results in a so-called Executed each command ICommand switchClose = new Clos-
Routed Event that during the event’s tunneling eSwitchCommand(lamp); ICommand switchOpen =
or bubbling may encounter a so-called binding new OpenSwitchCommand(lamp); //Pass reference to
4.3. COMMAND PATTERN 57
instances of the Command objects to the switch Switch Command> commands; private CommandFactory()
@switch = new Switch(switchClose, switchOpen); if { commands = new HashMap<String,Command>();
(argument == “ON”) { // Switch (the Invoker) will in- } public void addCommand(final String name, fi-
voke Execute() (the Command) on the command object nal Command command) { commands.put(name,
- _closedCommand.Execute(); @switch.Close(); } else command); } public void executeCommand(String
if (argument == “OFF”) { //Switch (the Invoker) will name) { if (commands.containsKey(name))
invoke the Execute() (the Command) on the command { commands.get(name).apply(); } }
object - _openedCommand.Execute(); @switch.Open(); public void listCommands() { Sys-
} else { Console.WriteLine(“Argument \"ON\" or tem.out.println(“Enabled commands: " + com-
\"OFF\" is required.”); } } } } mands.keySet().stream().collect(Collectors.joining(",
"))); } /* Factory pattern */ public static Command-
Factory init() { final CommandFactory cf = new
CommandFactory(); // commands are added here using
Java
lambdas. It is also possible to dynamically add com-
mands without editing the code. cf.addCommand(“Light
import java.util.List; import java.util.ArrayList; /**
on”, () -> System.out.println(“Light turned
The Command interface */ public interface Command
on”)); cf.addCommand(“Light off”, () -> Sys-
{ void execute(); } /** The Invoker class */ public
tem.out.println(“Light turned off”)); return cf; } }
class Switch { private List<Command> history = new
public final class Main { public static void main(final
ArrayList<Command>(); public void storeAndExe-
String[] arguments) { final CommandFactory cf =
cute(final Command cmd) { this.history.add(cmd);
CommandFactory.init(); cf.executeCommand(“Light
// optional cmd.execute(); } } /** The Receiver
on”); cf.listCommands(); } }
class */ public class Light { public void turnOn() {
System.out.println(“The light is on”); } public void
turnOff() { System.out.println(“The light is off”); }
} /** The Command for turning on the light - Con-
Python
creteCommand #1 */ public class FlipUpCommand
implements Command { private Light theLight; public
The following code is an implementation of Command
FlipUpCommand(final Light light) { this.theLight =
pattern in Python.
light; } @Override // Command public void execute()
{ theLight.turnOn(); } } /** The Command for turning class Switch(object): """The INVOKER class"""
off the light - ConcreteCommand #2 */ public class def __init__(self): self._history = () @property def
FlipDownCommand implements Command { private history(self): return self._history def execute(self,
Light theLight; public FlipDownCommand(final Light command): self._history = self._history + (com-
light) { this.theLight = light; } @Override // Command mand,) command.execute() class Command(object):
public void execute() { theLight.turnOff(); } } /* The """The COMMAND interface""" def __init__(self,
test class or client */ public class PressSwitch { public obj): self._obj = obj def execute(self): raise NotIm-
static void main(final String[] arguments){ // Check plementedError class TurnOnCommand(Command):
number of arguments if (arguments.length != 1) { """The COMMAND for turning on the light""" def
System.err.println(“Argument \"ON\" or \"OFF\" is execute(self): self._obj.turn_on() class TurnOffCom-
required.”); System.exit(−1); } final Light lamp = mand(Command): """The COMMAND for turning
new Light(); final Command switchUp = new FlipUp- off the light""" def execute(self): self._obj.turn_off()
Command(lamp); final Command switchDown = new class Light(object): """The RECEIVER class""" def
FlipDownCommand(lamp); final Switch mySwitch turn_on(self): print(“The light is on”) def turn_off(self):
= new Switch(); switch(arguments[0]) { case “ON": print(“The light is off”) class LightSwitchClient(object):
mySwitch.storeAndExecute(switchUp); break; case """The CLIENT class""" def __init__(self): self._lamp
“OFF": mySwitch.storeAndExecute(switchDown); = Light() self._switch = Switch() @property def
break; default: System.err.println(“Argument \"ON\" or switch(self): return self._switch def press(self,
\"OFF\" is required.”); System.exit(−1); } } } cmd): cmd = cmd.strip().upper() if cmd == “ON":
self._switch.execute(TurnOnCommand(self._lamp))
elif cmd == “OFF":
self._switch.execute(TurnOffCommand(self._lamp))
Java 8 Using a functional interface. else: print(“Argument 'ON' or 'OFF' is required.”) #
/** * The Command functional interface.<br/> */ Execute if this file is run as a script and not imported as a
@FunctionalInterface public interface Command module if __name__ == "__main__": light_switch
{ public void apply(); } /** * The Command- = LightSwitchClient() print(“Switch ON test.”)
Factory class.<br/> */ import java.util.HashMap; light_switch.press(“ON”) print(“Switch OFF test.”)
import java.util.stream.Collectors; public final class light_switch.press(“OFF”) print(“Invalid Command
CommandFactory { private final HashMap<String, test.”) light_switch.press("****") print(“Command
58 CHAPTER 4. BEHAVIORAL PATTERNS
• http://www.javaworld.com/javaworld/javatips/
defines a language that contains Reverse Polish Notation
jw-javatip68.html
expressions like:
ab+abc+-ab+ca--
4.4 Interpreter pattern
C#
In computer programming, the interpreter pattern is a
design pattern that specifies how to evaluate sentences in This structural code demonstrates the Interpreter pat-
a language. The basic idea is to have a class for each sym- terns, which using a defined grammar, provides the in-
bol (terminal or nonterminal) in a specialized computer terpreter that processes parsed statements.
language. The syntax tree of a sentence in the language is
namespace DesignPatterns.Interpreter { // “Context”
an instance of the composite pattern and is used to eval-
class Context { } // “AbstractExpression” abstract
uate (interpret) the sentence for a client.[1]:243 See also
class AbstractExpression { public abstract void In-
Composite pattern. terpret(Context context); } // “TerminalExpression”
class TerminalExpression : AbstractExpression {
public override void Interpret(Context context) { Con-
4.4.1 Uses sole.WriteLine(“Called Terminal.Interpret()"); } } //
“NonterminalExpression” class NonterminalExpression
• Specialized database query languages such as SQL.
: AbstractExpression { public override void Inter-
• Specialized computer languages that are often used pret(Context context) { Console.WriteLine(“Called
to describe communication protocols. Nonterminal.Interpret()"); } } class MainApp { static
void Main() { var context = new Context(); // Usually
• Most general-purpose computer languages actually a tree var list = new List<AbstractExpression>(); //
incorporate several specialized languages. Populate 'abstract syntax tree' list.Add(new Terminal-
Expression()); list.Add(new NonterminalExpression());
list.Add(new TerminalExpression()); list.Add(new
4.4.2 Structure TerminalExpression()); // Interpret foreach (AbstractEx-
pression exp in list) { exp.Interpret(context); } } } }
var primes = new List<int>{ 2, 3, 5, 7, 11, 13, 17, 19}; function range(start, end) { return { [Symbol.iterator]()
long m = 1; foreach (var p in primes) m *= p; { //#A return this; }, next() { if(start < end) { return {
value: start++, done:false }; //#B } return { done: true,
value:end }; //#B } } } for(number of range(1, 5)) {
console.log(number); //-> 1, 2, 3, 4 }
C++
The iteration mechanism of built-in types, like strings,
C++ implements iterators with the semantics of pointers can also be manipulated:
in that language. In C++, a class can overload all of the
pointer operations, so an iterator can be implemented that let iter = ['I', 't', 'e', 'r', 'a', 't', 'o', 'r'][Symbol.iterator]();
acts more or less like a pointer, complete with derefer- iter.next().value; //-> I iter.next().value; //-> t
ence, increment, and decrement. This has the advantage
that C++ algorithms such as std::sort can immediately be
applied to plain old memory buffers, and that there is no PHP
new syntax to learn. However, it requires an “end” itera-
tor to test for equality, rather than allowing an iterator to PHP supports the iterator pattern via the Iterator inter-
know that it has reached the end. In C++ language, we face, as part of the standard distribution.[4] Objects that
say that an iterator models the iterator concept. implement the interface can be iterated over with the
foreach language construct.
Java Example of patterns using PHP:
<?php // BookIterator.php namespace DesignPatterns;
Java has the Iterator interface. class BookIterator implements \Iterator { private
As of Java 5, objects implementing the Iterable inter- $i_position = 0; private $booksCollection; public func-
face, which returns an Iterator from its only method, can tion __construct(BookCollection $booksCollection) {
be traversed using the enhanced for loop syntax.[2] The $this->booksCollection = $booksCollection; } public
Collection interface from the Java collections framework function current() { return $this->booksCollection-
extends Iterable. >getTitle($this->i_position); } public function key()
{ return $this->i_position; } public function next()
{ $this->i_position++; } public function rewind()
JavaScript { $this->i_position = 0; } public function valid() {
return !is_null($this->booksCollection->getTitle($this-
JavaScript, as part of ECMAScript 6, supports the itera- >i_position)); } }
tor pattern with any object that provides a next() method, <?php // BookCollection.php namespace DesignPatterns;
which returns an object with two specific properties: done class BookCollection implements \IteratorAggregate {
and value. Here’s an example that shows a reverse array private $a_titles = array(); public function getIterator()
iterator: { return new BookIterator($this); } public function
62 CHAPTER 4. BEHAVIORAL PATTERNS
• Iterator
• Observer pattern
4.5.4 References
[1] Gang Of Four The mediator behavioural design pattern
[2] “An enhanced for loop for the Java™ Programming Lan- The essence of the Mediator Pattern is to “define an ob-
guage”. Retrieved 25 June 2013. ject that encapsulates how a set of objects interact”. It
promotes loose coupling by keeping objects from refer-
[3] “Iterators and generators”. Retrieved 18 March 2016.
ring to each other explicitly, and it allows their interac-
[4] “PHP: Iterator”. Retrieved 23 June 2013. tion to be varied independently.[1] Client classes can use
the mediator to send messages to other clients, and can
[5] “Python v2.7.1 documentation: The Python Standard Li- receive messages from other clients via an event on the
brary: 5. Built-in Types”. Retrieved 2 May 2011. mediator class.
4.6. MEDIATOR PATTERN 63
med = m; med.registerBook(this); } public void ex- cannot, or should not, change). When using this pattern,
ecute() { med.book(); } } class LblDisplay extends care should be taken if the originator may change other
JLabel { Mediator med; LblDisplay(Mediator m) { su- objects or resources - the memento pattern operates on a
per(“Just start...”); med = m; med.registerDisplay(this); single object.
setFont(new Font(“Arial”, Font.BOLD, 24)); } } Classic examples of the memento pattern include the seed
class MediatorDemo extends JFrame implements of a pseudorandom number generator (it will always pro-
ActionListener { Mediator med = new Participant- duce the same sequence thereafter when initialized with
Mediator(); MediatorDemo() { JPanel p = new the seed state) and the state in a finite state machine.
JPanel(); p.add(new BtnView(this, med)); p.add(new
BtnBook(this, med)); p.add(new BtnSearch(this,
med)); getContentPane().add(new LblDisplay(med),
“North”); getContentPane().add(p, “South”); set- 4.7.1 Java example
Size(400, 200); setVisible(true); } public void ac-
tionPerformed(ActionEvent ae) { Command comd = The following Java program illustrates the “undo” usage
(Command) ae.getSource(); comd.execute(); } public of the memento pattern.
static void main(String[] args) { new MediatorDemo(); }
import java.util.List; import java.util.ArrayList; class
}
Originator { private String state; // The class could also
contain additional data that is not part of the // state saved
in the memento.. public void set(String state) { Sys-
4.6.4 See also tem.out.println(“Originator: Setting state to " + state);
this.state = state; } public Memento saveToMemento() {
• Data mediation System.out.println(“Originator: Saving to Memento.”);
return new Memento(this.state); } public void restore-
• Design Patterns, the book which gave rise to the FromMemento(Memento memento) { this.state = me-
study of design patterns in computer science mento.getSavedState(); System.out.println(“Originator:
State after restoring from Memento: " + state); }
• Design pattern (computer science), a standard solu- public static class Memento { private final String
tion to common problems in software design state; public Memento(String stateToSave) { state
= stateToSave; } private String getSavedState() {
return state; } } } class Caretaker { public static
4.6.5 References void main(String[] args) { List<Originator.Memento>
savedStates = new ArrayList<Originator.Memento>();
[1] Gang Of Four
Originator originator = new Originator(); origina-
tor.set(“State1”); originator.set(“State2”); saved-
4.6.6 External links States.add(originator.saveToMemento()); origi-
nator.set(“State3”); // We can request multiple
• Mediator Design Pattern mementos, and choose which one to roll back
to. savedStates.add(originator.saveToMemento());
• Is the use of the mediator pattern recommend? - originator.set(“State4”); origina-
Stack Overflow tor.restoreFromMemento(savedStates.get(1)); } }
4.8 Null Object pattern Given a binary tree, with this node structure:
class node { node left node right }
“Null object” redirects here. For the concept in category One may implement a tree size procedure recursively:
theory, see Initial object.
function tree_size(node) { return 1 + tree_size(node.left)
+ tree_size(node.right) }
In object-oriented computer programming, a Null Ob-
ject is an object with no referenced value or with defined Since the child nodes may not exist, one must modify the
neutral (“null”) behavior. The Null Object design pattern procedure by adding non-existence or null checks:
describes the uses of such objects and their behavior (or function tree_size(node) { set sum = 1 if node.left exists
lack thereof). It was first published in the Pattern Lan- { sum = sum + tree_size(node.left) } if node.right exists
guages of Program Design book series.[1] { sum = sum + tree_size(node.right) } return sum }
This however makes the procedure more complicated by
mixing boundary checks with normal logic, and it be-
4.8.1 Motivation
comes harder to read. Using the null object pattern, one
In most object-oriented languages, such as Java or C#, can create a special version of the procedure but only for
references may be null. These references need to be null nodes:
checked to ensure they are not null before invoking any function tree_size(node) { return 1 + tree_size(node.left)
66 CHAPTER 4. BEHAVIORAL PATTERNS
IAnimal Null = new NullAnimal(); // The Null Case: tion call to list needs to reduce its argument expression to
this NullAnimal class should be used in place of C# null a value, the null object is automatically substituted.
keyword. private class NullAnimal : Animal { public
override void MakeSound() { // Purposefully provides
no behaviour. } } public abstract void MakeSound(); } CLOS
// Dog is a real animal. class Dog : IAnimal { public
void MakeSound() { Console.WriteLine(“Woof!"); } In Common Lisp, the object nil is the one and only in-
} /* ========================= * Simplistic stance of the special class null. What this means is that a
usage example in a Main entry point. */ static class Pro- method can be specialized to the null class, thereby im-
gram { static void Main() { IAnimal dog = new Dog(); plementing the null design pattern. Which is to say, it is
dog.MakeSound(); // outputs “Woof!" /* Instead of using essentially built into the object system:
C# null, use the Animal.Null instance. * This example ;; empty dog class (defclass dog () ()) ;; a dog object
is simplistic but conveys the idea that if the Animal.Null makes a sound by barking: woof! is printed on standard
instance is used then the program * will never experience output ;; when (make-sound x) is called, if x is an instance
a .NET System.NullReferenceException at runtime, of the dog class. (defmethod make-sound ((obj dog))
unlike if C# null were used. */ IAnimal unknown = (format t “woof!~%")) ;; allow (make-sound nil) to work
Animal.Null; //<< replaces: IAnimal unknown = null; via specialization to null class. ;; innocuous empty body:
unknown.MakeSound(); // outputs nothing, but does not nil makes no sound. (defmethod make-sound ((obj null)))
throw a runtime exception } }
The class null is a subclass of the symbol class, because nil
is a symbol. Since nil also represents the empty list, null
Smalltalk is a subclass of the list class, too. Methods parameters
specialized to symbol or list will thus take a nil argument.
Following the Smalltalk principle, everything is an object, Of course, a null specialization can still be defined which
the absence of an object is itself modeled by an object, is a more specific match for nil.
called nil. In the GNU Smalltalk for example, the class
of nil is UndefinedObject, a direct descendant of Object.
Scheme
Any operation that fails to return a sensible object for its
purpose may return nil instead, thus avoiding the special Unlike Common Lisp, and many dialects of Lisp, the
case of returning “no object”. This method has the ad- Scheme dialect does not have a nil value which works
vantage of simplicity (no need for a special case) over this way; the functions car and cdr may not be applied
the classical “null” or “no object” or “null reference” ap- to an empty list; Scheme application code therefore has
proach. Especially useful messages to be used with nil are to use the empty? or pair? predicate functions to sidestep
isNil or ifNil:, which make it practical and safe to deal this situation, even in situations where very similar Lisp
with possible references to nil in Smalltalk programs. would not need to distinguish the empty and non-empty
cases thanks to the behavior of nil.
Common Lisp
Ruby
In Lisp, functions can gracefully accept the special ob-
ject nil, which reduces the amount of special case testing In duck-typed languages like Ruby, language inheritance
in application code. For instance, although nil is an atom is not necessary to provide expected behavior.
and does not have any fields, the functions car and cdr ac-
cept nil and just return it, which is very useful and results class Dog def sound “bark” end end class
in shorter code. NilAnimal def sound(*); end end def
get_animal(animal=NilAnimal.new) animal
Since nil is the empty list in Lisp, the situation described end get_animal(Dog.new).sound => “bark”
in the introduction above doesn't exist. Code which re- get_animal.sound => nil
turns nil is returning what is in fact the empty list (and
not anything resembling a null reference to a list type), so
the caller does not need to test the value to see whether Attempts to directly monkey-patch NilClass instead of
or not it has a list. providing explicit implementations give more unexpected
side effects than benefits.
The null object pattern is also supported in multiple value
processing. If the program attempts to extract a value
from an expression which returns no values, the behavior JavaScript
is that the null object nil is substituted. Thus (list (values))
returns (nil) (a one-element list containing nil). The (val- In duck-typed languages like JavaScript, language inher-
ues) expression returns no values at all, but since the func- itance is not necessary to provide expected behavior.
68 CHAPTER 4. BEHAVIORAL PATTERNS
class Dog{ sound(){ return 'bark'; } } class NullAnimal{ Animal = New AnimalEmpty() Public Overridable Sub
sound(){ return null; } } function getAnimal(type) MakeSound() Console.WriteLine(“Woof!") End Sub
{ return type === 'dog' ? new Dog() : new Nul- End Class Friend NotInheritable Class AnimalEmpty
lAnimal(); } ['dog', null].map((animal) => getAni- Inherits Animal Public Overrides Sub MakeSound() '
mal(animal).sound()); // Returns ["bark”, null] End Sub End Class
Public Class Animal Public Shared ReadOnly Empty As [6] Fowler, Martin (1999). Refactoring pp. 216
4.9. OBSERVER PATTERN 69
4.8.10 External links maintenance (also called event or notification loss), the
lack of flexibility in conditional dispersion and possible
• Jeffrey Walkers’ account of the Null Object Pattern hindrance to desired security measures. In some (non-
polling) implementations of the publish-subscribe pattern
• Martin Fowlers’ description of Special Case, a (also called the pub-sub pattern), this is solved by creat-
slightly more general pattern ing a dedicated “message queue” server and at times an
• Null Object Pattern Revisited extra “message handler” object, as added stages between
the observer and the observed object who’s state is be-
• Introduce Null Object refactoring ing checked, thus “decoupling” the software components.
In these cases, the message queue server is accessed by
• Why NULL Is Bad by Yegor Bugayenko the observers with the observer pattern, “subscribing to
certain messages” knowing only about the expected mes-
• SourceMaking Tutorial
sage (or even that not), but knowing nothing about the
• Null Object Pattern in Swift message sender itself, and the sender may know noth-
ing about the receivers. Other implementations of the
publish-subscribe pattern, which achieve a similar effect
of notification and communication to interested parties,
4.9 Observer pattern do not use the observer pattern altogether.[2][3]
Still, in early implementations of multi-window operat-
The observer pattern is a software design pattern in
ing systems like OS2 and Windows, the terms “publish-
which an object, called the subject, maintains a list of
subscribe pattern” and “event driven software develop-
its dependents, called observers, and notifies them auto-
ment” were used as a synonym for the observer pattern.[4]
matically of any state changes, usually by calling one of
their methods. The observer pattern, as described in the GOF book, is a
very basic concept and does not deal with observance re-
It is mainly used to implement distributed event han-
moval or with any conditional or complex logic handling
dling systems, in “event driven” software. Most mod-
to be done by the observed “subject” before or after no-
ern languages such as Java and C# have built in “event”
tifying the observers. The pattern also does not deal with
constructs which implement the observer pattern compo-
recording the “events”, the asynchronous passing of the
nents, for easy programming and short code.
notifications or guaranteeing their being received. These
The observer pattern is also a key part in the familiar concerns are typically dealt with in message queueing sys-
model–view–controller (MVC) architectural pattern.[1] tems of which the observer pattern is only a small part.
The observer pattern is implemented in numerous
Related patterns: Publish–subscribe pattern, mediator,
programming libraries and systems, including almost all
singleton.
GUI toolkits.
• Implicit invocation
tics of the underlying event schema and values. The high message volume. However, as the number of nodes and
degree of semantic heterogeneity of events in large and messages grows, the likelihood of instabilities increases,
open deployments such as smart cities and the sensor limiting the maximum scalability of a pub/sub network.
web makes it difficult to develop and maintain pub/sub Example throughput instabilities at large scales include:
systems. In order to address semantic coupling within
pub/sub systems the use of approximate semantic match- • Load surges—periods when subscriber requests sat-
ing of events is an active area of research.[2] urate network throughput followed by periods of low
message volume (underutilized network bandwidth)
Message Delivery Issues • Slowdowns—more and more applications use the
system (even if they are communicating on separate
A pub/sub system must be designed carefully to be able pub/sub channels) the message volume flow to an in-
to provide stronger system properties that a particular ap- dividual subscriber will slow
plication might require, such as assured delivery.
• IP broadcast storms—a local area network may be
• The broker in a pub/sub system may be designed to shut down entirely by saturating it with overhead
deliver messages for a specified time, but then stop messages that choke out all normal traffic unrelated
attempting delivery, whether or not it has received to the pub/sub traffic
confirmation of successful receipt of the message by
all subscribers. A pub/sub system designed in this For pub/sub systems that use brokers (servers), the argu-
way cannot guarantee delivery of messages to any ment for a broker to send messages to a subscriber is in-
applications that might require such assured deliv- band, and can be subject to security problems. Brokers
ery. Tighter coupling of the designs of such a pub- might be fooled into sending notifications to the wrong
lisher and subscriber pair must be enforced outside client, amplifying denial of service requests against the
of the pub/sub architecture to accomplish such as- client. Brokers themselves could be overloaded as they
sured delivery (e.g. by requiring the subscriber to allocate resources to track created subscriptions.
publish receipt messages). Even with systems that do not rely on brokers, a sub-
• A publisher in a pub/sub system may assume that scriber might be able to receive data that it is not au-
a subscriber is listening, when in fact it is not. A thorized to receive. An unauthorized publisher may be
factory may utilize a pub/sub system where equip- able to introduce incorrect or damaging messages into the
ment can publish problems or failures to a subscriber pub/sub system. This is especially true with systems that
that displays and logs those problems. If the logger broadcast or multicast their messages. Encryption (e.g.
fails (crashes), equipment problem publishers won't Transport Layer Security (SSL/TLS)) can prevent unau-
necessarily receive notice of the logger failure, and thorized access, but cannot prevent damaging messages
error messages will not be displayed or recorded by from being introduced by authorized publishers. Archi-
any equipment on the pub/sub system. It should be tectures other than pub/sub, such as client/server systems,
noted that this is also a design challenge for alterna- are also vulnerable to authorized message senders that be-
tive messaging architectures, such as a client/server have maliciously.
system. In a client/server system, when an error
logger fails, the system will receive an indication
4.10.6 See also
of the error logger (server) failure. However, the
client/server system will have to deal with that fail- • Atom (standard), another highly scalable web-
ure by having redundant logging servers online, or syndication protocol
by dynamically spawning fallback logging servers.
This adds complexity to the client and server de- • Data Distribution Service (DDS)
signs, as well as to the client/server architecture as
a whole. However, in a pub/sub system, redundant • Event-driven programming
logging subscribers that are exact duplicates of the • High-level architecture
existing logger can be added to the system to in-
crease logging reliability without any impact to any • Internet Group Management Protocol
other equipment on the system. In a pub/sub sys-
tem, the feature of assured error message logging • Message brokers
can be added incrementally, subsequent to imple- • Message queue
menting the basic functionality of equipment prob-
lem message logging. • Observer Pattern
• PubSubHubbub, an implementation of pub/sub
The pub/sub pattern scales well for small networks with a
small number of publisher and subscriber nodes and low • RSS, a highly scalable web-syndication protocol
4.11. DESIGN PATTERN SERVANT 73
calls the method of servant and passes serviced ob- // Servant class, offering its functionality to classes imple-
jects as parameters. This situation is shown on figure menting // Movable Interface public class MoveServant
1. { // Method, which will move Movable implementing
class to position where public void moveTo(Movable
serviced, Position where) { // Do some other stuff to
ensure it moves smoothly and nicely, this is // the place
to offer the functionality serviced.setPosition(where); }
// Method, which will move Movable implementing class
by dx and dy public void moveBy(Movable serviced, int
dx, int dy) { // this is the place to offer the functionality
dx += serviced.getPosition().xPosition; dy += ser-
viced.getPosition().yPosition; serviced.setPosition(new
Position(dx, dy)); } } // Interface specifying what
Figure 2: User requests operations from serviced instances, serviced classes needs to implement, to be // serviced by
which then asks servant to do it for them. servant. public interface Movable { public void setPosi-
tion(Position p); public Position getPosition(); } // One
of geometric classes public class Triangle implements
1. Serviced instances know the servant and the user Movable { // Position of the geometric object on some
sends them messages with his requests (in which canvas private Position p; // Method, which sets position
case she doesn’t have to know the servant). The ser- of geometric object public void setPosition(Position
viced instances then send messages to the instances p) { this.p = p; } // Method, which returns position of
of servant, asking for service. geometric object public Position getPosition() { return
this.p; } } // One of geometric classes public class Ellipse
2. On figure 2 is shown opposite situation, where user implements Movable { // Position of the geometric
don’t know about servant class and calls directly ser- object on some canvas private Position p; // Method,
viced classes. Serviced classes then asks servant which sets position of geometric object public void
themselves to achieve desired functionality. setPosition(Position p) { this.p = p; } // Method, which
returns position of geometric object public Position
getPosition() { return this.p; } } // One of geometric
4.11.3 How to implement Servant classes public class Rectangle implements Movable { //
Position of the geometric object on some canvas private
1. Analyze what behavior servant should take care of. Position p; // Method, which sets position of geometric
State what methods servant will define and what object public void setPosition(Position p) { this.p = p; }
these methods will need from serviced parameter. // Method, which returns position of geometric object
By other words, what serviced instance must pro- public Position getPosition() { return this.p; } } // Just
vide, so that servants methods can achieve their a very simple container class for position. public class
goals. Position { public int xPosition; public int yPosition;
public Position(int dx, int dy) { xPosition = dx; yPosition
2. Analyze what abilities serviced classes must have, so
= dy; } }
they can be properly serviced.
6. Implement defined interface with serviced classes. • For the Servant pattern we have some objects to
which we want to offer some functionality. We cre-
ate a class whose instances offer that functionality
4.11.4 Example and which defines an interface that serviced objects
must implement. Serviced instances are then passed
This simple example shows the situation described above. as parameters to the servant.
This example is only illustrative and will not offer any
actual drawing of geometric objects, nor specification of • For the Command pattern we have some objects
what they look like. that we want to modify with some functionality. So,
4.12. SPECIFICATION PATTERN 75
we define an interface which commands which de- Composite Specification class has one function called Is-
sired functionality must be implemented. Instances SatisfiedBy that returns a boolean value. After instanti-
of those commands are then passed to original ob- ation, the specification is “chained” with other specifica-
jects as parameters of their methods. tions, making new specifications easily maintainable, yet
highly customizable business logic. Furthermore, upon
instantiation the business logic may, through method in-
Even though design patterns Command and Servant are
vocation or inversion of control, have its state altered in
similar it doesn’t mean it’s always like that. There are
order to become a delegate of other classes such as a per-
a number of situations where use of design pattern Com-
sistence repository.
mand doesn’t relate to the design pattern Servant. In these
situations we usually need to pass to called methods just
a reference to another method, which it will need in ac-
complishing its goal. Since we can’t pass references to 4.12.1 Code examples
methods in many languages, we have to pass an object
implementing an interface which declares the signature C#
of passed method.
public interface ISpecification { bool IsSatisfiedBy(object
candidate); ISpecification And(ISpecification other);
4.11.6 See also ISpecification AndNot(ISpecification other); IS-
pecification Or(ISpecification other); ISpecification
• Command pattern OrNot(ISpecification other); ISpecification Not(); }
public abstract class CompositeSpecification : ISpec-
ification { public abstract bool IsSatisfiedBy(object
4.11.7 Resources candidate); public ISpecification And(ISpecification
other) { return new AndSpecification(this, other); }
Pecinovský, Rudolf; Jarmila Pavlíčková; Luboš Pavlíček public ISpecification AndNot(ISpecification other) {
(June 2006). Let’s Modify the Objects First Approach into return new AndNotSpecification(this, other); } public
Design Patterns First (PDF). Eleventh Annual Conference ISpecification Or(ISpecification other) { return new
on Innovation and Technology in Computer Science Ed- OrSpecification(this, other); } public ISpecification
ucation, University of Bologna. OrNot(ISpecification other) { return new OrNotSpecifi-
cation(this, other); } public ISpecification Not() { return
new NotSpecification(this); } } public class AndSpecifi-
cation : CompositeSpecification { private ISpecification
4.12 Specification pattern leftCondition; private ISpecification rightCondition;
public AndSpecification(ISpecification left, ISpecifica-
tion right) { leftCondition = left; rightCondition = right;
} public override bool IsSatisfiedBy(object candidate)
{ return leftCondition.IsSatisfiedBy(candidate) &&
rightCondition.IsSatisfiedBy(candidate); } } public
class AndNotSpecification : CompositeSpecifica-
tion { private ISpecification leftCondition; private
ISpecification rightCondition; public AndNotSpec-
ification(ISpecification left, ISpecification right) {
leftCondition = left; rightCondition = right; } public
override bool IsSatisfiedBy(object candidate) { return
leftCondition.IsSatisfiedBy(candidate) && rightCondi-
tion.IsSatisfiedBy(candidate) != true; } } public class
OrSpecification : CompositeSpecification { private
Specification Pattern in UML
ISpecification leftCondition; private ISpecification right-
Condition; public OrSpecification(ISpecification left, IS-
In computer programming, the specification pattern is a pecification right) { leftCondition = left; rightCondition
particular software design pattern, whereby business rules = right; } public override bool IsSatisfiedBy(object can-
can be recombined by chaining the business rules together didate) { return leftCondition.IsSatisfiedBy(candidate)
using boolean logic. The pattern is frequently used in the || rightCondition.IsSatisfiedBy(candidate); } } public
context of domain-driven design. class OrNotSpecification : CompositeSpecifica-
A specification pattern outlines a business rule that is tion { private ISpecification leftCondition; private
combinable with other business rules. In this pattern, a ISpecification rightCondition; public OrNotSpec-
unit of business logic inherits its functionality from the ification(ISpecification left, ISpecification right) {
abstract aggregate Composite Specification class. The leftCondition = left; rightCondition = right; } public
76 CHAPTER 4. BEHAVIORAL PATTERNS
• Cargo Cult Programming - There lacks a well- • The Specification Pattern in Swift by Simon
defined purpose for this pattern, and there’s no guide Strandgaard
when to implement it or not. Also, see Law of the
instrument. • specification pattern in flash actionscript 3 by Rolf
Vreijdenberger
• Inner-platform effect - And() function which di-
rectly replicate && in C#. Also, Not() and poten-
tially more. Also, see Reinventing the square wheel. 4.13 State pattern
• Spaghetti/Lasagna Code - Separate classes for each
part of the specification fragments what could be a The state pattern is a behavioral software design pat-
cohesive object. In the example above, OverDue is tern that implements a state machine in an object-oriented
an extra layer between the Logic for SendToCollec- way. With the state pattern, a state machine is imple-
tion and the OverDueSpecification implementation. mented by implementing each individual state as a de-
rived class of the state pattern interface, and implement-
Most natural programming languages can accommodate ing state transitions by invoking methods defined by the
domain-driven design with the core Object Oriented con- pattern’s superclass.
cepts. The state pattern can be interpreted as a strategy pattern
Alternative example, without the Specification Pattern: which is able to switch the current strategy through invo-
cations of methods defined in the pattern’s interface.
var InvoiceCollection = Service.GetInvoices(); fore-
ach (Invoice invoice in InvoiceCollection) { in- This pattern is used in computer programming to encap-
voice.SendToCollectionIfNecessary(); } // Invoice sulate varying behavior for the same object based on its
methods: public void SendToCollectionIfNecessary() { internal state. This can be a cleaner way for an object to
if (ShouldSendToCollection()) { SendToCollection(); change its behavior at runtime without [1]:395
resorting to large
} } private bool ShouldSendToCollection() { return monolithic conditional statements and thus improve
[2]
currentInvoice.OverDue && currentInvoice.NoticeSent maintainability.
&& !currentInvoice.InCollection; }
4.13.1 Structure
This alternative uses foundation concepts of Get-Only
Properties, Condition-Logic, and Functions. The key al- Context State
ternative here is Get-Only Properties, which are well-
+request() +handle()
named to maintain the Domain-Driven language, and en-
able the continued use of the natural && operator, in-
stead of the Specification Pattern’s And() function. Fur- state.handle() ConcreteStateA ConcreteStateB
thermore, the creation of a well-named function Send-
+handle() +handle()
ToCollectionIfNecessary is potentially more useful and
descriptive, than the previous example (which could also
State in UML[1][3]
be contained in such a function, except not directly on the
object apparently).
4.12.4 References
• Evans, Eric (2004). Domain Driven Design.
Addison-Wesley. p. 224.
[2] Jaeger, Thomas. “The State Design Pattern vs. State Ma- The following example is in C#.
4.14. STRATEGY PATTERN 79
PrimitiveOperation1()
The template pattern is useful working with auto-
generated code. The challenge of working with generated
PrimitiveOperation2()
code is that any refinement of the source material will lead
doSomething()
to changes in the generated code, which could overwrite
hand-written modifications. This may be solved using the
Template method: UML class diagram. Template pattern, by generating abstract code, and mak-
ing hand-written modifications to a concrete subclass or
implementation class. The abstract code may be in the
form of an abstract class in C++, or an interface in Java
4.15.3 Usage or C#. The hand-written code would go into a subclass
in C++, and an implementing class in Java or C#. When
The template method is used in frameworks, where each used with code generation, this pattern is sometimes re-
implements the invariant parts of a domain’s architecture, ferred to as the Generation Gap pattern.[6]
leaving “placeholders” for customization options. This is
an example of inversion of control. The template method
is used for the following reasons:[3] 4.15.4 See also
• Inheritance (computer science)
• Let subclasses implement varying behavior (through
method overriding).[5] • Method overriding (programming)
82 CHAPTER 4. BEHAVIORAL PATTERNS
• Adapter pattern
visit(a : ConcretesElementA) : void
visit(b : ConcretesElementB) : void
4.15.5 References
ConcreteVisitor1 ConcreteVisitor2
[1] Gamma, Erich; Helm, Richard; Johnson, Ralph;
Vlissides, John (1994). “Template Method”. Design Pat- visit(a : ConcretesElementA) : void visit(a : ConcretesElementA) : void
visit(b : ConcretesElementB) : void visit(b : ConcretesElementB) : void
terns. Addison-Wesley. pp. 325–330. ISBN 0-201-
63361-2.
Object structure Element
[3] “Template Method Design Pattern”. Source Making - accept(visitor : Visitor) : void accept(visitor : Visitor) : void
teaching IT professional. Retrieved 2012-09-12. Tem-
plate Method is used prominently in frameworks.
Visitor in Unified Modeling Language (UML)
[4] LePUS3 legend. Retrieved from http://lepus.org.uk/ref/
legend/legend.xml.
an algorithm from an object structure on which it oper-
[5] Chung, Carlo (2011). Pro Objective-C Design Patterns for ates. A practical result of this separation is the ability
iOS. Berkely, CA: Apress. p. 266. ISBN 978-1-4302-
to add new operations to extant object structures with-
3331-2.
out modifying the structures. It is one way to follow the
[6] Vlissides, John (1998-06-22). Pattern Hatching: Design open/closed principle.
Patterns Applied. Addison-Wesley Professional. pp. 85–
In essence, the visitor allows adding new virtual functions
101. ISBN 978-0201432930.
to a family of classes, without modifying the classes. In-
stead, a visitor class is created that implements all of the
4.15.6 External links appropriate specializations of the virtual function. The
visitor takes the instance reference as input, and imple-
• Working with Template Classes in PHP 5 ments the goal through double dispatch.
4.16.2 Motivation
Consider the design of a 2D computer-aided design
(CAD) system. At its core there are several types to rep-
Visitor in LePUS3 (legend) resent basic geometric shapes like circles, lines, and arcs.
The entities are ordered into layers, and at the top of the
In object-oriented programming and software engineer- type hierarchy is the drawing, which is simply a list of
ing, the visitor design pattern is a way of separating layers, plus some added properties.
4.16. VISITOR PATTERN 83
A fundamental operation on this type hierarchy is sav- • When the associated visit method is called, its im-
ing a drawing to the system’s native file format. At first plementation is chosen based on both:
glance it may seem acceptable to add local save methods
to all types in the hierarchy. But it is also useful to be • The dynamic type of the visitor.
able to save drawings to other file formats. Adding ever
more methods for saving into many different file formats • The static type of the element as known
soon clutters the relatively pure original geometric data from within the implementation of the
structure. accept method, which is the same as the
dynamic type of the element. (As a
A naive way to solve this would be to maintain separate bonus, if the visitor can't handle an ar-
functions for each file format. Such a save function would gument of the given element’s type, then
take a drawing as input, traverse it, and encode into that the compiler will catch the error.)
specific file format. As this is done for each added dif-
ferent format, duplication between the functions accu-
• Thus, the implementation of the visit method is cho-
mulates. For example, saving a circle shape in a raster
sen based on both:
format requires very similar code no matter what specific
raster form is used, and is different from other primitive
shapes. The case for other primitive shapes like lines and • The dynamic type of the element.
polygons is similar. Thus, the code becomes a large outer • The dynamic type of the visitor.
loop traversing through the objects, with a large decision
This effectively implements double dispatch.
tree inside the loop querying the type of the object. An-
For languages which object systems support
other problem with this approach is that it is very easy to
multiple dispatch, not only single dispatch,
miss a shape in one or more savers, or a new primitive
such as Common Lisp, implementing the visi-
shape is introduced, but the save routine is implemented
tor pattern in them is trivial.
only for one file type and not others, leading to code ex-
tension and maintenance problems.
In this way, one algorithm can be written to traverse a
Instead, the Visitor pattern can be applied. It encodes a graph of elements, and many different kinds of opera-
logical operation on the whole hierarchy into one class tions can be performed during that traversal by supplying
containing one method per type. In the CAD example, different kinds of visitors to interact with the elements
each save function would be implemented as a separate based on the dynamic types of both the elements and the
Visitor subclass. This would remove all duplication of visitors.
type checks and traversal steps. It would also make the
compiler complain if a shape is omitted. Some languages (e.g., C# via the Dynamic Language
Runtime (DLR)) support multiple dispatch, which greatly
Another motive is to reuse iteration code. For exam- simplifies implementing the Visitor pattern (a.k.a. Dy-
ple, iterating over a directory structure could be imple- namic Visitor) by allowing use of simple function over-
mented with a visitor pattern. This would allow creating loading to cover all the cases being visited. A dynamic
file searches, file backups, directory removal, etc., by im- visitor, provided it operates on public data only, conforms
plementing a visitor for each function while reusing the to the open/closed principle (since it does not modify ex-
iteration code. tant structures) and to the single responsibility principle
(since it implements the Visitor pattern in a separate com-
ponent).
4.16.3 Details
Body, and Car), one visitor class (CarElementPrintVisi- to accept is bound at run time. This can be considered
tor) performs the required printing action. Because dif- * the *first* dispatch. However, the decision to call
ferent node subclasses require slightly different actions * visit(Wheel) (as opposed to visit(Engine) etc.) can
to print properly, CarElementPrintVisitor dispatches ac- be * made during compile time since 'this’ is known
tions based on the class of the argument passed to its visit at compile * time to be a Wheel. Moreover, each
method. CarElementDoVisitor, which is analogous to a implementation of * CarElementVisitor implements the
save operation for a different file format, does likewise. visit(Wheel), which is * another decision that is made
at run time. This can be * considered the *second*
dispatch. */ visitor.visit(this); } } class CarElement-
Diagram DoVisitor implements CarElementVisitor { public void
visit(final Body body) { System.out.println(“Moving
my body”); } public void visit(final Car car) { Sys-
tem.out.println(“Starting my car”); } public void
visit(final Wheel wheel) { System.out.println(“Kicking
my " + wheel.getName() + " wheel”); } public void
visit(final Engine engine) { System.out.println(“Starting
my engine”); } } class CarElementPrintVisitor imple-
ments CarElementVisitor { public void visit(final Body
body) { System.out.println(“Visiting body”); } public
void visit(final Car car) { System.out.println(“Visiting
car”); } public void visit(final Engine engine) {
System.out.println(“Visiting engine”); } public void
visit(final Wheel wheel) { System.out.println(“Visiting
" + wheel.getName() + " wheel”); } } public class Visi-
torDemo { public static void main(final String[] args) {
final Car car = new Car(); car.accept(new CarElement-
PrintVisitor()); car.accept(new CarElementDoVisitor());
}}
traverse (function object other-object)) (defmethod way to print-traverse (traverse (lambda (o) (print o
traverse (function (a auto) other-object) (with-slots *standard-output*)) a) ;; alternative way to do-something
(elements) a (dolist (e elements) (funcall function e with ;; elements of a and integer 42 (traverse (lambda
other-object)))) ;; do-something visitations ;; catch all (o) (do-something o 42)) a)
(defmethod do-something (object other-object) (format
t “don't know how ~s and ~s should interact~%" object Now, the multiple dispatch occurs in the call issued from
other-object)) ;; visitation involving wheel and integer the body of the anonymous function, and so traverse is
(defmethod do-something ((object wheel) (other-object just a mapping function that distributes a function ap-
integer)) (format t “kicking wheel ~s ~s times~%" object
plication over the elements of an object. Thus all traces
other-object)) ;; visitation involving wheel and symbol of the Visitor Pattern disappear, except for the mapping
(defmethod do-something ((object wheel) (other-object
function, in which there is no evidence of two objects be-
symbol)) (format t “kicking wheel ~s symbolically ing involved. All knowledge of there being two objects
using symbol ~s~%" object other-object)) (defmethod
and a dispatch on their types is in the lambda function.
do-something ((object engine) (other-object integer))
(format t “starting engine ~s ~s times~%" object other-
object)) (defmethod do-something ((object engine) 4.16.8 Related design patterns
(other-object symbol)) (format t “starting engine ~s
symbolically using symbol ~s~%" object other-object)) • Command pattern – encapsulates like the visitor pat-
(let ((a (make-instance 'auto :elements `(,(make-instance tern one or more functions in an object to present
'wheel :name “front-left-wheel”) ,(make-instance 'wheel them to a caller; unlike the visitor, this pattern does
:name “front-right-wheel”) ,(make-instance 'wheel not enclose a principle to traverse the object struc-
:name “rear-left-wheel”) ,(make-instance 'wheel :name ture
“rear-right-wheel”) ,(make-instance 'body :name “body”)
,(make-instance 'engine :name “engine”))))) ;; traverse • Iterator pattern – defines a traversal principle like the
to print elements ;; stream *standard-output* plays the visitor pattern, without making a type differentiation
role of other-object here (traverse #'print a *standard- within the traversed objects
output*) (terpri) ;; print newline ;; traverse with arbitrary
context from other object (traverse #'do-something a
42) ;; traverse with arbitrary context from other object
4.16.9 See also
(traverse #'do-something a 'abc)) • Algebraic data type
• Double dispatch
Output • Multiple dispatch
Concurrency patterns
In software engineering, concurrency patterns are those • ScaleConf Presentation about concurrency patterns
types of design patterns that deal with the multi-threaded
programming paradigm. Examples of this class of pat-
Recordings about concurrency patterns from Software
terns include:
Engineering Radio:
• Active Object[1][2]
• Episode 12: Concurrency Pt. 1
• Balking pattern
• Barrier • Episode 19: Concurrency Pt. 2
[2] R. Greg Lavender, Doublas C Scmidt (1995). “Active Ob- • A callback or variable for the client to receive the
ject” (PDF). Retrieved 2010-06-17. result.
88
5.3. BALKING PATTERN 89
5.2.1 Example [2] Bass, L., Clements, P., Kazman, R. Software Architecture
in Practice. Addison Wesley, 2003
Java
[3] Lavender, R. Greg; Schmidt, Douglas C. “Active Object”
[4] (PDF). Retrieved 2007-02-02.
An example of active object pattern in Java.
class OriginalClass { private double val = 0.0; void [4] Holub, Allen. “Java Active Objects - A Proposal”. Re-
doSomething() { val = 1.0; } void doSomethingElse() trieved 2014-06-16.
{ val = 2.0; } } class BecomeActiveObject { private
double val = 0.0; private BlockingQueue<Runnable> dis-
patchQueue = new LinkedBlockingQueue<Runnable>();
5.2.4 External links
public BecomeActiveObject() { new Thread (new
• Active Object implementation in C++11
Runnable() { @Override public void run() { while(true)
{ try { dispatchQueue.take().run(); } catch (Interrupt-
edException e) { // okay, just terminate the dispatcher
} } } } ).start(); } // void doSomething() throws Inter- 5.3 Balking pattern
ruptedException { dispatchQueue.put(new Runnable()
{ @Override public void run() { val = 1.0; } } ); } // The balking pattern is a software design pattern that
void doSomethingElse() throws InterruptedException { only executes an action on an object when the object is
dispatchQueue.put(new Runnable() { @Override public in a particular state. For example, if an object reads ZIP
void run() { val = 2.0; } } ); } } files and a calling method invokes a get method on the ob-
ject when the ZIP file is not open, the object would “balk”
at the request. In the Java programming language, for ex-
ample, an IllegalStateException might be thrown under
Java 8 (alternative) these circumstances.
Another example of active object pattern in Java. There are some specialists in this field who consider balk-
ing more of an anti-pattern than a design pattern. If an
public class AnotherActiveObject { private double object cannot support its API, it should either limit the
val; // container for tasks // decides which request to API so that the offending call is not available, or so that
execute next // asyncMode=true means our worker the call can be made without limitation it should:
thread processes its local task queue in the FIFO
order // only single thread may modify internal state
private final ForkJoinPool fj = new ForkJoinPool(1, • Be created in a “sane state”
ForkJoinPool.defaultForkJoinWorkerThreadFactory, • Not make itself available until it is in a sane state
null, true); // implementation of active object method
public void doSomething() throws InterruptedException • Become a facade and answer back an object that is
{ fj.execute(() -> {val = 1.0;}); } // implementation of in a sane state
active object method public void doSomethingElse()
throws InterruptedException { fj.execute(() -> {val =
2.0;}); } } 5.3.1 Usage
Objects that use this pattern are generally only in a state
that is prone to balking temporarily but for an unknown
5.2.2 See also amount of time. If objects are to remain in a state which
is prone to balking for a known, finite period of time, then
• Concurrent object-oriented programming the guarded suspension pattern may be preferred.
• Actor model
5.3.2 Implementation
• Futures and promises
public class Example { private boolean jobInProgress = sponds with a message or fault and the consumer re-
false; public void job() { synchronized(this) { if (jobIn- sponds with a status.
Progress) { return; } jobInProgress = true; } // Code
to execute job goes here // ... } void jobCompleted() { 4. In-Optional-Out: A standard two-way message ex-
synchronized(this) { jobInProgress = false; } } } change where the provider’s response is optional.
• Read and write lock pattern 6. Robust Out-Only: Similar to the out-only pattern,
except it can trigger a fault message. The outbound
• Guarded suspension pattern message initiates the transmission.
[1] Grand, Mark (2002). Patterns in Java, Volume 1: A Cata- 8. Out-Optional-In: The reverse of In-Optional-Out.
log of Reusable Design Patterns Illustrated with UML, Sec- The service produces an outbound message. The in-
ond Edition. Indianapolis, Ind: John Wiley & Sons. coming message is optional (“Optional-in”).
The term “Message Exchange Pattern” has a specific • Exclusive pair connects two sockets in an exclu-
meaning within the Simple Object Access protocol sive pair. This is a low-level pattern for specific, ad-
(SOAP).[2][3] SOAP MEP types include: vanced use cases.
1. In-Only: This is equivalent to one-way. A standard Each pattern defines a particular network topology.
one-way messaging exchange where the consumer Request-reply defines so-called “service bus”, publish-
sends a message to the provider that provides only a subscribe defines “data distribution tree”, push-pull de-
status response. fines “parallelised pipeline”. All the patterns are deliber-
ately designed in such a way as to be infinitely scalable
2. Robust In-Only: This pattern is for reliable one- and thus usable on Internet scale.[5]
way message exchanges. The consumer initiates
with a message to which the provider responds with
status. If the response is a status, the exchange is 5.4.3 See also
complete, but if the response is a fault, the consumer
must respond with a status. • Push technology
3. In-Out: This is equivalent to request–response. A • Distributed data flow
standard two-way message exchange where the con-
sumer initiates with a message, the provider re- • Enterprise Integration Patterns
5.5. DOUBLE-CHECKED LOCKING 91
5.4.4 References If one wished to use this idiom in C++11 (For instance
with Visual Studio 2013 because lack of “Magic statics”
[3]
[1] Erl, Thomas (2005). Service Oriented Architecture: Con- ) they should use acquire and release fences:[4]
cepts, Technology, and Design. Indiana: Pearson Educa-
tion. p. 171. ISBN 0-13-185858-0. std::atomic<Singleton*> Singleton::m_instance;
std::mutex Singleton::m_mutex; Singleton*
[2] http://www.w3.org/TR/soap12-part1/#soapmep SOAP Singleton::getInstance() { Singleton* tmp =
MEPs in SOAP W3C Recommendation v1.2 m_instance.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);
[3] Web Services Description Language (WSDL) Version if (tmp == nullptr) { std::lock_guard<std::mutex>
2.0: Additional MEPs
lock(m_mutex); tmp =
[4] ØMQ User Guide m_instance.load(std::memory_order_relaxed);
if (tmp == nullptr) { tmp = new Singleton;
[5] Scalability Layer Hits the Internet Stack std::atomic_thread_fence(std::memory_order_release);
m_instance.store(tmp, std::memory_order_relaxed); } }
return tmp; }
5.4.5 External links
• Enterprise Integration Patterns - Pattern Catalog Consider, for example, this code segment in the Java pro-
gramming language as given by [2] (as well as all other
Java code segments):
5.5 Double-checked locking // Single-threaded version class Foo { private Helper
helper; public Helper getHelper() { if (helper == null)
In software engineering, double-checked locking (also { helper = new Helper(); } return helper; } // other
known as “double-checked locking optimization”[1] ) is a functions and members... }
software design pattern used to reduce the overhead of
acquiring a lock by first testing the locking criterion (the The problem is that this does not work when using multi-
“lock hint”) without actually acquiring the lock. Only if ple threads. A lock must be obtained in case two threads
the locking criterion check indicates that locking is re- call getHelper() simultaneously. Otherwise, either they
quired does the actual locking logic proceed. may both try to create the object at the same time, or
The pattern, when implemented in some lan- one may wind up getting a reference to an incompletely
guage/hardware combinations, can be unsafe. At initialized object.
times, it can be considered an anti-pattern.[2] The lock is obtained by expensive synchronizing, as is
It is typically used to reduce locking overhead when im- shown in the following example.
plementing "lazy initialization" in a multi-threaded envi- // Correct but possibly expensive multithreaded version
ronment, especially as part of the Singleton pattern. Lazy class Foo { private Helper helper; public synchronized
initialization avoids initializing a value until the first time Helper getHelper() { if (helper == null) { helper =
it is accessed. new Helper(); } return helper; } // other functions and
members... }
Singleton& instance() { static Singleton s; return s; } 1. Check that the variable is initialized (without obtain-
ing the lock). If it is initialized, return it immedi-
92 CHAPTER 5. CONCURRENCY PATTERNS
// Broken multithreaded version // “Double-Checked Note the local variable result, which seems unnecessary.
Locking” idiom class Foo { private Helper helper; public The effect of this is that in cases where helper is already
Helper getHelper() { if (helper == null) { synchro- initialized (i.e., most of the time), the volatile field is only
nized(this) { if (helper == null) { helper = new Helper(); accessed once (due to “return result;" instead of “return
} } } return helper; } // other functions and members... } helper;"), which can improve the method’s overall perfor-
mance by as much as 25 percent.[7]
Intuitively, this algorithm seems like an efficient solution If the helper object is static (one per class loader), an al-
to the problem. However, this technique has many subtle ternative is the initialization-on-demand holder idiom[8]
problems and should usually be avoided. For example, (See Listing 16.6[9] from the previously cited text.)
consider the following sequence of events: // Correct lazy initialization in Java class Foo { private
static class HelperHolder { public static final Helper
1. Thread A notices that the value is not initialized, so helper = new Helper(); } public static Helper getHelper()
it obtains the lock and begins to initialize the value. { return HelperHolder.helper; } }
2. Due to the semantics of some programming lan-
guages, the code generated by the compiler is al- This relies on the fact that nested classes are not loaded
lowed to update the shared variable to point to a par- until they are referenced.
tially constructed object before A has finished per-
Semantics of final field in Java 5 can be employed to safely
forming the initialization. For example, in Java if a
publish the helper object without using volatile:[10]
call to a constructor has been inlined then the shared
variable may immediately be updated once the stor- public class FinalWrapper<T> { public final T value;
age has been allocated but before the inlined con- public FinalWrapper(T value) { this.value = value; }
structor initializes the object.[6] } public class Foo { private FinalWrapper<Helper>
helperWrapper; public Helper getHelper() { Final-
3. Thread B notices that the shared variable has been Wrapper<Helper> tempWrapper = helperWrapper;
initialized (or so it appears), and returns its value. if (tempWrapper == null) { synchronized(this) { if
Because thread B believes the value is already ini- (helperWrapper == null) { helperWrapper = new Fi-
tialized, it does not acquire the lock. If B uses the nalWrapper<Helper>(new Helper()); } tempWrapper =
object before all of the initialization done by A is helperWrapper; } } return tempWrapper.value; } }
seen by B (either because A has not finished initial-
izing it or because some of the initialized values in
the object have not yet percolated to the memory The local variable tempWrapper is required for correct-
B uses (cache coherence)), the program will likely ness: simply using helperWrapper for both null checks
crash. and the return statement could fail due to read reordering
allowed under the Java Memory Model.[11] Performance
One of the dangers of using double-checked locking in of this implementation is not necessarily better than the
J2SE 1.4 (and earlier versions) is that it will often appear volatile implementation.
to work: it is not easy to distinguish between a correct
implementation of the technique and one that has sub-
tle problems. Depending on the compiler, the interleav- 5.5.3 Usage in Microsoft .NET (Visual Ba-
ing of threads by the scheduler and the nature of other sic, C#)
concurrent system activity, failures resulting from an in-
correct implementation of double-checked locking may Double-checked locking can be implemented efficiently
only occur intermittently. Reproducing the failures can in .NET. A common usage pattern is to add double-
be difficult. checked locking to Singleton implementations:
As of J2SE 5.0, this problem has been fixed. The volatile public class MySingleton { private static object myLock
keyword now ensures that multiple threads handle the sin- = new object(); private static volatile MySingleton
gleton instance correctly. This new idiom is described in mySingleton = null; // 'volatile' is unnecessary in .NET
and . 2.0 and later private MySingleton() { } public static
5.5. DOUBLE-CHECKED LOCKING 93
MySingleton GetInstance() { if (mySingleton == null) { [6] Haggar, Peter (1 May 2002). “Double-checked locking
// 1st check lock (myLock) { if (mySingleton == null) { and the Singleton pattern”. IBM.
// 2nd (double) check mySingleton = new MySingleton();
// In .NET 1.1, write-release semantics are implicitly [7] Joshua Bloch “Effective Java, Second Edition”, p. 283-
handled by marking mySingleton with // 'volatile', which 284
inserts the necessary memory barriers between the
constructor call // and the write to mySingleton. The [8] Brian Goetz et al. Java Concurrency in Practice, 2006
barriers created by the lock are not sufficient // because pp348
the object is made visible before the lock is released. In
.NET 2.0 and later, // the lock is sufficient and 'volatile' [9] Goetz, Brian; et al. “Java Concurrency in Practice – list-
is not needed. } } } // In .NET 1.1, the barriers created ings on website”. Retrieved 21 October 2014.
by the lock are not sufficient because not all threads will
// acquire the lock. A fence for read-acquire semantics [10] Javamemorymodel-discussion mailing list
is needed between the test of mySingleton // (above)
and the use of its contents.This fence is automatically [11] Manson, Jeremy. “Date-Race-Ful Lazy Initialization for
inserted because mySingleton is // marked as 'volatile'. Performance – Java Concurrency (&c)". Retrieved 3 De-
// In .NET 2.0 and later, 'volatile' is not required. return cember 2016.
mySingleton; } }
[12] Albahari, Joseph (2010). “Threading in C#: Using
Threads”. C# 4.0 in a Nutshell. O'Reilly Media. ISBN 0-
In this example, the “lock hint” is the mySingleton object 596-80095-9. Lazy<T> actually implements […] double-
which is no longer null when fully constructed and ready checked locking. Double-checked locking performs an
for use. additional volatile read to avoid the cost of obtaining a
In .NET Framework 4.0, the Lazy<T> class was intro- lock if the object is already initialized.
duced, which internally uses double-checked locking by
default (ExecutionAndPublication mode) to store either
the exception that was thrown during construction, or the 5.5.6 External links
result of the function that was passed to Lazy<T>:[12]
public class MySingleton { private static read- • Issues with the double checked locking mechanism
only Lazy<MySingleton> _mySingleton = new captured in Jeu George’s Blogs Pure Virtuals
Lazy<MySingleton>(() => new MySingleton()); private
MySingleton() { } public static MySingleton Instance { • “Double Checked Locking” Description from the
get { return _mySingleton.Value; } } } Portland Pattern Repository
5.6.3 References
.NET Framework
[1] “Asynchronous Method Invocation”. Distributed Pro-
gramming with Ice. ZeroC, Inc. Archived from the origi-
• Asynchronous Programming Model (APM) pattern
nal on 5 January 2008. Retrieved 22 November 2008.
(used before .NET Framework 2.0)[6]
[2] Vermeulen, Allan (June 1996). “An Asynchronous De-
• Event-based Asynchronous Pattern (EAP) (used in sign Pattern”. Dr. Dobb’s Journal. Retrieved 22 Novem-
.NET Framework 2.0)[7] ber 2008.
5.7. GUARDED SUSPENSION 95
[3] Nash, Trey (2007). “Threading in C#". Accelerated C# 5.7 Guarded suspension
2008. Apress. ISBN 978-1-59059-873-3.
In concurrent programming, guarded suspension[1] is a
[4] Lavender, R. Greg; Douglas C. Schmidt. “Active Object”
(PDF). Retrieved 22 November 2008.
software design pattern for managing operations that re-
quire both a lock to be acquired and a precondition to
[5] “Class FutureTask”. Oracle. 2011. Retrieved 2015-06- be satisfied before the operation can be executed. The
29. guarded suspension pattern is typically applied to method
calls in object-oriented programs, and involves suspend-
[6] “Asynchronous Programming Model”. Microsoft. 2015. ing the method call, and the calling thread, until the pre-
Retrieved 2015-06-29. condition (acting as a guard) is satisfied.
• lock contention: this occurs whenever one process There are mechanisms employed to manage the actions
or thread attempts to acquire a lock held by another of multiple concurrent users on a database—the purpose
process or thread. The more fine-grained the avail- is to prevent lost updates and dirty reads. The two types
able locks, the less likely one process/thread will re- of locking are pessimistic locking and optimistic locking:
quest a lock held by the other. (For example, locking
a row rather than the entire table, or locking a cell • Pessimistic locking: a user who reads a record, with
rather than the entire row.); the intention of updating it, places an exclusive lock
on the record to prevent other users from manipulat-
• deadlock: the situation when each of at least two ing it. This means no one else can manipulate that
tasks is waiting for a lock that the other task holds. record until the user releases the lock. The down-
Unless something is done, the two tasks will wait side is that users can be locked out for a very long
forever. time, thereby slowing the overall system response
and causing frustration.
There is a tradeoff between decreasing lock overhead and
decreasing lock contention when choosing the number of Where to use pessimistic locking:
locks in synchronization. this is mainly used in environments
An important property of a lock is its granularity. The where data-contention (the degree
granularity is a measure of the amount of data the lock of users request to the database
is protecting. In general, choosing a coarse granularity (a system at any one time) is heavy;
small number of locks, each protecting a large segment of where the cost of protecting data
data) results in less lock overhead when a single process through locks is less than the cost of
is accessing the protected data, but worse performance rolling back transactions, if concur-
when multiple processes are running concurrently. This rency conflicts occur. Pessimistic
is because of increased lock contention. The more coarse concurrency is best implemented
the lock, the higher the likelihood that the lock will stop when lock times will be short,
an unrelated process from proceeding. Conversely, using as in programmatic processing of
a fine granularity (a larger number of locks, each pro- records. Pessimistic concurrency
tecting a fairly small amount of data) increases the over- requires a persistent connection to
head of the locks themselves but reduces lock contention. the database and is not a scalable
Granular locking where each process must hold multiple option when users are interacting
locks from a common set of locks can create subtle lock with data, because records might be
dependencies. This subtlety can increase the chance that locked for relatively large periods
a programmer will unknowingly introduce a deadlock. of time. It is not appropriate for use
in Web application development.
In a database management system, for example, a lock
could protect, in order of decreasing granularity, part of • Optimistic locking: this allows multiple concurrent
a field, a field, a record, a data page, or an entire table. users access to the database whilst the system keeps
Coarse granularity, such as using table locks, tends to give a copy of the initial-read made by each user. When a
the best performance for a single user, whereas fine gran- user wants to update a record, the application deter-
ularity, such as record locks, tends to give the best per- mines whether another user has changed the record
formance for multiple users. since it was last read. The application does this by
comparing the initial-read held in memory to the
database record to verify any changes made to the
5.8.3 Database locks
record. Any discrepancies between the initial-read
and the database record violates concurrency rules
Main article: Lock (database)
and hence causes the system to disregard any up-
date request. An error message is generated and
Database locks can be used as a means of ensuring trans- the user is asked to start the update process again.
action synchronicity. i.e. when making transaction pro- It improves database performance by reducing the
cessing concurrent (interleaving transactions), using 2- amount of locking required, thereby reducing the
phased locks ensures that the concurrent execution of the load on the database server. It works efficiently with
transaction turns out equivalent to some serial ordering tables that require limited updates since no users are
of the transaction. However, deadlocks become an un- locked out. However, some updates may fail. The
fortunate side-effect of locking in databases. Deadlocks downside is constant update failures due to high vol-
are either prevented by pre-determining the locking or- umes of update requests from multiple concurrent
der between transactions or are detected using waits-for users - it can be frustrating for users.
graphs. An alternate to locking for database synchronic-
ity while avoiding deadlocks involves the use of totally Where to use optimistic lock-
ordered global timestamps. ing: this is appropriate in envi-
98 CHAPTER 5. CONCURRENCY PATTERNS
ronments where there is low con- • Convoying: all other threads have to wait if a thread
tention for data, or where read-only holding a lock is descheduled due to a time-slice in-
access to data is required. Op- terrupt or page fault.
timistic concurrency is used ex-
tensively in .NET to address the Some concurrency control strategies avoid some or all
needs of mobile and disconnected of these problems. For example, a funnel or serializing
applications,[4] where locking data tokens can avoid the biggest problem: deadlocks. Al-
rows for prolonged periods of time ternatives to locking include non-blocking synchroniza-
would be infeasible. Also, main- tion methods, like lock-free programming techniques and
taining record locks requires a per- transactional memory. However, such alternative meth-
sistent connection to the database ods often require that the actual lock mechanisms be im-
server, which is not possible in dis- plemented at a more fundamental level of the operating
connected applications. software. Therefore, they may only relieve the applica-
tion level from the details of implementing locks, with
the problems listed above still needing to be dealt with
5.8.4 Disadvantages beneath the application.
In most cases, proper locking depends on the CPU pro-
Lock-based resource protection and thread/process syn- viding a method of atomic instruction stream synchro-
chronization have many disadvantages: nization (for example, the addition or deletion of an item
into a pipeline requires that all contemporaneous opera-
• Contention: some threads/processes have to wait tions needing to add or delete other items in the pipe be
until a lock (or a whole set of locks) is released. If suspended during the manipulation of the memory con-
one of the threads holding a lock dies, stalls, blocks, tent required to add or delete the specific item). There-
or enters an infinite loop, other threads waiting for fore, an application can often be more robust when it rec-
the lock may wait forever. ognizes the burdens it places upon an operating system
and is capable of graciously recognizing the reporting of
• Overhead: the use of locks adds overhead for each impossible demands.
access to a resource, even when the chances for col-
lision are very rare. (However, any chance for such Lack of composability
collisions is a race condition.)
One of lock-based programming’s biggest problems is
• Debugging: bugs associated with locks are time de- that “locks don't compose": it is hard to combine small,
pendent and can be very subtle and extremely hard correct lock-based modules into equally correct larger
to replicate, such as deadlocks. programs without modifying the modules or at least
knowing about their internals. Simon Peyton Jones (an
• Instability: the optimal balance between lock over- advocate of software transactional memory) gives the fol-
head and lock contention can be unique to the prob- lowing example of a banking application:[5] design a class
lem domain (application) and sensitive to design, Account that allows multiple concurrent clients to deposit
implementation, and even low-level system architec- or withdraw money to an account; and give an algorithm
tural changes. These balances may change over the to transfer money from one account to another. The lock-
life cycle of an application and may entail tremen- based solution to the first part of the problem is:
dous changes to update (re-balance).
class Account: member balance : Integer member mu-
• Composability: locks are only composable (e.g., tex : Lock method deposit(n : Integer) mutex.lock() bal-
managing multiple concurrent locks in order to ance ← balance + n mutex.unlock() method withdraw(n
atomically delete item X from table A and insert : Integer) deposit(−n)
X into table B) with relatively elaborate (overhead) The second part of the problem is much more compli-
software support and perfect adherence by applica- cated. A transfer routine that is correct for sequential
tions programming to rigorous conventions. programs would be
locks on both account prior to changing any of the two ac- • x86 assembly provides the LOCK prefix on certain
counts, but then the locks have to be taken according to operations to guarantee their atomicity.
some arbitrary, global ordering to prevent deadlock:
• PHP provides a file based locking [18] as well as a
function transfer(from : Account, to : Account, Mutex class in the pthreads extension. [19]
amount : integer) if from < to // arbitrary order-
ing on the locks from.lock() to.lock() else to.lock()
from.lock() from.withdraw(amount) to.deposit(amount) 5.8.6 See also
from.unlock() to.unlock()
• Critical section
This solution gets more complicated when more locks are
involved, and the transfer function needs to know about • Double-checked locking
all of the locks, so they cannot be hidden.
• File locking
• Monitor (synchronization)
See also: Barrier (computer science)
• Mutual exclusion
Programming languages vary in their support for synchro- • Read/write lock pattern
nization:
• Semaphore (programming)
• The ISO/IEC C standard provides a standard mutual
exclusion (locks) API since C11. The current
5.8.7 References
ISO/IEC C++ standard supports threading facilities
since C++11. The OpenMP standard is supported [1] “lock Statement (C# Reference)".
by some compilers, and allows critical sections to
be specified using pragmas. The POSIX pthread [2] “ThreadPoolPriority, and MethodImplAttribute”. http:
API provides lock support.[6] Visual C++ provides //msdn.microsoft.com/en-us/magazine/cc163896.aspx:
the synchronize attribute of methods to be synchro- MSDN. p. ??. Retrieved 2011-11-22.
nized, but this is specific to COM objects in the [3] “C# From a Java Developer’s Perspective”. http://www.
Windows architecture and Visual C++ compiler.[7] 25hoursaday.com/CsharpVsJava.html#attributes. Re-
C and C++ can easily access any native operating trieved 2011-11-22.
system locking features.
[4] “Designing Data Tier Components and Passing Data
• Objective-C provides the keyword Through Tiers”. Microsoft. August 2002. Retrieved
@synchronized[8] to put locks on blocks of 2008-05-30.
code and also provides the classes NSLock,[9]
[5] Peyton Jones, Simon (2007). “Beautiful concurrency”
NSRecursiveLock,[10] and NSConditionLock[11] (PDF). In Wilson, Greg; Oram, Andy. Beautiful Code:
along with the NSLocking protocol[12] for locking Leading Programmers Explain How They Think. O'Reilly.
as well.
[6] Marshall, Dave (March 1999). “Mutual Exclusion
• C# provides the lock keyword on a thread to ensure Locks”. Retrieved 2008-05-30.
its exclusive access to a resource.
[7] “Synchronize”. msdn.microsoft.com. Retrieved 2008-
• VB.NET provides a SyncLock keyword like C#'s 05-30.
lock keyword. [8] “Apple Threading Reference”. Apple, inc. Retrieved
2009-10-17.
• Java provides the keyword synchronized to lock
code blocks, methods or objects[13] and libraries fea- [9] “NSLock Reference”. Apple, inc. Retrieved 2009-10-17.
turing concurrency-safe data structures.
[10] “NSRecursiveLock Reference”. Apple, inc. Retrieved
• Python provides a low-level mutex mechanism with- 2009-10-17.
out a keyword.[14]
[11] “NSConditionLock Reference”. Apple, inc. Retrieved
• Ruby provides a low-level mutex object and no 2009-10-17.
keyword.[15] [12] “NSLocking Protocol Reference”. Apple, inc. Retrieved
2009-10-17.
• Ada provides protected objects that have visible
protected subprograms or entries[16] as well as [13] “Synchronization”. Sun Microsystems. Retrieved 2008-
rendezvous.[17] 05-30.
100 CHAPTER 5. CONCURRENCY PATTERNS
[14] Lundh, Fredrik (July 2007). “Thread Synchronization 5.9.1 Mutual exclusion
Mechanisms in Python”. Retrieved 2008-05-30.
As a simple example, consider a thread-safe object for
[15] “Programming Ruby: Threads and Processes”. 2001. Re- performing transactions on a bank account:
trieved 2008-05-30.
monitor class Account { private int balance := 0 in-
[16] ISO/IEC 8652:2007. “Protected Units and Protected Ob- variant balance >= 0 public method boolean with-
jects”. Ada 2005 Reference Manual. Retrieved 2010-02- draw(int amount) precondition amount >= 0 { if bal-
27. A protected object provides coordinated access to ance < amount { return false } else { balance := bal-
shared data, through calls on its visible protected opera- ance - amount return true } } public method deposit(int
tions, which can be protected subprograms or protected amount) precondition amount >= 0 { balance := balance
entries. + amount } }
[17] ISO/IEC 8652:2007. “Example of Tasking and Synchro- While a thread is executing a method of a thread-safe ob-
nization”. Ada 2005 Reference Manual. Retrieved 2010- ject, it is said to occupy the object, by holding its mutex
02-27. (lock). Thread-safe objects are implemented to enforce
that at each point in time, at most one thread may occupy
[18] http://php.net/manual/en/function.flock.php. Missing or the object. The lock, which is initially unlocked, is locked
empty |title= (help) at the start of each public method, and is unlocked at each
return from each public method.
[19] http://php.net/manual/en/class.mutex.php. Missing or
empty |title= (help) Upon calling one of the methods, a thread must wait un-
til no other thread is executing any of the thread-safe ob-
ject’s methods before starting execution of its method.
5.8.8 External links Note that without this mutual exclusion, in the present
example, two threads could cause money to be lost or
gained for no reason. For example, two threads with-
• Tutorial on Locks and Critical Sections
drawing 1000 from the account could both return true,
while causing the balance to drop by only 1000, as fol-
lows: first, both threads fetch the current balance, find it
5.9 Monitor greater than 1000, and subtract 1000 from it; then, both
threads store the balance and return.
In concurrent programming, a monitor is a synchroniza- The syntactic sugar “monitor class” in the above example
tion construct that allows threads to have both mutual ex- is implementing the following basic representation of the
clusion and the ability to wait (block) for a certain con- code, by wrapping each function’s execution in mutexes:
dition to become true. Monitors also have a mechanism
class Account { private lock myLock private int bal-
for signalling other threads that their condition has been
ance := 0 invariant balance >= 0 public method boolean
met. A monitor consists of a mutex (lock) object and
withdraw(int amount) precondition amount >= 0 { my-
condition variables. A condition variable is basically
Lock.acquire() try { if balance < amount { return false
a container of threads that are waiting for a certain condi-
} else { balance := balance - amount return true } } fi-
tion. Monitors provide a mechanism for threads to tem-
nally { myLock.release() } } public method deposit(int
porarily give up exclusive access in order to wait for some
amount) precondition amount >= 0 { myLock.acquire()
condition to be met, before regaining exclusive access and
try { balance := balance + amount } finally { my-
resuming their task.
Lock.release() } } }
Another definition of monitor is a thread-safe class,
object, or module that uses wrapped mutual exclusion in
order to safely allow access to a method or variable by 5.9.2 Condition variables
more than one thread. The defining characteristic of a
monitor is that its methods are executed with mutual ex-
Problem statement
clusion: At each point in time, at most one thread may be
executing any of its methods. By using one or more con-
dition variables it can also provide the ability for threads For many applications, mutual exclusion is not enough.
to wait on a certain condition (thus using the above def- Threads attempting an operation may need to wait until
inition of a “monitor”). For the rest of this article, this some condition P holds true. A busy waiting loop
sense of “monitor” will be referred to as a “thread-safe while not( P ) do skip
object/class/module”. will not work, as mutual exclusion will prevent any other
Monitors were invented by Per Brinch Hansen[1] and C. thread from entering the monitor to make the condition
A. R. Hoare,[2] and were first implemented in Brinch true. Other “solutions” exist such as having a loop that un-
Hansen’s Concurrent Pascal language.[3] locks the monitor, waits a certain amount of time, locks
5.9. MONITOR 101
the monitor and check for the condition P. Theoretically, threads’ accesses to the queue. The queue.enqueue and
it works and will not deadlock, but issues arise. It’s hard to queue.dequeue methods likely have instructions to up-
decide an appropriate amount of waiting time, too small date the queue’s member variables such as its size, begin-
and the thread will hog the CPU, too big and it will be ning and ending positions, assignment and allocation of
apparently unresponsive. What is needed is a way to sig- queue elements, etc. In addition, the queue.isEmpty() and
nal the thread when the condition P is true (or could be queue.isFull() methods read this shared state as well. If
true). producer/consumer threads are allowed to be interleaved
during the calls to enqueue/dequeue, then inconsistent
state of the queue can be exposed leading to race con-
Case study: classic bounded producer/consumer ditions. In addition, if one consumer makes the queue
problem empty in-between another consumer’s exiting the busy-
wait and calling “dequeue”, then the second consumer
A classic concurrency problem is that of the bounded will attempt to dequeue from an empty queue leading to
producer/consumer, in which there is a queue or ring an error. Likewise, if a producer makes the queue full
buffer of tasks with a maximum size, with one or more in-between another producer’s exiting the busy-wait and
threads being “producer” threads that add tasks to the calling “enqueue”, then the second producer will attempt
queue, and one or more other threads being “consumer” to add to a full queue leading to an error.
threads that take tasks out of the queue. The queue is as-
sumed to be non–thread-safe itself, and it can be empty,
full, or between empty and full. Whenever the queue is Spin-waiting One naive approach to achieve synchro-
full of tasks, then we need the producer threads to block nization, as alluded to above, is to use "spin-waiting", in
until there is room from consumer threads dequeueing which a mutex is used to protect the critical sections of
tasks. On the other hand, whenever the queue is empty, code and busy-waiting is still used, with the lock being
then we need the consumer threads to block until more acquired and released in between each busy-wait check.
tasks are available due to producer threads adding them.
global RingBuffer queue; // A thread-unsafe ring-buffer
As the queue is a concurrent object shared between of tasks. global Lock queueLock; // A mutex for
threads, accesses to it must be made atomic, because the ring-buffer of tasks. // Method representing each
the queue can be put into an inconsistent state dur- producer thread’s behavior: public method producer(){
ing the course of the queue access that should never while(true){ task myTask=...; // Producer makes some
be exposed between threads. Thus, any code that ac- new task to be added. queueLock.acquire(); // Acquire
cesses the queue constitutes a critical section that must lock for initial busy-wait check. while(queue.isFull()){
be synchronized by mutual exclusion. If code and pro- // Busy-wait until the queue is non-full. queue-
cessor instructions in critical sections of code that ac- Lock.release(); // Drop the lock temporarily to allow a
cess the queue could be interleaved by arbitrary context chance for other threads // needing queueLock to run so
switches between threads on the same processor or by that a consumer might take a task. queueLock.acquire();
simultaneously-running threads on multiple processors, // Re-acquire the lock for the next call to “queue.isFull()".
then there is a risk of exposing inconsistent state and caus- } queue.enqueue(myTask); // Add the task to the queue.
ing race conditions. queueLock.release(); // Drop the queue lock until we
need it again to add the next task. } } // Method
representing each consumer thread’s behavior: public
Incorrect without synchronization A naïve approach method consumer(){ while(true){ queueLock.acquire();
is to design the code with busy-waiting and no synchro-
// Acquire lock for initial busy-wait check. while
nization, making the code subject to race conditions: (queue.isEmpty()){ // Busy-wait until the queue is
global RingBuffer queue; // A thread-unsafe ring-buffer non-empty. queueLock.release(); // Drop the lock
of tasks. // Method representing each producer thread’s temporarily to allow a chance for other threads // needing
behavior: public method producer(){ while(true){ task queueLock to run so that a producer might add a task.
myTask=...; // Producer makes some new task to be queueLock.acquire(); // Re-acquire the lock for the next
added. while(queue.isFull()){} // Busy-wait until the call to “queue.isEmpty()". } myTask=queue.dequeue();
queue is non-full. queue.enqueue(myTask); // Add the // Take a task off of the queue. queueLock.release(); //
task to the queue. } } // Method representing each Drop the queue lock until we need it again to take off the
consumer thread’s behavior: public method consumer(){ next task. doStuff(myTask); // Go off and do something
while(true){ while (queue.isEmpty()){} // Busy-wait with the task. } }
until the queue is non-empty. myTask=queue.dequeue();
// Take a task off of the queue. doStuff(myTask); // Go This method assures that an inconsistent state does not
off and do something with the task. } } occur, but wastes CPU resources due to the unnecessary
busy-waiting. Even if the queue is empty and producer
This code has a serious problem in that accesses to threads have nothing to add for a long time, consumer
the queue can be interrupted and interleaved with other threads are always busy-waiting unnecessarily. Likewise,
102 CHAPTER 5. CONCURRENCY PATTERNS
even if consumers are blocked for a long time on pro- The atomicity of the operations within
cessing their current tasks and the queue is full, producers step 1 is important to avoid race condi-
are always busy-waiting. This is a wasteful mechanism. tions that would be caused by a preemp-
What is needed is a way to make producer threads block tive thread switch in-between them. One
until the queue is non-full, and a way to make consumer failure mode that could occur if these
threads block until the queue is non-empty. were not atomic is a missed wakeup, in
(N.B.: Mutexes themselves can also be spin-locks which which the thread could be on c's sleep-
involve busy-waiting in order to get the lock, but in order queue and have released the mutex, but
a preemptive thread switch occurred be-
to solve this problem of wasted CPU resources, we as-
sume that queueLock is not a spin-lock and properly uses fore the thread went to sleep, and an-
other thread called a signal/notify oper-
a blocking lock queue itself.)
ation (see below) on c moving the first
thread back out of c's queue. As soon
Condition variables as the first thread in question is switched
back to, its program counter will be at
The solution is to use condition variables. Conceptually step 1c, and it will sleep and be unable to
a condition variable is a queue of threads, associated with be woken up again, violating the invari-
a monitor, on which a thread may wait for some condition ant that it should have been on c's sleep-
to become true. Thus each condition variable c is associ- queue when it slept. Other race condi-
ated with an assertion P . While a thread is waiting on a tions depend on the ordering of steps 1a
condition variable, that thread is not considered to occupy and 1b, and depend on where a context
the monitor, and so other threads may enter the monitor switch occurs.
to change the monitor’s state. In most types of monitors,
these other threads may signal the condition variable c to • signal c, also known as notify c, is called by a thread
indicate that assertion P is true in the current state. to indicate that the assertion P is true. Depending
on the type and implementation of the monitor, this
Thus there are two main operations on condition vari- moves one or more threads from c’s sleep-queue to
ables: the “ready queue” or another queues for it to be exe-
cuted. It is usually considered a best practice to per-
• wait c, m, where c is a condition variable and m is form the “signal"/"notify” operation before releasing
a mutex (lock) associated with the monitor. This mutex m that is associated with c, but as long as the
operation is called by a thread that needs to wait un- code is properly designed for concurrency and de-
til the assertion P is true before proceeding. While pending on the threading implementation, it is often
the thread is waiting, it does not occupy the moni- also acceptable to release the lock before signalling.
tor. The function, and fundamental contract, of the Depending on the threading implementation, the or-
“wait” operation, is to do the following steps: dering of this can have scheduling-priority ramifica-
tions. (Some authors instead advocate a preference
1. Atomically: for releasing the lock before signalling.) A threading
(a) release the mutex m, implementation should document any special con-
(b) move this thread from the straints on this ordering.
“ready queue” to c's “wait- • broadcast c, also known as notifyAll c, is a
queue” (a.k.a. “sleep-queue”) similar operation that wakes up all threads in
of threads, and c’s wait-queue. This empties the wait-queue.
(c) sleep this thread. (Context Generally, when more than one predicate con-
is synchronously yielded to an- dition is associated with the same condition
other thread.) variable, the application will require broad-
2. Once this thread is subsequently noti- cast instead of signal because a thread wait-
fied/signalled (see below) and resumed, then ing for the wrong condition might be woken up
automatically re-acquire the mutex m. and then immediately go back to sleep without
waking up a thread waiting for the correct con-
Steps 1a and 1b can occur in either order, dition that just became true. Otherwise, if the
with 1c usually occurring after them. predicate condition is one-to-one with the con-
While the thread is sleeping and in c's dition variable associated with it, then signal
wait-queue, the next program counter to may be more efficient than broadcast.
be executed is at step 2, in the middle
of the “wait” function/subroutine. Thus, As a design rule, multiple condition variables can be as-
the thread sleeps and later wakes up in sociated with the same mutex, but not vice versa. (This
the middle of the “wait” operation. is a one-to-many correspondence.) This is because the
5.9. MONITOR 103
predicate P is the same for all threads using the moni- section, so you *MUST* // be holding the lock when
tor and must be protected with mutual exclusion from all executing this “while” loop condition! // If this is not
other threads that might cause the condition to be changed the first time the “while” condition is being checked,
or that might read it while the thread in question causes then we are asking the question, // “Now that another
it to be changed, but there may be different threads that thread using this monitor has notified me and woken
want to wait for a different condition on the same variable me up and I have been // context-switched back to, did
requiring the same mutex to be used. In the producer- the condition/predicate/assertion we are waiting on stay
consumer example described above, the queue must be true between // the time that I was woken up and the
protected by a unique mutex object, m. The “producer” time that I // re-acquired the lock inside the “wait” call
threads will want to wait on a monitor using lock m and in the last iteration of this loop, // or did some other
a condition variable cf ull which blocks until the queue is thread cause the condition to become false again in the
non-full. The “consumer” threads will want to wait on a meantime // thus making this a spurious wakeup? { // If
different monitor using the same mutex m but a different this is the first iteration of the loop, then the answer is
condition variable cempty which blocks until the queue is “no” -- the condition is not ready yet. // Otherwise, the
non-empty. It would (usually) never make sense to have answer is: the latter. This was a spurious wakeup, some
different mutexes for the same condition variable, but this other thread occurred first // and caused the condition to
classic example shows why it often certainly makes sense become false again, and we must wait again. wait(m, cv);
to have multiple condition variables using the same mu- // Temporarily prevent any other thread on any core from
tex. A mutex used by one or more condition variables doing operations on m or cv. // release(m) // Atomically
(one or more monitors) may also be shared with code that release lock “m” so other code using this concurrent data
does not use condition variables (and which simply ac- // // can operate, move this thread to cv’s wait-queue so
quires/releases it without any wait/signal operations), if that it will be notified // // sometime when the condition
those critical sections do not happen to require waiting becomes true, and sleep this thread. // // Re-enable other
for a certain condition on the concurrent data. threads and cores to do operations on m and cv. // //
Context switch occurs on this core. // // At some future
time, the condition we are waiting for becomes true,
Monitor usage // and another thread using this monitor (m, cv) does
either a signal/notify // that happens to wake this thread
The proper basic usage of a monitor is: up, or a notifyAll that wakes us up, meaning // that we
have been taken out of cv’s wait-queue. // // During this
acquire(m); // Acquire this monitor’s lock. while time, other threads may be switched to that caused the
(!p) { // While the condition/predicate/assertion that condition to become // false again, or the condition may
we are waiting for is not true... wait(m, cv); // Wait toggle one or more times, or it may happen to // stay
on this monitor’s lock and condition variable. } // true. // // This thread is switched back to on some core.
... Critical section of code goes here ... signal(cv2); // // acquire(m) // Lock “m” is re-acquired. // End this
-- OR -- notifyAll(cv2); // cv2 might be the same as loop iteration and re-check the “while” loop condition to
cv or different. release(m); // Release this monitor’s lock. make sure the predicate is // still true. } // The condition
we are waiting for is true! // We are still holding the lock,
To be more precise, this is the same pseudocode but with either from before entering the monitor or from the //
more verbose comments to better explain what is going last execution of “wait”. // Critical section of code goes
on: here, which has a precondition that our predicate // must
be true. // This code might make cv’s condition false,
// ... (previous code) // About to enter the monitor.
and/or make other condition variables’ // predicates true.
// Acquire the advisory mutex (lock) associated with
// Call signal/notify or notifyAll, depending on which
the concurrent data that is shared between threads,
condition variables’ predicates // (who share mutex m)
// to ensure that no two threads can be preemptively
have been made true or may have been made true, and
interleaved or run simultaneously on different cores //
the monitor semantic type // being used. for (cv_x in
while executing in critical sections that read or write this
cvs_to_notify){ notify(cv_x); -- OR -- notifyAll(cv_x);
same concurrent data. // If another thread is holding
} // One or more threads have been woken up but will
this mutex, then this thread will be sleeped (blocked)
block as soon as they try // to acquire m. // Release the
and placed on // m’s sleep queue. (Mutex “m” shall not
mutex so that notified thread(s) and others can enter //
be a spin-lock.) acquire(m); // Now, we are holding
their critical sections. release(m);
the lock and can check the condition for the first time.
// The first time we execute the while loop condition
after the above “acquire”, we are asking, // “Does the
condition/predicate/assertion we are waiting for happen
to already be true?" while ( ! p() ) // “p” is any expression Solving the bounded producer/consumer problem
(e.g. variable or function-call) that checks the condition Having introduced the usage of condition variables, let’s
// and evaluates to boolean. This itself is a critical use it to revisit and solve the classic bounded pro-
104 CHAPTER 5. CONCURRENCY PATTERNS
move and get the next thread to run from the ready threadSleep() for more efficiency so that this thread will
queue. currentThread=otherThread; // Replace the be sleeped // right after going on the condition-
global current-thread pointer value so it is ready for variable queue. systemCall_disableInterrupts();
the next thread. // Restore the registers from current- while (!c.waitingThreads.isEmpty()){ wo-
Thread/otherThread, including a jump to the stored PC kenThread=c.waitingThreads.dequeue();
of the other thread // (at “resume” below). Again, the readyQueue.enqueue(wokenThread); } threadingSys-
details of how this is done are beyond this scope. restor- temBusy=false; // Must be an atomic assignment.
eRegisters(otherThread.registers); // *** Now running systemCall_enableInterrupts(); // Turn pre-emptive
“otherThread” (which is now “currentThread”)! The switching back on on this core. // Mesa style: // The
original thread is now “sleeping”. *** resume: // This is woken threads are not given any priority. } class
where another contextSwitch() call needs to set PC to Mutex { protected volatile bool held=false; private
when switching context back here. // Return to where volatile ThreadQueue blockingThreads; // Thread-unsafe
otherThread left off. } public method wait(Mutex m, queue of blocked threads. Elements are (Thread*).
ConditionVariable c){ // Internal spin-lock while other public method acquire(){ // Internal spin-lock while
threads on any core are accessing this object’s // “held” other threads on any core are accessing this object’s
and “threadQueue”, or “readyQueue”. while (testAnd- // “held” and “threadQueue”, or “readyQueue”. while
Set(threadingSystemBusy)){} // N.B.: “threadingSys- (testAndSet(threadingSystemBusy)){} // N.B.: “thread-
temBusy” is now true. // System call to disable interrupts ingSystemBusy” is now true. // System call to disable
on this core so that threadSleep() doesn't get interrupted interrupts on this core so that threadSleep() doesn't
by // the thread-switching timer on this core which would get interrupted by // the thread-switching timer on
call contextSwitchISR(). // Done outside threadSleep() this core which would call contextSwitchISR(). //
for more efficiency so that this thread will be sleeped // Done outside threadSleep() for more efficiency so
right after going on the condition-variable queue. system- that this thread will be sleeped // right after going
Call_disableInterrupts(); assert m.held; // (Specifically, on the lock queue. systemCall_disableInterrupts();
this thread must be the one holding it.) m.release(); assert !blockingThreads.contains(currentThread); if
c.waitingThreads.enqueue(currentThread); thread- (held){ // Put “currentThread” on this lock’s queue so
Sleep(); // Thread sleeps ... Thread gets woken up from a that it will be // considered “sleeping” on this lock. //
signal/broadcast. threadingSystemBusy=false; // Must be Note that “currentThread” still needs to be handled
an atomic assignment. systemCall_enableInterrupts(); // by threadSleep(). readyQueue.remove(currentThread);
Turn pre-emptive switching back on on this core. // Mesa blockingThreads.enqueue(currentThread); thread-
style: // Context switches may now occur here, making Sleep(); // Now we are woken up, which must be
the client caller’s predicate false. m.acquire(); } public because “held” became false. assert !held; assert
method signal(ConditionVariable c){ // Internal spin-lock !blockingThreads.contains(currentThread); } held=true;
while other threads on any core are accessing this object’s threadingSystemBusy=false; // Must be an atomic
// “held” and “threadQueue”, or “readyQueue”. while assignment. systemCall_enableInterrupts(); // Turn
(testAndSet(threadingSystemBusy)){} // N.B.: “thread- pre-emptive switching back on on this core. } pub-
ingSystemBusy” is now true. // System call to disable lic method release(){ // Internal spin-lock while
interrupts on this core so that threadSleep() doesn't get other threads on any core are accessing this ob-
interrupted by // the thread-switching timer on this core ject’s // “held” and “threadQueue”, or “readyQueue”.
which would call contextSwitchISR(). // Done outside while (testAndSet(threadingSystemBusy)){} // N.B.:
threadSleep() for more efficiency so that this thread will “threadingSystemBusy” is now true. // System call
be sleeped // right after going on the condition- to disable interrupts on this core for efficiency.
variable queue. systemCall_disableInterrupts(); systemCall_disableInterrupts(); assert held; // (Re-
if (!c.waitingThreads.isEmpty()){ wo- lease should only be performed while the lock is
kenThread=c.waitingThreads.dequeue(); held.) held=false; if (!blockingThreads.isEmpty()){
readyQueue.enqueue(wokenThread); } threadingSys- Thread* unblockedThread=blockingThreads.dequeue();
temBusy=false; // Must be an atomic assignment. readyQueue.enqueue(unblockedThread); } thread-
systemCall_enableInterrupts(); // Turn pre-emptive ingSystemBusy=false; // Must be an atomic assignment.
switching back on on this core. // Mesa style: // The systemCall_enableInterrupts(); // Turn pre-emptive
woken thread is not given any priority. } public method switching back on on this core. } } struct ConditionVa-
broadcast(ConditionVariable c){ // Internal spin-lock riable { volatile ThreadQueue waitingThreads; }
while other threads on any core are accessing this object’s
// “held” and “threadQueue”, or “readyQueue”. while
(testAndSet(threadingSystemBusy)){} // N.B.: “thread-
Semaphore
ingSystemBusy” is now true. // System call to disable
interrupts on this core so that threadSleep() doesn't get
As an example, consider a thread-safe class that imple-
interrupted by // the thread-switching timer on this core
ments a semaphore. There are methods to increment (V)
which would call contextSwitchISR(). // Done outside
and to decrement (P) a private integer s. However, the in-
5.9. MONITOR 107
teger must never be decremented below 0; thus a thread // (The semaphore’s internal state is necessarily private.)
that tries to decrement must wait until the integer is pos- protected Semaphore sem=Semaphore(0); // Provides
itive. We use a condition variable sIsPositive with an as- the wait queue. protected Mutex internalMutex; //
sociated assertion of PsIsP ositive = (s > 0) . (Really another Semaphore. Protects “numWaiters”.) }
monitor class Semaphore { private int s := 0 invariant
s >= 0 private Condition sIsPositive /* associated with s When a signal happens on a condition variable that at
> 0 */ public method P() { while s = 0: wait sIsPositive least one other thread is waiting on, there are at least two
assert s > 0 s := s - 1 } public method V() { s := s + 1 threads that could then occupy the monitor: the thread
assert s > 0 signal sIsPositive } } that signals and any one of the threads that is waiting. In
Implemented showing all synchronization (removing the order that at most one thread occupies the monitor at each
assumption of a thread-safe class and showing the mutex): time, a choice must be made. Two schools of thought
exist on how best to resolve this choice. This leads to two
class Semaphore { private volatile int s := 0 invariant kinds of condition variables which will be examined next:
s >= 0 private ConditionVariable sIsPositive /* associ-
ated with s > 0 */ private Mutex myLock /* Lock on
• Blocking condition variables give priority to a sig-
“s” */ public method P() { myLock.acquire() while s =
naled thread.
0: wait(myLock, sIsPositive) assert s > 0 s := s - 1 my-
Lock.release() } public method V() { myLock.acquire() • Nonblocking condition variables give priority to the
s := s + 1 assert s > 0 signal sIsPositive myLock.release() signaling thread.
}}
Monitor implemented using semaphores Con- The original proposals by C. A. R. Hoare and Per Brinch
versely, locks and condition variables can also be derived Hansen were for blocking condition variables. With a
from semaphores, thus making monitors and semaphores blocking condition variable, the signaling thread must
reducible to one another: wait outside the monitor (at least) until the signaled thread
The implementation given here is incorrect. If a thread relinquishes occupancy of the monitor by either returning
calls wait() after signal() has been called it may be stuck or by again waiting on a condition variable. Monitors us-
indefinitely, since signal() increments the semaphore only ing blocking condition variables are often called Hoare-
enough times for threads already waiting. style monitors or signal-and-urgent-wait monitors.
public method wait(Mutex m, ConditionVariable c){ as-
sert m.held; c.internalMutex.acquire(); c.numWaiters++;
m.release(); // Can go before/after the neighboring
lines. c.internalMutex.release(); // Another thread
could signal here, but that’s OK because of how //
semaphores count. If c.sem’s number becomes 1,
we'll have no // waiting time. c.sem.Proberen(); //
Block on the CV. // Woken m.acquire(); // Re-acquire
the mutex. } public method signal(ConditionVariable
c){ c.internalMutex.acquire(); if (c.numWaiters >
0){ c.numWaiters--; c.sem.Verhogen(); // (Doesn't
need to be protected by c.internalMutex.) }
c.internalMutex.release(); } public method broad-
cast(ConditionVariable c){ c.internalMutex.acquire();
while (c.numWaiters > 0){ c.numWaiters--;
c.sem.Verhogen(); // (Doesn't need to be protected
by c.internalMutex.) } c.internalMutex.release(); }
class Mutex { protected boolean held=false; // For
assertions only, to make sure sem’s number never goes
> 1. protected Semaphore sem=Semaphore(1); // The
number shall always be at most 1. // Not held <--> 1; A Hoare style monitor with two condition variables a and b. After
held <--> 0. public method acquire(){ sem.Proberen(); Buhr et al.
assert !held; held=true; } public method release(){ assert
held; // Make sure we never Verhogen sem above 1. We assume there are two queues of threads associated
That would be bad. held=false; sem.Verhogen(); } } with each monitor object
class ConditionVariable { protected int numWaiters=0;
// Roughly tracks the number of waiters blocked in sem. • e is the entrance queue
108 CHAPTER 5. CONCURRENCY PATTERNS
• s is a queue of threads that have signaled. of the monitor postcondition P and I signal c : precon-
dition P and I modifies the state of the monitor post-
In addition we assume that for each condition variable c, condition I signal c and return : precondition P and
there is a queue I
In these contracts, it is assumed that I and P do not de-
• c.q, which is a queue for threads waiting on condi- pend on the contents or lengths of any queues.
tion variable c
(When the condition variable can be queried as to the
All queues are typically guaranteed to be fair and, in some number of threads waiting on its queue, more sophisti-
implementations, may be guaranteed to be first in first cated contracts can be given. For example, a useful pair
out. of contracts, allowing occupancy to be passed without es-
tablishing the invariant, is
The implementation of each operation is as follows. (We
assume that each operation runs in mutual exclusion to wait c : precondition I modifies the state of the monitor
the others; thus restarted threads do not begin executing postcondition P signal c precondition (not empty(c)
until the operation is complete.) and P ) or (empty(c) and I) modifies the state of the
monitor postcondition I
enter the monitor: enter the method if the monitor is [4] [5]
locked add this thread to e block this thread else lock See Howard and Buhr et al., for more).
the monitor leave the monitor: schedule return from the It is important to note here that the assertion P is entirely
method wait c : add this thread to c.q schedule block this up to the programmer; he or she simply needs to be con-
thread signal c : if there is a thread waiting on c.q select sistent about what it is.
and remove one such thread t from c.q (t is called “the
We conclude this section with an example of a thread-
signaled thread”) add this thread to s restart t (so t will
safe class using a blocking monitor that implements a
occupy the monitor next) block this thread schedule : if
bounded, thread-safe stack.
there is a thread on s select and remove one thread from
s and restart it (this thread will occupy the monitor next) monitor class SharedStack { private const capacity :=
else if there is a thread on e select and remove one thread 10 private int[capacity] A private int size := 0 invari-
from e and restart it (this thread will occupy the monitor ant 0 <= size and size <= capacity private BlockingCon-
next) else unlock the monitor (the monitor will become dition theStackIsNotEmpty /* associated with 0 < size
unoccupied) and size <= capacity */ private BlockingCondition theS-
tackIsNotFull /* associated with 0 <= size and size <
The schedule routine selects the next thread to occupy
capacity */ public method push(int value) { if size = ca-
the monitor or, in the absence of any candidate threads,
pacity then wait theStackIsNotFull assert 0 <= size and
unlocks the monitor.
size < capacity A[size] := value ; size := size + 1 assert 0
The resulting signaling discipline is known a “signal and < size and size <= capacity signal theStackIsNotEmpty
urgent wait,” as the signaler must wait, but is given prior- and return } public method int pop() { if size = 0 then
ity over threads on the entrance queue. An alternative is wait theStackIsNotEmpty assert 0 < size and size <=
“signal and wait,” in which there is no s queue and signaler capacity size := size - 1 ; assert 0 <= size and size <
waits on the e queue instead. capacity signal theStackIsNotFull and return A[size] }
Some implementations provide a signal and return op- }
eration that combines signaling with returning from a pro- Note that, in this example, the thread-safe stack is in-
cedure. ternally providing a mutex, which, as in the earlier pro-
signal c and return : if there is a thread waiting on c.q ducer/consumer example, is shared by both condition
select and remove one such thread t from c.q (t is called variables, which are checking different conditions on the
“the signaled thread”) restart t (so t will occupy the mon- same concurrent data. The only difference is that the pro-
itor next) else schedule return from the method ducer/consumer example assumed a regular non-thread-
safe queue and was using a standalone mutex and con-
In either case (“signal and urgent wait” or “signal and dition variables, without these details of the monitor ab-
wait”), when a condition variable is signaled and there is stracted away as is the case here. In this example, when
at least one thread on waiting on the condition variable, the “wait” operation is called, it must somehow be sup-
the signaling thread hands occupancy over to the signaled plied with the thread-safe stack’s mutex, such as if the
thread seamlessly, so that no other thread can gain occu- “wait” operation is an integrated part of the “monitor
pancy in between. If P is true at the start of each signal class”. Aside from this kind of abstracted functionality,
c operation, it will be true at the end of each wait c oper- when a “raw” monitor is used, it will always have to in-
ation. This is summarized by the following contracts. In clude a mutex and a condition variable, with a unique mu-
these contracts, I is the monitor’s invariant. tex for each condition variable.
enter the monitor: postcondition I leave the monitor:
precondition I wait c : precondition I modifies the state
5.9. MONITOR 109
Nonblocking condition variables Howard[4] and Buhr et al.[5] for further discussion.
It is possible to associate an assertion P with each condi-
With nonblocking condition variables (also called “Mesa tion variable c such that P is sure to be true upon return
style” condition variables or “signal and continue” con- from wait c. However, one must ensure that P is pre-
dition variables), signaling does not cause the signaling served from the time the notifying thread gives up occu-
thread to lose occupancy of the monitor. Instead the sig- pancy until the notified thread is selected to re-enter the
naled threads are moved to the e queue. There is no need monitor. Between these times there could be activity by
for the s queue. other occupants. Thus it is common for P to simply be
true.
For this reason, it is usually necessary to enclose each
wait operation in a loop like this
while not( P ) do wait c
where P is some condition stronger than P . The opera-
tions notify c and notify all c are treated as “hints” that
P may be true for some waiting thread. Every iteration
of such a loop past the first represents a lost notification;
thus with nonblocking monitors, one must be careful to
ensure that too many notifications can not be lost.
As an example of “hinting” consider a bank account in
which a withdrawing thread will wait until the account
has sufficient funds before proceeding
monitor class Account { private int balance := 0 invari-
ant balance >= 0 private NonblockingCondition balance-
MayBeBigEnough public method withdraw(int amount)
precondition amount >= 0 { while balance < amount
do wait balanceMayBeBigEnough assert balance >=
amount balance := balance - amount } public method
deposit(int amount) precondition amount >= 0 { balance
:= balance + amount notify all balanceMayBeBigEnough
}}
In this example, the condition being waited for is a func-
A Mesa style monitor with two condition variables a and b tion of the amount to be withdrawn, so it is impossible
for a depositing thread to know that it made such a condi-
With nonblocking condition variables, the signal opera- tion true. It makes sense in this case to allow each waiting
tion is often called notify — a terminology we will follow thread into the monitor (one at a time) to check if its as-
here. It is also common to provide a notify all operation sertion is true.
that moves all threads waiting on a condition variable to
the e queue. Implicit condition variable monitors
The meaning of various operations are given here. (We
assume that each operation runs in mutual exclusion to In the Java language, each object may be used as a moni-
the others; thus restarted threads do not begin executing tor. Methods requiring mutual exclusion must be explic-
until the operation is complete.) itly marked with the synchronized keyword. Blocks of
code may also be marked by synchronized.
enter the monitor: enter the method if the monitor is
locked add this thread to e block this thread else lock Rather than having explicit condition variables, each
the monitor leave the monitor: schedule return from the monitor (i.e. object) is equipped with a single wait queue
method wait c : add this thread to c.q schedule block this in addition to its entrance queue. All waiting is done on
thread notify c : if there is a thread waiting on c.q select this single wait queue and all notify and notifyAll opera-
and remove one thread t from c.q (t is called “the notified tions apply to this queue. This approach has been adopted
thread”) move t to e notify all c : move all threads wait- in other languages, for example C#.
ing on c.q to e schedule : if there is a thread on e select
and remove one thread from e and restart it else unlock
Implicit signaling
the monitor
As a variation on this scheme, the notified thread may be Another approach to signaling is to omit the signal opera-
moved to a queue called w, which has priority over e. See tion. Whenever a thread leaves the monitor (by returning
110 CHAPTER 5. CONCURRENCY PATTERNS
• Concurrent Euclid
• Concurrent Pascal
• D
• Mesa
• Modula-3
• Ruby
• Squeak Smalltalk
• µC++
• Semaphore (programming)
5.9.3 History
Brinch Hansen and Hoare developed the monitor con- 5.9.5 Notes
cept in the early 1970s, based on earlier ideas of their
own and of Edsger Dijkstra.[6] Brinch Hansen published [1] Brinch Hansen, Per (1973). “7.2 Class Concept”.
the first monitor notation, adopting the class concept Operating System Principles (PDF). Prentice Hall. ISBN
of Simula 67,[1] and invented a queueing mechanism.[7] 0-13-637843-9.
Hoare refined the rules of process resumption.[2] Brinch
[2] Hoare, C. A. R. (October 1974). “Monitors: an operating
Hansen created the first implementation of monitors, in system structuring concept”. Comm. ACM. 17 (10): 549–
Concurrent Pascal.[6] Hoare demonstrated their equiva- 557. doi:10.1145/355620.361161.
lence to semaphores.
[3] Hansen, P. B. (June 1975). “The programming language
Monitors (and Concurrent Pascal) were soon used to Concurrent Pascal”. IEEE Trans. Softw. Eng. SE–1 (2):
structure process synchronization in the Solo operating 199–207. doi:10.1109/TSE.1975.6312840.
system.[8][9]
[4] Howard, John H. (1976). “Signaling in monitors”. ICSE
Programming languages that have supported monitors in- '76 Proceedings of the 2nd international conference on
clude Software engineering. International Conference on Soft-
ware Engineering. Los Alamitos, CA, USA: IEEE Com-
• Ada since Ada 95 (as protected objects) puter Society Press. pp. 47–52.
5.10. REACTOR PATTERN 111
[5] Buhr, Peter A.; Fortier, Michel; Coffin, Michael H. • Wefts::Condition Class Reference
(March 1995). “Monitor classification”. ACM Computing
Surveys. 27 (1): 63–107. doi:10.1145/214037.214100. • ACE_Condition Class Template Reference
[6] Hansen, Per Brinch (1993). “Monitors and concur- • QWaitCondition Class Reference
rent Pascal: a personal history”. HOPL-II: The sec-
ond ACM SIGPLAN conference on History of pro- • Common C++ Conditional Class Reference
gramming languages. History of Programming Lan-
guages. New York, NY, USA: ACM. pp. 1–35. • at::ConditionalMutex Class Reference
doi:10.1145/155360.155361. ISBN 0-89791-570-4.
• threads::shared – Perl extension for sharing data
[7] Brinch Hansen, Per (July 1972). “Structured multipro- structures between threads
gramming (Invited Paper)". Communications of the ACM.
• http://msdn.microsoft.com/en-us/library/
[8] Brinch Hansen, Per (April 1976). “The Solo operating ms682052(VS.85).aspx
system: a Concurrent Pascal program” (PDF). Software—
Practice and Experience. • Monitors in Visual Prolog.
[9] Brinch Hansen, Per (1977). The Architecture of Concur-
rent Programs. Prentice Hall. ISBN 0-13-044628-9.
5.10 Reactor pattern
5.9.6 Further reading The reactor design pattern is an event handling pattern for
handling service requests delivered concurrently to a ser-
• Monitors: an operating system structuring concept, vice handler by one or more inputs. The service handler
C. A. R. Hoare – Communications of the ACM, then demultiplexes the incoming requests and dispatches
v.17 n.10, p. 549-557, Oct. 1974 them synchronously to the associated request handlers.[1]
• Monitor classification P.A. Buhr, M. Fortier, M.H.
Coffin – ACM Computing Surveys, 1995
5.10.1 Structure
• Resources: Any resource that can provide input to
5.9.7 External links
or consume output from the system.
• Java Monitors (lucid explanation) • Synchronous Event Demultiplexer: Uses an event
• "Monitors: An Operating System Structuring Con- loop to block on all resources. When it is possible to
cept" by C. A. R. Hoare start a synchronous operation on a resource without
blocking, the demultiplexer sends the resource to the
• "Signalling in Monitors" by John H. Howard (com- dispatcher.
puter scientist)
• Dispatcher: Handles registering and unregistering
• "Proving Monitors" by John H. Howard (computer of request handlers. Dispatches resources from the
scientist) demultiplexer to the associated request handler.
• "Experience with Processes and Monitors in Mesa" • Request Handler: An application defined request
by Butler W. Lampson and David D. Redell handler and its associated resource.
• pthread_cond_wait – description from the Open
Group Base Specifications Issue 6, IEEE Std 1003.1 5.10.2 Properties
• "Block on a Condition Variable" by Dave Marshall
(computer scientist) All reactor systems are single threaded by definition, but
can exist in a multithreaded environment.
• "Strategies for Implementing POSIX Condition
Variables on Win32" by Douglas C. Schmidt and
Irfan Pyarali Benefits
• Condition Variable Routines from the Apache The reactor pattern completely separates application spe-
Portable Runtime Library cific code from the reactor implementation, which means
that application components can be divided into modu-
• wxCondition description lar, reusable parts. Also, due to the synchronous calling
• Boost Condition Variables Reference of request handlers, the reactor pattern allows for simple
coarse-grain concurrency while not adding the complex-
• ZThread Condition Class Reference ity of multiple threads to the system.
112 CHAPTER 5. CONCURRENCY PATTERNS
Limitations the data, all other writers or readers will be blocked until
the writer is finished writing. A common use might be to
The reactor pattern can be more difficult to debug[2] than control access to a data structure in memory that cannot
a procedural pattern due to the inverted flow of control. be updated atomically and is invalid (and should not be
Also, by only calling request handlers synchronously, the read by another thread) until the update is complete.
reactor pattern limits maximum concurrency, especially
Readers–writer locks are usually constructed on top of
on Symmetric multiprocessing hardware. The scalability
mutexes and condition variables, or on top of semaphores.
of the reactor pattern is limited not only by calling request
handlers synchronously, but also by the demultiplexer. [3]
5.11.1 Upgradable RW lock
5.10.3 See also Some RW locks allow the lock to be atomically upgraded
from being locked in read-mode to write-mode, as well
• Proactor pattern (a pattern that also demultiplexes
as being downgraded from write-mode to read-mode.
and dispatches events, but asynchronously)
• Application server
5.11.2 Priority policies
• C10k problem
RW locks can be designed with different priority policies
for reader vs. writer access. The lock can either be de-
5.10.4 References signed to always give priority to readers (read-preferring),
to always give priority to writers (write-preferring) or be
[1] Schmidt, Douglas et al. Pattern-Oriented Software Archi- unspecified with regards to priority. These policies lead
tecture Volume 2: Patterns for Concurrent and Networked to different tradeoffs with regards to concurrency and
Objects. Volume 2. Wiley, 2000. starvation.
[2] Schmidt, Douglas C., An Object Behavioral Pattern for
Demultiplexing and Dispatching Handles for Synchronous • Read-preferring RW locks allow for maximum con-
Events (PDF) currency, but can lead to write-starvation if con-
tention is high. This is because writer threads will
[3] Kegel, Dan, The C10K problem, retrieved 2007-07-28
not be able to acquire the lock as long as at least
one reading thread holds it. Since multiple reader
5.10.5 External links threads may hold the lock at once, this means that
a writer thread may continue waiting for the lock
• An Object Behavioral Pattern for Demultiplexing while new reader threads are able to acquire the lock,
and Dispatching Handles for Synchronous Events by even to the point where the writer may still be wait-
Douglas C. Schmidt ing after all of the readers which were holding the
lock when it first attempted to acquire it have re-
• APR Networking & the Reactor Pattern leased the lock. Priority to readers may be weak,
as just described, or strong, meaning that whenever
• Architecture of a Highly Scalable NIO-Based Server a writer releases the lock, any blocking readers al-
• Akka’s I/O Layer Architecture ways acquire it next.[3]:76
• Write-preferring RW locks avoid the problem of
writer starvation by preventing any new readers from
5.11 Readers-writer lock acquiring the lock if there is a writer queued and
waiting for the lock; the writer will acquire the lock
For the psychological difficulty sometimes encountered as soon as all readers which were already holding
by writers, see Writer’s block. the lock have completed.[4] The downside is that
write-preferring locks allows for less concurrency in
the presence of writer threads, compared to read-
In computer science, a readers–writer (RW) or preferring RW locks. Also the lock is less perfor-
shared-exclusive lock (also known as a multiple mant because each operation, taking or releasing the
readers/single-writer lock[1] or multi-reader lock[2] ) is lock for either read or write, is more complex, in-
a synchronization primitive that solves one of the readers– ternally requiring taking and releasing two mutexes
writers problems. An RW lock allows concurrent access instead of one. This variation is sometimes also
for read-only operations, while write operations require known as “write-biased” readers–writer lock.[5]
exclusive access. This means that multiple threads can
read the data in parallel but an exclusive lock is needed • Unspecified priority RW locks does not provide any
for writing or modifying data. When a writer is writing guarantees with regards read vs. write access. Un-
5.11. READERS-WRITER LOCK 113
specified priority can in some situations be prefer- • Input: mutex m, condition variable c, integer r
able if it allows for a more efficient implementation. (number of readers waiting), flag w (writer waiting).
• Lock m (blocking).
5.11.3 Implementation • While w:
Several implementation strategies for readers–writer • wait c, m[lower-alpha 1]
locks exist, reducing them to synchronization primitives
that are assumed to pre-exist. • Increment r.
• Unlock m.
Using two mutexes
The lock-for-write operation is similar, but slightly dif-
[6][7][8]
Raynal demonstrates how to implement an R/W lock ferent (inputs are the same as for lock-for-read):
using two mutexes and a single integer counter. The
counter, b, tracks the number of blocking readers. One • Lock m (blocking).
mutex, r, protects b and is only used by readers; the other,
• While (w or r > 0):
g (for “global”) ensures mutual exclusion of writers. This
requires that a mutex acquired by one thread can be re- • wait c, m
leased by another. The following is pseudocode for the
operations: • Set w to true.
Alternatively, a read-preferring R/W lock can be imple- • std::sync::RwLock read/write lock in Rust[17]
mented in terms of a condition variable and an ordinary • Poco::RWLock in POCO C++ Libraries
(mutex) lock, in addition to an integer counter and a
boolean flag. The lock-for-read operation in this setup • txrwlock.ReadersWriterDeferredLock Read-
is:[6][7][8] ers/Writer Lock for Twisted[18]
114 CHAPTER 5. CONCURRENCY PATTERNS
5.11.5 Alternatives [12] “New adopted paper: N3659, Shared Locking in C++—
Howard Hinnant, Detlef Vollmann, Hans Boehm”. Stan-
The read-copy-update (RCU) algorithm is one solution to dard C++ Foundation.
the readers–writers problem. RCU is wait-free for read-
[13] Anthony Williams. “Synchronization – Boost 1.52.0”.
ers. The Linux kernel implements a special solution for Retrieved 31 Jan 2012.
few writers called seqlock.
[14] Alessandrini, Victor (2015). Shared Memory Application
Programming: Concepts and Strategies in Multicore Appli-
5.11.6 See also cation Programming. Morgan Kaufmann.
In real-time environments, such as embedded systems hand, if all processes are CPU-bound, the I/O waiting
for automatic control in industry (for example robotics), queue will almost always be empty, devices will go un-
the scheduler also must ensure that processes can meet used, and again the system will be unbalanced. The sys-
deadlines; this is crucial for keeping the system stable. tem with the best performance will thus have a combina-
Scheduled tasks can also be distributed to remote devices tion of CPU-bound and I/O-bound processes. In modern
across a network and managed through an administrative operating systems, this is used to make sure that real-time
back end. processes get enough CPU time to finish their tasks.[3]
Long-term scheduling is also important in large-scale sys-
tems such as batch processing systems, computer clus-
5.12.1 Types of operating system sched- ters, supercomputers, and render farms. For example,
ulers in concurrent systems, coscheduling of interacting pro-
cesses is often required to prevent them from blocking
See also: Network scheduler, I/O scheduling, and Job due to waiting on each other. In these cases, special-
scheduler purpose job scheduler software is typically used to assist
these functions, in addition to any underlying admission
The scheduler is an operating system module that selects scheduling support in the operating system.
the next jobs to be admitted into the system and the next
process to run. Operating systems may feature up to
three distinct scheduler types: a long-term scheduler (also Medium-term scheduling The medium-term sched-
known as an admission scheduler or high-level scheduler), uler temporarily removes processes from main memory
a mid-term or medium-term scheduler, and a short-term and places them in secondary memory (such as a hard
scheduler. The names suggest the relative frequency with disk drive) or vice versa, which is commonly referred to
which their functions are performed. as “swapping out” or “swapping in” (also incorrectly as
"paging out” or “paging in”). The medium-term sched-
uler may decide to swap out a process which has not been
Process scheduler active for some time, or a process which has a low pri-
ority, or a process which is page faulting frequently, or a
The process scheduler is a part of the operating system process which is taking up a large amount of memory in
that decides which process runs at a certain point in time. order to free up main memory for other processes, swap-
It usually has the ability to pause a running process, move ping the process back in later when more memory is avail-
it to the back of the running queue and start a new pro- able, or when the process has been unblocked and is no
cess; such a scheduler is known as preemptive scheduler, longer waiting for a resource. [Stallings, 396] [Stallings,
otherwise it is a cooperative scheduler.[2] 370]
In many systems today (those that support mapping vir-
tual address space to secondary storage other than the
Long-term scheduling The long-term scheduler, or
swap file), the medium-term scheduler may actually per-
admission scheduler, decides which jobs or processes are
form the role of the long-term scheduler, by treating bina-
to be admitted to the ready queue (in main memory); that
ries as “swapped out processes” upon their execution. In
is, when an attempt is made to execute a program, its
this way, when a segment of the binary is required it can
admission to the set of currently executing processes is
be swapped in on demand, or “lazy loaded”. [Stallings,
either authorized or delayed by the long-term scheduler.
394]
Thus, this scheduler dictates what processes are to run on
a system, and the degree of concurrency to be supported
at any one time – whether many or few processes are to Short-term scheduling The short-term scheduler (also
be executed concurrently, and how the split between I/O- known as the CPU scheduler) decides which of the ready,
intensive and CPU-intensive processes is to be handled. in-memory processes is to be executed (allocated a CPU)
The long-term scheduler is responsible for controlling the after a clock interrupt, an I/O interrupt, an operating
degree of multiprogramming. system call or another form of signal. Thus the short-
In general, most processes can be described as either I/O- term scheduler makes scheduling decisions much more
bound or CPU-bound. An I/O-bound process is one that frequently than the long-term or mid-term schedulers
spends more of its time doing I/O than it spends doing – a scheduling decision will at a minimum have to be
computations. A CPU-bound process, in contrast, gen- made after every time slice, and these are very short.
erates I/O requests infrequently, using more of its time This scheduler can be preemptive, implying that it is
doing computations. It is important that a long-term capable of forcibly removing processes from a CPU
scheduler selects a good process mix of I/O-bound and when it decides to allocate that CPU to another pro-
CPU-bound processes. If all processes are I/O-bound, cess, or non-preemptive (also known as “voluntary” or
the ready queue will almost always be empty, and the “co-operative”), in which case the scheduler is unable to
short-term scheduler will have little to do. On the other “force” processes off the CPU.
116 CHAPTER 5. CONCURRENCY PATTERNS
A preemptive scheduler relies upon a programmable in- In advanced packet radio wireless networks such as
terval timer which invokes an interrupt handler that runs HSDPA (High-Speed Downlink Packet Access ) 3.5G
in kernel mode and implements the scheduling function. cellular system, channel-dependent scheduling may be
used to take advantage of channel state information. If
the channel conditions are favourable, the throughput
Dispatcher Another component that is involved in the and system spectral efficiency may be increased. In
CPU-scheduling function is the dispatcher, which is the even more advanced systems such as LTE, the schedul-
module that gives control of the CPU to the process se- ing is combined by channel-dependent packet-by-packet
lected by the short-term scheduler. It receives control in dynamic channel allocation, or by assigning OFDMA
kernel mode as the result of an interrupt or system call. multi-carriers or other frequency-domain equalization
The functions of a dispatcher involve the following: components to the users that best can utilize them.[4]
Earliest deadline first The operating system assigns a fixed priority rank to every
process, and the scheduler arranges the processes in the
Main article: Earliest deadline first scheduling ready queue in order of their priority. Lower-priority pro-
cesses get interrupted by incoming higher-priority pro-
Earliest deadline first (EDF) or least time to go is a dy- cesses.
namic scheduling algorithm used in real-time operating
systems to place processes in a priority queue. When- • Overhead is not minimal, nor is it significant.
ever a scheduling event occurs (a task finishes, new task
is released, etc.), the queue will be searched for the pro- • FPPS has no particular advantage in terms of
cess closest to its deadline, which will be the next to be throughput over FIFO scheduling.
scheduled for execution.
• If the number of rankings is limited, it can be char-
acterized as a collection of FIFO queues, one for
Shortest remaining time first each priority ranking. Processes in lower-priority
queues are selected only when all of the higher-
Main article: Shortest remaining time first priority queues are empty.
• If a shorter process arrives during another process’ • Starvation of lower-priority processes is possible
execution, the currently running process is inter- with large numbers of high-priority processes queu-
rupted (known as preemption), dividing that process ing for CPU time.
into two separate computing blocks. This creates
excess overhead through additional context switch-
ing. The scheduler must also place each incoming Round-robin scheduling
process into a specific place in the queue, creating
additional overhead. Main article: Round-robin scheduling
Main article: Fixed priority pre-emptive scheduling • If Time-Slice is large It becomes FCFS /FIFO or If
it is short then it becomes SJF/SRTF.
118 CHAPTER 5. CONCURRENCY PATTERNS
• The Multiple Sequential Scheduler option, known as Classic Mac OS and macOS
Multiprogramming with a Fixed Number of Tasks
(MFT) provided execution of multiple concurrent Mac OS 9 uses cooperative scheduling for threads, where
jobs. Execution was governed by a priority which one process controls multiple cooperative threads, and
had a default for each stream or could be requested also provides preemptive scheduling for multiprocess-
separately for each job. MFT version II added sub- ing tasks. The kernel schedules multiprocessing tasks
tasks (threads), which executed at a priority based using a preemptive scheduling algorithm. All Process
on that of the parent job. Each job stream defined Manager processes run within a special multiprocess-
the maximum amount of memory which could be ing task, called the “blue task”. Those processes are
used by any job in that stream. scheduled cooperatively, using a round-robin schedul-
ing algorithm; a process yields control of the processor
to another process by explicitly calling a blocking func-
• The Multiple Priority Schedulers option, or Multipro-
tion such as WaitNextEvent. Each process has its own
gramming with a Variable Number of Tasks (MVT),
copy of the Thread Manager that schedules that process’s
featured subtasks from the start; each job requested
threads cooperatively; a thread yields control of the pro-
the priority and memory it required before execu-
cessor to another thread by calling YieldToAnyThread or
tion.
YieldToThread.[9]
macOS uses a multilevel feedback queue, with four prior-
Later virtual storage versions of MVS added a Workload ity bands for threads – normal, system high priority, ker-
Manager feature to the scheduler, which schedules pro- nel mode only, and real-time.[10] Threads are scheduled
cessor resources according to an elaborate scheme de- preemptively; macOS also supports cooperatively sched-
fined by the installation. uled threads in its implementation of the Thread Manager
in Carbon.[9]
Windows AIX
Very early MS-DOS and Microsoft Windows systems In AIX Version 4 there are three possible values for
were non-multitasking, and as such did not feature a thread scheduling policy:
scheduler. Windows 3.1x used a non-preemptive sched-
uler, meaning that it did not interrupt programs. It relied • First In, First Out: Once a thread with this policy is
on the program to end or tell the OS that it didn't need scheduled, it runs to completion unless it is blocked,
the processor so that it could move on to another process. it voluntarily yields control of the CPU, or a higher-
This is usually called cooperative multitasking. Windows priority thread becomes dispatchable. Only fixed-
95 introduced a rudimentary preemptive scheduler; how- priority threads can have a FIFO scheduling policy.
ever, for legacy support opted to let 16 bit applications
• Round Robin: This is similar to the AIX Version 3
run without preemption.[5]
scheduler round-robin scheme based on 10ms time
Windows NT-based operating systems use a multilevel slices. When a RR thread has control at the end of
feedback queue. 32 priority levels are defined, 0 through the time slice, it moves to the tail of the queue of dis-
to 31, with priorities 0 through 15 being “normal” priori- patchable threads of its priority. Only fixed-priority
ties and priorities 16 through 31 being soft real-time pri- threads can have a Round Robin scheduling policy.
orities, requiring privileges to assign. 0 is reserved for the
• OTHER: This policy is defined by POSIX1003.4a
Operating System. Users can select 5 of these priorities
as implementation-defined. In AIX Version 4, this
to assign to a running application from the Task Manager
policy is defined to be equivalent to RR, except that
application, or through thread management APIs. The
it applies to threads with non-fixed priority. The re-
kernel may change the priority level of a thread depend-
calculation of the running thread’s priority value at
ing on its I/O and CPU usage and whether it is interactive
each clock interrupt means that a thread may lose
(i.e. accepts and responds to input from humans), raising
control because its priority value has risen above that
the priority of interactive and I/O bounded processes and
of another dispatchable thread. This is the AIX Ver-
lowering that of CPU bound processes, to increase the re-
[6] sion 3 behavior.
sponsiveness of interactive applications. The scheduler
was modified in Windows Vista to use the cycle counter
register of modern processors to keep track of exactly Threads are primarily of interest for applications that cur-
how many CPU cycles a thread has executed, rather than rently consist of several asynchronous processes. These
just using an interval-timer interrupt routine.[7] Vista also applications might impose a lighter load on the system if
uses a priority scheduler for the I/O queue so that disk converted to a multithreaded structure.
defragmenters and other such programs do not interfere AIX 5 implements the following scheduling policies:
with foreground operations.[8] FIFO, round robin, and a fair round robin. The
120 CHAPTER 5. CONCURRENCY PATTERNS
FIFO policy has three different implementations: FIFO, The Completely Fair Scheduler (CFS) uses a well-
FIFO2, and FIFO3. The round robin policy is named studied, classic scheduling algorithm called fair queuing
SCHED_RR in AIX, and the fair round robin is called originally invented for packet networks. Fair queuing
SCHED_OTHER.[11] had been previously applied to CPU scheduling under the
name stride scheduling. The fair queuing CFS scheduler
has a scheduling complexity of O(log N), where N is the
Linux number of tasks in the runqueue. Choosing a task can be
done in constant time, but reinserting a task after it has
SCI (System Call Interface)
Linux kernel
Memory Process run requires O(log N) operations, because the run queue
I/O subsystem management management
Linux kernel
subsystem subsystem is implemented as a red-black tree.
Virtual File System
Virtual Signal
Terminals Sockets File systems memory handling The Brain Fuck Scheduler (BFS), also created by Con
Netfilter / Nftables Generic
Kolivas, is an alternative to the CFS.
discipline
Solaris
Linux 2.6.0 to Linux 2.6.22 In versions 2.6.0 to
2.6.22, the kernel used an O(1) scheduler developed by
Ingo Molnar and many other kernel developers during the Solaris uses a multilevel feedback queue with priorities
Linux 2.5 development. For many kernel in time frame, ranging between 0 and 169. Priorities 0–59 are reserved
Con Kolivas developed patch sets which improved inter- for time-shared threads, 60–99 for system threads, 100–
activity with this scheduler or even replaced it with his 159 for real-time threads, and 160–169 for low priority
own schedulers. interrupts. Unlike Linux,[14] when a process is done using
its time quantum, it is given a new priority and put back
in the queue. Solaris 9 introduced two new scheduling
Since Linux 2.6.23 Con Kolivas’s work, most signif- classes, namely fixed priority class and fair share class.
icantly his implementation of "fair scheduling" named The threads with fixed priority have the same priority
“Rotating Staircase Deadline”, inspired Ingo Molnár to range as that of the time-sharing class, but their prior-
develop the Completely Fair Scheduler as a replacement ities are not dynamically adjusted. The fair scheduling
for the earlier O(1) scheduler, crediting Kolivas in his class uses CPU shares to prioritize threads for scheduling
announcement.[12] CFS is the first implementation of a decisions. CPU shares indicate the entitlement to CPU
fair queuing process scheduler widely used in a general- resources. They are allocated to a set of processes, which
purpose operating system.[13] are collectively known as a project.[3]
5.12. SCHEDULER PATTERN 121
Summary [8]
[9] “Technical Notes”. Developer.apple.com. Retrieved
5.12.4 See also 2016-12-09.
• Activity selection problem [10] “Guides and Sample Code”. Developer.apple.com. Re-
trieved 2016-12-09.
• Aging (scheduling)
[11]
• Atropos scheduler [12] Molnár, Ingo (2007-04-13). "[patch] Modular Scheduler
Core and Completely Fair Scheduler [CFS]". linux-kernel
• Automated planning and scheduling
(Mailing list).
• Cyclic executive [13] Tong Li; Dan Baumberger; Scott Hahn. “Efficient
and Scalable Multiprocessor Fair Scheduling Using Dis-
• Dynamic priority scheduling
tributed Weighted Round-Robin” (PDF). Happyli.org.
• Foreground-background Retrieved 2016-12-09.
[14] “Comparison of Solaris, Linux, and FreeBSD Kernels”
• Interruptible operating system
(PDF). Archived from the original (PDF) on August 7,
• Least slack time scheduling 2008.
[2] Paul Krzyzanowski (2014-02-19). “Process Scheduling: • Brief discussion of Job Scheduling algorithms
Who gets to run next?". cs.rutgers.edu. Retrieved 2015- • Understanding the Linux Kernel: Chapter 10 Pro-
01-11.
cess Scheduling
[3] Abraham Silberschatz, Peter Baer Galvin and Greg Gagne • Kerneltrap: Linux kernel scheduler articles
(2013). Operating System Concepts. 9. John Wiley &
Sons,Inc. ISBN 978-1-118-06333-0. • AIX CPU monitoring and tuning
[4] Guowang Miao; Jens Zander; Ki Won Sung; Ben Sli- • Josh Aas’ introduction to the Linux 2.6.8.1 CPU
mane (2016). Fundamentals of Mobile Data Networks. scheduler implementation
Cambridge University Press. ISBN 1107143217.
• Peter Brucker, Sigrid Knust. Complexity results for
[5] Early Windows at the Wayback Machine (archive index) scheduling problems
[6] Sriram Krishnan. “A Tale of Two Schedulers Windows • TORSCHE Scheduling Toolbox for Matlab is a tool-
NT and Windows CE”. Archived from the original on July box of scheduling and graph algorithms.
22, 2012.
• A survey on cellular networks packet scheduling
[7] “Windows Administration: Inside the Windows Vista
Kernel: Part 1”. Technet.microsoft.com. 2016-11-14. Re- • Large-scale cluster management at Google with
trieved 2016-12-09. Borg
122 CHAPTER 5. CONCURRENCY PATTERNS
5.13 Thread pool pattern pool itself, distributes tasks to worker processes on differ-
ent computers, in order to increase the overall throughput.
Embarrassingly parallel problems are highly amenable to
Task Queue this approach.
...
The number of threads may be dynamically adjusted dur-
ing the lifetime of an application based on the number of
Thread waiting tasks. For example, a web server can add threads
Pool if numerous web page requests come in and can remove
threads when those requests taper down. The cost of hav-
Completed Tasks
ing a larger thread pool is increased resource usage. The
...
algorithm used to determine when to create or destroy
threads affects the overall performance:
A sample thread pool (green boxes) with waiting tasks (blue) and
completed tasks (yellow) • Creating too many threads wastes resources and
costs time creating the unused threads.
In computer programming, a thread pool is a software
design pattern for achieving concurrency of execution • Destroying too many threads requires more time
in a computer program. Often also called a replicated later when creating them again.
workers or worker-crew model,[1] a thread pool main-
tains multiple threads waiting for tasks to be allocated • Creating threads too slowly might result in poor
for concurrent execution by the supervising program. By client performance (long wait times).
maintaining a pool of threads, the model increases per-
formance and avoids latency in execution due to frequent • Destroying threads too slowly may starve other pro-
creation and destruction of threads for short-lived tasks.[2] cesses of resources.
The number of available threads is tuned to the comput-
ing resources available to the program, such as parallel
processors, cores, memory, and network sockets.[3] 5.13.2 See also
A common method of scheduling tasks for thread execu-
tion is a synchronized queue, known as a task queue. The • Object pool pattern
threads in the pool remove waiting tasks from the queue,
and place them into a completed task queue after com- • Concurrency pattern
pletion of execution.
• Grand Central Dispatch
Typically, a thread pool executes on a single computer. [4] Yibei Ling; Tracy Mullen; Xiaola Lin (April 2000).
However, thread pools are conceptually related to server “Analysis of optimal thread pool size”. ACM SIGOPS Op-
farms in which a master process, which might be a thread erating Systems Review. 34 (2): 42–55.
5.14. THREAD-LOCAL STORAGE 123
5.13.4 External links implying that there can be no race conditions). Threads
then only have to synchronise a final accumulation from
• "Query by Slice, Parallel Execute, and Join: A their own thread-local variable into a single, truly global
Thread Pool Pattern in Java" by Binildas C. A. variable.
• "Thread pools and work queues" by Brian Goetz Many systems impose restrictions on the size of the
thread-local memory block, in fact often rather tight lim-
• "A Method of Worker Thread Pooling" by Pradeep its. On the other hand, if a system can provide at least
Kumar Sahu a memory address (pointer) sized variable thread-local,
then this allows the use of arbitrarily sized memory blocks
• "Work Queue" by Uri Twig: C++ code demonstra- in a thread-local manner, by allocating such a memory
tion of pooled threads executing a work queue. block dynamically and storing the memory address of that
• "Windows Thread Pooling and Execution Chaining" block in the thread-local variable.
the key is explicitly left opaque and is referred to as • Solaris Studio C/C++, IBM XL C/C++,[3] GNU
pthread_key_t. This key can be seen by all threads. C,[4] Clang[5] and Intel C++ Compiler (Linux
In each thread, the key can be associated with thread- systems)[6] use the syntax:
specific data via pthread_setspecific. The data can later
be retrieved using pthread_getspecific. __thread int number;
In addition pthread_key_create can optionally accept a • Visual C++,[7] Intel C/C++ (Windows systems),[8]
destructor function that will automatically be called at C++Builder, and Digital Mars C++ use the syntax:
thread exit, if the thread-specific data is not NULL. The
destructor receives the value associated with the key as __declspec(thread) int number;
parameter so it can perform cleanup actions (close con-
nections, free memory, etc.). Even when a destructor is • C++Builder also supports the syntax:
specified, the program must still call pthread_key_delete
to free the thread-specific data at process level (the de- int __thread number;
structor only frees the data local to the thread).
It should be noted pthreads isn't the only way Unix multi- On Windows versions before Vista and Server 2008,
threaded and multi-cpu can share memory; far from __declspec(thread) works in DLLs only when those
it. i.e. MIT-SHM is an older yet capable standard. DLLs are bound to the executable, and will not work
Note pthreads has undergone many incompatible version for those loaded with LoadLibrary() (a protection fault
changes, also that (linux) libc stopped using /lib/tls/libs, or data corruption may occur).[9]
that pthreads is not “tls” and is not limited to sharing
memory between threads in a particular manner struc- Common Lisp (and maybe other dialects)
tured as a “standard tls”. Moreso that in linux gas(1) and
ld(1) have been continually modifying how pthreads gets Common Lisp provides a feature called dynamically
implemented at compile time. tls is important for libc scoped variables.
efficiency when multi-thread applications link against it
but is rarely a concern for non-OS-lib libs and apps and Dynamic variables have a binding which is private to the
should perhaps be avoided (due to rapid incompatibility invocation of a function and all of the children called by
of code). that function.
This abstraction naturally maps to thread-specific stor-
age, and Lisp implementations that provide threads do
5.14.3 Language-specific implementation this. Common Lisp has numerous standard dynamic vari-
ables, and so threads cannot be sensibly added to an im-
Apart from relying on programmers to call the appropri-
plementation of the language without these variables hav-
ate API functions, it is also possible to extend the pro-
ing thread-local semantics in dynamic binding.
gramming language to support TLS.
For instance the standard variable *print-base* deter-
mines the default radix in which integers are printed. If
C and C++ this variable is overridden, then all enclosing code will
print integers in an alternate radix:
In C11, the keyword _Thread_local is used to define
thread-local variables. The header <threads.h>, if sup- ;;; function foo and its children will print ;; in hexadeci-
ported, defines thread_local as a synonym for that key- mal: (let ((*print-base* 16)) (foo))
word. Example usage:
#include <threads.h> thread_local int foo = 0; If functions can execute concurrently on different
threads, this binding has to be properly thread-local, oth-
erwise each thread will fight over who controls a global
C++11 introduces the thread_local[2] keyword which can printing radix.
be used in the following cases
• File static variables In D version 2, all static and global variables are thread-
local by default and are declared with syntax similar to
• Function static variables
“normal” global and static variables in other languages.
• Static member variables Global variables must be explicitly requested using the
shared keyword:
Aside from that, various C++ compiler implementations int threadLocal; // This is a thread-local variable. shared
provide specific ways to declare thread-local variables: int global; // This is a global variable shared with all
5.14. THREAD-LOCAL STORAGE 125
threads. Objective-C
Perl
Java
In Perl threads were added late in the evolution of the
In Java, thread-local variables are implemented by the language, after a large body of extant code was already
ThreadLocal class object. ThreadLocal holds variable of present on the Comprehensive Perl Archive Network
type T, which is accessible via get/set methods. For ex- (CPAN). Thus, threads in Perl by default take their own
ample, ThreadLocal variable holding Integer value looks local storage for all variables, to minimise the impact
like this: of threads on extant non-thread-aware code. In Perl, a
thread-shared variable can be created using an attribute:
private static final ThreadLocal<Integer> myThreadLo-
calInteger = new ThreadLocal<Integer>(); use threads; use threads::shared; my $localvar; my
$sharedvar :shared;
At least for Oracle/OpenJDK, this does not use native
thread-local storage in spite of OS threads being used for
other aspects of Java threading. Instead, each Thread ob- Python
ject stores a (non-thread-safe) map of ThreadLocal ob-
jects to their values (as opposed to each ThreadLocal hav- In Python version 2.4 or later, local class in threading
ing a map of Thread objects to values and incurring a module can be used to create thread-local storage.
performance overhead).[12]
import threading mydata = threading.local() mydata.x = 1
Also an API is available for dynamically allocating [2] Section 3.7.2 in C++11 standard
thread-local variables.
[3] IBM XL C/C++: Thread-local storage
• GCC ""
Chapter 6
6.1 Text
• Software design pattern Source: https://en.wikipedia.org/wiki/Software_design_pattern?oldid=769792638 Contributors: Fubar Obfusco,
Hirzel, Edward, Michael Hardy, Fred Bauder, Nixdorf, Pnm, Kku, Jizzbug, Rudyment, Wapcaplet, Graue, Zeno Gantner, TakuyaMurata,
Pcb21, MartinSpamer, Ahoerstemeier, Ronz, Julesd, Lancevortex, Halfdan, Ed Brey, Fuzheado, Greenrd, DJ Clayworth, Furrykef, Wern-
her, Bevo, PierreCaboche, Patrick McDonough, Phil Boswell, RickBeton, Robbot, Chealer, Craig Stuntz, Fredrik, Mountain, RedWolf,
Forseti, Wikibot, Jleedev, Cronian~enwiki, Tea2min, Enochlau, Lantzilla, Kevin Saff, BenFrantzDale, Msm, Curps, Jorend, Bovlb, Ferdi-
nand Pienaar, Khalid hassani, Neilc, Alexf, Quagmire, Beland, Maximaximax, Burschik, WOT, Rwmcfa1, Frau Holle, Andreas Kaufmann,
Zondor, Perey, Francois Trazzi~enwiki, RossPatterson, Leibniz, Michal Jurosz, Abelson, TheJames, Khalid, ZeroOne, S.K., JustinWick,
El C, Vinsci, Edward Z. Yang, Jonon, Cyc~enwiki, Cesar Moura, Flxmghvgvk, SpeedyGonsales, WikiLeon, Crdoconnor, Mdd, Melah
Hashamaim, Gary, Liao, Theuser, AdamBradley, Clubmarx, HenkvD, 2mcm, Egg, Mahanga, Boothy443, Mindmatrix, RHaworth, Un-
cle G, Bkkbrad, Unixer, Jeff3000, Nklatt, Stuartroebuck, GregorB, Prashanthns, Marudubshinki, Xtian~enwiki, BD2412, FreplySpang,
Grammarbot, Koavf, Adjusting, Salix alba, RyanNerd, Ltruett, Ligulem, Fred Bradstadt, Orborde, Quuxplusone, Fresheneesz, Jopincar,
Lambyuk, Chobot, Georgenaing, YurikBot, Albanaco, Wavelength, Borgx, JWB, Hairy Dude, Peter S., Hede2000, Rodasmith, Grubber,
SteveLoughran, EngineerScotty, Welsh, SAE1962, PrologFan, Dethomas, Natkeeran, Bota47, Dirk Riehle, FF2010, Cconnett, Lt-wiki-
bot, Ninly, JLaTondre, Shevonsilva, Eaefremov, Benandorsqueaks, TuukkaH, SmackBot, Vald, Pieleric, Renesis, AlecMcEachran, Nick-
Shaforostoff, Mdd4696, Mirokado, JMSwtlk, Nbarth, DHN-bot~enwiki, ACupOfCoffee, A. B., J00tel, Olff, Stevemidgley, Allan McInnes,
NoIdeaNick, Opticyclic, Cybercobra, Polonium, Ligulembot, Vina-iwbot~enwiki, Ugur Basak Bot~enwiki, Guehene, Triskell, Mamouri,
Antonielly, Edenphd, MarkSutton, Arch4ngel, Wikidrone, MTSbot~enwiki, Kvng, Amitch, Hu12, TingChong Ma, CzarB, Skorpion87,
JHP, Evoluzion~enwiki, Az1568, Courcelles, Tawkerbot2, Shabbirbhimani, Spdegabrielle, Ahy1, Errandir, JohnCD, WeggeBot, Neelix,
Mblumber, Snarpel, A876, Torrg, Tonymarston, Davhorn, Chrislk02, ThistleDew172, Gnewf, Sxilderik, Marek69, WinBot, Gioto, Luna
Santin, QuiteUnusual, Harborsparrow, Danger, Morten Johnsen, Legare, JAnDbot, BenjaminGittins, Sonicsuns, .anacondabot, Xypron,
Magioladitis, Parsecboy, VoABot II, Meredyth, Msjegan, Necklace, Azbarcea, Tonyfaull, Alexmadon, A3nm, Breandandalton, Mcavigelli,
Lelkesa, NunoAgostinho, Oicumayberight, MartinBot, Jackhwl, Stephanakib, J.delanoy, Seanhan, Jesperborgstrup, Katalaveno, McSly,
Plasticup, Tristan ph, Tiggerjay, Mistercupcake, Declanmcd, Hammersoft, VolkovBot, Tiktuk, Philip Trueman, Rponamgi, LeaveSleaves,
Amazedsaint, Fiskah~enwiki, Matthewdjb, VidGa, Billinghurst, Andy Dingley, Charliearcuri, Enviroboy, Mohansn, Coolestdude1, Mor-
mat, Skraedingie, Jamilsh, Jerryobject, Flyer22 Reborn, Treekids, PsyberS, Sfermigier, ClueBot, Stokito, Tesakoff, Redeyed Treefrog,
Gwyddgwyrdd, Stachelfisch, Janesconference, Excirial, M4gnum0n, Dmyersturnbull, Hans Adler, Mikaey, Bravegag, Bwoolf, XLinkBot,
Saiful vonair, BBL5660, Airplaneman, Eightcien, Addbot, Tgmattso, Jafeluv, DOI bot, Landon1980, Maria C Mosak, Asphatasawhale, Jo-
sevellezcaldas, MrOllie, Lost on Belmont, Bogdanmata, Haskellguy, Architectureblog, AtheWeatherman, Tassedethe, Numbo3-bot, Light-
bot, Adaniels.nl, Jarble, Luckas-bot, Yobot, TaBOT-zerem, TonyFlury, Pcap, Wonderfl, 4th-otaku, AnomieBOT, Jim1138, Galoubet, Der
Hakawati, Law, Citation bot, SlavMFM, Davhdavh, Xqbot, Gilo1969, Martnym, BluePlateSpecial, GrouchoBot, Khaderv, RibotBOT,
RabbiGregory, Pomoxis, BozzieBear, Vmlaker, Mark Renier, Sae1962, Alex.ryazantsev, Slivicon, Cannolis, Umbr, Citation bot 1, Mar-
coscata, Maggyero, CaptainPinko, I dream of horses, Jonesey95, Docsman, Ruudjah, Kimmelb, RedBot, Ibbbi, Pcwitchdr, Wo.luren,
Mean as custard, Ripchip Bot, Sandman25 again, Stryn, Primefac, Dcirovic, Amitdipsite, Realbox, ZéroBot, Bollyjeff, H3llBot, De-
monkoryu, Rcsprinter123, Kirby2010, Lylez, ClueBot NG, Alexandernolasco, Ptrb, Sudhanshuss, Satellizer, Frietjes, Helpful Pixie Bot,
BG19bot, Basamajoe, Northamerica1000, Devintseo, Thornbirda, Pratyya Ghosh, Irene31, Umlcat, Pintoch, SudhakarNimmala, Bogdan-
mionescu, Ibjacked, LibreNico, BurritoBazooka, Phamnhatkhanh, William Di Luigi, Biogeographist, Int80, Star767, Svoboman, Ramram
43210, Monkbot, Serv49, Omkarsoft, KasparBot, 1Wiki8Q5G7FviTHBac3dx8HhdNYwDVstR, Wikipedia acc0, Emiya~ruwiki, Jsg68x,
Bradarv90, Cmartin.scruthut, GreenC bot, Mohsin gujjar, Vanderjoe and Anonymous: 538
• Creational pattern Source: https://en.wikipedia.org/wiki/Creational_pattern?oldid=764013572 Contributors: Mrwojo, TakuyaMurata,
Lancevortex, Steinsky, IceKarma, Fredrik, RedWolf, Khalid hassani, Kusunose, Khalid, Rjwilmsi, Cdiggins, SmackBot, Kellen, Nbarth,
SashatoBot, Hu12, Aaronas, Magioladitis, Jacob Robertson, Saigyo, Andy Dingley, EmxBot, Acflorea, Bob1960evens, Excirial, PixelBot,
Marraco~enwiki, Addbot, Luckas-bot, Erik9bot, Sae1962, Arigoldx, Surement, Mean as custard, RjwilmsiBot, Ripchip Bot, Zoolium,
Ninad Nagwekar, BattyBot, Yungtrang, Ramram 43210, Vanderjoe and Anonymous: 36
• Abstract factory pattern Source: https://en.wikipedia.org/wiki/Abstract_factory_pattern?oldid=769076235 Contributors: The Anome,
Boleslav Bobcik, Hephaestos, TakuyaMurata, Pcb21, Ronabop, Ronz, Benno~enwiki, Dcoetzee, Jay, Hao2lian, Furrykef, Saltine, Phil
Boswell, Robbot, RedWolf, Treutwein, Tea2min, BenFrantzDale, Nkocharh, Quamaretto, Superborsuk, Int19h, Tomwalden, Klemen Koc-
jancic, Mecanismo, CanisRufus, Sietse Snel, Bobo192, Solra Bizna, Enric Naval, Flammifer, Anthony Appleyard, Www.koeberl.priv.at,
127
128 CHAPTER 6. TEXT AND IMAGE SOURCES, CONTRIBUTORS, AND LICENSES
RainbowOfLight, Mahanga, Joriki, Woohookitty, Tabletop, Bluemoose, GregorB, Magister Mathematicae, Fred Bradstadt, FlaBot, Thomas
Linder Puls, Chobot, Peterl, Roboto de Ajvol, YurikBot, RussBot, Michael Slone, Balkrishnatalele, Stephenb, Manop, Krzyp~enwiki, The-
Mandarin, Zixyer, Pelister, Naasking, Drable, Eaefremov, SmackBot, Oben, HalfShadow, Gilliam, Vvarkey, Ekamaloff~enwiki, DHN-
bot~enwiki, Scray, Rnapier, Cybercobra, Matt.forestpath, A5b, Daniel.Cardenas, Tobiasly, Sir Nicholas de Mimsy-Porpington, RoboD-
ick~enwiki, Edenphd, Lunavorax, Hu12, Rory O'Kane, Hetar, Dan Gluck, Jsgoupil, Tawkerbot2, Eastlaw, Dgquintas, Skittleys, JoshHol-
loway, Merutak, Epbr123, Oddity-, Bdean42, MER-C, Magioladitis, Msjegan, Wikidudeman, Twsx, Jay.233, Abednigo, Ftiercel, Gwern,
MartinBot, Jonathan Hall, R'n'B, Linuraj, YurfDog, LordAnubisBOT, Roboto1148, Vinod.pahuja, Wikieditor06, Vikasgoyal77, Quack-
Guru, Wilfried Loche, Rican7, Imdonatello, Topdeck, Magnub, Mormat, Tronster, WikiJonathanpeter, Frór, Alx359, Niceguyedc, Pointil-
list, Vghuston, Sun Creator, Bigscoop, Diaa abdelmoneim, Gurjinder.rathore, XLinkBot, Venturor, Druckles, Addbot, Msthil, Fluffernutter,
MrOllie, AndersBot, SpBot, Yobot, Yonghuster, SergejDergatsjev, Nallimbot, Piano non troppo, Materialscientist, Obersachsebot, Xqbot,
Mtasic, TechBot, Vinhphunguyen, Phresnel, RibotBOT, Shadowjams, AJCham, Sae1962, RedBot, Pikiwyn, Kallikanzarid, Rupendrad-
hillon, Rtushar, Trappist the monk, Sdillman, Minimac, EmausBot, Lukasz.gosik, GoingBatty, David.nussio, Nitinpai2000, Demonkoryu,
Reyjose, 28bot, ClueBot NG, Jdcollins13, Smithrondive, Strike Eagle, Firetinder, Edbecnel, MusikAnimal, Shakethehill, Pilode, Fylbe-
catulous, BluesLf, AutisticCatnip, Mumeriqbal786, Winstonne, Nicktmro, Matinict, Miladrahimi93, Blair.butterworth, Napstr4u, Zymut,
GregKalapos, Mfilatov, Sadegh 1990 hosseini, Bthachdev and Anonymous: 256
• Builder pattern Source: https://en.wikipedia.org/wiki/Builder_pattern?oldid=762978473 Contributors: Hephaestos, Edward, Ixfd64,
Phoe6, TakuyaMurata, Ronz, Rossami, Jay, Wik, Hao2lian, Brooklyn1, Finlay McWalter, RedWolf, Cyrius, Per Abrahamsen, HelgeHan,
BenFrantzDale, Bensaccount, Khalid hassani, Madoka, Beland, DcoetzeeBot~enwiki, Jarsyl, Umreemala, Anthony Appleyard, Sligocki,
Cbiffle, Uncle G, Coldboyqn, Shyal-b, Fred Bradstadt, FlaBot, Thomas Linder Puls, AlphaFoobar, CiaPan, YurikBot, Ssimsekler, Hairy
Dude, Shell Kinney, Vdevigere, Arichnad, Pelister, Cedar101, Betacommand, Bluebot, IAmAI, SonOfNothing, Emcmanus, Mikethegreen,
Sadads, Frap, Allan McInnes, Cybercobra, Dreadstar, Daniel.Cardenas, Geh, Beetstra, Hu12, Cmcginnis, Lathspell, Amniarix, JForget,
CmdrObot, BennyD, Pmussler, Blankfrack, Sanspeur, Ketorin, Aneeshpu, Odie5533, Mital.vora, Ezraj, JMatthews, West Brom 4ever,
MER-C, Magioladitis, Msjegan, Abednigo, Ftiercel, Marcusmax, Vinod.pahuja, Wikidicted, Bináris, JavierMC, PeaceNT, Vikasgoyal77,
VolkovBot, Satyr9, Aesopos, Rponamgi, Lramos, Trashtoy, Mormat, AlleborgoBot, Janpolowinski, Yintan, Nijelprim~enwiki, Oxy-
moron83, Neoguru12, Supersid01, Glylvyn, The Thing That Should Not Be, Mzedeler, Drmies, Pointillist, Vghuston, Alexbot, Sun Creator,
Rimian, Khmerang, XLinkBot, Salazard1, Addbot, Dyker, MrOllie, SpBot, Numbo3-bot, Sedziwoj~enwiki, Ptbotgourou, AnomieBOT,
Rubinbot, Beetny, Inmyhand77, DirlBot, Xqbot, Mtasic, RibotBOT, Sae1962, Craig Pemberton, Naaram, Jesus Escaped, MastiBot, Jeroen
De Dauw, Capt. James T. Kirk, EmausBot, Lukasz.gosik, T638403, Booler80, Nitinpai2000, Toteb5, Demonkoryu, Nafeezabrar, Lylez,
ClueBot NG, WinerFresh, Oddbodz, Strike Eagle, Controllersphere, Rh.vieira, Shakethehill, Alex.Cham, Gallas.aladdin, Ghuckabone,
Ecabiac, Abba-best, Marcocast, Fuksito, Ahmed Jolani, Nishanthan144, Sbhukar, MSRylander, KroOoze, KroOoOze, Metalktulu, Ev-
geniiKhomutsky, Hannibal.hero, Dkolegov, Herpesklaus, Leem02, Justacoder, Bthachdev and Anonymous: 193
• Factory method pattern Source: https://en.wikipedia.org/wiki/Factory_method_pattern?oldid=767698277 Contributors: Ed Poor,
TakuyaMurata, Haakon, Ronz, Jay, Hao2lian, Jeffrey Smith, Bearcat, Robbot, Fredrik, RedWolf, Hemanshu, KellyCoinGuy, Wlievens,
Hadal, Acm, BenFrantzDale, Khalid hassani, Beland, ArthurDenture, Kefka, Andreas Kaufmann, RedWordSmith, Jkl, Sesse, Will2k, Um-
reemala, BrokenSegue, Kjkolb, Gnyus, Jakew, Aisaac, Gary, Liao, Anthony Appleyard, AmunRa84, Nforbes, NTK, Blomskoe, Mahanga,
Jogla~enwiki, Esben~enwiki, FBarber, Qwertyus, JIP, Rjwilmsi, Yamamoto Ichiro, FlaBot, Alvin-cs, Chobot, Ssimsekler, Hairy Dude,
Michael Slone, Little3lue, Sasuke Sarutobi, Chaser, Petur Runolfsson, Matthew0028, Pelister, Nielses, CWenger, LeonardoRob0t, Allens,
Samwilson, That Guy, From That Show!, SmackBot, InverseHypercube, Vald, Apanait, Rajah9, Evilandi, Thumperward, Nbarth, Charles
Moss, Frap, Decltype, OnixWP, Rjmooney, Neshatian, LtPowers, Edenphd, Hu12, Dreftymac, Courcelles, Enselic, Cydebot, Jamitzky,
Juansempere, Ebrahim, JMatthews, Bouchecl, Stannered, Dmprantz, AntiVandalBot, Tormit, MER-C, Pergriffiths, .anacondabot, Andreas
Toth, Magioladitis, Msjegan, Nomad311, Cartoro, Abednigo, Gwern, MartinBot, Mjworthey, R'n'B, Ncmvocalist, Gman124, MikeEagling,
Bigboojum, MartinRinehart, Brvman, Kshivakumar, Vikasgoyal77, VolkovBot, Philip Trueman, Slaunger, Oshwah, Vipinhari, Andy Din-
gley, Jddahl, Arturs Licis, Mormat, AlleborgoBot, Lexxsoft, SieBot, Khoango, VVVBot, Matthewhaworth, Zvpunry, Duplicity, Toddst1,
Flyer22 Reborn, Faradayplank, Svick, AlanUS, Gerold Broser, RobinHood70, Jobriath, Dynamiclc, Binksternet, Lucascullen, Mhtzdt,
Pointillist, Vghuston, Excirial, Alexbot, Bender2k14, Diaa abdelmoneim, Bpssoft, BOTarate, Aprock, 9thbit, Joswig, XLinkBot, Fell-
Gleaming, Vianello, Addbot, Alquantor, Architectureblog, OrlinKolev, Tide rolls, Krano, Zch051383471952, Westcoastr13, Khmer42,
Luckas-bot, Yobot, Fraggle81, SergejDergatsjev, Nowforever~enwiki, Starsareblueandfaraway, AnomieBOT, Rubinbot, Mbunyard, Ci-
tation bot, FreeRangeFrog, Xqbot, Edward.in.Edmonton, Redroof, Mtasic, Khrom, Marco.panichi, Alainr345, Thehelpfulbot, Ain32,
Sae1962, Guentherwagner, Julianjensen, Paradrop, Sumone10154, Galestar, MichielDMN, Slhck, RjwilmsiBot, Jowa fan, DASHBot, Mat-
tbierner, EmausBot, Rolf the wolf, Leo Cavalcante, RA0808, Thadguidry, RenamedUser01302013, Tommy2010, Nunopicado, Demonko-
ryu, MauiBoyInMaltby, Donner60, Dineshkumar Ponnusamy, Reyjose, ClueBot NG, BlueTaRaKa, Frietjes, Widr, Zero4573, Alklazema,
Helpful Pixie Bot, Soufiane2011, BG19bot, Pup500, Thesquaregroot, 1typesetter, BattyBot, C5st4wr6ch, Emilhdiaz, DavidLeighEllis,
Matinict, Anurag870, Monkbot, Jcodetips, Kurousagi, Alaskanloops, Rforuupt, Anareth, Fmadd, SebNag and Anonymous: 347
• Lazy initialization Source: https://en.wikipedia.org/wiki/Lazy_initialization?oldid=772758993 Contributors: Derek Ross, Ed Poor,
Michael Hardy, RedWolf, Lumingz, Enochlau, Rheun, Quagmire, Maximaximax, Rhomboid, Anthony Appleyard, Sundar2000,
Bilbo1507, BD2412, TheIncredibleEdibleOompaLoompa, FlaBot, VKokielov, Cedar101, JLaTondre, Tackline, JonHarder, Doug Bell,
The9muse, Brittannica, Gustavo.mori, Blankfrack, Thijs!bot, Tormit, Magioladitis, Msjegan, Avisnacks, Abednigo, Gwern, Atropos235,
Bcraun, YordanGeorgiev, Alexey Luchkovsky, Jerryobject, MASQUERAID, RobinHood70, Sun Creator, Addbot, Ztyx~enwiki, Spock
lone wolf, RepeatUntil, Luckas-bot, Amirobot, Psychogears, Rubinbot, Xqbot, Mtasic, BluePlateSpecial, Phresnel, GrouchoBot, Angilly,
Dotyoyo, Sae1962, MastiBot, Michael9422, Demonkoryu, ClueBot NG, Dexp, Manohar reddy123123, Mark.knol, Loriendrew, TotalDe-
pravity, Anoop Manakkalath, Vieque, Bender the Bot, Bthachdev and Anonymous: 70
• Multiton pattern Source: https://en.wikipedia.org/wiki/Multiton_pattern?oldid=730408885 Contributors: Peak, Khalid hassani, Beland,
Pavel Vozenilek, Janaagaard, Spoon!, Qwertyus, .digamma, Wavelength, Bmord, Chris the speller, Nbarth, Dubwai, Gang65, A876,
Drealecs, Magioladitis, Destynova, Abednigo, Gwern, Steve R Barnes, Viy75, CliffHall, Addbot, MrOllie, Ettrig, Yobot, DanielcWiki,
DavidHarkness, AnomieBOT, Mtasic, FrescoBot, Sae1962, Rentzepopoulos, Galestar, Inumedia, ZéroBot, Ros Original, Ranjit.sail,
Wookietreiber, Demonkoryu, Heavenlyhash, CraigDWells and Anonymous: 50
• Object pool pattern Source: https://en.wikipedia.org/wiki/Object_pool_pattern?oldid=750409665 Contributors: Tenbaset, CesarB, An-
dreas Kaufmann, Abdull, Jkl, Purplefeltangel, Dgpop, Pearle, Arunkd13, Anthony Appleyard, Mahanga, Munificent, Marudubshinki,
YurikBot, Hairy Dude, Aaron Schulz, SmackBot, Christoofar, PJTraill, Nbarth, Audriusa, Vorburger, Hectorpal, Moala, Arch4ngel,
Noodlez84, Cydebot, Juansempere, Magioladitis, Msjegan, Swpb, Jestar jokin, Ruijoel, Vinod.pahuja, Saigyo, Qxz, SieBot, Svick, Robin-
Hood70, M4gnum0n, WikHead, Addbot, Luckas-bot, Yobot, ArthurBot, Obersachsebot, GrouchoBot, Prari, Sae1962, Trappist the monk,
Softwayer, DoctorKubla, Dexbot, Izkala, Sadegh 1990 hosseini and Anonymous: 39
6.1. TEXT 129
ietreiber, Demonkoryu, Anonymous2420, Jk2q3jrklse, Conditioner1, Jordanarseno, Conditioner123, Mshravan wiki, Happyser, MCSH,
Matinict, Alex Muscar, Stamptrader, PriyankaSabharwal, Vovanada, Klaus3b, Ashrwe4a, Bthachdev and Anonymous: 158
• Bridge pattern Source: https://en.wikipedia.org/wiki/Bridge_pattern?oldid=771791961 Contributors: Zundark, IanLewis~enwiki, Heron,
Mintguy, Frecklefoot, Wapcaplet, TakuyaMurata, Pcb21, Sugarfish, Mxn, Hao2lian, Phil Boswell, RedWolf, Tea2min, BenFrantzDale,
Areicher, Khalid hassani, Beland, Supadawg, S.K., Umreemala, Cmdrjameson, DCEdwards1966, Anthony Appleyard, MattGiuca, Cho-
chopk, ErikHaugen, Fred Bradstadt, Deathy, Drrngrvy, Thomas Linder Puls, Quuxplusone, YurikBot, TheMandarin, Długosz, NickelShoe,
SmackBot, Kellen, Unyoyega, ImageObserver, DHN-bot~enwiki, Frap, OrphanBot, Daydreamer302000, Luís Felipe Braga, Springnuts,
Narcelio, Albert cheng, Michael miceli, Edenphd, Lexxdark, Hu12, Iridescent, Rouven Thimm, Lathspell, Pmussler, Kazubon~enwiki,
Odie5533, Torc2, Omicronpersei8, Thijs!bot, Bytebear, GiM, Cdunn2001, MER-C, Vladimir Bosnjak, Tim.simpson, Patrick Schneider,
Magioladitis, Mikemill, Msjegan, Abednigo, Mcavigelli, Ftiercel, Mjworthey, Jimlonj, Wiki Raja, Hnc14, Wikidicted, Honestshrubber,
Andy Dingley, Topdeck, Djmckee1, Mormat, Argel1200, Faradayplank, Dddenton, Supersid01, Malaki12003, RobinHood70, ClueBot,
Vghuston, M4gnum0n, MichalKwiatkowski, Ykhwong, Ryanvolpe, Seethefellow, Rimian, Cra88y, XLinkBot, Rror, Cipherynx, Profaisal,
Addbot, Mkell85, Legobot, Luckas-bot, Yobot, Ptbotgourou, Nallimbot, Billyblind, Chimply, Obersachsebot, Mtasic, SassoBot, Alainr345,
Javier.eguiluz, Sae1962, Joke de Buhr, Usmanmyname, TjBot, EmausBot, Lukasz.gosik, Andriiko, Burns700, Lylez, Helpful Pixie Bot,
Pratyya Ghosh, Eacameron, Seanhalle, My-2-bits, Editorfun, Gronk Oz, Eahlay, M.mateeullah, Bthachdev and Anonymous: 157
• Composite pattern Source: https://en.wikipedia.org/wiki/Composite_pattern?oldid=755394959 Contributors: Hephaestos, Mrwojo,
TakuyaMurata, Ronz, Nikai, Charles Matthews, Dysprosia, Hao2lian, RedWolf, BenFrantzDale, DCrazy, Pinguin.tk~enwiki, Joyous!,
Kate, Will2k, Narcisse, Umreemala, CatharticMoment, Pearle, Kars~enwiki, Anthony Appleyard, Gaurav1146, Zoz, Fred Bradstadt,
Thomas Linder Puls, Vonkje, BradBeattie, Winnwang, FrankTobia, YurikBot, Hairy Dude, Larry laptop, J0no, Nick1915, Wainstead, Snef-
tel, Coffeeflower, SmackBot, InverseHypercube, Eskimbot, Gilliam, Gene Thomas, ImageObserver, Emufarmers, OrphanBot, Decltype,
Luís Felipe Braga, Albert cheng, Michael miceli, Edenphd, Stwalkerster, Waggers, Hu12, Lathspell, Judgesurreal777, Skapur, Thama-
raiselvan, Shabbirbhimani, Dycedarg, Pmussler, A876, Thijs!bot, Hervegirod, Harborsparrow, MikalZiane, MER-C, VoABot II, Msje-
gan, Rishichauhan, Sebras, Abednigo, Mefyl~enwiki, AdrianHesketh, MartinBot, Mike926908240680, J.delanoy, CMosher01, Darkspots,
Jeepday, Aaron Rotenberg, Trashtoy, Damien Cassou, Shivendradayal, Gkarlic, RobinHood70, The Thing That Should Not Be, Braiam,
Alexbot, M4gnum0n, Bravegag, Jogerh, Andrewtkchan, Skarebo, Vishalmamania, Ewger, Addbot, Zarcadia, MrOllie, Matěj Grabovský,
Matekm, Mik01aj, Luckas-bot, Yobot, Bunnyhop11, Ptbotgourou, Nagnatron, Chimply, Mtasic, Vinhphunguyen, Alainr345, Wkjyh, Red-
Bot, EmausBot, Lukasz.gosik, Tubalubalu, ZéroBot, Anonymous2420, Helpful Pixie Bot, AvocatoBot, Whirlium, OccultZone, Monkbot,
Zymut, Hujintao hjt, Bthachdev and Anonymous: 131
• Decorator pattern Source: https://en.wikipedia.org/wiki/Decorator_pattern?oldid=771904864 Contributors: Mjb, BryceHarrington,
TakuyaMurata, Dori, Ahoerstemeier, Ronz, Doradus, Wik, ErikStewart, Hao2lian, Itai, Jeeves, RedWolf, Tea2min, Connelly, BenFrantz-
Dale, Khalid hassani, Matt Crypto, Urhixidur, Will2k, Murtasa, Triskaideka, Ascánder, JRM, Photonique, ACiD2, Minghong, Hesperian,
Anthony Appleyard, AmunRa84, Joriki, Cruccone, Qwertyus, Grokus, WouterBot, P0per, YurikBot, RussBot, Romanc19s, RUL3R,
Cedar101, Mostapha, SmackBot, Arny, Nbarth, DHN-bot~enwiki, Rrburke, Cybercobra, Doug Bell, Edenphd, Wikidrone, Mjresin,
EdC~enwiki, Drae, Hu12, Francesco Terenzani~enwiki, Snooper77, FatalError, CmdrObot, Pmussler, Aihtdikh, XcepticZP, Odie5533,
Bob Stein - VisiBone, Wackimonki, Dantheman531, Harborsparrow, Tgwizard, MER-C, Msjegan, Abednigo, Gwern, Pharaoh of the
Wizards, Awistaiw, Servel333, Motine, Adam Zivner, Tomerfiliba, VolkovBot, A4bot, Ggenellina, J1o1h1n, Andy Dingley, Trashtoy,
SieBot, Gerel, Anakin101, Mild Bill Hiccup, ThomHehl, Vghuston, Alexbot, Bravegag, XLinkBot, Gslockwood, J.lonnee~enwiki, Addbot,
Mortense, Download, Hunting dog, Khmer42, Yobot, Eric-Wester, Jim1138, Materialscientist, Mtasic, Phresnel, GrouchoBot, FrescoBot,
Sae1962, Maggyero, RedBot, Alph Bot, EmausBot, Booler80, Pljungqv, Gasparovicm, Tashuhka, Nheirbaut, Nafeezabrar, ClueBot NG,
Wildewouter, Codysnider, Widr, Conditioner1, Yuqingalex, Manohar reddy123123, Einsub, ʘx, Umlcat, Makecat-bot, Radiodef, Sean-
halle, Nichobouma, Dineshmore, Ghinrael, João Guilherme Farias Duda, Monkbot, Mipiro, Zymut, InternetArchiveBot, Eellor, ISynpi,
Dnesteruk, Bthachdev and Anonymous: 203
• Facade pattern Source: https://en.wikipedia.org/wiki/Facade_pattern?oldid=759884239 Contributors: IanLewis~enwiki, Nate Silva,
TakuyaMurata, Hofoen, Mxn, Dysprosia, Jogloran, Hao2lian, Narcissus, PBS, RedWolf, Forseti, BenFrantzDale, Jorend, Leonard G., Red-
Crystal, Ran, Beland, Abdull, Lpenz, Scullder, Chestertan, Kwamikagami, Anthony Appleyard, Ashlux, Tony Sidaway, Nibblus, Jussist,
Mahanga, Darkmane, Xrm0, Immure, YurikBot, Wavelength, Hairy Dude, Zwobot, LeonardoRob0t, Andyluciano~enwiki, Jfalvarez, Vald,
DHN-bot~enwiki, Frap, Kaikko~enwiki, Cybercobra, Luís Felipe Braga, A5b, Arch4ngel, Frederikton, Hu12, Lathspell, Dreftymac, Dlo-
hcierekim, Owen214, CmdrObot, Arvindkumar.avinash, Thadius856, Tormit, Joe Schmedley, Deflective, Hangy, MER-C, Magioladitis,
Msjegan, Otterfan, Abednigo, Dw31415, Moggie2002, Wookie2u, Andy Dingley, Trashtoy, Fuhrmanator, COBot, Svick, ~enwiki,
RobinHood70, Dkeithmorris, Puchiko, BOTarate, XLinkBot, Wwjdcsk, Albambot, Addbot, MrOllie, M4c0~enwiki, Jarble, Luckas-bot,
Xiaoddkkwe, Nallimbot, Rubinbot, Materialscientist, Aff123a, Xqbot, Mtasic, Sae1962, B3t, RedBot, Synook, RjwilmsiBot, EmausBot,
Lukasz.gosik, Rajeevrvis, AvicBot, Demonkoryu, Khishig.s, ClueBot NG, Santihollmann, ChamithN and Anonymous: 135
• Front Controller pattern Source: https://en.wikipedia.org/wiki/Front_controller?oldid=771918758 Contributors: Kku, Bevo, Jpp,
Uzume, Andreas Kaufmann, RHaworth, Wavelength, SmackBot, Frap, Griba2010, Ludde23, Dmforcier, AlanUS, Ekerazha, Chadmyers,
MystBot, BBL5660, Dsimic, Addbot, MrOllie, Matekm, Yobot, Nperriault, FrescoBot, Sae1962, Bcosca, Jase21, Hmglasgow, EmausBot,
Angrytoast, Dewritech, Helpful Pixie Bot, Kentoshi, TheJJJunk, Userform, Prasanna143, Softzen, Bmarriner, Frank.blaauw, Jb10210,
Monkbot, Narky Blert, Ian (Wiki Ed), InternetArchiveBot, Biosunbj, Qizhongzhi and Anonymous: 39
• Flyweight pattern Source: https://en.wikipedia.org/wiki/Flyweight_pattern?oldid=770139706 Contributors: PierreAbbat, Ray Van De
Walker, Kurt Jansson, TakuyaMurata, Pcb21, Mxn, Hao2lian, Justo, RedWolf, BenFrantzDale, Beryllium, Beland, Teglsbo, Twyford, Diego
Moya, Sproul, Debajit, M7bot, Kri, Roboto de Ajvol, Zozakral~enwiki, ZacBowling, Ryanl, Naasking, Cedar101, SmackBot, Eskimbot,
Emj, DHN-bot~enwiki, SuperDuffMan, Gnp, Cgodley, Warren, Albert cheng, Ebswift, Hu12, Lathspell, Amniarix, Micah hainline, Al-
phaWiki~enwiki, Odie5533, MER-C, Msjegan, Abednigo, Blastthisinferno, Ageekymonk, Senu, CMosher01, LordAnubisBOT, Entropy,
VolkovBot, Wizgob~enwiki, The Wild Falcon, Vipinhari, Anirudhvyas010, Maxim, BigDunc, Andy Dingley, Anthonygerrard, Op12,
Henke37, Ctxppc, FroZman, Rdhettinger, RobinHood70, Night Goblin, Mdjpurdon, WestwoodMatt, Alexbot, PixelBot, Sun Creator,
Northerly Star, XLinkBot, Anticipation of a New Lover’s Arrival, The, Addbot, LaaknorBot, Luckas-bot, Yobot, Ptbotgourou, DavidHark-
ness, Rubinbot, Tshak, ArthurBot, Mtasic, Nexus26, Martnym, Sae1962, Trappist the monk, DanielBrauer, Hmglasgow, EmausBot, John
of Reading, Dennis714, Demonkoryu, Lazeroptyx, Lylez, ClueBot NG, Accelerometer, DaveLiu, Jk2q3jrklse, Helpful Pixie Bot, Lyric-
Coder, BattyBot, Mylesmcdonnell, Chase.Gilliam, Lambda Fairy, Abhi2434, Raymond.naseef, Vltsu, Hrs2, Ramram 43210, Monkbot,
CayceBalara, Zymut, Pkinsky, SolskGaer, Empatiia, Qzd, Cmthacker, Pauljohanneskraft, Markuzo, Zhaojianhua, Bthachdev, Alanjds,
Vusalalishov, Cline22 and Anonymous: 105
6.1. TEXT 131
JonatanAndersson, Cp111, Vghuston, XLinkBot, Addbot, Normandomac, Pbyhistorian, Teles, Yobot, Ptbotgourou, AnomieBOT, Rubin-
bot, Anjsimmo, KJedi, Sae1962, Jonesey95, NuclearDuckie, Anonymous2420, Ontist, DaveLiu, David.moreno72, Klodr, Rafsan 033,
Jcodetips, Unnikked, Asorgiu, Remcelfr and Anonymous: 88
• Visitor pattern Source: https://en.wikipedia.org/wiki/Visitor_pattern?oldid=771572502 Contributors: Eob, TakuyaMurata, Karada,
Pcb21, Ronz, Gamma~enwiki, Andrewman327, Hao2lian, Phil Boswell, Fredrik, Mountain, RedWolf, Wlievens, Hadal, Lumingz,
Tea2min, Vir4030, BenFrantzDale, Beland, Int19h, Kate, Leibniz, Nchaimov, Sleske, VoluntarySlave, Forderud, Mcsee, Woohookitty,
MattGiuca, GregorB, Salix alba, FlaBot, Riki, YurikBot, Hairy Dude, Zozakral~enwiki, Gaius Cornelius, Wiki alf, Brandon, Nander-
man, Dethomas, Matthew0028, Pelister, Reyk, Luiscolorado, Alfredo.correa, SmackBot, Mitchan, Pkirlin, Eskimbot, Ohnoitsjamie, Jcar-
roll, Akanksh, Bluebot, Autarch, Theone256, DHN-bot~enwiki, Gyrobo, Gandalfgeek, Decltype, Kuru, Albert cheng, Edenphd, Poly-
Glot, Kvng, Hu12, Jokes Free4Me, Vinz83, Gnewf, Oerjan, Skarkkai, Fbahr, MER-C, Jrduncans, Magioladitis, Afsinbey, VoABot II,
Wikipodium, Cic, Ibic, Abednigo, Ftiercel, HGoat, Gwern, Hedwig in Washington, Ntalamai, Szeder, Alfatrion~enwiki, Kraftlos, Fyl-
wind, CardinalDan, Maghnus, Bennor, Anirudhvyas010, Andy Dingley, Fuhrmanator, Joel falcou~enwiki, Computerwguy, Jerryobject,
Pweifan, Svick, AlanUS, Iffypop, Devjava, Chris G Bot, PuercoPop, Bricegeumez, PipepBot, Alksentrs, Friskpeppermint, Vghuston,
M4gnum0n, Aeolian145, Bravegag, Versus22, Joswig, Thinking Stone, XLinkBot, C3foncea, MystBot, Addbot, Jjdawson7, Luckas-bot,
Yobot, AnomieBOT, Fizzbann1234, Billegge, Marau~enwiki, Materialscientist, Xqbot, Martnym, Sae1962, Mfwitten, B3t, Andy.m.jost,
Timenkov Fedor, Ржавый Хомяк, D chivaluri, Hajatvrc, EmausBot, JamesPoulson, Pewchies, Eight40, Sergei49, Hazard-SJ, Demonko-
ryu, ChuispastonBot, Prodigel, Anonymous2420, Objarni, My Name is Christopher, Rahab rx, Justincheng12345-bot, FoCuSandLeArN,
Goyalsachin22, Zymut, WansWeter, H662, Stokkie64, --, Dnesteruk, Kee.nam and Anonymous: 222
• Concurrency pattern Source: https://en.wikipedia.org/wiki/Concurrency_pattern?oldid=747226059 Contributors: Kku, Fredrik, Red-
Wolf, Khalid, TheParanoidOne, RJFJR, GregorB, Jopincar, Frap, Pcgomes, SashatoBot, Atreys, Casbah~enwiki, Torinthiel~enwiki, Magi-
oladitis, Mati22081979, Vinod.pahuja, Jogerh, Addbot, Luckas-bot, AshleySt, Sae1962, EmausBot, Ipsign, Enlilos, Sherbinko and Anony-
mous: 9
• Active object Source: https://en.wikipedia.org/wiki/Active_object?oldid=759572504 Contributors: Kku, Weeble, Beland, RHaworth,
Wigy, SmackBot, Stimpy, Tim@, JennyRad, Nbarth, Nixeagle, Tarcieri, Gingerjoos, ShakespeareFan00, Vegarwe, Keith D, Hans Adler,
Mitch Ames, Addbot, Zyx, Citation bot, Silesianus, Kobrabones, Trappist the monk, ZéroBot, Ipsign, BattyBot, Dexbot, 069952497a,
Wenerme, Zymut and Anonymous: 15
• Balking pattern Source: https://en.wikipedia.org/wiki/Balking_pattern?oldid=746485234 Contributors: Kku, TakuyaMurata, RedWolf,
DavidBrooks, Beland, Abdull, GregorB, Spliffy, Crystallina, SmackBot, Gwern, Jarble, Amiceli, Demonkoryu, Loopy48, Reify-tech,
Viperidaenz, Maiden taiwan and Anonymous: 12
• Messaging pattern Source: https://en.wikipedia.org/wiki/Messaging_pattern?oldid=764521786 Contributors: Beland, Abdull, Munahaf,
Anrie Nord, Prickus, Rwwww, SmackBot, Tinucherian, NunoAgostinho, 1000Faces, Djmackenzie, DumZiBoT, XLinkBot, Addbot, 4th-
otaku, JerryLerman, Lambda Magician, ChrisGualtieri, Dough34 and Anonymous: 19
• Double-checked locking Source: https://en.wikipedia.org/wiki/Double-checked_locking?oldid=764325639 Contributors: Taw, Freckle-
foot, TakuyaMurata, (, Haakon, ToastyKen, Julesd, RedWolf, Gracefool, Neilc, Beland, Andreas Kaufmann, RossPatterson, Rich Farm-
brough, Marudubshinki, E090, Ysangkok, YurikBot, Hairy Dude, Cryptic, Jyke, Jwir3, Nlu, Cedar101, SmackBot, Chronodm, PJTraill,
Jm307, Dripp, Dubwai, Doug Bell, Msundman, Jczeus, Bdawson, ShelfSkewed, AndrewHaley, Billyoneal, Wootery, Forbidder, Avisnacks,
Gwern, Javawizard, Billinghurst, Andy Dingley, Michaeldsuarez, Triesault, Initworks, SimonTrew, Quercus basaseachicensis, Alexbot,
XLinkBot, Addbot, Ghettoblaster, Atlaste, Bultro, Jarble, Yobot, AnomieBOT, Rubinbot, Digulla, Bbbush, Karl80, Dhvik, Mìthrandir,
Maggyero, I dream of horses, HRoestBot, Flyingped, BeeOnRope, Demonkoryu, AManWithNoPlan, ClueBot NG, MikeZar, Starry-
Grandma, Nikpantera, EdwardJKerley, Nurieta, Monkbot, Wenerme, Vikas.vksingh, InternetArchiveBot and Anonymous: 93
• Asynchronous method invocation Source: https://en.wikipedia.org/wiki/Asynchronous_method_invocation?oldid=764667365 Contrib-
utors: Pnm, Andreas Kaufmann, Abdull, Smalljim, Ron Ritzman, RHaworth, Uncle G, Qwertyus, Hairy Dude, JulesH, Cedar101, Smack-
Bot, JzG, Cydebot, Christian75, Cander0000, Aervanath, JL-Bot, Drmies, Hans Adler, Addbot, Freikorp, Davhdavh, HRoestBot, Trappist
the monk, DASHBot, Dcirovic, Ipsign, Sumeet.chhetri, Helpful Pixie Bot, BG19bot, Killjay89, Monkbot, Gpeja, WhyDoesSheRefuseTo-
HaveIntercourseWithMe, InternetArchiveBot, GreenC bot and Anonymous: 4
• Guarded suspension Source: https://en.wikipedia.org/wiki/Guarded_suspension?oldid=722162925 Contributors: TakuyaMurata, Pcb21,
HappyDog, Fredrik, CryptoDerk, Beland, Remuel, TheParanoidOne, MithrandirMage, TuukkaH, SmackBot, Reedy, Frap, Allan McInnes,
Citation bot, Amiceli, Citation bot 1, DrilBot, Loopy48 and Anonymous: 3
• Lock (computer science) Source: https://en.wikipedia.org/wiki/Lock_(computer_science)?oldid=767850805 Contributors: Zundark,
Taw, Edward, Nealmcb, TakuyaMurata, Dori, (, ²¹², Clausen, Jay, Zoicon5, Furrykef, Craig Stuntz, Altenmann, Tea2min, DavidCary,
Zigger, CyborgTosser, JimD, Jason Quinn, Neilc, Pgan002, Beland, Gazpacho, Ross bencina, KeyStroke, FT2, Wrp103, CanisRufus,
PaulMcKenney, Liao, Suruena, Jacobolus, Qwertyus, Rjwilmsi, Hathawayc, FlaBot, Maxal, Shivamohan, Quuxplusone, Chozan, Michael
Suess, YurikBot, RussBot, Michael Slone, Robert Will, Długosz, AnObfuscator, Gslin, SmackBot, Vald, OrangeDog, Allan McInnes,
Fuhghettaboutit, General Ization, Dicklyon, Torc2, Thijs!bot, McJaje, Hervegirod, Rsocol, Wmbolle, Magioladitis, SBunce, Gwern,
SJP, YB3, Zeroflag, Amorken, Wykypydya, Togamaru, Jerryobject, JCLately, Svick, Andahazy, Sun Creator, StanContributor, Erkin-
Batu, Addbot, Tothwolf, Lightbot, Omikronuk, Luckas-bot, Yobot, Amirobot, AnomieBOT, Kaycee srk, Mark Renier, Javier.eguiluz,
Sae1962, Roman12345, Maggyero, I dream of horses, Moonwolf14, Olawlor, Jfmantis, EmausBot, WikitanvirBot, GoingBatty, De-
monkoryu, Radik.khisamov, VictorianMutant, Danim, Helpful Pixie Bot, Saikrishna Chunchu, Dexbot, Softzen, Joshua.j.grossman,
SfEOaBx36VBaQKEL, B2u9vm1ea8g, Fmadd and Anonymous: 84
• Monitor (synchronization) Source: https://en.wikipedia.org/wiki/Monitor_(synchronization)?oldid=769326155 Contributors: Axel-
Boldt, Dcoetzee, Joy, Raul654, RickBeton, Jason Quinn, Abdull, Flex, Gazpacho, Mormegil, Rich Farmbrough, Bender235, Park-
landspanaway, John Vandenberg, Franl, Musiphil, Marudubshinki, Assimil8or~enwiki, Thomas Linder Puls, Intgr, Chobot, YurikBot,
Pburka, Cleared as filed, Waqas1987, Cedar101, JLaTondre, SmackBot, InverseHypercube, Ianb1469, Delldot, Charlesb, MalafayaBot,
Thiagomacieira, Chruck, Gennaro Prota, Yukoba~enwiki, Torc2, Dinnerbone, Thijs!bot, AntiVandalBot, Theodore.norvell, Gwern,
MartinBot, Niyue~enwiki, Fylwind, Rv74, Pdcook, Anna Lincoln, Wykypydya, Jerryobject, ClueBot, Gonnet, Moshewe, Niceguyedc,
Jeroen74~enwiki, Pacman128, Elizium23, Carriearchdale, DumZiBoT, Asafshelly, WikHead, Addbot, Tcncv, Leszek Jańczuk, Luckas-
bot, Yobot, GevorgVoskanyan1, Ipatrol, Xqbot, Miym, RibotBOT, Jacosi, FrescoBot, Moulaali, Craig Pemberton, I dream of horses,
TPReal, Surement, Ivanvector, DARTH SIDIOUS 2, Jfmantis, Herrturtur, John of Reading, AKEB~enwiki, Dewritech, GoingBatty,
Kislay kishore2003, ClueBot NG, Rinaku, Maarten Baert, Trevayne08, Chmarkine, Khazar2, Mtzguido, Quenhitran, Mohanagrawal13,
Arvindraivns, Monkbot, Nullptr, Jsg68x and Anonymous: 106
134 CHAPTER 6. TEXT AND IMAGE SOURCES, CONTRIBUTORS, AND LICENSES
6.2 Images
• File:Abstract_Factory_in_LePUS3_vector.svg Source: https://upload.wikimedia.org/wikipedia/commons/5/54/Abstract_Factory_in_
LePUS3_vector.svg License: Public domain Contributors: File:Abstract Factory in LePUS3.png Original artist: Amnon Eden
• File:Abstract_factory.svg Source: https://upload.wikimedia.org/wikipedia/commons/a/a7/Abstract_factory.svg License: CC-BY-SA-
3.0 Contributors: Recreation of Abstract_factory.png by Bdean42 in SVG format. Original artist: <a href='//commons.wikimedia.
org/wiki/User:DoktorMandrake' class='mw-redirect' title='User:DoktorMandrake'>Doktor</a><a href='//commons.wikimedia.org/wiki/
User_talk:DoktorMandrake' class='mw-redirect' title='User talk:DoktorMandrake'>Mandrake</a>
• File:Abstract_factory_UML.svg Source: https://upload.wikimedia.org/wikipedia/commons/9/9d/Abstract_factory_UML.svg License:
CC-BY-SA-3.0 Contributors: My own work, generated with omondo for eclipse 3.1.2, modified with inkscape. Original artist: Giacomo
Ritucci
• File:Adapter(Class)_pattern_in_LePUS3.png Source: https://upload.wikimedia.org/wikipedia/en/b/b3/Adapter%28Class%29_
pattern_in_LePUS3.png License: CC-BY-SA-3.0 Contributors:
self-made
Original artist:
Edenphd
• File:Adapter(Object)_pattern_in_LePUS3.png Source: https://upload.wikimedia.org/wikipedia/commons/1/1a/Adapter%28Object%
29_pattern_in_LePUS3.png License: Public domain Contributors: Own work Original artist: Amnon Eden (User:Edenphd)
6.2. IMAGES 135