11. Why use design patterns?
• Proven solutions
• Simplify code structure
• Promote loose coupling, high cohesion
• Enhance testing/testability
Design Patterns are where the power of OOP comes from
13. Common Themes
• Code to an Interface, not an Implementation
• One class == one responsibility
• Favor Compostion over Inheritance
• Replace branching with polymorphism
• Low coupling, high cohesion
14. Types of Patterns
• Architectural • Code
o Client-Server o Adapter
o Cloud o Chain-of-Command
o Command
• Application o Decorator
o MVC o Delegate
o Services o Factory
o Message Queue o Flyweight
o Observer
• UX o Singleton
o Call to Action o Strategy
o Progressive o Visitor
disclosure
16. Strategy
• Define a family of behaviors
• Each behavior is accessed via a common interface
• Client code doesn't care which behavior it uses
• Behaviors can be shared across class hierarchies
17. Delegate
• Delegator passes a request to a helper (the delegate)
• Delegate handles request, passes result back
• Delegator passes result back to caller
18. Decorator
• Add behaviors to a base object dynamically
• Base decorator passes through unmodified
• Decorators that modify requests or responses
• Decorators wrap a base object or decorator
21. Patterns derive from each other
• Delegate is based on Strategy
• CoR is a string of Delegates that call each other
• Decorator & Observer are CoR that always run to the end
22. Wrap Up
• More patterns out there: Command, Facade, Pool,
Mediator, Visitor, Adapter
• Use this vocabulary during technical discussions
• Refactor spaghetti and long-winded code
• Decrease coupling, increase cohesion!
* Use classes to hold data structures together * Logic is procedural * Ask for data, but operates on data outside of where the data resides * Rules are hard-coded * Stage 0: Egg, all code is procedural, global state, arrays/scalars for data
* Use classes to hold data structures together, and provide behaviors for maintaining the data * Ensure data integrity * Most logic is still procedural, hard-coded
* Use classes to hold data structures together, and provide behaviors for maintaining the data * Objects also represent behavior, not just data * Logic comes from the interaction of objects via contracts/interfaces * Behavior emerges from interactions, not predetermined rules
* Gang of Four * Best practices
* No one-size-fits-all * Require forethought to determine which pattern is appropriate * No excuse for poorly designed code
* pre-mature optimization * misunderstood refactoring * Any pattern taken to an extreme can become an anti-pattern
* Provide a common vocabulary for discussing architecture * Simplicity through code re-use * Coupling: unnecessary linking of one component to another. Hard to change one without changing the other. * Solve by coding to an interface! * Cohesion: component parts fit together in logical, narrowly-defined ways. * One class or method = one responsibility
* An object has only one responsibility * Objects are open for extension but closed for modification * Any entity can be replaced by a sub-type of that entity (or one that meets the same contract) * Many specific interfaces are better than one general interface * Depend on contracts/interfaces, not concrete instantiations
* themes that underly all the design patterns * at least the ones we're going to talk about * De-coupling * Tight cohesion * small classes and methods are easier to work with than large ones * easier to debug * easier to test! * Dependency Injection * Objects create objects or do business logic, not both
* architectural: how systems fit together, interact * application: how code systems are divided, layered * Code: how code logic is divided, behaves and interacts * Common to all: how bits of a system talk to each other, pass information (code, servers, users) * You've probably used these patterns without knowing it, or knowing their names
* Next slides: * Introduce a pattern * Concept * When to use * Show an example
* Very common pattern, can be seen as the basis for many other patterns * If you learn only one, learn this one! * Each behavior is its own class * Behavior can be selected and changed at runtime * Behavior not tied to client * Composition over inheritance! * Unit testing tip: pass in a mock strategy to test that client calls it correctly Use when: * behavior needed across multiple classes/heirarchies * behavior needs to change dynamically
* Strategy's brother * Code sample-1 * Code sample-2 Use when: * Single object has a wide interface
* Classis example is ordering pizza, coffee, car options * Notice that no decorator knows if it's talking to a decorator or the base object. * Can unit test decorator by passing in a mock base, know it will work on any decorator or base in the family * Code sample-3 Use when: * Behaviors are conditional * Behaviors are chained * Order (probably) doesn't matter
* Also see this called "Chain of Command" * I used to call it this, but saw people get it confused with the actual "Command" pattern * Dispatcher only knows the first handler * Dispatcher doesn't care who handled the event, only that it was or was not handled * Handlers handle their own errors internally, should not affect dispatcher or any other handler * Code sample-4 * Code sample-5 Use when: * More than one way to handle an event * How it's handled doesn't matter; just that it is handled or not
* Broadcast is an event and any associated parameters * Subscribers can request only to hear about specific events * Subscribers must cleanup after themselves, handle their own failure * Decouples generation of event from its handling * Doctrine * Javascript in general * Code sample-6 Use when: * Event triggers many independent behaviors * Event generator doesn't care about results * State changes need to be known by many objects
* Said before, if you only learn one, learn Strategy. * All other can be derived from it