B8. Design Patterns En
B8. Design Patterns En
ĐỐI TƯỢNG
GV: Đặng Ngọc Hoàng Thành
Email: thanhdnh@ueh.edu.vn
Agenda
• 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
OO Principles
• Abstract class can have non abstract methods, methods of an interface are effectively
abstract since they contain only the signature
• A class can implement any no of interfaces, but can subclass at most one abstract
class.
• An abstract class can declare and use variables, an interface can not.
• An abstract class can have methods whose access is public, internal, protected,
protected internal and private. Interface members implicitly have public access.
• An abstract class can declare constructor, an interface can not.
• An abstract class can have delegate, an interface can not.
O
Does compile and work, but should be avoided
P
Object of type Interface should be used
• Dependency
• Association
• Aggregation
• Composition
• Generalization / Inheritance
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.
Student Course
Association – Loose form of relationship
Student Enrolls in Course (Student can enroll in multiple Course, and A
Attributes
1..* 1..*
Attributes Course can have multiple Student)
Operations Operations
Person
Attributes
Operations
Employee Customer
Attributes Attributes
Operations Operations
FullTimeEmployee Contractor
Attributes Attributes
Operations Operations
• Expert.
• Creator.
• Controller.
• Low Coupling.
• High Cohesion.
• Polymorphism.
• Pure Fabrication.
• Indirection.
• Don’t Talk to Strangers.
• Primitive Obsession: use small objects to represent data such as money (which combines quantity and currency) or a date
range object
• Data class: Classes with fields and getters and setters and nothing else (aka, Data Transfer Objects - DTO)
• Data Clumps: Clumps of data items that are always found together.
• Refused Bequest: 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.
• Inappropriate Intimacy: Two classes are overly enter twined.
• Lazy Class: Classes that aren't doing enough should be refactored away.
• Feature Envy: 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.
• Message Chains: 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.
• Middle Man: When a class is delegating almost everything to another class, it may be time to refactor out the middle man.
• Divergent Change: Occurs when one class is commonly changed in different ways for different reasons. Any change to
handle a variation should change a single class.
• Shotgun Surgery: The opposite of Divergent Change. A change results in the need to make a lot of little changes in several
classes.
• Parallel Inheritance Hierarchies: Special case of Shotgun Surgery. Every time you make a subclass of a class, you also have
to make a subclass of another
What is Design Pattern
• Advantages:
– 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.
• Disadvantages:
– 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.
Design Patterns (GoF)
Thread Safe Singleton in .NET (using Static)
• 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)
Multithreaded Singleton in .NET
• In practice, an application rarely requires this type of implementation. In most cases, the static
initialization approach is sufficient.
Design Patterns (GoF)
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.
GetEnumerator() returns
an specific enumerator
type based on the collection
class
• 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.
• Builder often builds a Composite.
• Specify the kinds of objects to create using a prototypical instance, and create new
objects by copying this prototype.
• Co-opt one instance of a class for use as a breeder of all future instances.
Before
originalEmployee originalAddress
:Employee :Address
After
newEmployee newEmployee newAddress
:Employee :Employee :Address
• Adapter pattern (also called wrapper pattern or wrapper) translates one interface for a
class into a compatible interface.
• Allows classes to work together that normally could not because of incompatible
interfaces, by providing its interface to clients while using the original interface.
• The adapter translates calls to its interface into calls to original interface. Amount of
code necessary to do this is typically small.
• The adapter is also responsible for transforming data into appropriate forms.
• Often used while working with existing API/code base and while adapting code for
which no source is not available.
• Could be of two types
– Object Adapter
– Class Adapter
• Data Adapters adapts data from different source (SQL Server, Oracle, ODBC, OLE DB)
to dataset which is data-source unaware
• Different Data Adapter classes are used
– SqlDataAdapter
– OdbcDataAdapter
– OleDbDataAdapter
Object Adapter
66
Implement Adapter Pattern in .NET
Class Adapter
Adapter for extracting data
• 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
• 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.
Design Patterns (GoF)
Bridge
Contract
Contract Implementation
Host
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.
Client
Online
Offline
• Define a one-to-many dependency between objects so that when one object changes
state, all its dependents are notified and updated automatically.
• Encapsulate the core (or common or engine) components in a Subject abstraction, and
the variable (or optional or user interface) components in an Observer hierarchy.
• The “View” part of Model-View-Controller.
View Model
• .NET 4.0 introduces two new interfaces in BCL that implements Observer pattern - are
part of larger Reactive/Rx framework
• The IObserver<T> and IObservable<T> interfaces provide a generalized mechanism
for push-based notification
– IObservable<T> interface represents the class that sends notifications (the provider)
– IObserver<T> interface represents the class that receives them (the observer)
Push
IObserver IObservable
View Model
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).
• Strategy pattern (also known as the policy pattern) is a design pattern, whereby
algorithms can be selected at runtime.
• Intended to provide a means to define a family of algorithms, encapsulate each one as
an object, and make them interchangeable.
• The strategy pattern lets the algorithms vary independently from clients that use
them.
• For example, while sorting has many algorithm (like binary sort, quick sort), the sorting
algorithm is independent of how to objects/elements are compared. So the sorting
algorithm can vary/change independent of compare algorithm.
• Strategy is used to allow callers to vary an entire algorithm, like how to compare two
objects, while Template Method is used to vary steps in an algorithm.
• Because of this, Strategy is more coarsely grained.
• There can be vast differences between different client implementations, while with
Template Method the algorithm remains fundamentally the same.
• Strategy uses delegation while Template Method uses inheritance. In the sorting
example of Strategy, the comparison algorithm is delegated to the IComparer
parameter, but with custom controls you subclass the base and override methods to
make changes. Both, however, let you easily alter processes to fit your specific needs.
• Abstraction inversion: Not exposing implemented functionality required by users, so that they
re-implement it using higher level functions
• Ambiguous viewpoint: Presenting a model (usually Object-oriented analysis and design (OOAD))
without specifying its viewpoint
• Big ball of mud: A system with no recognizable structure
• Database-as-IPC: Using database as message queue for interprocess communication where a
more lightweight mechanism would be suitable
• Gold plating: Continuing to work on a task or project well past the point at which extra effort is
adding value
• Inner-platform effect: A system so customizable as to become a poor replica of the software
development platform
• Input kludge: Failing to specify and implement the handling of possibly invalid input
• Interface bloat: Making an interface so powerful that it is extremely difficult to implement
• Magic pushbutton: Coding implementation logic directly within interface code, without using
abstraction.
• Race hazard: Failing to see the consequence of different orders of events
• Stovepipe system: A barely maintainable assemblage of ill-related components
• 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
• 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
• 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
• Facade or Façade 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".
• 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
• My namespace
– Application: Gets access to Application object
– Computer: Contains info about computer like Audio, Clock Clipboard, File
System, Registry, Keyboard, Mouse, Screen, Network, Ports etc
– Forms: Provides access to all Forms in a Win Forms App
– Settings: Provides access to Settings collection
– User: Points to the current logged in user (Principal, Role)
– WebService: Provides access to all Web Services referenced
Sub System A
Sub System B
Sub System C
Closed
[Press]
SwitchedOff
[Press]
[Press]
Opened
[Press]
Playing
Design Patterns (GoF)
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.