chapter 3: design patterns

71
Chapter 3: Design Patt erns Feng Zhiyong Tianjin University March 12, 2006

Upload: nadda

Post on 05-Jan-2016

69 views

Category:

Documents


2 download

DESCRIPTION

Chapter 3: Design Patterns. Feng Zhiyong Tianjin University March 12, 2006. Architectural Patterns. Design Patterns. programming language-specific idioms. Introduction. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Chapter 3: Design Patterns

Chapter 3: Design Patterns

Feng Zhiyong

Tianjin University

March 12, 2006

Page 2: Chapter 3: Design Patterns

Introduction

Design patterns are medium-scale patterns. They are smaller in scale than architectural patterns, but are at a higher level than the programming language-specific idioms.

Architectural Patterns

Design Patterns

programming language-specific idioms

Page 3: Chapter 3: Design Patterns

Group Design Patterns

Structural DecompositionOrganization of Work Access Control ManagementCommunication

Page 4: Chapter 3: Design Patterns

Overview(1)

Structural Decomposition This category includes patterns that support a suitable decomposition of subsystems and complex components into cooperating parts. The Whole-Part pattern is the most general pattern we are aware of in this category.

Organization of Work. This category comprises patterns that define how components collaborate together to solve a complex problem. We describe the Master-Slave pattern, which helps you to organize the computation of services for which fault tolerance or computational accuracy is required.

Page 5: Chapter 3: Design Patterns

Overview(2)

Access Control. Such patterns guard and control access to services or components. We describe the Proxy pattern here.

Management. This category includes patterns for handling homogenous collections of objects, services and components in their entirety. We describe two patterns: the Command Processor pattern addresses the management and scheduling of user commands, while the View Handler pattern describes how to manage views in a software system.

Page 6: Chapter 3: Design Patterns

Overview(3)

Communication. Patterns in this category help to organize communication between components. Two patterns address issues of inter-process communication: the Forwarder-Receiver pattern deals with peer-to-peer communication, while the Client Dispatcher-Server pattern describes location-transparent communication in a Client-Server structure. The Publisher-Subscriber pattern helps with the task of keeping data consistent between cooperating components.

*An important property of all design patterns is that they are independent of a particular application domain.

*Most design patterns are independent of a particular programming paradigm.

Page 7: Chapter 3: Design Patterns

Structural Decomposition(1)

Structural DecompositionOrganization of Work Access Control ManagementCommunication

Page 8: Chapter 3: Design Patterns

Structural Decomposition()

The Whole-Part design pattern helps with the aggregation of components that together form a semantic unit.

The Composite pattern organizes objects into tree structures that represent part-whole hierarchies.

Page 9: Chapter 3: Design Patterns

The Whole-part Design Pattern

Example Context Problem Solution Structure Dynamics Implementation Variants Example Resolved Known Uses See also

Page 10: Chapter 3: Design Patterns

Whole-part-- Example

Page 11: Chapter 3: Design Patterns

Whole-part-- Context

Context Implementing aggregate objects.

Page 12: Chapter 3: Design Patterns

Whole-part-- Problem

A complex object should either be decomposed into smaller objects, or composed of existing objects, to support reusability, changeability and the recombination of the constituent objects in other types of aggregate.

Clients should see the aggregate object as an atomic object that does not allow any direct access to its constituent parts.

Page 13: Chapter 3: Design Patterns

Whole-part-- Solution

Introduce a component that encapsulates smaller objects, and prevents clients from accessing these constituent parts directly. Define an interface for the aggregate that is the only means of access to the functionality of the encapsulated objects. allowing the aggregate to appear as a semantic unit.

The general principle of the Whole-Part pattern is applicable to the organization of three types of relationship:

An assembly-parts relationship A container-contents relationship The collection-members relationship

Page 14: Chapter 3: Design Patterns

Whole-part—Structure(1)

Page 15: Chapter 3: Design Patterns

Whole-part—Structure(2)

Page 16: Chapter 3: Design Patterns

Whole-part—Dynamics(1)

Page 17: Chapter 3: Design Patterns

Whole-part—Dynamics(2)

Page 18: Chapter 3: Design Patterns

Whole-part– Implementation(1)

1 Design the public interface of the Whole. Analyze the functionality the Whole must offer to its clients.

2 Separate the Whole into Parts, or synthesize it from existing ones. There are two approaches:

The bottom-up approach allows you to compose Wholes from loosely-coupled Parts that you can later reuse when implementing other types of Whole.

The top-down approach makes it is possible to cover all of the Whole's functionality.

Page 19: Chapter 3: Design Patterns

Whole-part– Implementation(2)

