Tải bản đầy đủ (.pdf) (10 trang)

Software Engineering For Students: A Programming Approach Part 19 pptx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (157.62 KB, 10 trang )

158 Chapter 12 ■ Design patterns
These relationships between components are the essence of the MVC pattern. The
advantages are that the model, the view or the controller can be changed without
affecting any other part of the system. Furthermore, additional views and controls can
be added easily.
In the software for the cyberspace invaders game, there must be a method or meth-
ods that test to see whether a laser has hit an alien and whether a bomb has hit the
defender. The question is: Where are these methods? One option is to place this col-
lision detection within class
Laser and class Bomb. Unfortunately this leads to a com-
plex structure in which every bomb has to know about the defender object and every
laser has to know about every alien object. This is high coupling. For example, if we
introduce additional objects into the game we will need to modify class
Bomb and
class
Laser.
A better approach is to create a mediator class. As its name suggests, this is respon-
sible for handling relationships between objects – termed colleague objects. The
essence of the mediator pattern is that colleague objects are changing (because, in this
example, they are moving).
This is how the pattern is implemented. First, all the colleague objects register with
the mediator object. Thereafter, when a colleague object changes its state (in this exam-
ple, when it moves) it calls the mediator object. The mediator decides whether a
notable event has occurred (a collision in this example) and, if necessary, notifies appro-
priate colleague objects (the objects involved in the collision).
The advantages are:
■ all the dependency logic is in one place
■ the colleague objects are simpler because they do not embody code to check
dependencies.
12.9


Mediator
SELF-TEST QUESTION
12.3 Identify differences between the Mediator pattern and the MVC pattern.
This pattern describes a way of building software from a group of components that
collaborate by passing a stream of information. The components behave like an
assembly line. Each component inputs some information from one component,
processes it and passes it on to another component, Figure 12.4. Each component is
12.10

Pipe and Filter
BELL_C12.QXD 1/30/05 4:22 PM Page 158
12.12 Layers 159
known as a filter and the connections are known as pipes. The information flow
between components is a one-way serial stream of data. Each component knows
nothing about any other component. This scheme corresponds to the pipe and filter
scheme that Unix provides. Many of the Unix utility programs process a stream of
data and create a new output stream. Examples are given in Chapter 18 on scripting
languages. Arguably, this type of connection means that the components have mini-
mal coupling.
A proxy object acts instead of some other object or objects. It fields requests, passing
them on as necessary.
The classic example is that of a proxy server on the internet, which acts in place of
another server because the actual server is too busy. The proxy either handles requests
itself or passes a request on to an available server. A busy website, such as a success-
ful search engine, cannot handle all the requests using a single server. Instead it uses
a collection of servers, fronted by a proxy server that farms out the work to an avail-
able server.
12.11

Proxy

Filter 1 Filter 2 Filter 3
Figure 12.4 Pipe and Filter pattern
SELF-TEST QUESTION
12.4 Compare and contrast the Proxy pattern with the Façade pattern.
The Layers pattern, sometimes called tiers, is a classic pattern that is used in many
systems. This pattern divides a software system into hierarchical layers. In one incar-
nation, Figure 12.5, there are three layers. The top layer handles the user interface
(sometimes called the presentation layer), the middle layer handles the application
logic (sometimes called the domain logic or the business logic) and the bottom layer
handles access to the database. Each layer makes requests on the services provided
by the layer immediately below it, and receives replies, but there are no other
dependencies in this structure.
The layers pattern can be used to structure the word processor (Appendix A). The
user interface provides the display of the current document and a set of commands. The
12.12

Layers
BELL_C12.QXD 1/30/05 4:22 PM Page 159
160 Chapter 12 ■ Design patterns
database level stores and retrieves documents. The middle layer processes commands,
such as deleting text.
The strength of the Layers pattern is that it provides a large-scale structure for cer-
tain types of software. It also means that each layer of the software can be modified
without affecting the other layers. For example, in the word processor, we can alter the
way that commands are invoked (the presentation layer), for example, by adding
menus, without changing the database access layer.
The word processor is a single-machine application. However, many current
applications – such as an ATM – are network-based or internet-based. The simplest
network-based architecture is the client-server architecture. This consists of two layers –
the client software running on the client machine and the server software running on the

