|
@@ -0,0 +1,136 @@
|
|
|
+# Design Patterns
|
|
|
+## Introduction
|
|
|
+- General, reusable solution in a commonly occurring problem within a given context in software design
|
|
|
+- Patterns have been used for the longest times in architecture (Arches, doors, support structures)
|
|
|
+- The same applies to Software Engineering
|
|
|
+
|
|
|
+## Design Patterns - Elements of Reusable Objective-Oriented Software 1994
|
|
|
+- Still valid but other patterns and paradigms have been discovered since
|
|
|
+- Patterns you would come up with regardless just from experience
|
|
|
+- Put into a book, formally, to create a language around the patterns
|
|
|
+- Major Patterns: Creational, Structural, Behavioural
|
|
|
+- Added Patterns: Concurrency
|
|
|
+
|
|
|
+## Creational
|
|
|
+### Factory Method
|
|
|
+- Subclasses dictate the class instance created
|
|
|
+- Design patterns don't have to be implemented as-is
|
|
|
+- Useful to use slightly different approaches for similar problems
|
|
|
+- Simplify creation of objects with default arguments
|
|
|
+
|
|
|
+#### Example
|
|
|
+`create_ipc_message`
|
|
|
+
|
|
|
+### Object Pool Pattern
|
|
|
+- Many objects of same type that are expensive to instantiate: thread, file, workers
|
|
|
+- These objects are used often, but possibly for a short period of time
|
|
|
+#### Example
|
|
|
+Webserver wants each request to run in its own thread, but don't want to create a thread each time.
|
|
|
+Solution: Create a thread pool
|
|
|
+
|
|
|
+## Resource Acquisition is Initialization (RAII)
|
|
|
+Idiom used in object-oriented, statically-typed languages.
|
|
|
+
|
|
|
+Useful to make sure resources are released when an exception is thrown.
|
|
|
+
|
|
|
+Mostly in C++
|
|
|
+
|
|
|
+### Singleton Pattern
|
|
|
+- Ensure class has one instance
|
|
|
+- Easily access the sole instance
|
|
|
+- Control instantiation
|
|
|
+- Restrict number of instances
|
|
|
+- Access a global variable
|
|
|
+- Private constructor - method to give you access to the one instance
|
|
|
+
|
|
|
+## Structural Patterns
|
|
|
+Adapter: adapt interface per a given set of expectations
|
|
|
+Aggregate: Composite with methods for aggregation of children
|
|
|
+Bridge: decouple an abstraction from its implementation so they can vary
|
|
|
+Composite: free structure of objects where every object has same interface
|
|
|
+Decorator: Add additional functional to an object
|
|
|
+Extensibility:
|
|
|
+Facade
|
|
|
+Flyweight
|
|
|
+Marker
|
|
|
+Pipes and filters
|
|
|
+Opaque pointer
|
|
|
+Proxy
|
|
|
+*These all adapt interfaces*
|
|
|
+
|
|
|
+## Behaviour Patterns
|
|
|
+### Chain of Responsibility
|
|
|
+*Have a single request handled by several different objects/levels/systems etc*
|
|
|
+1. Send a request
|
|
|
+2. Each of 3 handlers must perform an action
|
|
|
+
|
|
|
+#### Example
|
|
|
+Logger has 3 different possible loggers
|
|
|
+In calling code, instantiate logger and add the loggers with each their own log level
|
|
|
+When the logger is asked to a log a message, it will only call the loggers appropriate to the particular log level provided to the call
|
|
|
+
|
|
|
+Works well with protocol stacks: send a message and it goes up or down the stack to the physical layer, and then goes back to the application layer
|
|
|
+
|
|
|
+### Command Pattern
|
|
|
+Object wrapping a function.
|
|
|
+You give that object to be executed by someone else
|
|
|
+
|
|
|
+### Iterator Pattern
|
|
|
+Class which has or is a container
|
|
|
+Instead of iterating through each element of the container, you have an interface which returns an object with a `next()` method which navigates to the subsequent element of that same container
|
|
|
+Abstraction layer over a container
|
|
|
+
|
|
|
+### Memento Pattern
|
|
|
+Used in user interfaces
|
|
|
+Infamous `Undo` and `Redo`
|
|
|
+Memento has a state that can be stored. If you have a stack of memento, you can implement the logic to work through the stack of previous states
|
|
|
+
|
|
|
+### Subject Observer Pattern
|
|
|
+AKA Observer Pattern
|
|
|
+- One to many dependency between objects defined without making objects tightly coupled
|
|
|
+- We don't know how many observers we will have on the subject
|
|
|
+- It should be possible that one object can notify an open ended number of objects
|
|
|
+Event loop with possible observers to receive events
|
|
|
+
|
|
|
+### State Pattern
|
|
|
+- Object should change its behaviour when internal state changes
|
|
|
+- State-specific behaviour should be defined independently
|
|
|
+
|
|
|
+How:
|
|
|
+- Define separate state objects that encapsulate state-specific behaviour
|
|
|
+- Class delegates state-specific behaviour to its current sate object, instead of implementating state-specific behaviour directly
|
|
|
+
|
|
|
+### Visitor Pattern
|
|
|
+Like chain of responsibility, but rather than a request going to a bunch of different objects, instead it's something which happens while visiting a certain structure
|
|
|
+
|
|
|
+## Concurrency Patterns
|
|
|
+### Active Object Pattern
|
|
|
+Activeobject design pattern decouples method execution from method invocation for objects that reside in their own thread.
|
|
|
+
|
|
|
+Command pattern is applied here.
|
|
|
+
|
|
|
+Pattern consists of six elements:
|
|
|
+- Proxy providing interface towards clients
|
|
|
+- Interface with request() to active object
|
|
|
+- List of pending requests
|
|
|
+- Scheduler which decides which request to execute
|
|
|
+- Active object method
|
|
|
+- Callback or variable for client to receive the result
|
|
|
+
|
|
|
+### Double-checked Locking
|
|
|
+See example in code
|
|
|
+
|
|
|
+### Concurrency Lock Pattern
|
|
|
+If two threads can change bank balance, you are in trouble. Lock access to account balance
|
|
|
+
|
|
|
+### CPU Atomic Operation
|
|
|
+Allows for locking of variable without a mutex
|
|
|
+Atomic operations cannot be interrupted by another thread
|
|
|
+Works with fundamental types (int, float)
|
|
|
+Made possible through Assembler call "Compare and Exchange" CMPXCHG
|
|
|
+Modern languages support this and take care of calling the right Assembler instruction
|
|
|
+Checks the value of a variable and then sets its value in a single operation without the possibility of being interrupted
|
|
|
+```
|
|
|
+static std::atomic_bool exiting(false);
|
|
|
+if (exiting.exchange(true)) return;
|
|
|
+```
|