Computer Engineering Department
Computer Engineering Department
Object Oriented Software Modeling and Design
CE 350Abdel-Karim Al-Tamimi, Ph.D.
[email protected]://faculty.yu.edu.jo/
altamimi
Al-Tamimi 2011 © 1
Overview
• Design Patterns
Al-Tamimi 2011 © 2
Design Patterns• Design patterns are commonly accepted solutions to some
problems that recur during designing different applications• The basic idea behind patterns is that if you can master a few
important patterns, you can easily spot them in application development problems and effortlessly use the pattern solution
• Patterns can be viewed as helping designers to make certain important design decisions. At a basic level, patterns can also be viewed as well-documented building blocks for software design
• The pattern provides an abstract description of a design problem, and how a general arrangement of elements (classes and objects in our case) solves it
• The common definition of a pattern: “A solution to a problem in a context”
Al-Tamimi 2011 © 3
Motivation for Design Patterns
• Designing reusable code is difficult– Patterns provide reusable frameworks– Successful reusable designs must exists
• Software components supports the reuse of code but not knowledge– Expert knowledge are lost
• Communication of such architecture knowledge is difficult (it includes an abstract design that is a language independent) – The purpose of the framework, and its usage– Detailed design of the framework
Al-Tamimi 2011 © 4
Pros and Cons of Design Patterns
• Pros– Design pattern provide common vocabulary– Design pattern help capture and spread
expert knowledge– Use of design patterns helps producing
code that is efficient, flexible and easily maintainable (provide a structure for change)
– Improve the quality of the overall design– Improve the designer productivity
Al-Tamimi 2011 © 5
Pros and Cons of Design Patterns
• Cons– Design patterns does not lead directly
to code reuse– At present time there are no
methodology is available that can be used to select the right design pattern at the right point during the design phase
– Being deceptively simple
Al-Tamimi 2011 © 6
Pattern’s Four Elements• Pattern Name
– A good name that be associated with the design framework (pattern) used, that also indicates the problem and its solution
– Having a concise, meaningful name for a pattern improves communication among developers
• The Problem– Describes when to apply the pattern It explains the problem and
its contents and the conditions to be implemented
• The Solution– Describes the elements that make up the design, their
relationships, responsibilities, and collaborations (abstract description)
• The Consequences– Are the results and tradeoffs of applying the pattern (space, time,
system flexibility , system portability , system extensibility … )
Al-Tamimi 2011 © 7
Type of Patterns
• Creational Patterns– These patterns provide guidance on the creation of
objects. They help hide the details of the object instantiation from the code that uses those objects
• Structural Patterns– Such patterns describe the organization of objects; that is,
how classes and objects are composed to form larger structures
• Behavioral Patterns– Behavioral patterns are concerned with organizing,
managing and assigning responsibilities to objects during execution; that is, the focus on the patterns of communication between the objects involved during some task
Al-Tamimi 2011 © 8
Examples of Patterns
• Creational Patterns– Factory Pattern– Singleton Pattern
• Structural Patterns– Façade Pattern–MVC Pattern
• Behavioral Patterns– Observer Pattern– Chain of Responsibility Pattern
Al-Tamimi 2011 © 9
Creational Patterns Factory Pattern & Singleton Pattern
Al-Tamimi 2011 © 10
Creational Patterns : Factory Pattern
• Problem: Creating objects (products) without specifying the exact class of object that will be created
• Solution: Define a separate method for creating the objects, which subclasses can then override to specify the derived type of product that will be created
• "Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."
Al-Tamimi 2011 © 11
Factory Pattern: Example
Al-Tamimi 2011 © 12
Document Factory Classpublic class DocumentFactory {…
public static Document getDocument() {Document doc = null;//type is loaded from properties file, or you can pass itif (DocumentType.WORD == type) { doc = new WordDocument();} else if (DocumentType.STAROFFICE == type) {
doc = new StarOfficeDocument();}
return doc;}
}
Al-Tamimi 2011 © 13
ImageReaderFactory Example
public class ImageReaderFactory { public static ImageReader getImageReader(InputStream is) { int imageType = determineImageType(is); switch(imageType) { case ImageReaderFactory.GIF: return new GifReader(is); case ImageReaderFactory.JPEG: return new JpegReader(is); // etc. } }}
Al-Tamimi 2011 © 14
Creational Patterns: Singleton Pattern
• Problem: Needs a class that can only have one object constructed for it
• Solution: the singleton pattern ensures that only one instance of a class is created. All objects that use an instance of that class use the same instance
• This is useful when exactly one object is needed to coordinate actions across the system
• In mathematics, a singleton is a set with exactly one element
Al-Tamimi 2011 © 15
Singleton Implementation in C#
Al-Tamimi 2011 © 16
Public class Singleton{ private static readonly Singleton _instance = new Singleton(); private Singleton() { } public static Singleton Instance { get { return _instance; } }}
Structural Patterns Façade Pattern & MVC Pattern
Al-Tamimi 2011 © 17
Structural Patterns: Façade Pattern
• Problem: How should the services be requested from a service package by client classes (classes outside the package)
• Solution: A separate class should be created to provide a common interface to their services provided by the classes in the package
Al-Tamimi 2011 © 18
Façade Pattern
Al-Tamimi 2011 © 19
Façade Pattern : Example - Subsystems
public class CPU {
public void Freeze() { }public void Jump(long addr) { }public void Execute() { }
} public class Memory{
public void Load(long position, byte[] data) { } } public class HardDrive{
public byte[] Read(long lba, int size) { return null; }}
Al-Tamimi 2011 © 20
Façade Pattern:Example – Façade Class
public class Computer{
CPU cpu = new CPU();Memory memory = new Memory();HardDrive hardDrive = new HardDrive();
public void StartComputer(){
cpu.Freeze();memory.Load(0x22, hardDrive.Read(0x66, 0x99));cpu.Jump(0x44);cpu.Execute();
}}
Al-Tamimi 2011 © 21
MVC Pattern
• Problem: How should the non-GUI classes communicate with the GUI classes
• Solution: use MVC pattern to separate data domain from non-data domain modules
• Consequences: loose coupling between view and model objects. Clear separation between the code that handles input, processes data and displays the data
Al-Tamimi 2011 © 22
Structural Pattern: MVC Pattern
• The model manages the behavior and data of the application domain,– responds to requests for information about its state (usually from the
view)– responds to instructions to change state (usually from the controller)
• The view renders the model into a form suitable for interaction, typically a user interface element. – Multiple views can exist for a single model for different purposes. – A viewport typically has a one to one correspondence with a display
surface and knows how to render to it
• The controller receives input and initiates a response by making calls on model objects. – A controller accepts input from the user and instructs the model and
viewport to perform actions based on that input
Al-Tamimi 2011 © 23
MVC Pattern
Al-Tamimi 2011 © 24
MVC Pattern Communications
Al-Tamimi 2011 © 25
:Controller:Controller :Model:Model :View:View
11
2233
11
22
33
Update: Collect input data and passes them to Model object
Notify: Change the model state and notify dependent Controller object
Notify: Change the model state and notify dependent Viewobject
Behavioral Patterns Observer Pattern & Chain of Responsibility Pattern
Al-Tamimi 2011 © 26
Behavioral Patterns: Observer Pattern
• Problem: when a model object is accessed by several view objects, how should the interactions between the model and the view objects be structured
• Solution: observers should register themselves with the model object. All registered observers will be notified. Observer can also ask the model about specific data or status (both push and pull)
• Consequences: decoupling between observers. Overhead on the model object. Different observers may ask for different notifications (inefficient notification)
Al-Tamimi 2011 © 27
Behavioral Pattern: Observer Pattern
Al-Tamimi 2011 © 28
Observer Pattern: Example
Al-Tamimi 2011 © 29
Observer Pattern Implementation in C#
// "Subject" abstract class Subject { private ArrayList observers = new ArrayList();
public void Attach(Observer observer){ observers.Add(observer); } public void Detach(Observer observer){ observers.Remove(observer); } public void Notify() { foreach (Observer o in observers){ o.Update();} } }// "ConcreteSubject" class ConcreteSubject:Subject { public string SubjectState; }
Al-Tamimi 2011 © 30
Model ObjectModel Object
Observer Pattern Implementation in C#
// "Observer" abstract class Observer{ public abstract void Update(); } // "ConcreteObserver" class ConcreteObserver : Observer { private string name; private string observerState; private ConcreteSubject subject; // Constructor public ConcreteObserver(ConcreteSubject subject, string name){ this.subject = subject; this.name = name; } public override void Update(){ observerState = subject.SubjectState; Console.WriteLine("Observer {0}'s new state is {1}", name, observerState); } }
Al-Tamimi 2011 © 31
Observer Object
Observer Object
Observer Pattern Implementation in C#
static void Main() { // Configure Observer pattern ConcreteSubject s = new ConcreteSubject();
s.Attach(new ConcreteObserver(s,"X")); s.Attach(new ConcreteObserver(s,"Y")); s.Attach(new ConcreteObserver(s,"Z"));
// Change subject and notify observers s.SubjectState = "ABC"; s.Notify();
}
Al-Tamimi 2011 © 32
Using Observer Pattern
Using Observer Pattern
Behavioral Patterns:Chain of Responsibility
Al-Tamimi 2011 © 33
• Problem: There is a potentially variable number of “processing element” and a stream of requests that must be handled. Need to efficiently process the requests
Behavioral Patterns:Chain of Responsibility
Al-Tamimi 2011 © 34
• Solution: Encapsulate the processing elements inside a “pipeline” abstraction; and have clients “launch and leave” their requests at the entrance to the pipeline
Behavioral Patterns:Chain of Responsibility
• Consequences: Chain of Responsibility simplifies object interconnections. Instead of senders and receivers maintaining references to all candidate receivers, each sender keeps a single reference to the head of the chain, and each receiver keeps a single reference to its immediate successor in the chain. The number and type of handler objects isn’t known a priori, they can be configured dynamically
Al-Tamimi 2011 © 35
Chain of Responsibility: Structure
Al-Tamimi 2011 © 36
Chain of Responsibility: Example
Al-Tamimi 2011 © 37
Chain of Responsibility : Implementation
// "Handler" abstract class Handler { protected Handler successor;
public void SetSuccessor(Handler successor) { this.successor = successor; }
public abstract void HandleRequest(int request); }
Al-Tamimi 2011 © 38
Handler (abstract)Handler
(abstract)
Chain of Responsibility : Implementation
// "ConcreteHandler1" class ConcreteHandler1 : Handler { public override void HandleRequest(int request) { if (request >= 0 && request < 10) { Console.WriteLine("{0} handled request {1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } }
Al-Tamimi 2011 © 39
Handler 1Handler 1
Chain of Responsibility : Implementation
// "ConcreteHandler2" class ConcreteHandler2 : Handler { public override void HandleRequest(int request) { if (request >= 10 && request < 20) { Console.WriteLine("{0} handled request {1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } }
Al-Tamimi 2011 © 40
Handler 2Handler 2
Chain of Responsibility : Implementation
// "ConcreteHandler3" class ConcreteHandler3 : Handler { public override void HandleRequest(int request) { if (request >= 20 && request < 30) { Console.WriteLine("{0} handled request {1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } }
Al-Tamimi 2011 © 41
Handler 3Handler 3
Chain of Responsibility : Implementation
static void Main() { // Setup Chain of Responsibility Handler h1 = new ConcreteHandler1(); Handler h2 = new ConcreteHandler2(); Handler h3 = new ConcreteHandler3(); h1.SetSuccessor(h2); h2.SetSuccessor(h3);
// Generate and process request int[] requests = {2, 5, 14, 22, 18, 3, 27, 20};
foreach (int request in requests) { h1.HandleRequest(request); }
// Wait for user Console.Read(); }
Al-Tamimi 2011 © 42
Using CoRUsing CoR
Pattern vs. Algorithms
• Beginners often confuses patterns and algorithms
• Both similar since they provide reusable solutions
• Algorithms : solving problems with reduced space and/or time requirements
• Patterns : focuses on understandability and maintainability of the design and on easier development
Al-Tamimi 2011 © 43
Antipattern
• If the patterns represents the best practice, anti-patterns represents lessons learned from bad designs– Those that describe bad solutions to
problems which leads to bad situations– Those that describe how to avoid bad
solutions to problems
• Very important to know what to avoid in your design phase/solving a problem
Al-Tamimi 2011 © 44
Resources
• http://sourcemaking.com/design_patterns
• Chapter 8, Fundamentals of Software Engineering by Rajib Mall
• Object Oriented Thought Process• Guide to Unified Process Featuring UML,
JAVA and Design Patterns• http://en.wikipedia.org/ [for each pattern]
Al-Tamimi 2011 © 45