3 If you follow a bottom-up approach, use existing Parts from component libraries or class libraries and specify their collaboration.

4 If you follow a top-down approach, partition the Mirhole's services into smaller collaborating services and map these collaborating services to separate Parts.

Page 20: Chapter 3: Design Patterns

Whole-part– Implementation(3)

5 Specify the services of the W'hole in terms of services of the Parts.---two possible ways to call a Part service:

If a client request is forwarded to a Part service, the Part does not use any knowledge about the execution context of the Whole, relying on its own environment instead.

A delegation approach requires the Whole to pass its own context information to the Part.

Page 21: Chapter 3: Design Patterns

Whole-part– Implementation(4)

6 Implement the Parts. If the Parts are Whole-Part structures themselves, design them recursively starting with step 1. If not, reuse existing Parts from a library, or just implement them if their implementation is straightforward and further decomposition is not necessary.

7 Implement the Whole. Implement the Whole's services based on the structure you developed in the preceding steps.

Page 22: Chapter 3: Design Patterns

Whole-part– Variants(1)

Shared Parts. This variant relaxes the restriction that each Part must be associated with exactly one Whole by allowing several Wholes to share the same Part.

Page 23: Chapter 3: Design Patterns

Whole-part– Variants(2)

The next three variants describe the implementation of the Whole-to-Parts relationships we introduced in the Solution section:

Assembly-Parts In this variant the Whole may be an object that represents an assembly of smaller objects.

Container-Contents. In this variant a container is responsible for maintaining differing contents.

The Collection-Members variant is a specialization of Container-Contents, in that the Part objects all have the same type.

Page 24: Chapter 3: Design Patterns

Whole-part– Example Resolved(1)

Page 25: Chapter 3: Design Patterns

Whole-part– Example Resolved(2)

Page 26: Chapter 3: Design Patterns

Whole-part– Example Resolved(3)

Page 27: Chapter 3: Design Patterns

Whole-part– Known Uses

The key abstractions of many object-oriented applications follow the Whole-Part pattern.

Most object-oriented class libraries provide collection classes such as lists. sets. and maps. These classes implement the Collection-Member and Container-Contents variants.

Graphical user interface toolkits such as Fresco or ET++ use the Composite variant of the Whole-Part pattern.

Page 28: Chapter 3: Design Patterns

Whole-part– Consequences

Benefits: Changeability of Parts Separation of concerns Reusabilityliabilities: Lower eminency through indirection Complexity of decomposition into Parts

Page 29: Chapter 3: Design Patterns

Whole-part– See also

the Composite design pattern is applicable when: You want to represent whole-part hierarchies of

objects. You want clients to be able to ignore the difference

between compositions of objects and individual objects.

Composite is a variant of the Whole-Part design pattern that you should consider when facing these two requirements.

The Facade design pattern helps to provide a simple interface to a complex subsystem.

Page 30: Chapter 3: Design Patterns

3.3 Organization of Work(1)

Structural DecompositionOrganization of Work Access Control ManagementCommunication

Page 31: Chapter 3: Design Patterns

Organization of Work(2)

The implementation of complex services is often solved by several components in cooperation.

The Master-Slave pattern supports fault computation and computational accuracy.

Master-Slave applies the 'divide and conquer' principle. The Master-Slave pattern is widely applied in the areas of

parallel and distributed computing. The Chain of Responsibility, Command and Mediator

patterns also belong to this category

Page 32: Chapter 3: Design Patterns

3.3.1Master-Slave

Example Context Problem Solution Structure Dynamics Implementation Variants Known Uses See also

Page 33: Chapter 3: Design Patterns

Master-Slave-- Example

Page 34: Chapter 3: Design Patterns

Master-Slave-- Context

Context Partitioning work into semantically-identical sub-tasks.

Page 35: Chapter 3: Design Patterns

Master-Slave– Problem(1)

Clients should not be aware that the calculation is based on the “divide and conquer” principle.

Neither clients nor the processing of sub-tasks should depend on the algorithms for partitioning work and assembling the final result.

Page 36: Chapter 3: Design Patterns

Master-Slave– Problem(2)

It can be helpful to use different but semantically-identical implementations for processing sub-tasks, for example to increase computational accuracy.

Processing of sub-tasks sometimes needs coordination, for example in simulation applications using the finite element method.

Page 37: Chapter 3: Design Patterns

Master-Slave-- Solution

A master component divides work into equal sub-tasks, delegates

these sub-tasks to several independent but semantically-identical

shve components, and computes a final result from the partial

results the slaves return.

This general principle is found in three application areas:

Fault tolerance Parallel computing Computational accuracy

Page 38: Chapter 3: Design Patterns

Master-Slave—Structure(1)