server. The classic example is a web browser and a web server. The client passes a request
to the server; the server responds.
A classic example of the Layers pattern is the structure of the software for internet
communication, called the TCP/IP stack. Every computer that uses the internet has
this software. A typical application program makes requests on the transport layer that
supports the TCP protocol. This in turn makes requests of the internet layer that sup-
ports the IP protocol. This in turn calls the physical layer which actually carries out
data transfers. Thus the software consists of four levels, including the application level.
Another version of the Layers pattern, with four levels, describes many networked
solutions, Figure 12.6. Again, each layer uses the layer below it. The communication
between presentation and server layer is carried out according to a chosen network pro-
tocol, such as HTTP.
In designing a distributed system, there are choices about which layer does what. In
a thin client system, the client software does very little, while the bulk of the work is
carried out on the server. In a fat client architecture, the business logic layer migrates
to the client machine. The decision about where to perform processing depends on
such issues as performance, maintenance and security.
Another benefit of the Layers pattern is facilitating security. The boundaries between
layers serve as well-defined interfaces where security checks can be carried out. For
example encryption can be used between the client and the server. Finally, Layers pro-
vide for scalability. A server acting as a proxy (see pattern above) can delegate its task
to other servers as the load increases.
Figure 12.5 Layers
user interface layer
business logic layer
database access layer
BELL_C12.QXD 1/30/05 4:22 PM Page 160
12.14 Discussion 161
SELF-TEST QUESTION
12.5 What is the similarity between the Layer pattern and the MVC pattern?

12.6 What are the differences between the Layers pattern and the Pipe and
Filter pattern.
The blob is a bad structure – an anti-pattern. All the classes in the program are merged
into one large class. There is structure in terms of constituent methods, but that is all.
There is no large-scale structure. The blob is what someone would create if they did
not really understand what OOP is about – or if they could not see how to structure
the software into meaningful classes.
At one extreme the designer has the option of creating a design that consists only of
one single class. This is always possible, and corresponds to a non-OOP. At the other
extreme, the designer might create an unnecessarily large number of classes with many
interconnections. Thus design is a matter of judgment in order to arrive at the optimal
classes for the problem.
Patterns represent a valuable type of reuse. You do not reuse code or classes, you reuse
a design or a software structure. Such a design is probably a revelation for a novice,
but is probably recognizable by experts. Giving patterns individual names means that
they can be discussed easily. Cataloging patterns makes them widely available.
12.14

Discussion
12.13

Blob – an anti-pattern
Figure 12.6 Layers in a distributed system
presentation layer
server
business logic layer
data access layer
BELL_C12.QXD 1/30/05 4:22 PM Page 161
162 Chapter 12 ■ Design patterns
Summary

Patterns embody the experience of developers. They document useful architectur-
al structures (Some patterns also record techniques for activities such as testing.) A
pattern has a name, an application domain and a suggestion for a solution. Patterns
enable novices to use the knowledge of experts. They provide a body of knowledge
and a language for talking about structure. Patterns are documented in catalogs
(see the reading list below) for browsing prior to and during architectural software
design.
This chapter explains how to use some useful design patterns (and some anti-
patterns):
■ Inheritance – extending an existing class
■ Delegation – using other classes to perform useful tasks
■ Singleton – a class with only one instance
■ Factory Method – creating the appropriate class at run time
■ Façade – creating a front end to make using a collection of classes easier
■ Immutable – an object that does not change
■ Model-View-Controller – separating input, output and logic
■ Mediator – encapsulating the interaction between classes
■ Pipe and Filter – components that process a serial stream of data, passing it
from one to another
■ Proxy – a component that accepts requests on behalf of other components
■ Layers – separating large scale architecture into levels
■ Blob – an anti-pattern, a single complex class.
Some people like to distinguish types of patterns:
■ architectural patterns – the highest level structures, applicable to large numbers of
classes
■ design patterns – patterns applicable at the level of small groups of classes
■ coding patterns – applicable to detailed algorithms within methods
■ anti-patterns – the opposites of patterns.
You know you understand patterns when you can see how to use two or more in
your project. Many software systems use two or sometimes more patterns.

BELL_C12.QXD 1/30/05 4:22 PM Page 162
Answers to self-test questions 163
Exercises
12.1 Review the architectural structure of the cyberspace invaders game (Appendix A).
Suggest which patterns would be useful.
12.2 In a word processor (Appendix A), how would you use the MVC pattern? Hints:
what views does a word processor display? What commands does it provide?
12.3 Show how the Layers pattern can be used in the ATM software and in the library sys-
tem (Appendix A).

Answers to self-test questions
12.1 If people had static roles, we could model the structures using inheri-
tance. We could say “a private is-a soldier”. But army personnel get pro-
moted, so the best structure is delegation.
12.2 It means that it can only be called from within the class. Thus no program
can call the constructor from another class. The only way to create an
instance is to call getInstance, and this always returns the same
object.
12.3 1. The MVC pattern is concerned only with the user interface, while the
Mediator pattern is more general.
2. A Mediator class is more complex because it embodies logic gov-
erning the interaction of the objects.
12.4 Both patterns act as a front end to a component or collection of compo-
nents. But the motivation for Façade is to provide a clean interface. Proxy
does it for performance reasons.
12.5 Both explicitly separate out the presentation software from the business
logic component.
12.6 Pipe and Filter passes data in one direction only, whereas in Layers it is
passed to and fro between layers. In Pipe and Filter, communication is
solely by passing a stream of data, whereas in layers, some of the com-

