Aniruddha Chakrabarti: Singleton Factory Method
Aniruddha Chakrabarti: Singleton Factory Method
Agenda
What is Design Pattern History of Design Pattern Background
Principles of OOP and OOAD What is Good Design Other Design Patterns and Principles (SOLID, GRASP) Anti Patterns
Classification of different types of design patterns Creational Design Patterns Structural Design Patterns Behavioral Design Patterns Architecture Patterns (Brief) Takeaway
2
OO Basic Tenants
Abstraction Encapsulation Polymorphism Inheritance Loose/Low Coupling
low dependency between classes; low impact in a class of changes in other classes high reuse potential
High Cohesion
measure of how strongly-related or focused the responsibilities of a single module are If methods of a class tend to be similar in many aspects, then the class have high cohesion In highly-cohesive system, code readability and the likelihood of reuse is increased, while complexity is kept manageable
Design Patterns (GoF) 3
OO Principles
Encapsulate what varies Favor Composition over Inheritance Program to interface not implementation Strive for loosely coupled design between objects that interact
Interface
Like an abstract base class: any non-abstract type inheriting the interface must implement all its members. Can not be instantiated directly. Can contain events, indexers, methods and properties. Contain no implementation of methods. Classes and structs can inherit from more than one interface. An interface can itself inherit from multiple interfaces.
10
11
Class Relationship
Dependency Association Aggregation Composition Generalization / Inheritance
12
Dependency
Dependency - Weaker form of relationship which indicates that one class depends on another because it uses it at some point of time. Dependency exists if a class is a parameter variable or local variable of a method of another class.
13
Aggregation - Whole part relationship. Part can exist without Whole. (Engine can exist even if Car is destroyed, the same Engine could be used in a different Car)
Composition Stronger form of whole part relationship. Part can not exist without Whole. (OrderDetail can not exist if Order is deleted. If Order is deleted, OrderDetail also gets deleted)
14
Generalization / Inheritance
15
16
GRASP Pattern
Acronym for General Responsibility Assignment Software Patterns. Assigning responsibilities to classes is a critical aspect of objectoriented design. Appropriate assignment of responsibilities to classes is the key to successful design. There are fundamental principles in assigning responsibilities that experienced designers apply. These principles are summarized in the GRASP patterns. Has nine core principles that object-oriented designers apply when assigning responsibilities to classes and designing message interactions.
17
18
19
Primitive Obsession
Data Class
Use small objects to represent data such as money (which combines quantity and currency) or a date range object Classes with fields and getters and setters and nothing else (aka, Data Transfer Objects - DTO) Clumps of data items that are always found together. Subclasses don't want or need everything they inherit. Liskov Substitution Principle (LSP) says that you should be able to treat any subclass of a class as an example of that class. Two classes are overly enter twined. Classes that aren't doing enough should be refactored away. Often a method that seems more interested in a class other than the one it's actually in. In general, try to put a method in the class that contains most of the data the method needs. This is the case in which a client has to use one object to get another, and then use that one to get to another, etc. Any change to the intermediate relationships causes the client to have to change. When a class is delegating almost everything to another class, it may be time to refactor out the middle man. Occurs when one class is commonly changed in different ways for different reasons. Any change to handle a variation should change a single class. The opposite of Divergent Change. A change results in the need to make a lot of little changes in several classes.
Data Clumps
Refused Bequest
Feature Envy
Special case of Shotgun Surgery. Every time you make a subclass of a class, you also have to make a subclass of another. 21
23
Behavioral Patterns
Chain of Responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template Method Visitor
Structural Patterns
24
25
Singleton Pattern
Used to implement the mathematical concept of a singleton, by restricting the instantiation of a class to one object. Useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects (say, five). Common Uses:
Abstract Factory, Builder and Prototype patterns can use Singletons in their implementation. Facade objects are often Singletons because only one Facade object is required. Singletons are often preferred to global variables because:
They don't pollute the global name space (or, in languages with namespaces, their containing namespace) with unnecessary variables. They permit lazy allocation and initialization, whereas global variables in many languages will always consume resources.
26
27
28
Advantages:
Disadvantages:
Because the instance is created inside the Instance property method, the class can exercise additional functionality. The instantiation is not performed until an object asks for an instance; this approach is referred to as lazy instantiation. Lazy instantiation avoids instantiating unnecessary singletons when the application starts. Not safe for multithreaded environments. If separate threads of execution enter the Instance property method at the same time, more that one instance of the Singleton object may be created.
29
In this strategy, the instance is created the first time any member of the class is referenced. CLR takes care of the variable initialization. The class is marked sealed to prevent derivation, which could add instances. In addition, the variable is marked readonly, which means that it can be assigned only during static initialization (which is shown here) or in a class constructor.
Design Patterns (GoF) 30
Double-check locking approach solves thread concurrency problems while avoiding an exclusive lock in every call to the Instance property method. Also allows you to delay instantiation until the object is first accessed. In practice, an application rarely requires this type of implementation. In most cases, the static initialization approach is sufficient.
31
Factory Method
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
32
33
34
35
36
37
38
39
40
41
Builder Pattern
Separate construction of a complex object from its representation so that the same construction process can create different representations. Parse a complex representation, create one of several targets. Difference Between Builder and Factory
Builder focuses on constructing a complex object step by step. Abstract Factory emphasizes a family of product objects - simple or complex. Builder returns the product as a final step, but as far as the Abstract Factory is concerned, the product gets returned immediately.
42
43
44
45
46
47
48
49
50
51
52
originalEmployee :Employee
originalAddress :Address
originalEmployee :Employee
originalAddress :Address
After
newEmployee :Employee newEmployee :Employee newAddress :Address
Shallow Copy
Deep Copy
53
54
55
56
57
DI Example - Unity
Lightweight, extensible dependency injection container Supports interception, constructor injection, property injection, and method call injection Part of MS Enterprise Library Application Block
58
Unity Example
59
Unity Example
60
61
62
63
64
65
Object Adapter
66
Class Adapter
67
68
69
70
71
72
73
74
Decorator Pattern
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. Client-specified embellishment of a core object by recursively wrapping it. Wrapping a gift, putting it in a box, and wrapping the box You want to add behavior or state to individual objects at run-time. Inheritance is not feasible because it is static and applies to an entire class.
75
76
Decorator in WPF
77
78
79
80
Bridge
Decouple an abstraction from its implementation so that the two can vary independently. Based on the principle Prefer Composition (and Association, Aggregation) over Inheritance Publish interface in an inheritance hierarchy, and bury implementation in its own inheritance hierarchy Beyond encapsulation, to insulation
81
82
A new type of Platform (JVM) is added. What happens if another type of scheduler is added and No of Platforms increase to four from three No of classes increases exponentially - Inheritance Hierarchy become complex, bloated and difficult to maintain.
83
Bridge Example
Decompose the component's interface and implementation into orthogonal class hierarchies. Abstract/Interface class contains a pointer to abstract implementation class. This pointer is initialized with an instance of a concrete implementation class, but all subsequent interaction from the interface class to the implementation class is limited to the abstraction maintained in the implementation base class. Client interacts with interface class - "delegates" all requests to implementation class.
84
Bridge
85
86
Contract Implementation
Host
Design Patterns (GoF) 87
Proxy
Client
Cannot have two operations in the same contract with the same name, methods Add and Add in type ConsoleApplication1.ICalculatorService violate this rule. You can change the name of one of the operations by changing the method name or by using the Name property of OperationContractAttribute.
88
Solution
89
Online
Offline
90
91
92
View
Model
93
94
Implement an Event
3. Determine when to raise the event in the class. Call OnEventName to raise the event. 1. Define a public event member in class. Set the type of event member to System.EventHandler delegate.
2. Provide a protected method in the class that raises the event. Name the method OnEventName. Raise the event within the method
Client can register for the events they are interested. Client can un-register for the events they have already registered.
95
96
IObserver
Push
IObservable
View
Model
97
98
99
Since String class implements IComparable Array.Sort (and Sort method of all collection classes including Generic and non-Generic collection classes) uses string's IComparable implementation to sort the array (String.CompareTo is used).
100
101
102
Generic version of CompareTo is used by CLR if both non generic and generic versions are present. Always prefer implementing IComparable<T> for better performance (no boxing, unboxing overhead)
Design Patterns (GoF) 103
104
Generic version of IComparer is used by CLR if both non Generic and Generic version is present. Always prefer implementing IComparer <T> for better performance (no boxing, unboxing overhead)
105
106
107
108
109
110
111
112
113
114
115
116
117
AntiPatterns
Pattern that may be commonly used but is ineffective and/or counterproductive in practice. The term was coined in 1995 by Andrew Koenig inspired by Gang of Four's book Design Patterns, The term was widely popularized three years later by the book AntiPatterns
118
Organizational AntiPatterns
Analysis paralysis: Devoting disproportionate effort to the analysis phase of a project Cash cow: A profitable legacy product that often leads to complacency about new products Design by committee: The result of having many contributors to a design, but no unifying vision Moral hazard: Insulating a decision-maker from the consequences of his or her decision. Stovepipe or Silos: A structure that supports mostly up-down flow of data but inhibits cross organizational communication Vendor lock-in: Making a system excessively dependent on an externally supplied component
119
120
Anemic Domain Model: Use of domain model without business logic. The domain model's objects cannot guarantee their correctness at any moment, because their validation logic is placed somewhere outside (most likely in multiple places). BaseBean: Inheriting functionality from a utility class rather than delegating to it Call super: Requiring subclasses to call a superclass's overridden method Circle-ellipse problem: Subtyping variable-types on the basis of value-subtypes Circular dependency: Introducing unnecessary direct or indirect mutual dependencies between objects or software modules Constant interface: Using interfaces to define constants God object: Concentrating too many functions in a single part of design (class) Object cesspool: Reusing objects whose state does not conform to the (possibly implicit) contract for re-use Object orgy: Failing to properly encapsulate objects permitting unrestricted access to their internals Poltergeists: Objects whose sole purpose is to pass information to another object Sequential coupling: A class that requires its methods to be called in a particular order Yo-yo problem: A structure (e.g., of inheritance) that is hard to understand due to excessive fragmentation
Dependency hell: Problems with versions of required products DLL hell: Inadequate management of dynamic-link libraries (DLLs), specifically on Microsoft Windows
121
Programming AntiPattern
Accidental complexity: Introducing unnecessary complexity into a solution Action at distance: Unexpected interaction between widely separated parts of system Blind faith: Lack of checking of correctness of a bug fix or result of a subroutine Boat anchor: Retaining a part of a system that no longer has any use Busy spin: Consuming CPU while waiting for something to happen, usually by repeated checking instead of messaging Caching failure: Forgetting to reset an error flag when an error has been corrected Cargo cult programming: Using patterns and methods without understanding why Coding by exception: Adding new code to handle each special case as it is recognized Error hiding: Catching an error message before it can be shown to the user and either showing nothing or showing a meaningless message Hard code: Embedding assumptions about environment of a system in its implementation Lava flow: Retaining undesirable (redundant or low-quality) code because removing it is too expensive or has unpredictable consequences Loop-switch sequence: Encoding a set of sequential steps using a switch within a loop statement Magic numbers: Including unexplained numbers in algorithms Magic strings: Including literal strings in code, for comparisons, as event types etc. Soft code: Storing business logic in configuration files rather than source code[7] Spaghetti code: Programs whose structure is barely comprehensible, especially because of misuse of code structures
122
Methodological AntiPatterns
Copy and paste programming: Copying (and modifying) existing code rather than creating generic solutions Golden hammer: Assuming that a favorite solution is universally applicable Improbability factor: Assuming that it is improbable that a known error will occur Not Invented Here (NIH) syndrome: The tendency towards reinventing the wheel (Failing to adopt an existing, adequate solution) Premature optimization: Coding early-on for perceived efficiency, sacrificing good design, maintainability, and sometimes even real-world efficiency Programming by permutation (or "programming by accident"): Trying to approach a solution by successively modifying the code to see if it works Reinventing the wheel: Failing to adopt an existing, adequate solution Reinventing the square wheel: Failing to adopt an existing solution and instead adopting a custom solution which performs much worse than the existing one. Silver bullet: Assuming that a favorite technical solution can solve a larger process or problem Tester Driven Development: Software projects in which new requirements are specified in bug reports
123
Resources
Discover the Design Patterns You're Already Using in the .NET Framework Exploring the Observer Design Pattern Observer Design Pattern in .NET 4 AntiPattern AntiPattern: Wikipedia
124
Facade
Facade or Faade is generally one side of the exterior of a building, especially the front, but also sometimes the sides and rear. The word comes from the French language, literally meaning "frontage" or "face".
Carlo Maderno's monumental faade of Saint Peter's basilica in Vatican City 125
Faade Pattern
A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:
Make a software library easier to use, understand and test, since the facade has convenient methods for common tasks Make code that uses the library more readable, for the same reason Reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system Wrap a poorly-designed collection of APIs with a single well-designed API
126
127
Sub System A
Sub System B
Sub System C
128
129
130
131
Mediator
132
Mediator
133
Mediator
134
135
136
137
138
Different classes representing different states of the object (CD Player) Each State specific class implements an interface (ICDPlayerStateChange) Each State specific class contains the code for the state change. The object (CDPlayer) simply delegates the call to these state specific classes. State of the object (CD Player) is managed by new State specific classes.
139
140
141
Chain of Responsibility
Decouples the sender of the request to the receiver. The only link between sender and the receiver is the request which is sent. Based on the request data sent, the receiver is picked. This is called data-driven. Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. Launch-and-leave requests with a single processing pipeline that contains many possible handlers. Promotes the idea of loose coupling.
142
143
144
145
146
147