Page 39: Chapter 3: Design Patterns

Master-Slave—Structure(2)

Page 40: Chapter 3: Design Patterns

Master-Slave—Dynamics(1)

A client requests a service from the master The master partitions the task into several equal sub-tasks. The master delegates the execution of these sub-tasks to

several slave instances, starts their execution and waits for the results they return

The slaves perform the processing of the sub-tasks and return the results of their computation back to the master

The master computes a final result for the whole task from the partial results received from the slaves

The master returns this result to the client

Page 41: Chapter 3: Design Patterns

Master-Slave—Dynamics(2)

Page 42: Chapter 3: Design Patterns

Master-Slave– Implementation(1)

The implementation of the Master-Slave pattern follows five steps:

1.Divide work. Specify how the computation of the task can be split into a set of equal sub-tasks. Identify the sub-services that are necessary to process a sub-task.

2.Combine sub-task results. Specify how the final result of the whole service can be computed with the help of the results obtained from processing individual sub-tasks.

Page 43: Chapter 3: Design Patterns

Master-Slave– Implementation(2)

3. Specify the cooperation between master and slaves. Define an interface for the sub-service identified in step 1. It will be implemented by

the slave and used by the master to delegate the processing of individual sub-tasks.

4.Implement the slave components according to the specifications developed in the previous step.

5.Implement the master according to the specifications developed in step 1 to 3.

Page 44: Chapter 3: Design Patterns

Master-Slave– Variants(1)

Master Slave for fault tolerance. In this variant the master just delegates the execution of a service to a fixed number of replicated implementations, each represented by a slave.

Master-Slave for parallel computation. The master divides a complex task into a number of identical sub-tasks, each of which is executed in parallel by a separate slave. The master builds the final result from the results obtained from the slaves.

Page 45: Chapter 3: Design Patterns

Master-Slave– Variants(2)

Master-Slave for computational accuracy. The execution of a service is delegated to at least three different implementations, each of which is a separate slave.

Page 46: Chapter 3: Design Patterns

Master-Slave– Variants(3)

Further variants exist for implementing slaves:Slaves as Processes. To handle slaves located in separate

processes, you can extend the original Master-Slave structure with two additional components

Slaves as Threads. Every slave is implemented withinits own thread of control.Master Slave with slave coordination. The computation

of a slave may depend on the state of computation of other slaves

Page 47: Chapter 3: Design Patterns

Master-Slave– Known Uses

Matrix multiplication. Each row in the product matrix can be computed by a separate slave.

Transform-coding an image, for example in computing the discrete cosine transform (DCT) of every 8 x 8 pixel block in an image. Each block can be computed by a separate slave.

Computing the cross-correlation of two signals. This is done by iterating over all samples in the signal, computing the mean-square distance between the sample and its correlate, and summing the distances.

Page 48: Chapter 3: Design Patterns

Master-Slave– Consequences

Benefits: Exchangeability and extensibility Separation of concerns Efficiencyliabilities: Feasibility Hard to implement Portability

Page 49: Chapter 3: Design Patterns

Master-Slave– See also

The Master-Slave Pattern for Parallel Compute Services [Bro96] provides additional insights for implementing a Master-Slave structure.

The book Programming with Threads [KSS96] describes the Slaves as Threads variant in detail.

Object Group [Maf96] is a pattern for group communication and support of fault tolerance in distributed applications. It corresponds to the Master-Slave for fault tolerance variant and provides additional details for its implementation.

Page 50: Chapter 3: Design Patterns

3.4 Access Control (1)

Structural DecompositionOrganization of Work Access Control ManagementCommunication

Page 51: Chapter 3: Design Patterns

Access Control(2)

Sometimes a component or even a whole subsystem cannot or should not be accessible directly by its clients.

The Proxy design pattern makes the clients of a component communicate with a representative rather than to the component itself.

The Facade pattern provides a uniform interface to a set of interfaces in a subsystem.

The Iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

Page 52: Chapter 3: Design Patterns

3.4.1Proxy

Example Context Problem Solution Structure Dynamics Implementation Variants Example Resolved Known Uses See also

Page 53: Chapter 3: Design Patterns

Proxy-- Example

Page 54: Chapter 3: Design Patterns

Proxy-- Context

Context A client needs access to the services of another component. Direct access is technically possible, but may not be the best approach.

Page 55: Chapter 3: Design Patterns

Proxy– Problem(1)

Accessing the component should be run-time-efficient, costeffective, and safe for both the client and the component.

Access to the component should be transparent and simple for the client. The client should particularly not have to change its calling behavior and syntax from that used to call any other direct-access component.

Page 56: Chapter 3: Design Patterns

