East West Institute of Technology: Sadp Notes
East West Institute of Technology: Sadp Notes
SADP NOTES
(17IS72)
Prepared by,
Mr. Sanju D J
Asst. Prof
Dept. of ISE
Software Architecture and Design Patterns (17IS72)
Module 1 - Introduction
Design pattern
“A proven solution to a common problem in a specified context”
“A pattern describes a problem which occurs over and over again in our environment, and
then describes the core of the solution to that problem, in such a way that you can use this
solution a million times over, without ever doing it the same way twice”
Essential Elements:
The pattern name is a handle we can use to describe a design problem, its solutions, and
consequences in a word or two.
The solution describes the elements that make up the design, their relationships,
responsibilities, and collaborations. The pattern provides an abstract description of a design
problem and how a general arrangement of classes and objects solves it.
The consequences are the results and trade-offs of applying the pattern.
Example Pattern:
By Appointment
By Order of Arrival
By Extending Gratitude
By Exception
Consequences
Patient Satisfaction
Clinic’s Efficiency
Doctor’s Productivity
Motivation – A scenario illustrating a design problem and how it’s being solved by the
pattern
Structure – OMT (Object Modelling Technique) based graphic representation of the classes
in the pattern
Consequences –
What pitfalls, hints, or techniques should you be aware of when implementing the
pattern?
Are there language-specific issues?
Sample Code – Code fragments to implement the pattern in specific language (C++or C# or
java).
Related Patterns – Other patterns closely related with the pattern under consideration
Adapter:
Convert the inter face of a class into another interface client’s expect.
Adapter lets classes work together
Bridge: Decouple an abstraction from its implementation so that two can vary independently.
Builder: Separates the construction of the complex object from its representation so that the
same construction process can create different representations.
Chain of Responsibility: Avoid coupling the sender of a request to it‘s 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 objects handles it.
Factory Method: Defines an interface for creating an object ,but let subclasses decide which
class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Interpreter: For the given language, it defines the representation of its grammar to interpret
sentences in the language.
Iterator: Provide a way to access the element of an aggregate object sequentially without
exposing its underlying representation.
Mediator: Define an object that encapsulates how a set of objects interact. Mediator
promotes loose coupling of objects and allows to vary their interaction independently.
Memento: Without violating encapsulation, capture and externalize an object‘s internal state
so that object can be restored to this state later.
Observer: Define a one-to-many dependency between objects so that when one object
changes state, all it‘s dependents are notified and updated automatically.
Proxy: Provide a surrogate or placeholder (substitute) to control the access to the original
object.
Singleton: Ensure a class has only one instance, and provide a point of access to it.
State: Allow an object to alter its behavior when its internal state changes. The object will
appear to change its class
Strategy: Define a family of algorithms, encapsulate each one, and make them
interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Template Method: Define the Skelton of an operation, deferring some steps to subclasses.
Template method subclasses redefine certain steps of an algorithm without changing the
algorithms structure
3. Behavioral patterns characterize the ways in which classes or objects interact and
distribute responsibility.
Class patterns deal with relationships between classes and their subclasses.
These relationships are established through inheritance, so they are static— fixed at
compile-time.
Object patterns deal with object relationships, which can be changed at run-time and
are more dynamic.
Interface:
Binding
Polymorphism
The class specifies the object‘s internal data and defines the operations the object can
perform
Class inheritance
Visitor is used to reflect all classes of objects that visitors can visit
Inheritance
New classes can be defined in terms of existing classes using class inheritance. When
a subclass inherits from a parent class, it includes the definitions of all the data and
operations that the parent class defines. Objects that are instances of the subclass will
contain all data defined by the subclass and its parent classes.
We indicate the subclass relationship with a vertical line and a triangle.
Abstract Class
Abstract Class is one whose main purpose is to define a common interface for its
subclasses. The operations that an abstract class declares but doesn't implement are
called abstract operations.
The names of abstract classes appear in slanted type. Slanted type is also used to
denote abstract operations.
The implementation of the operation is represented by dog-eared box, the code will
appear connected with a dashed line to the operation it implements
Concrete classes
Override an operation
Mixin Class
Augmented class:
Allows user to create own projects without having any previous knowledge
Benefits
Abstract Factory, Builder, Factor method, Prototype and Singleton are the
creational patterns
Creational patterns ensures that the system is written in terms of interfaces, not
implementations
7. Putting Reuse Mechanisms to work
The challenge lies in applying the concepts like objects, interfaces, classes and inheritance
to build the design patterns to be flexible and reusable
Delegation
Two techniques for reusing the functionality in object-oriented systems are class
inheritance and object composition
class inheritance
White-box reuse
object composition
Black-box reuse
White-box reuse:
Black-box reuse:
Class inheritance define the implementation of one class in terms of the other
Class inheritance: Reuse by sub classing is often referred to as “white-box reuse”.
The term "white-box" refers to visibility: With inheritance, the internals of parent classes
are often visible to subclasses.
Defined at compile-time. and straightforward to use
“Inheritance breaks encapsulation” (superclass implementation exposed to subclasses)
Advantages
Disadvantages
Parent classes often define at least part of their subclasses physical representation
Breaks encapsulation
Object composition:
Delegation
In delegation, two objects are involved in handling a request: receiving object delegates
operations to its delegate
Advantages: Makes it easy to compose behaviors at run-time and to change the way
they are composed.
Disadvantages: Dynamic, highly parameterized software is harder to understand than
more static software and there are also run-time inefficiencies
Delegation is a good design choice only when it simplifies more than it complicates
Delegation is an extreme example of object composition
Here are some common causes of redesign along with the design pattern( s) that
address them:
Algorithmic dependencies
Tight coupling
Creating an object by specifying a class explicitly: Specifying a class name when you create
an object commits you to a particular implementation instead of a particular interface.
Dependence on specific operations: When you specify a particular operation, you commit to
one way of satisfying a request. By avoiding hard-coded requests, you make it easier to
change the way a request gets satisfied both at compile-time and at run-time.
Dependence on hardware and software platform: External operating system interfaces and
application programming interfaces (APIs) are different on different hardware and software
platforms. Software that depends on a particular platform will be harder to port to other
platforms. It may even be difficult to keep it up to date on its native platform. It's important
therefore to design your system to limit its platform dependencies.
Algorithmic dependencies: Algorithms are often extended, optimized, and replaced during
development and reuse. Objects that depend on an algorithm will have to change when the
algorithm changes. Therefore algorithms that are likely to change should be isolated.
Tight coupling: Classes that are tightly coupled are hard to reuse in isolation, since they
depend on each other. Tight coupling leads to monolithic systems, where you can't change or
remove a class without understanding and changing many other classes.
Inability to alter classes conveniently: Sometimes you have to modify a class that can't be
modified conveniently. Perhaps you need the source code and don't have it (as may be the
case with a commercial class library).
• Design patterns also make an application more maintainable when they are used to
limit platform dependencies and to layer a system
• Looser coupling boosts the likelihood that one class of object can cooperate with
several others
For example, when you eliminated dependencies on specific operations by isolating and
encapsulating each operation, you make it easier to reuse an operation in different contexts.
A toolkit is a set of related and reusable classes designed to provide useful, general-
purpose functionality.
An example of a toolkit is a set of collection classes for lists, associative tables, stacks,
and the like.
Toolkits don't impose a particular design on your application; they just provide
functionality that can help your application do its job.
Toolkit design is arguably harder than application design, because toolkits have to work
in many applications to be useful.
Moreover, the toolkit writer isn't in a position to know what those applications will be or
their special needs.
A framework is a set of cooperating classes that makeup a reusable design for a specific
class of software.
For example, a framework can be geared toward building graphical editors for different
domains like artistic drawing, music composition, and mechanical.
Another framework can help you build compilers for different programming languages
and target machines.
The framework dictates the architecture of the application. It will define the overall
structure; it’s partitioning into classes and objects, the key responsibilities thereof, how
the classes and objects collaborate, and the thread of control.
The framework captures the design decisions that are common to its application domain.
Frameworks thus emphasize design reuse over code reuse, though a framework will
usually include concrete subclasses you can put to work immediately.
When we use a toolkit, we can write the main body of the application and call the code
which we want to reuse. When we use a framework, we reuse the main body and write
the code it calls.
Advantages: Builds an application faster, easier to maintain, and more consistent to their
users
The patterns help make the framework's architecture suitable to many different
applications without redesign
An added benefit comes when the framework is documented with the design patterns it
uses.
People who know the patterns gain insight into the framework faster.
Even people who don't know the patterns can benefit from the structure they lend to the
framework's documentation.
Enhancing documentation is important for all types of software, but it's particularly
important for frameworks.
Frameworks often pose a steep learning curve that must be overcome before they're
useful.
Frameworks can be embodied in code, but only examples of patterns can be embodied
in code.
Design patterns also explain the intent, trade-offs, and consequences of a design.
A typical framework contains several design patterns, but the reverse is never true.
In contrast, the design patterns in this catalo g can be used in nearly any kind of
application.
Determine object granularity; specify object interfaces, and several other ways in which
design patterns solve design problems.
Read through each pattern's intent (purpose) to find one or more that should relevant to your
problem.
Studying these relationships can help direct you to the right pattern or group of patterns.
Study only those patterns which are of specific purposes ( creational patterns, structural
patterns, and behavioural patterns).
Look at the patterns that help you avoid the causes of redesign
Choose names for pattern participants that are meaningful in the application context.
Pay attention to the Applicability and Consequences sections to ensure the pattern
Make sure you understand the classes and objects in the pattern and how they relate
to one another.
3. Look at the Sample Code section to see a concrete example of the pattern in code
4. Choose names for pattern participants that are meaningful in the application context
It is useful to incorporate the participant name into the name that appears in the
application.
Declare their interfaces, establish their inheritance relationships, and define the
7. Implement the operations to carry out the responsibilities and collaborations in the
pattern
The first step in such a design was to recognize what the process had to deliver
which was followed by decomposition of the process into functional modules.
Structures to store data were defined and the computation was carried out by
invoking the modules, which performed some computation on the stored data
elements.
The life of a process-centred design was short because changes to the process
specification required a change in the entire program.
• Thus engineering disciplines started soon after, and the disciplines of ‘software
design’ and ‘software engineering’ came into existence.
The components can also communicate with each other as needed to complete
the process
5. Standard Solutions
Modular Design
The interface also defines how other components may interact or communicate with
the module.
We would like that a module clearly specify what it does, but not expose its
implementation. This separation of concerns gives rise to the notion of encapsulation,
Encapsulation
Encapsulation, which means that the module hides details of its implementation from
external agents. Example of applying encapsulation.
The abstract data type (ADT), is generalization of primitive data types such as
integers and characters.
The programmer specifies the collection of operations on the data type and the data
structures that are needed for data storage.
Users of the ADT perform the operations without concerning themselves with the
implementation.
Cohesion
Cohesion of a module tells us how well the entities within a module work together to
provide functionality. Cohesion is a measure of how focused the responsibilities of a
module are.
If the responsibilities of a module are unrelated or varied and use different sets of
data, cohesion is reduced.
Highly cohesive modules tend to be more reliable, reusable, and understandable than
less cohesive ones.
Coupling
The very fact that we split a program into multiple modules introduces some coupling
into the system.
Coupling could result because of several factors: a module may refer to variables
defined in another module or a module may call methods of another module and use
the return values.
In general, if modules do not depend on each others implementation we say that the
coupling is low
Low coupling allows us to modify a module without worrying changes on the rest of
the system.
By contrast, high coupling means that changes in one module would necessitate
changes in other modules, which may make it harder to understand the code.
Modifiability
The modification in software can be done to change both functionality and design.
The ability to change the functionality of a component allows for systems to be more
adaptable;
In both cases, the organization of the system in terms of objects and classes has
helped develop systematic procedures that mitigate the risk.
Testability
Testability refers to both falsifiability, and ease with which we can find bugs in
Software and the extent to which the structure of the system facilitates the detection of
bugs.
1. Objects often reflect entities in application systems. This makes it easier for a
designer to come up with classes in the design. In a process-oriented design, it is
much harder to find such a connection that can simplify the initial design.
4. The ability to isolate changes, encapsulate data, and employ modularity reduces the
risks involved in system development.
Drawbacks
2. Interactions of many objects are complex Example: Banking application, Video game
that has often a large number of objects.
3. Objects tend to have complex associations, which can result in non-locality, leading to
poor memory access times.
5. Programmers may need a year to start feeling comfortable with these concepts.
6. Some researchers are of the opinion that the programming environments also have
not kept up with research in language capabilities.
7. Editors and testing and debugging facilities do not directly support many of the
advances such as design patterns.