Practical C++ Design - From Programming to Architecture
von: Adam B. Singer
Apress, 2017
ISBN: 9781484230572
Sprache: Englisch
257 Seiten, Download: 2928 KB
Format: PDF, auch als Online-Lesen
Table of Contents | 5 | ||
About the Author | 11 | ||
About the Technical Reviewer | 12 | ||
Preface | 13 | ||
Chapter 1: Defining the Case Study | 19 | ||
1.1 A Brief Introduction | 19 | ||
1.2 A Few Words About Requirements | 20 | ||
1.3 Reverse Polish Notation | 21 | ||
1.4 The Calculator’s Requirements | 23 | ||
1.5 The Source Code | 24 | ||
Chapter 2: Decomposition | 26 | ||
2.1 The Elements of a Good Decomposition | 27 | ||
2.2 Selecting an Architecture | 29 | ||
2.2.1 Multi-Tiered Architecture | 29 | ||
2.2.2 Model-View-Controller (MVC) Architecture | 31 | ||
2.2.3 Architectural Patterns Applied to the Calculator | 32 | ||
2.2.4 Choosing the Calculator’s Architecture | 33 | ||
2.3 Interfaces | 34 | ||
2.3.1 Calculator Use Cases | 35 | ||
2.3.1.1 Use Case: User Enters a Floating Point Number onto the Stack | 35 | ||
2.3.1.2 Use Case: User Undoes Last Operation | 35 | ||
2.3.1.3 Use Case: User Redoes Last Operation | 35 | ||
2.3.1.4 Use Case: User Swaps Top Stack Elements | 35 | ||
2.3.1.5 Use Case: User Drops the Top Stack Element | 36 | ||
2.3.1.6 Use Case: User Clears the Stack | 36 | ||
2.3.1.7 Use Case: User Duplicates the Top Stack Element | 36 | ||
2.3.1.8 Use Case: User Negates the Top Stack Element | 36 | ||
2.3.1.9 Use Case: User Performs an Arithmetic Operation | 36 | ||
2.3.1.10 Use Case: User Performs a Trigonometric Operation | 37 | ||
2.3.1.11 Use Case: User Performs yx | 37 | ||
2.3.1.12 Use Case: User Performs | 37 | ||
2.3.1.13 Use Case: User Loads a Plugin | 37 | ||
2.3.2 Analysis of Use Cases | 38 | ||
2.3.3 A Quick Note on Actual Implementation | 44 | ||
2.4 Assessment of Our Current Design | 45 | ||
2.5 Next Steps | 45 | ||
Chapter 3: The Stack | 47 | ||
3.1 Decomposition of the Stack Module | 47 | ||
3.2 The Stack Class | 50 | ||
3.2.1 The Singleton Pattern | 50 | ||
3.2.2 The Stack Module as a Singleton Class | 52 | ||
3.2.2.1 The Pimpl Idiom | 54 | ||
3.3 Adding Events | 56 | ||
3.3.1 The Observer Pattern | 57 | ||
3.3.1.1 Enhancing the Observer Pattern Implementation | 58 | ||
3.3.1.2 Handling Event Data | 63 | ||
3.3.2 The Stack as an Event Publisher | 68 | ||
3.3.3 The Complete Stack Interface | 69 | ||
3.4 A Quick Note on Testing | 70 | ||
Chapter 4: The Command Dispatcher | 72 | ||
4.1 Decomposition of the Command Dispatcher | 72 | ||
4.2 The Command Class | 73 | ||
4.2.1 The Command Pattern | 73 | ||
4.2.2 More on Implementing Undo/Redo | 74 | ||
4.2.3 The Command Pattern Applied to the Calculator | 76 | ||
4.2.3.1 The Command Interface | 76 | ||
4.2.3.2 The Undo Strategy | 85 | ||
4.2.3.3 Concrete Commands | 90 | ||
4.2.3.4 An Alternative to Deep Command Hierarchies | 91 | ||
4.3 The Command Repository | 96 | ||
4.3.1 The CommandRepository Class | 96 | ||
4.3.2 Registering Core Commands | 102 | ||
4.4 The Command Manager | 103 | ||
4.4.1 The Interface | 103 | ||
4.4.2 Implementing Undo and Redo | 104 | ||
4.5 The Command Dispatcher | 106 | ||
4.5.1 The Interface | 107 | ||
4.5.2 Implementation Details | 108 | ||
4.6 Revisiting Earlier Decisions | 110 | ||
Chapter 5: The Command Line Interface | 112 | ||
5.1 The User Interface Abstraction | 112 | ||
5.1.1 The Abstract Interface | 113 | ||
5.1.2 User Interface Events | 116 | ||
5.1.2.1 Command Data | 117 | ||
5.1.2.2 User Interface Observers | 118 | ||
5.2 The Concrete CLI Class | 120 | ||
5.2.1 Requirements | 120 | ||
5.2.2 The CLI Design | 122 | ||
5.2.2.1 The Interface | 122 | ||
5.2.2.2 The Implementation | 123 | ||
5.3 Tying It Together: A Working Program | 127 | ||
Chapter 6: The Graphical User Interface | 129 | ||
6.1 Requirements | 129 | ||
6.2 Building GUIs | 132 | ||
6.2.1 Building GUIs in IDEs | 133 | ||
6.2.2 Building GUIs in Code | 134 | ||
6.2.3 Which GUI Building Method Is Better? | 135 | ||
6.3 Modularization | 136 | ||
6.3.1 The CommandButton Abstraction | 136 | ||
6.3.2 The CommandButton Design | 137 | ||
6.3.3 The CommandButton Interface | 141 | ||
6.3.4 Getting Input | 143 | ||
6.3.5 The Design of the InputWidget | 143 | ||
6.3.6 The Interface of the InputWidget | 145 | ||
6.4 The Display | 146 | ||
6.4.1 The Design of the Display Class | 148 | ||
6.4.2 A Poor Design | 148 | ||
6.4.3 An Improved Display Design | 149 | ||
6.5 The Model | 150 | ||
6.6 The Display Redux | 152 | ||
6.7 Tying It Together: The Main Window | 153 | ||
6.8 Look-and-Feel | 155 | ||
6.9 A Working Program | 156 | ||
6.10 A Microsoft Windows Build Note | 158 | ||
Chapter 7: Plugins | 159 | ||
7.1 What Is a Plugin? | 159 | ||
7.1.1 Rules for C++ Plugins | 160 | ||
7.2 Problem 1: The Plugin Interface | 163 | ||
7.2.1 The Interface for Discovering Commands | 163 | ||
7.2.2 The Interface for Adding New GUI Buttons | 168 | ||
7.2.3 Plugin Allocation and Deallocation | 170 | ||
7.2.4 The Plugin Command Interface | 170 | ||
7.2.5 API Versioning | 173 | ||
7.2.6 Making the Stack Available | 174 | ||
7.3 Problem 2: Loading Plugins | 175 | ||
7.3.1 Platform-Specific Plugin Loading | 176 | ||
7.3.2 Loading, Using, and Closing a Shared Library | 176 | ||
7.3.3 A Design for Multi-Platform Code | 178 | ||
7.3.3.1 The Obvious Solution: Libraries | 179 | ||
7.3.3.2 Raw Preprocessor Directives | 179 | ||
7.3.3.3 (Slightly) More Clever Preprocessor Directives | 180 | ||
7.3.3.4 A Build System Solution | 181 | ||
7.3.3.5 A Platform Factory Function | 182 | ||
7.3.3.6 An Abstract Factory for Generalized Platform Independent Code | 186 | ||
7.4 Problem 3: Retrofitting pdCalc | 191 | ||
7.4.1 Module Interfaces | 192 | ||
7.4.1.1 Source Code Hiding | 192 | ||
7.4.1.2 DLL Hiding | 193 | ||
7.4.1.3 Implicit or Documentation Hiding | 195 | ||
7.4.1.4 Module Design for pdCalc | 195 | ||
7.4.2 Adding Plugin Buttons to the GUI | 196 | ||
7.5 Incorporating Plugins | 197 | ||
7.5.1 Loading Plugins | 198 | ||
7.5.2 Injecting Functionality | 199 | ||
7.6 A Concrete Plugin | 201 | ||
7.6.1 Plugin Interface | 201 | ||
7.6.2 Source Code Dependency Inversion | 203 | ||
7.6.3 Implementing HyperbolicLnPlugin’s Functionality | 204 | ||
7.7 Next Steps | 207 | ||
Chapter 8: New Requirements | 208 | ||
8.1 Fully Designed New Features | 208 | ||
8.1.1 Batch Operation | 209 | ||
8.1.2 Stored Procedures | 210 | ||
8.1.2.1 The User Interface | 212 | ||
8.1.2.2 Changes to the Command Dispatcher | 213 | ||
8.1.2.3 Designing the StoredProcedure Class | 217 | ||
8.1.2.4 The Composite Pattern | 218 | ||
8.1.2.5 A First Attempt | 219 | ||
8.1.2.6 A Final Design for the StoredProcedure Class | 221 | ||
8.2 Designs Toward a More Useful Calculator | 224 | ||
8.2.1 Complex Numbers | 224 | ||
8.2.1.1 Modifying Input and Output | 225 | ||
8.2.1.2 Modifying the Stack | 227 | ||
8.2.1.3 Modifying Commands | 229 | ||
8.2.2 Variables | 229 | ||
8.2.2.1 Input and New Commands | 230 | ||
8.2.2.2 Number Representation and the Stack | 231 | ||
8.2.2.3 The Symbol Table | 232 | ||
8.2.2.4 A Trivial Extension: Numeric Constants | 233 | ||
8.2.2.5 Functionality Enabled by Variables | 233 | ||
8.3 Some Interesting Extensions for Self-Exploration | 234 | ||
8.3.1 High DPI Scaling | 234 | ||
8.3.2 Dynamic Skinning | 234 | ||
8.3.3 Flow Control | 235 | ||
8.3.4 An Alternative GUI Layout | 235 | ||
8.3.5 A Graphing Calculator | 235 | ||
8.3.6 A Plugin Management System | 236 | ||
8.3.7 A Mobile Device Interface | 236 | ||
Appendix A: Acquiring, Building, and Executing pdCalc | 237 | ||
A.1 Getting the Source Code | 237 | ||
A.2 Dependencies | 237 | ||
A.3 Building pdCalc | 238 | ||
A.3.1 Using Qt Creator | 239 | ||
A.3.2 Using the Command Line | 240 | ||
A.4 Executing pdCalc | 241 | ||
A.4.1 Using Qt Creator | 241 | ||
A.4.2 Using the Command Line | 241 | ||
A.5 Troubleshooting | 242 | ||
Appendix B: Organization of the Source Code | 245 | ||
B.1 The src Directory | 245 | ||
B.1.1 The pdCalc Directory | 245 | ||
B.1.2 The pdCalc-simple-cli Directory | 246 | ||
B.1.3 The pdCalc-simple-gui Directory | 246 | ||
B.1.4 The utilities Directory | 246 | ||
B.1.5 The backend Directory | 246 | ||
B.1.6 The cli Directory | 247 | ||
B.1.7 The gui Directory | 248 | ||
B.1.8 The plugins Directory | 248 | ||
B.2 The test Directory | 248 | ||
B.2.1 The testDriver Directory | 249 | ||
B.2.2 The utilitiesTest Directory | 249 | ||
B.2.3 The backendTest Directory | 249 | ||
B.2.4 The cliTest Directory | 250 | ||
B.2.5 The guiTest Directory | 250 | ||
B.2.6 The pluginsTest Directory | 250 | ||
References | 251 | ||
Index | 254 |