Software Design
Design Patterns
Introduction
• Designing software is hard:
– Design has to be reusable.
– Need to determine the right classes and
relationships between them.
– Design should be specific to the current
requirements
– Design should be general enough to handle future
requirements.
– Hard to get reusable and flexible design in the first
round.
Cont. Introduction
• Experienced designers can make good designs.
• Beginner designers find that hard.
• Learning process can be long.
• Expert users know that they don’t have to
solve every problem with a new design.
– Once they find a new solution, they reuse it again
and again.
• Beginner designers can reuse such solutions.
What is a Design Pattern
• Christopher Alexander (an architect) says
“Each 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”
• Alexander was talking about patterns in buildings
but what he says is true as well in software
design.
The Gang of Four (GoF)
• The book that started
it all
• Software Community
refers to authors as
the “Gang of Four”
• Figures and some
text in these slides
come from book
Design Pattern FOUR Elements
• The Pattern Name:
– Identify the pattern, distinguish it and defines terminology.
• The Problem:
– Describes when to apply the pattern describing the
problem and its context.
• The Solution:
– Describes elements that makes up the design, their
relationships and responsibilities.
– A general arrangement of classes and objects that provide
a solution the pattern problem.
• The Consequences:
– The results and trade offs of applying the pattern.
– E.g. space and time.
Design Patterns are NOT
• Programming codes that can be reused.
• OR data structures that can be encoded in classes and
reused
• Design Patterns are:
Descriptions of communicating objects and classes
that are customized to solve a general design problem
in a particular context.
Types of Design Patterns
• Creational patterns:
– Deal with initializing and configuring classes
and objects
• Structural patterns:
– Deal with decoupling interface and
implementation of classes and objects
– Composition of classes or objects
• Behavioral patterns:
– Deal with dynamic interactions among
societies of classes and objects
– How they distribute responsibility
Creational pattern
Singleton Pattern
Motivation
• Sometimes it's important to have only one instance for a class.
• For example, in a system there should be only one window
manager.
• Usually singletons are used for centralized management of internal
or external resources and they provide a global point of access to
themselves.
• The singleton pattern is one of the simplest design patterns:
– it involves only one class which is responsible to instantiate
itself,
– to make sure it creates not more than one instance;
– in the same time it provides a global point of access to that
instance.
– In this case the same instance can be used from everywhere,
being impossible to invoke directly the constructor each time.
Singleton Pattern
Purpose (Intent)
• Ensure that only one instance of a class is
created.
• Provide a global point of access to the object.
Singleton Pattern
Design
• Private Singleton
attribute
• Private constructor
• Public getInstance
method
Singleton Pattern
Implementation
class Singleton
{
private static Singleton instance;
private Singleton()
{
...
}
public static synchronized Singleton getInstance()
{
if (instance == null)
instance = new Singleton();
return instance;
}
...
public void doSomething()
{... } }
Creational patterns
Factory Pattern
Intent
• Creates objects without exposing the
instantiation logic to the client.
• Refers to the newly created object through a
common interface
Factory Pattern - Design
• The client needs a product,
but instead of creating it
directly using the new
operator, it asks the factory
object for a new product,
providing the information
about the type of object it
needs.
• The factory instantiates a new
concrete product and then
returns to the client the newly
created product(casted to
abstract product class).
• The client uses the products
as abstract products without
being aware about their
concrete implementation.
Factory Pattern - Example
• A graphical application works with shapes.
• The drawing framework is the client.
• The shapes are the products.
• All the shapes are derived from an abstract shape class (or
interface).
• The Shape class defines the draw and move operations which must
be implemented by the concrete shapes.
• Let's assume a command is selected from the menu to create a
new Circle.
• The framework receives the shape type as a string parameter, it
asks the factory to create a new shape sending the parameter
received from menu.
• The factory creates a new circle and returns it to the framework,
casted to an abstract shape.
• Then the framework uses the object as casted to the abstract class
without being aware of the concrete object type.
Factory Pattern - Advantage
• New shapes can be added without changing a
single line of code in the framework (the client
code that uses the shapes from the factory).
Factory Pattern - Implementation
Behavioral Patterns
Chain of Responsibility
Motivation
• In writing an application of any kind, it often
happens that the event generated by one
object needs to be handled by another one.
• In this case there are two possibilities:
– the beginner/lazy approach of making everything
public, creating reference to every object and
continuing from there and
– the expert approach of using the Chain of
Responsibility.
Chain of Responsibility
Cont. Motivation
• The Chain of Responsibility design pattern
allows an object to send a command without
knowing what object will receive and handle
it.
• The request is sent from one object to another
making them parts of a chain and each object
in this chain can handle the command, pass it
on or do both.
Chain of Responsibility
Intent
• It avoids attaching the sender of a request to
its receiver, giving this way other objects the
possibility of handling the request too.
• The objects become parts of a chain and the
request is sent from one object to another
across the chain until one of the objects will
handle it
Chain of Responsibility - Design
• Handler : defines an
interface for handling
requests
• RequestHandler: handles
the requests it is
responsible for. If it can
handle the request it does
so, otherwise it sends the
request to its successor
• Client: sends commands
to the first object in the
chain that may handle the
command
Chain of Responsibility
Implementation
public class Request {
private int m_value;
private String m_description;
public Request(String description, int value) {
m_description = description;
m_value = value; }
public int getValue() { return m_value; } public
String getDescription() { return m_description; }
}
Chain of Responsibility
Cont. Implementation
public abstract class Handler {
protected Handler m_successor;
public void setSuccessor(Handler successor) {
m_successor = successor;
}
public abstract void handleRequest(Request request);
}
Chain of Responsibility
Cont. Implementation
public class ConcreteHandlerOne extends Handler {
public void handleRequest(Request request) {
if (request.getValue() < 0) { //handle it if request is eligible
System.out.println("Negative values are handled by
ConcreteHandlerOne:");
System.out.println(“Handler One: " +
request.getDescription() + request.getValue()); }
else {
m_successor.handleRequest(request);
}
}
}
Chain of Responsibility
Cont. Implementation
public class ConcreteHandlerTwo extends Handler {
public void handleRequest(Request request) {
if (request.getValue() > 0) { //handle it if request is eligible
System.out.println(“Positive values are handled by
ConcreteHandlerTwo:");
System.out.println(“Handler Two: " +
request.getDescription() + request.getValue()); }
else {
m_successor.handleRequest(request);
}
}
}
Chain of Responsibility
Cont. Implementation
public class ConcreteHandlerThree extends Handler {
public void handleRequest(Request request) {
if (request.getValue()==0) { //handle it if request is eligible
System.out.println(“Zero value is handled by
ConcreteHandlerThree:");
System.out.println(“Handler Three: " +
request.getDescription() + request.getValue()); }
else {
m_successor.handleRequest(request);
}
}
}
Chain of Responsibility
Cont. Implementation
public class Main {
// Setup Chain of Responsibility Handler
public static void main(String[] args) {
Handler h1 = new ConcreteHandlerOne();
Handler h2 = new ConcreteHandlerTwo();
Handler h3 = new ConcreteHandlerThree();
h1.setSuccessor(h2);
h2.setSuccessor(h3);
// Send requests to the chain
h1.handleRequest(new Request("Negative Value ", -1));
h1.handleRequest(new Request(“zero Value ", 0));
h1.handleRequest(new Request(“positive Value ", 1));
h1.handleRequest(new Request(“positive Value ", 2));
h1.handleRequest(new Request("Negative Value ", -5));
}
Structural Patterns
Adaptor Pattern - Motivation
• The adapter pattern is adapting between classes and
objects.
• Like any adapter in the real world it is used to be an
interface, a bridge between two objects.
• Supports the situation when you have some class
expecting some type of object and you have an object
offering the same features, but exposing a different
interface.
– Of course, you want to use both of them so you don't
implement again one of them,
– and you don't want to change existing classes,
– so an adapter is used.
Structural Patterns
Adaptor Pattern - Intent
• Convert the interface of a class into another
interface clients expect.
• Adapter lets classes work together, that could
not otherwise because of incompatible
interfaces.
Structural Patterns
Adaptor Pattern - Design
• Target - defines the
domain-specific interface
that Client uses.
• Adapter - adapts the
interface Adaptee to the
Target interface.
• Adaptee - defines an
existing interface that
needs adapting.
• Client - collaborates with
objects conforming to
the Target interface.
Strategy Pattern
Behavioral Pattern
• Motivation
– There are common situations when classes differ only
in their behavior.
– For such cases, it is a good idea to isolate the
algorithms in separate classes in order to have the
ability to select different algorithms at runtime.
• Intent
– Define a family of algorithms,
– and make them interchangeable.
– Strategy lets the algorithm vary independently from
clients that use it.
Strategy Pattern - Design
Design Explained
• Strategy: defines an interface common to all supported algorithms.
• Context: uses this interface to call the algorithm defined by a
ConcreteStrategy.
– contains a reference to a strategy object.
– When an operation is required then the algorithm is run from the
strategy object.
– The Context is not aware of the strategy implementation. If necessary,
addition objects can be defined to pass data from context object to
strategy.
– The context object receives requests from the client and delegates
them to the strategy object.
– Usually the ConcreteStartegy is created by the client and passed to the
context.
– From this point the clients interacts only with the context.
• ConcreteStrategy: each concrete strategy implements an algorithm.
Composite Design Pattern
• Describes a group of objects that is treated
the same way as a single instance of the same
type of object.
• The intent of a composite is to “compose”
objects into tree structures to represent part-
whole hierarchies.
• It allows you to have a tree structure and ask
each node in the tree structure to perform a
task.
• Compose objects into tree structure to represent part-whole
hierarchies.
• Composite lets client treat individual objects and compositions of
objects uniformly”.
• When dealing with Tree-structured data, programmers often have
to discriminate between a leaf-node and a branch.
• This makes code more complex, and therefore, error prone.
• The solution is an interface that allows treating complex and
primitive objects uniformly.
• In object-oriented programming, a composite is an object designed
as a composition of one-or-more similar objects, all exhibiting
similar functionality.
• This is known as a “has-a”relationship between objects.
The Composite Pattern has four
participants:
• Component – Component declares the interface for objects
in the composition and for accessing and managing its child
components. It also implements default behavior for the
interface common to all classes as appropriate.
• Leaf – Leaf defines behavior for primitive objects in the
composition. It represents leaf objects in the composition.
• Composite – Composite stores child components and
implements child related operations in the component
interface.
• Client – Client manipulates the objects in the composition
through the component interface.
• need the Composite pattern to manipulate composites exactly the
same way we manipulate primitive objects.
• For example, graphic primitives such as lines or text must be drawn,
moved, and resized.
• But we also want to perform the same operation on composites,
such as drawings, that are composed of those primitives.
• Ideally, we'd like to perform operations on both primitive objects
and composites in exactly the same manner, without distinguishing
between the two.
• If we must distinguish between primitive objects and composites to
perform the same operations on those two types of objects, our
code would become more complex and more difficult to
implement, maintain, and extend.
Example – Employees Tree
Component Interface
public interface Employee
{
public void showEmployeeDetails();
}
Employee Leaf Type 1
public class Developer implements Employee
{
private String name;
private long empId;
private String position;
public Developer(long empId, String name, String position)
{
this.empId = empId;
this.name = name;
this.position = position;
}
@Override
public void showEmployeeDetails()
{
System.out.println(empId+" " +name+);
}
}
Employee Leaf Type 2
public class Manager implements Employee
{
private String name;
private long empId;
private String position;
public Manager(long empId, String name, String position)
{
this.empId = empId;
this.name = name;
this.position = position;
}
@Override
public void showEmployeeDetails()
{
System.out.println(empId+" " +name);
}
}
Composite of Employees
import java.util.ArrayList;
import java.util.List;
public class CompanyDirectory implements Employee
{
private List<Employee> employeeList = new ArrayList<Employee>();
@Override
public void showEmployeeDetails() {
for(Employee emp:employeeList){
emp.showEmployeeDetails();
}
}
public void addEmployee(Employee emp){
employeeList.add(emp);
}
public void removeEmployee(Employee emp){
employeeList.remove(emp);}}
Client
public class Company
{
public static void main (String[] args)
{
Developer dev1 = new Developer(100, “Ahmad Ahmad", "Pro Developer");
Developer dev2 = new Developer(101, “Sameer Sameer", "Developer");
CompanyDirectory engDirectory = new CompanyDirectory();
engDirectory.addEmployee(dev1);
engDirectory.addEmployee(dev2);
Manager man1 = new Manager(200, “Amal Ibrahim", "SEO Manager");
Manager man2 = new Manager(201, “Tamer Ismael ", “Ahmad's Manager");
CompanyDirectory accDirectory = new CompanyDirectory();
accDirectory.addEmployee(man1);
accDirectory.addEmployee(man2);
CompanyDirectory directory = new CompanyDirectory();
directory.addEmployee(engDirectory);
directory.addEmployee(accDirectory);
directory.showEmployeeDetails();
}
}
Exercise
• Provide a design representing a file system,
which contains files and folders, each has a
name and a size. A folder may contain other
folders or files. The size of the folder is the
sum of included file sizes.
Observable Pattern
• The cases when certain objects need to be
informed about the changes occurred in other
objects are frequent.
• To have a good design means to decouple as
much as possible and to reduce the
dependencies.
• The Observer Design Pattern can be used
whenever a subject has to be observed by one
or more observers.
Observable Pattern
Intent
• Defines a one-to-many dependency between
objects
– so that when one object changes state,
– all its dependents are notified and updated
automatically.
Design
• The participants classes in this pattern are:
Observable - interface or abstract class defining the
operations for attaching and de-attaching observers to
the client. In the GOF book this class/interface is
known as Subject.
• ConcreteObservable - concrete Observable class. It
maintain the state of the object and when a change in
the state occurs it notifies the attached Observers.
• Observer - interface or abstract class defining the
operations to be used to notify this object.
• ConcreteObserverA, ConcreteObserver2 -
concrete Observer implementations.
• The main framework instantiate the ConcreteObservable
object.
• Then it instantiate and attaches the concrete observers to it
using the methods defined in the Observable interface.
• Each time the state of the subject is changing, it notifies all
the attached Observers using the methods defined in the
Observer interface.
• When a new Observer is added to the application, all we
need to do is to instantiate it in the main framework and to
attach it to the Observable object.
• The classes already created will remain unchanged.
Observable Pattern
Examples
• Model View Controller Pattern - The observer
pattern is used in the model view controller
(MVC) architectural pattern. In MVC the this
pattern is used to decouple the model from the
view. View represents the Observer and the
model is the Observable object.
• Event management - This is one of the domains
where the Observer patterns is extensively used.
Swing and .Net are extensively using the
Observer pattern for implementing the events
mechanism.
• the agency is represented by an
Observable(Subject) class
named NewsPublisher.
• This one is created as an abstract class
because the agency want to create several
types of Observable objects: in the beginning
only for business news, but after some time
sport and political new will be published.
• The concrete class is BusinessNewsPublisher.
• The subscribers are represented by some
observers (SMSSubscriber, EmailSubscriber).
• Both the observers mentioned above are
inherited from the Subscriber.
• The subscriber is the abstract class which is
known to the publisher.
• The publisher doesn't know about concrete
observers, it knows only about their
abstraction.
• In the main class a publisher(Observable) is
built and a few subscribers(Observers).
• The subscribers are subscribed to the
publisher and they can be unsubscribed.
• In this architecture new types of subscribers
can be easily added(instant messaging, ...) and
new types of publishers(Weather News, Sport
News, ...).
Exercise
• A news agency gather news and publish them to
different subscribers. We need to create a
framework for the agency to be able to inform
immediately, when event occurs, its subscribers
about the event. The subscribers can receive the
news in different ways: Emails, SMS, ... The
solution need to be extensive enough to support
new types of subscribers(maybe new
communication technologies will appear), and
new types of news (political, business,
technology, etc.).

note2_DesignPatterns (1).pptx

  • 1.
  • 2.
    Introduction • Designing softwareis hard: – Design has to be reusable. – Need to determine the right classes and relationships between them. – Design should be specific to the current requirements – Design should be general enough to handle future requirements. – Hard to get reusable and flexible design in the first round.
  • 3.
    Cont. Introduction • Experienceddesigners can make good designs. • Beginner designers find that hard. • Learning process can be long. • Expert users know that they don’t have to solve every problem with a new design. – Once they find a new solution, they reuse it again and again. • Beginner designers can reuse such solutions.
  • 4.
    What is aDesign Pattern • Christopher Alexander (an architect) says “Each 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” • Alexander was talking about patterns in buildings but what he says is true as well in software design.
  • 5.
    The Gang ofFour (GoF) • The book that started it all • Software Community refers to authors as the “Gang of Four” • Figures and some text in these slides come from book
  • 6.
    Design Pattern FOURElements • The Pattern Name: – Identify the pattern, distinguish it and defines terminology. • The Problem: – Describes when to apply the pattern describing the problem and its context. • The Solution: – Describes elements that makes up the design, their relationships and responsibilities. – A general arrangement of classes and objects that provide a solution the pattern problem. • The Consequences: – The results and trade offs of applying the pattern. – E.g. space and time.
  • 7.
    Design Patterns areNOT • Programming codes that can be reused. • OR data structures that can be encoded in classes and reused • Design Patterns are: Descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context.
  • 8.
    Types of DesignPatterns • Creational patterns: – Deal with initializing and configuring classes and objects • Structural patterns: – Deal with decoupling interface and implementation of classes and objects – Composition of classes or objects • Behavioral patterns: – Deal with dynamic interactions among societies of classes and objects – How they distribute responsibility
  • 9.
    Creational pattern Singleton Pattern Motivation •Sometimes it's important to have only one instance for a class. • For example, in a system there should be only one window manager. • Usually singletons are used for centralized management of internal or external resources and they provide a global point of access to themselves. • The singleton pattern is one of the simplest design patterns: – it involves only one class which is responsible to instantiate itself, – to make sure it creates not more than one instance; – in the same time it provides a global point of access to that instance. – In this case the same instance can be used from everywhere, being impossible to invoke directly the constructor each time.
  • 10.
    Singleton Pattern Purpose (Intent) •Ensure that only one instance of a class is created. • Provide a global point of access to the object.
  • 11.
    Singleton Pattern Design • PrivateSingleton attribute • Private constructor • Public getInstance method
  • 12.
    Singleton Pattern Implementation class Singleton { privatestatic Singleton instance; private Singleton() { ... } public static synchronized Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; } ... public void doSomething() {... } }
  • 13.
    Creational patterns Factory Pattern Intent •Creates objects without exposing the instantiation logic to the client. • Refers to the newly created object through a common interface
  • 14.
    Factory Pattern -Design • The client needs a product, but instead of creating it directly using the new operator, it asks the factory object for a new product, providing the information about the type of object it needs. • The factory instantiates a new concrete product and then returns to the client the newly created product(casted to abstract product class). • The client uses the products as abstract products without being aware about their concrete implementation.
  • 15.
    Factory Pattern -Example • A graphical application works with shapes. • The drawing framework is the client. • The shapes are the products. • All the shapes are derived from an abstract shape class (or interface). • The Shape class defines the draw and move operations which must be implemented by the concrete shapes. • Let's assume a command is selected from the menu to create a new Circle. • The framework receives the shape type as a string parameter, it asks the factory to create a new shape sending the parameter received from menu. • The factory creates a new circle and returns it to the framework, casted to an abstract shape. • Then the framework uses the object as casted to the abstract class without being aware of the concrete object type.
  • 16.
    Factory Pattern -Advantage • New shapes can be added without changing a single line of code in the framework (the client code that uses the shapes from the factory).
  • 17.
    Factory Pattern -Implementation
  • 18.
    Behavioral Patterns Chain ofResponsibility Motivation • In writing an application of any kind, it often happens that the event generated by one object needs to be handled by another one. • In this case there are two possibilities: – the beginner/lazy approach of making everything public, creating reference to every object and continuing from there and – the expert approach of using the Chain of Responsibility.
  • 19.
    Chain of Responsibility Cont.Motivation • The Chain of Responsibility design pattern allows an object to send a command without knowing what object will receive and handle it. • The request is sent from one object to another making them parts of a chain and each object in this chain can handle the command, pass it on or do both.
  • 20.
    Chain of Responsibility Intent •It avoids attaching the sender of a request to its receiver, giving this way other objects the possibility of handling the request too. • The objects become parts of a chain and the request is sent from one object to another across the chain until one of the objects will handle it
  • 21.
    Chain of Responsibility- Design • Handler : defines an interface for handling requests • RequestHandler: handles the requests it is responsible for. If it can handle the request it does so, otherwise it sends the request to its successor • Client: sends commands to the first object in the chain that may handle the command
  • 22.
    Chain of Responsibility Implementation publicclass Request { private int m_value; private String m_description; public Request(String description, int value) { m_description = description; m_value = value; } public int getValue() { return m_value; } public String getDescription() { return m_description; } }
  • 23.
    Chain of Responsibility Cont.Implementation public abstract class Handler { protected Handler m_successor; public void setSuccessor(Handler successor) { m_successor = successor; } public abstract void handleRequest(Request request); }
  • 24.
    Chain of Responsibility Cont.Implementation public class ConcreteHandlerOne extends Handler { public void handleRequest(Request request) { if (request.getValue() < 0) { //handle it if request is eligible System.out.println("Negative values are handled by ConcreteHandlerOne:"); System.out.println(“Handler One: " + request.getDescription() + request.getValue()); } else { m_successor.handleRequest(request); } } }
  • 25.
    Chain of Responsibility Cont.Implementation public class ConcreteHandlerTwo extends Handler { public void handleRequest(Request request) { if (request.getValue() > 0) { //handle it if request is eligible System.out.println(“Positive values are handled by ConcreteHandlerTwo:"); System.out.println(“Handler Two: " + request.getDescription() + request.getValue()); } else { m_successor.handleRequest(request); } } }
  • 26.
    Chain of Responsibility Cont.Implementation public class ConcreteHandlerThree extends Handler { public void handleRequest(Request request) { if (request.getValue()==0) { //handle it if request is eligible System.out.println(“Zero value is handled by ConcreteHandlerThree:"); System.out.println(“Handler Three: " + request.getDescription() + request.getValue()); } else { m_successor.handleRequest(request); } } }
  • 27.
    Chain of Responsibility Cont.Implementation public class Main { // Setup Chain of Responsibility Handler public static void main(String[] args) { Handler h1 = new ConcreteHandlerOne(); Handler h2 = new ConcreteHandlerTwo(); Handler h3 = new ConcreteHandlerThree(); h1.setSuccessor(h2); h2.setSuccessor(h3); // Send requests to the chain h1.handleRequest(new Request("Negative Value ", -1)); h1.handleRequest(new Request(“zero Value ", 0)); h1.handleRequest(new Request(“positive Value ", 1)); h1.handleRequest(new Request(“positive Value ", 2)); h1.handleRequest(new Request("Negative Value ", -5)); }
  • 28.
    Structural Patterns Adaptor Pattern- Motivation • The adapter pattern is adapting between classes and objects. • Like any adapter in the real world it is used to be an interface, a bridge between two objects. • Supports the situation when you have some class expecting some type of object and you have an object offering the same features, but exposing a different interface. – Of course, you want to use both of them so you don't implement again one of them, – and you don't want to change existing classes, – so an adapter is used.
  • 29.
    Structural Patterns Adaptor Pattern- Intent • Convert the interface of a class into another interface clients expect. • Adapter lets classes work together, that could not otherwise because of incompatible interfaces.
  • 30.
    Structural Patterns Adaptor Pattern- Design • Target - defines the domain-specific interface that Client uses. • Adapter - adapts the interface Adaptee to the Target interface. • Adaptee - defines an existing interface that needs adapting. • Client - collaborates with objects conforming to the Target interface.
  • 31.
    Strategy Pattern Behavioral Pattern •Motivation – There are common situations when classes differ only in their behavior. – For such cases, it is a good idea to isolate the algorithms in separate classes in order to have the ability to select different algorithms at runtime. • Intent – Define a family of algorithms, – and make them interchangeable. – Strategy lets the algorithm vary independently from clients that use it.
  • 32.
  • 33.
    Design Explained • Strategy:defines an interface common to all supported algorithms. • Context: uses this interface to call the algorithm defined by a ConcreteStrategy. – contains a reference to a strategy object. – When an operation is required then the algorithm is run from the strategy object. – The Context is not aware of the strategy implementation. If necessary, addition objects can be defined to pass data from context object to strategy. – The context object receives requests from the client and delegates them to the strategy object. – Usually the ConcreteStartegy is created by the client and passed to the context. – From this point the clients interacts only with the context. • ConcreteStrategy: each concrete strategy implements an algorithm.
  • 34.
    Composite Design Pattern •Describes a group of objects that is treated the same way as a single instance of the same type of object. • The intent of a composite is to “compose” objects into tree structures to represent part- whole hierarchies. • It allows you to have a tree structure and ask each node in the tree structure to perform a task.
  • 36.
    • Compose objectsinto tree structure to represent part-whole hierarchies. • Composite lets client treat individual objects and compositions of objects uniformly”. • When dealing with Tree-structured data, programmers often have to discriminate between a leaf-node and a branch. • This makes code more complex, and therefore, error prone. • The solution is an interface that allows treating complex and primitive objects uniformly. • In object-oriented programming, a composite is an object designed as a composition of one-or-more similar objects, all exhibiting similar functionality. • This is known as a “has-a”relationship between objects.
  • 37.
    The Composite Patternhas four participants: • Component – Component declares the interface for objects in the composition and for accessing and managing its child components. It also implements default behavior for the interface common to all classes as appropriate. • Leaf – Leaf defines behavior for primitive objects in the composition. It represents leaf objects in the composition. • Composite – Composite stores child components and implements child related operations in the component interface. • Client – Client manipulates the objects in the composition through the component interface.
  • 39.
    • need theComposite pattern to manipulate composites exactly the same way we manipulate primitive objects. • For example, graphic primitives such as lines or text must be drawn, moved, and resized. • But we also want to perform the same operation on composites, such as drawings, that are composed of those primitives. • Ideally, we'd like to perform operations on both primitive objects and composites in exactly the same manner, without distinguishing between the two. • If we must distinguish between primitive objects and composites to perform the same operations on those two types of objects, our code would become more complex and more difficult to implement, maintain, and extend.
  • 40.
    Example – EmployeesTree Component Interface public interface Employee { public void showEmployeeDetails(); }
  • 41.
    Employee Leaf Type1 public class Developer implements Employee { private String name; private long empId; private String position; public Developer(long empId, String name, String position) { this.empId = empId; this.name = name; this.position = position; } @Override public void showEmployeeDetails() { System.out.println(empId+" " +name+); } }
  • 42.
    Employee Leaf Type2 public class Manager implements Employee { private String name; private long empId; private String position; public Manager(long empId, String name, String position) { this.empId = empId; this.name = name; this.position = position; } @Override public void showEmployeeDetails() { System.out.println(empId+" " +name); } }
  • 43.
    Composite of Employees importjava.util.ArrayList; import java.util.List; public class CompanyDirectory implements Employee { private List<Employee> employeeList = new ArrayList<Employee>(); @Override public void showEmployeeDetails() { for(Employee emp:employeeList){ emp.showEmployeeDetails(); } } public void addEmployee(Employee emp){ employeeList.add(emp); } public void removeEmployee(Employee emp){ employeeList.remove(emp);}}
  • 44.
    Client public class Company { publicstatic void main (String[] args) { Developer dev1 = new Developer(100, “Ahmad Ahmad", "Pro Developer"); Developer dev2 = new Developer(101, “Sameer Sameer", "Developer"); CompanyDirectory engDirectory = new CompanyDirectory(); engDirectory.addEmployee(dev1); engDirectory.addEmployee(dev2); Manager man1 = new Manager(200, “Amal Ibrahim", "SEO Manager"); Manager man2 = new Manager(201, “Tamer Ismael ", “Ahmad's Manager"); CompanyDirectory accDirectory = new CompanyDirectory(); accDirectory.addEmployee(man1); accDirectory.addEmployee(man2); CompanyDirectory directory = new CompanyDirectory(); directory.addEmployee(engDirectory); directory.addEmployee(accDirectory); directory.showEmployeeDetails(); } }
  • 45.
    Exercise • Provide adesign representing a file system, which contains files and folders, each has a name and a size. A folder may contain other folders or files. The size of the folder is the sum of included file sizes.
  • 46.
    Observable Pattern • Thecases when certain objects need to be informed about the changes occurred in other objects are frequent. • To have a good design means to decouple as much as possible and to reduce the dependencies. • The Observer Design Pattern can be used whenever a subject has to be observed by one or more observers.
  • 47.
    Observable Pattern Intent • Definesa one-to-many dependency between objects – so that when one object changes state, – all its dependents are notified and updated automatically.
  • 48.
  • 49.
    • The participantsclasses in this pattern are: Observable - interface or abstract class defining the operations for attaching and de-attaching observers to the client. In the GOF book this class/interface is known as Subject. • ConcreteObservable - concrete Observable class. It maintain the state of the object and when a change in the state occurs it notifies the attached Observers. • Observer - interface or abstract class defining the operations to be used to notify this object. • ConcreteObserverA, ConcreteObserver2 - concrete Observer implementations.
  • 50.
    • The mainframework instantiate the ConcreteObservable object. • Then it instantiate and attaches the concrete observers to it using the methods defined in the Observable interface. • Each time the state of the subject is changing, it notifies all the attached Observers using the methods defined in the Observer interface. • When a new Observer is added to the application, all we need to do is to instantiate it in the main framework and to attach it to the Observable object. • The classes already created will remain unchanged.
  • 51.
    Observable Pattern Examples • ModelView Controller Pattern - The observer pattern is used in the model view controller (MVC) architectural pattern. In MVC the this pattern is used to decouple the model from the view. View represents the Observer and the model is the Observable object. • Event management - This is one of the domains where the Observer patterns is extensively used. Swing and .Net are extensively using the Observer pattern for implementing the events mechanism.
  • 53.
    • the agencyis represented by an Observable(Subject) class named NewsPublisher. • This one is created as an abstract class because the agency want to create several types of Observable objects: in the beginning only for business news, but after some time sport and political new will be published. • The concrete class is BusinessNewsPublisher.
  • 54.
    • The subscribersare represented by some observers (SMSSubscriber, EmailSubscriber). • Both the observers mentioned above are inherited from the Subscriber. • The subscriber is the abstract class which is known to the publisher. • The publisher doesn't know about concrete observers, it knows only about their abstraction.
  • 55.
    • In themain class a publisher(Observable) is built and a few subscribers(Observers). • The subscribers are subscribed to the publisher and they can be unsubscribed. • In this architecture new types of subscribers can be easily added(instant messaging, ...) and new types of publishers(Weather News, Sport News, ...).
  • 56.
    Exercise • A newsagency gather news and publish them to different subscribers. We need to create a framework for the agency to be able to inform immediately, when event occurs, its subscribers about the event. The subscribers can receive the news in different ways: Emails, SMS, ... The solution need to be extensive enough to support new types of subscribers(maybe new communication technologies will appear), and new types of news (political, business, technology, etc.).