munication is via method calls.
BELL_C12.QXD 1/30/05 4:22 PM Page 163
164 Chapter 12 ■ Design patterns
The first and most significant of the books about reusable design patterns. Written by
authors now referred to as the Gang of Four (GoF). It presents a number of OO
patterns, each with a name, a rationale and examples. (The examples of use are
mainly in C++, but the designs are more widely applicable.) It is not an easy book
and many people report that reading it is a challenge: Erich Gamma, Richard Helm,
Ralph Johnson and John Vlissides, Design Patterns: Elements of Reusable Object-
Oriented Software, Addison-Wesley, 1995.
This book is a readable catalog. Although the code examples are given in Java, you do
not need to know about Java, or use Java to understand the patterns: Mark Grand,
Patterns in Java: A Catalog of Reusable Design Patterns Illustrated with UML, 2
vols, John Wiley, 1998, 1999.
This book explores what can go wrong (calling them anti-patterns) during software
development, particularly OO development, and explains how to recover from these
situations. Easy to read, enjoyable and refreshing: William Brown, Raphael Malveau,
Hays McCormick and Thomas Mowbray, Anti Patterns, John Wiley, 1998.
Further reading

BELL_C12.QXD 1/30/05 4:22 PM Page 164
Refactoring is about improving an architectural design. Nowadays a design tends to be an
OOD, expressed in terms of classes and their interrelationships (methods). However,
design does not usually proceed in a straightforward, linear manner. Most often, design
tends to be an iterative process. First, candidate classes are identified. Then some will be
accepted while others will be rejected – perhaps because they have no methods or because
their methods are subsumed by some other class. Methods tend to migrate from one class
to another as a better understanding of the objects and their role within the problem
emerges. This process is known as refactoring. Refactoring is the transformation of a cor-
rect program structure (e.g., a class diagram) into an improved structure.

Good ideas for refactoring are published in catalogs. Each idea has a name so that it
can be referred to in conversations between developers. In this chapter we present some
of the most popular refactorings. We use as an example the cyberspace invaders game
(Appendix A) whose architecture is designed in the chapter on OOD.
So, the steps of refactoring are:
1. create a design
2. review the design
3. identify possible refactorings
4. carry out refactoring.
13.1

Introduction
CHAPTER
13
Refactoring
This chapter:
■ explains how to carry out refactoring
■ explains several common refactorings.
BELL_C13.QXD 1/30/05 4:23 PM Page 165
166 Chapter 13 ■ Refactoring
An alternative approach is to refactor periodically as design proceeds:
1. carry out some partial design
2. review the design
3. identify possible refactorings
4. carry out refactoring
5. continue from step 1.
The term coupling describes the interaction between components, while cohesion
describes the interactions within a component. Many of the refactorings are aimed at
minimizing coupling between components and maximizing cohesion within compo-
nents. This combination promotes clarity, modularity and re-use.

A variable is defined as public and it is therefore unclear who uses it and why. The rem-
edy is to make it private and provide methods to access the data.
For example, in the game, the x coordinate of an alien could be declared (in Java) as:
public int x;
Instead, declare x as follows:
private int x;
And provide methods to read the value and change the value:
public void setX(int newX) {
x = newX;
}
public int getX() {
return x;
}
Encapsulating data makes it clear how data is being accessed and by whom. Data
declared as public can be accessed by any part of the software in an uncontrolled fashion.
Encapsulation is one of the central features of OOP.
This refactoring can always be used on any public data and its implementation is
straightforward.
13.2

Encapsulate Data
>
>
BELL_C13.QXD 1/30/05 4:23 PM Page 166
13.6 Inline Class 167
A method is written within a class, but it uses very little of its current class. Instead it
uses many of the facilities of another class. The remedy is to move the method from one
class to the other.
In the game, the software needs to check whether pairs of items have collided, for
example, a laser and an alien. For clarity, this collision detection is carried out by a method.

This method is part of both class
Laser and class Alien. This creates strong coupling
between the objects. Instead move the method to a class that is responsible for checking
collisions between all the objects in the game.
In general, moving a method may be necessary when:
■ a class has too many methods
■ a class has high coupling with another class.
Moving a method is a common refactoring situation.
A variable is declared within a class, but another class uses it more. The remedy is to
move the variable declaration. Clearly this also means moving the get and set methods.
A class has become too large and complex; it is doing the work of two classes. The rem-
edy is to create a new class, extracting the appropriate variables and methods from the
old class.
Ideally classes emerge from design as self-contained components that model some
element of the application. In practice, as design proceeds, classes sometimes take on
extra roles. Variables and methods are gradually added until the class becomes cumber-
some. It becomes a candidate for fission.
A class is very small, or it does not do very much. The remedy is to incorporate it into
some other class – ideally the class that uses it the most.
13.6

Inline Class
13.5

Extract Class
13.4

Move Data
13.3


Move Method
BELL_C13.QXD 1/30/05 4:23 PM Page 167

×