Proxy– Problem(2)

The client should be well aware of possible performance or financial penalties for accessing remote clients. Full transparency can obscure cost differences between services.

Page 57: Chapter 3: Design Patterns

Proxy-- Solution

Let the client communicate with a representative rather than the component itself.

This representative-called a proxy-offers the interface of the component but performs additional pre- and post- processing such as access-control checking or making read-only copies of the original.

Page 58: Chapter 3: Design Patterns

Proxy—Structure(1)

The original implements a particular service. The client is responsible for a specific task. The abstract original provides the interface

implemented by the proxy and the original

Page 59: Chapter 3: Design Patterns

Proxy—Structure(2)

Page 60: Chapter 3: Design Patterns

Proxy—Structure(3)

Page 61: Chapter 3: Design Patterns

Proxy—Dynamics(1)

While working on its task the client asks the proxy to carry out a service.

The proxy receives the incoming service request and pre-processes it.

If the proxy has to consult the original to fulfill the request, it forwards the request to the original using the proper communication protocols and security measures.

The original accepts the request and fulfills it. It sends the response back to the proxy.

The proxy receives the response.

Page 62: Chapter 3: Design Patterns

Proxy—Dynamics(2)

Page 63: Chapter 3: Design Patterns

Proxy– Implementation(1)

To implement the Proxy pattern, carry out the following steps:

1. Identify all responsibilities for dealing with access control to a component.

2. 2 If possible introduce an abstract base class that specifies the common parts of the interfaces of both the proxy and the original. Derive the proxy and the original from this abstract base.

Page 64: Chapter 3: Design Patterns

Proxy– Implementation(2)

3. Impkment the proxy's finctions. To this end check the roles specified in the first step.

4. Free the original and its clients from responsibilities that have migrated into the proxy.

5. Associate the proxy and the original by giving the proxy a handle to the original.

6. Remove all direct relationships between the original and its clients.

Page 65: Chapter 3: Design Patterns

Proxy– Variants(1)

Remote Proxy. Clients of remote components should be shielded from network addresses and inter-process communication protocols.

Protection Proxy. Components must be protected from unauthorized access.

Cache Proxy. Multiple local clients can share results from remote components.

Synchronization Proxy. Multiple simultaneous accesses to a component must be synchronized.

Page 66: Chapter 3: Design Patterns

Proxy– Variants(2)

Counting Proxy. Accidental deletion of components must be prevented or usage statistics collected.

Virtual Proxy. Processing or loading a component is costly, while partial information about the component may be sufficient.

Firewall Proxy. Local clients should be protected from the outside world.

Page 67: Chapter 3: Design Patterns

Proxy– Example Resolved

You may often need to use more than one of the above Proxy variants Resolved -you may want the proxy to play several of the above roles and fulfill the corresponding responsibilities.

You can solve remote data access problems by using proxies with the properties of both Remote and Cache Proxy variants. Implementing such a mixed-mode proxy can be accomplished by using the Whole-Part pattern

Page 68: Chapter 3: Design Patterns

Proxy– Known Uses(1)

NeXTSTEP. The Proxy pattern is used in the NeXTSTEP operating system to provide local stubs for remote objects.

OMG-CORBA uses the Proxy pattern for two purposes. Socalled 'client-stubs', or IDL-stubs, guard clients against the concrete implementation of their servers and the Object Request Broker.

Orbix, a concrete OMG-CORBA implementation, uses remote proxies.

Page 69: Chapter 3: Design Patterns

Proxy– Known Uses(2)

World Wide Web Proxy describes aspects of the CERN HTTP server that typically runs on a firewall machine. It gives people inside the firewall concurrent access to the outside world. Efficiency is increased by caching recently transferred files.

OLE. In Microsoft OLE servers may be implemented as libraries dynamically linked to the address space of the client, or as separate processes. Proxies are used to hide whether a particular server is local or remote from a client

Page 70: Chapter 3: Design Patterns

Proxy– Consequences

Benefits: Enhanced egiciency and lower cost Decoupling clients from the location of seruer comp

onents Separation of housekeeping code from functionalityliabilities: Less emiency due to indirection Overkill via sophisticated strategies

Page 71: Chapter 3: Design Patterns

Proxy– See also

The Decorator pattern is very similar in structure to Proxy. Concrete component-the original in the Proxy pattern-implements some behavior that is invoked via a decorator-the proxy in the Proxy pattern. Both classes inherit from a common base. The major difference between the Decorator and Proxy patterns is one of intent. The decorator adds functionality or, more generally, gives options for dynamically choosing functionality in addition to the core functionality of Concrete component. The proxy frees the original from very specific housekeeping code.