Download ebooks file (Ebook) Object-oriented software engineering : using UML, Patterns, and Java by Bruegge, Bernd; Dutoit, Allen H. ISBN 9781292024011, 1292024011 all chapters
Download ebooks file (Ebook) Object-oriented software engineering : using UML, Patterns, and Java by Bruegge, Bernd; Dutoit, Allen H. ISBN 9781292024011, 1292024011 all chapters
ebooknice.com
ebooknice.com
ebooknice.com
https://ebooknice.com/product/sat-ii-success-
math-1c-and-2c-2002-peterson-s-sat-ii-success-1722018
ebooknice.com
(Ebook) Master SAT II Math 1c and 2c 4th ed (Arco Master
the SAT Subject Test: Math Levels 1 & 2) by Arco ISBN
9780768923049, 0768923042
https://ebooknice.com/product/master-sat-ii-math-1c-and-2c-4th-ed-
arco-master-the-sat-subject-test-math-levels-1-2-2326094
ebooknice.com
ebooknice.com
ebooknice.com
ebooknice.com
ebooknice.com
Object oriented software engineering using UML
Patterns and Java 3rd, intern. Edition Bruegge Digital
Instant Download
Author(s): Bruegge, Bernd; Dutoit, Allen H.
ISBN(s): 9781292024011, 1292024011
Edition: 3rd, intern.
File Details: PDF, 4.83 MB
Year: 2014
Language: english
Object-Oriented Software Engineering
Object-Oriented Software Engineering
Using UML, Patterns, and Java
Bernd Bruegge Allen H. Dutoit
Third Edition
Bruegge Dutoit
3e
ISBN 978-1-29202-401-1
9 781292 024011
Object-Oriented Software Engineering
Using UML, Patterns, and Java
Bernd Bruegge Allen H. Dutoit
Third Edition
Pearson Education Limited
Edinburgh Gate
Harlow
Essex CM20 2JE
England and Associated Companies throughout the world
All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted
in any form or by any means, electronic, mechanical, photocopying, recording or otherwise, without either the
prior written permission of the publisher or a licence permitting restricted copying in the United Kingdom
issued by the Copyright Licensing Agency Ltd, Saffron House, 6–10 Kirby Street, London EC1N 8TS.
All trademarks used herein are the property of their respective owners. The use of any trademark
in this text does not vest in the author or publisher any trademark ownership rights in such
trademarks, nor does the use of such trademarks imply any affiliation with or endorsement of this
book by such owners.
Table of Contents
I
Chapter 14. Project Management
Bernd Bruegge/Allen H. Dutoit 563
Chapter 15. Software Life Cycle
Bernd Bruegge/Allen H. Dutoit 607
Chapter 16. Methodologies: Putting It All Together
Bernd Bruegge/Allen H. Dutoit 637
Appendix C: Bibliography
Bernd Bruegge/Allen H. Dutoit 693
Index 707
II
1
Introduction to
Software Engineering
The amateur software engineer is always in search of magic,
some sensational method or tool whose application promises to
render software development trivial. It is the mark of the
professional software engineer to know that no such panacea
exists.
T he term software engineering was coined in 1968 as a response to the desolate state of the
art of developing quality software on time and within budget. Software developers were not able
to set concrete objectives, predict the resources necessary to attain those objectives, and manage
the customers’ expectations. More often than not, the moon was promised, a lunar rover built,
and a pair of square wheels delivered.
The emphasis in software engineering is on both words, software and engineering. An
engineer is able to build a high-quality product using off-the-shelf components and integrating
them under time and budget constraints. The engineer is often faced with ill-defined problems
and partial solutions, and has to rely on empirical methods to evaluate solutions. Engineers
working in such application domains as passenger aircraft design and bridge construction have
successfully met similar challenges. Software engineers have not been as successful.
The problem of building and delivering complex software systems on time has been
actively investigated and researched. Everything has been blamed, from the customer (“What do
you mean I can’t get the moon for $50?”) to the “soft” in software (“If I could add that one last
feature ...”) to the youth of this discipline. What is the problem?
Useful software systems are complex. To remain useful they need to evolve with the end users’
need and the target environment. In this book, we describe object-oriented techniques for
conquering complex and changing software systems. In this chapter, we provide a motivation for
object-oriented techniques and define the basic concepts used throughout this book.
From Chapter 1 of Object-Oriented Software Engineering Using UML, Patterns, and Java, Third Edition.
Bernd Bruegge, Allen H. Dutoit. Copyright © 2010 by Pearson Education, Inc. All rights reserved.
1
Chapter 1 • Introduction to Software Engineering
2
What Is Software Engineering?
Each of the failures described above resulted from a software-related problem. In some cases,
developers did not anticipate seldom-occurring situations (a person living more than 100 years,
leap years impacting expiration dates). In other cases, developers did not anticipate the user
actively misusing the system (taping down a button, exploiting security holes in network
software). In yet other cases, system failures resulted from management failures (late and over-
budget delivery, on-time delivery of an incorrect system, unnecessary complexity).
Software systems are complex creations. They perform many functions; they are built to
achieve many different, and often conflicting, objectives. They comprise many components;
many of their components are custom made and complex themselves. Many participants from
different disciplines take part in the development of these components. The development process
and the software life cycle often spans many years. Finally, complex systems are difficult to
understand completely by any single person. Many systems are so hard to understand, even
during their development phase, that they are never finished: these are called vaporware.
Software development projects are subject to constant change. Because requirements are
complex, they need to be updated when errors are discovered and when the developers have a
better understanding of the application. If the project lasts many years, the staff turn-around is
high, requiring constant training. The time between technological changes is often shorter than
the duration of the project. The widespread assumptions of a software project manager that all
changes have been dealt with and that the requirements can be frozen will lead to the
deployment of an irrelevant system.
In the next section, we present a high-level view of software engineering. We describe
software engineering from the perspective of science, engineering, and knowledge acquisition
and formalization. In Section 1.3, we describe in more detail the main terms and concepts we
use in this book. In Section 1.4, we provide an overview of the development activities of
software engineering. In Section 1.5, we provide an overview of the managerial activities of
software engineering.
3
Chapter 1 • Introduction to Software Engineering
into knowledge. Knowledge acquisition is not sequential, as a single piece of additional data can
invalidate complete models.
Software engineering is a rationale-driven activity. When acquiring knowledge and
making decisions about the system or its application domain, software engineers also need to
capture the context in which decisions were made and the rationale behind these decisions.
Rationale information, represented as a set of issue models, enables software engineers to
understand the implication of a proposed change when revisiting a decision.
In this section, we describe in more detail software engineering from the perspectives of
modeling, problem solving, knowledge acquisition, and rationale. For each of these activities,
software engineers have to work under people, time, and budget constraints. In addition, we
assume that change can occur at any time.
1.2.1 Modeling
The purpose of science is to describe and understand complex systems, such as a system of
atoms, a society of human beings, or a solar system. Traditionally, a distinction is made between
natural sciences and social sciences to distinguish between two major types of systems. The
purpose of natural sciences is to understand nature and its subsystems. Natural sciences include,
for example, biology, chemistry, physics, and paleontology. The purpose of the social sciences is
to understand human beings. Social sciences include psychology and sociology.
There is another type of system that we call an artificial system. Examples of artificial
systems include the space shuttle, airline reservation systems, and stock trading systems. Herbert
Simon coined the term sciences of the artificial to describe the sciences that deal with artificial
systems [Simon, 1970]. Whereas natural and social sciences have been around for centuries, the
sciences of the artificial are recent. Computer science, for example, the science of understanding
computer systems, is a child of the twentieth century.
Many methods that have been successfully applied in the natural sciences and humanities
can be applied to the sciences of the artificial as well. By looking at the other sciences, we can
learn quite a bit. One of the basic methods of science is modeling. A model is an abstract
representation of a system that enables us to answer questions about the system. Models are
useful when dealing with systems that are too large, too small, too complicated, or too expensive
to experience firsthand. Models also allow us to visualize and understand systems that either no
longer exist or that are only claimed to exist.
Fossil biologists unearth a few bones and teeth preserved from some dinosaur that no one
has ever seen. From the bone fragments, they reconstruct a model of the animal, following rules
of anatomy. The more bones they find, the clearer their idea of how the pieces fit together and
the higher the confidence that their model matches the original dinosaur. If they find a sufficient
number of bones, teeth, and claws, they can almost be sure that their model reflects reality
accurately, and they can guess the missing parts. Legs, for example, usually come in pairs. If the
left leg is found, but the right leg is missing, the fossil biologists have a fairly good idea what the
4
What Is Software Engineering?
missing leg should look like and where it fits in the model. This is an example of a model of a
system that no longer exists.
Today’s high-energy physicists are in a position similar to that of a fossil biologist who has
found most of the bones. Physicists are building a model of matter and energy and how they fit
together at the most basic, subatomic level. Many years of experiments with particle accelerators
have given high-energy physicists enough confidence that their models reflect reality and that
the remaining pieces that are not yet found will fit into the so-called standard model. This is an
example of a model for a system that is claimed to exist.
Both system modelers, fossil biologists and high-energy physicists, deal with two types of
entities: the real-world system, observed in terms of a set of phenomena, and the application
domain model, represented as a set of interdependent concepts. The system in the real world is a
dinosaur or subatomic particles. The application domain model is a description of those aspects
of the real-world system that are relevant to the problem under consideration.
Software engineers face similar challenges as fossil biologists and high-energy physicists.
First, software engineers need to understand the environment in which the system has to operate.
For a train traffic control system, software engineers need to know train signaling procedures.
For a stock trading system, software engineers need to know trading rules. The software
engineer does not need to become a fully certified train dispatcher or a stock broker; they only
need to learn the application domain concepts that are relevant to the system. In other terms,
they need to build a model of the application domain.
Second, software engineers need to understand the systems they could build, to evaluate
different solutions and trade-offs. Most systems are too complex to be understood by any one
person, and most systems are expensive to build. To address these challenges, software
engineers describe important aspects of the alternative systems they investigate. In other terms,
they need to build a model of the solution domain.
Object-oriented methods combine the application domain and solution domain modeling
activities into one. The application domain is first modeled as a set of objects and relationships.
This model is then used by the system to represent the real-world concepts it manipulates. A
train traffic control system includes train objects representing the trains it monitors. A stock
trading system includes transaction objects representing the buying and selling of commodities.
Then, solution domain concepts are also modeled as objects. The set of lines used to depict a
train or a financial transaction are objects that are part of the solution domain. The idea of
object-oriented methods is that the solution domain model is a transformation of the application
domain model. Developing software translates into the activities necessary to identify and
describe a system as a set of models that addresses the end user’s problem. We describe in more
detail modeling and the concepts of objects in Chapter 2, Modeling with UML.
5
Chapter 1 • Introduction to Software Engineering
6
What Is Software Engineering?
that offered to teach all the German poems by pouring them into the student’s head in 6 hours
with a funnel.1 The idea of using a funnel for learning is based on the widespread assumption
that our mind is a bucket that is initially empty and can be filled in a linear fashion. Material
enters through our senses, accumulates, and is digested. Popper calls this linear acquisition
model for knowledge “the bucket theory of the mind.” Among the many other things that are
wrong with this theory (described in [Popper, 1992]) is the assumption that knowledge is
conceived as consisting of things that can fill a bucket; that is, the fuller the bucket, the more we
know.
Knowledge acquisition is a nonlinear process. The addition of a new piece of information
may invalidate all the knowledge we have acquired for the understanding of a system. Even if
we had already documented this understanding in documents and code (“The system is 90%
coded, we will be done next week”), we must be mentally prepared to start from scratch. This
has important implications on the set of activities and their interactions we define to develop the
software system. The equivalent of the bucket theory of the mind is the sequential waterfall
model for software development, in which all steps of the engineering method are accomplished
sequentially.
There are several software processes that deal with this problem by avoiding the sequential
dependencies inherent in the waterfall model. Risk-based development attempts to anticipate
surprises late in a project by identifying the high-risk components. Issue-based development
attempts to remove the linearity altogether. Any development activity—analysis, system design,
object design, implementation, testing, or delivery—can influence any other activity. In issue-
based development, all these activities are executed in parallel. The difficulty with nonsequential
development models, however, is that they are difficult to manage.
1.2.4 Rationale
When describing the acquisition or evolution of knowledge, we are even less well equipped than
when describing the knowledge of an existing system. How does a mathematician derive a
proof? Mathematical textbooks are full of proofs, but rarely provide hints about the proof
derivation. This is because mathematicians do not think this background is important. Once the
axioms and the rules of deduction have been stated, the proof is timeless.
For software engineers, the situation is different. Assumptions that developers make about
a system change constantly. Even though the application domain models eventually stabilize
once developers acquire an adequate understanding of the problem, the solution domain models
are in constant flux. Design and implementation faults discovered during testing and usability
problems discovered during user evaluation trigger changes to the solution models. Changes can
also be caused by new technology. The availability of a long-life battery and of high-bandwidth
wireless communication, for example, can trigger revisions to the concept of a portable terminal.
1. G. P. Harsdoerfer (1607–1658), “Poetischer Trichter, die teutsche Dicht- und Reimkunst, ohn Behuf der lateinischen
Sprache, in 6 Stunden einzugießen,” Nuernberg, 1630.
7
Chapter 1 • Introduction to Software Engineering
Change introduced by new technology often allows the formulation of new functional or
nonfunctional requirements. A typical task of software engineers is to change a currently
operational software system to incorporate this new enabling technology. To change the system,
it is not enough to understand its current components and behavior. It is also necessary to
capture and understand the context in which each design decision was made. This additional
knowledge is called the rationale of the system.
Capturing and accessing the rationale of a system is not trivial. First, for every decision
made, several alternatives may have been considered, evaluated, and argued. Consequently,
rationale represents a much larger amount of information than do the solution models. Second,
rationale information is often not explicit. Developers make many decisions based on their
experience and their intuition, without explicitly evaluating different alternatives. When asked to
explain a decision, developers may have to spend a substantial amount of time recovering its
rationale. In order to deal with changing systems, however, software engineers must address the
challenges of capturing and accessing rationale.
So far, we have presented a high-level view of software engineering from the perspectives of
modeling, problem solving, knowledge acquisition, and rationale. In this section, we describe
the main terms and concepts we use throughout the book.2 A Project, whose purpose is to
develop a software system, is composed of a number of Activities. Each Activity is in turn
composed of a number of Tasks. A Task consumes Resources and produces a WorkProduct. A
WorkProduct can be either a System, a Model, or a Document. Resources are either
Participants, Time, or Equipment. A graphical representation of these concepts is shown in
Figure 1-1. Each rectangle represents a concept. The lines among the rectangles represent
different relationships between the concepts. For example, the diamond shape indicates
aggregation: a Project includes a number of Activities, which includes a number of Tasks.
The triangle shape indicates a generalization relationship; Participants, Time, and Equipment
are specific kinds of Resources. Figure 1-1 is represented in the Unified Modeling Language
(UML) notation. We use UML throughout the book to represent models of software and other
systems. Intuitively, you should be able to understand this diagram without full knowledge of the
UML semantics. Similarly, you can also use UML diagrams when interacting with a client or a
user, even though they may not have any knowledge of UML. We describe the semantics of
these diagrams in detail in Chapter 2, Modeling with UML.
2. As much as possible, we follow the definitions of the IEEE standards on Software Engineering [IEEE Std. 610.12-
1990].
8
Software Engineering Concepts
Project
Activity
is produced by * consumes
* *
WorkProduct Task Resources
System Participant
Model Time
Document Equipment
Figure 1-1 Software engineering concepts depicted as a UML class diagram [OMG, 2009].
Developing a software system requires the collaboration of many people with different
backgrounds and interests. The client orders and pays for the system. The developers construct
the system. The project manager plans and budgets the project and coordinates the developers
and the client. The end users are supported by the system. We refer to all the persons involved in
the project as participants. We refer to a set of responsibilities in the project or the system as a
role. A role is associated with a set of tasks and is assigned to a participant. The same
participant can fill multiple roles.
Consider a TicketDistributor system:
TicketDistributor is a machine that distributes tickets for trains. Travelers have the option of
selecting a ticket for a single trip or for multiple trips, or selecting a time card for a day or a week. The
TicketDistributor computes the price of the requested ticket based on the area in which the trip will
take place and whether the traveler is a child or an adult. The TicketDistributor must be able to
handle several exceptions, such as travelers who do not complete the transaction, travelers who attempt
to pay with large bills, and resource outages, such as running out of tickets, change, or power.
9
Chapter 1 • Introduction to Software Engineering
Table 1-1 Examples of roles in software engineering for the TicketDistributor project.
Client The client is responsible for providing the high- Train company that
level requirements on the system and for defining contracts the
the scope of the project (delivery date, budget, TicketDistributor.
quality criteria).
Human Factors A human factors specialist is responsible for the Zoe (Human Computer
Specialist usability of the system. Interaction specialist)
a. As TicketDistributor is a small project, Zoe fills both the human factor specialist and the tester roles,
and John fills the analyst and the technical writer roles.
10
Software Engineering Concepts
Specification Deliverable The specification describes the system from the user’s point of
view. It is used as a contractual document between the project
and the client. The TicketDistributor specification
describes in detail how the system should appear to the traveler.
Status report Internal work A status report describes at a given time the tasks that have
product been completed and the tasks that are still in progress. The
status report is produced for the manager, Alice, and is usually
not seen by the train company.
Test manual Internal work The test plans and results are produced by the tester, Zoe. These
product documents track the known defects in the prototype
TicketDistributor and their state of repair. These documents
are usually not shared with the client.
11
Chapter 1 • Introduction to Software Engineering
A task represents an atomic unit of work that can be managed: A manager assigns it to a
developer, the developer carries it out, and the manager monitors the progress and completion of
the task. Tasks consume resources, result in work products, and depend on work products
produced by other tasks.
Resources are assets that are used to accomplish work. Resources include time,
equipment, and labor. When planning a project, a manager breaks down the work into tasks and
assigns them to resources.
Table 1-3 describes examples of activities, tasks, and resources in software engineering.
Table 1-3 Examples of activities, tasks, and resources for the TicketDistributor project.
Develop “Out of Change” Task This task, assigned to Zoe (the tester) focuses on
test case for verifying the behavior of the ticket distributor
TicketDistributor when it runs out of money and cannot give the
correct change back to the user. This activity
includes specifying the environment of the test, the
sequence of inputs to be entered, and the expected
outputs.
Review “Access Online Task This task, assigned to John (the human factors
Help” use case for usability specialist) focuses on detecting usability issues in
accessing the online help features of the system.
12
Software Engineering Concepts
colors are nonfunctional requirements. Other nonfunctional requirements may include using
specific hardware platform for the system, security requirements, how the system should deal
with failures and faults, and how to provide backward compatibility with an old system that the
client is unwilling to retire.
13
Chapter 1 • Introduction to Software Engineering
For solution domain modeling activities, such as system design and object design, we describe
object-oriented activities similar to those of OMT. For change-related activities, we focus on
rationale management, which originated from design rationale research [Moran & Carroll,
1996], and configuration management, which originated from the maintenance of large systems
[Babich, 1986].
Figure 1-2 depicts an overview of the relationship among these activities and their
products. In Section 1.5, we give an overview of the managerial activities associated with
software engineering. In Chapter 14, Project Management, and in Chapter 15, Software Life
Cycle, we discuss in more detail the modeling, planning, and software engineering activities.
1.4.2 Analysis
During analysis, developers aim to produce a model of the system that is correct, complete,
consistent, and unambiguous. Developers transform the use cases produced during requirements
elicitation into an object model that completely describes the system. During this activity,
developers discover ambiguities and inconsistencies in the use case model that they resolve with
the client. The result of analysis is a system model annotated with attributes, operations, and
14
Software Engineering Development Activities
problem
statement
Requirements
elicitation (Ch.4)
nonfunctional functional
requirements model use case diagram
Analysis (Ch.5)
analysis object
class diagram state machine
model
diagram
dynamic model
System design
(Ch.6 & 7) sequence diagram
subsystem
decomposition
system design
object model
design goals
Object design
(Ch.8 & 9)
object design
class diagram model
Implementation
(Ch. 10)
source code
Test (Ch.11)
deliverable system
Figure 1-2 An overview of object-oriented software engineering development activities and their
products. This diagram depicts only logical dependencies among work products. Object-oriented software
engineering is iterative; that is, activities can occur in parallel and more than once.
15
Chapter 1 • Introduction to Software Engineering
associations. The system model can be described in terms of its structure and its dynamic
interoperation. Figure 1-4 depicts an example of dynamic model for the TicketDistributor.
Figure 1-5 depicts an example of object model for the TicketDistributor.
insertChange()
updateBalance()
amountDue
insertChange()
updateBalance()
acknowledgement
«create»
printedTicket :Ticket
Figure 1-4 A dynamic model for the TicketDistributor (UML sequence diagram). This diagram
depicts the interactions between the actor and the system during the PurchaseOneWayTicket use case and
the objects that participate in the use case.
16
Software Engineering Development Activities
Coin
Balance
amount paid
Bill
Figure 1-5 An object model for the TicketDistributor (UML class diagram). In the
PurchaseOneWayTicket use case, a Traveler initiates a transaction that will result in a Ticket. A Ticket
is valid only for a specified Zone. During the Transaction, the system tracks the Balance due by counting
the Coins and Bills inserted.
17
Chapter 1 • Introduction to Software Engineering
TravelerInterface Updater
LocalTariff CentralTariff
Figure 1-6 A subsystem decomposition for the TicketDistributor (UML class diagram, packages
represent subsystems, dashed lines represent dependencies). The TravelerInterface subsystem is
responsible for collecting input from the Traveler and providing feedback (e.g., display ticket price,
returning change). The LocalTariff subsystem computes the price of different tickets based on a local
database. The CentralTariff subsystem, located on a central computer, maintains a reference copy of the
tariff database. An Updater subsystem is responsible for updating the local databases at each
TicketDistributor through a network when ticket prices change.
1.4.5 Implementation
During implementation, developers translate the solution domain model into source code. This
includes implementing the attributes and methods of each object and integrating all the objects
such that they function as a single system. The implementation activity spans the gap between
the detailed object design model and a complete set of source code files that can be compiled.
We describe the mapping of UML models to code in Chapter 10, Mapping Models to Code. We
assume the reader is already familiar with programming concepts and knows how to program
data structures and algorithms using an object-oriented language such as Java or C++.
1.4.6 Testing
During testing, developers find differences between the system and its models by executing the
system (or parts of it) with sample input data sets. During unit testing, developers compare the
object design model with each object and subsystem. During integration testing, combinations
of subsystems are integrated together and compared with the system design model. During
system testing, typical and exception cases are run through the system and compared with the
requirements model. The goal of testing is to discover as many faults as possible such that they
can be repaired before the delivery of the system. The planning of test phases occurs in parallel
to the other development activities: System tests are planned during requirements elicitation and
analysis, integration tests are planned during system design, and unit tests are planned during
object design. We describe these issues in more detail in Chapter 11, Testing.
18
Managing Software Development
Software maintenance, which we do not cover in this book, includes the development
activities that occur after the delivery of the system to the client. Traditionally, software
maintenance has been distinguished from the other development activities as it is highly change
driven and is performed by a different team than the original development team. As modern
software engineering projects become more change driven, the distinction between construction
activities and maintenance activities is blurred. Many of the activities described in this book
can carry on to maintenance, including object design, implementation, testing, rationale
management, and software configuration management.
1.5.1 Communication
Communication is the most critical and time-consuming activity in software engineering.
Misunderstandings and omissions often lead to faults and delays that are expensive to correct
later in the development. Communication includes the exchange of models and documents about
the system and its application domain, reporting the status of work products, providing feedback
on the quality of work products, raising and negotiating issues, and communicating decisions.
Communication is made difficult by the diversity of participants’ backgrounds, by their
geographic distribution, and by the volume, complexity, and evolution of the information
exchanged.
To deal with communication issues, project participants have many tools available. The
most effective one is conventions: When participants agree on notations for representing
information, on tools for manipulating information, and on procedures for raising and resolving
issues, they already have eliminated substantial sources of misunderstanding. Examples of
notations include UML diagrams, templates for writing documents and meeting minutes, and
identification schemes for naming software components. Examples of tools include Computer
Aided Software Engineering (CASE) tools for maintaining models, word processors for
generating documents, and interchange formats for publishing information. Examples of
procedures include meeting procedures for organizing, conducting, and capturing a meeting,
19
Chapter 1 • Introduction to Software Engineering
review procedures for reviewing documents and providing feedback, and inspection procedures
for detecting defects in models or source code. The selected conventions do not need to be the
best available; they only need to be shared and agreed on by everybody. We describe
communication issues in detail in Chapter 3, Project Organization and Communication.
20
ARENA Case Study
21
Chapter 1 • Introduction to Software Engineering
22
Further Reading
The work products associated with the ARENA system, along with a demonstration, are available
from http://wwwbruegge.in.tum.de/OOSE/WebHome.
1.8 Exercises
1-1 What is the purpose of modeling?
1-2 A programming language is a notation for representing algorithms and data structures.
List two advantages and two disadvantages of using a programming language as the
sole notation throughout the development process.
1-3 Consider a task you are not familiar with, such as designing a zero-emissions car. How
would you attack the problem?
1-4 What is meant by “knowledge acquisition is not sequential”? Provide a concrete
example of knowledge acquisition that illustrates this.
1-5 Hypothesize a rationale for the following design decisions:
23
Chapter 1 • Introduction to Software Engineering
1-6 Specify which of these statements are functional requirements and which are
nonfunctional requirements:
1-7 Specify which of these decisions were made during requirements or system design:
1-8 In the following description, explain when the term account is used as an application
domain concept and when as a solution domain concept:
“Assume you are developing an online system for managing bank accounts for
mobile customers. A major design issue is how to provide access to the accounts
when the customer cannot establish an online connection. One proposal is that
accounts are made available on the mobile computer, even if the server is not up. In
this case, the accounts show the amounts from the last connected session.”
1-10 A passenger aircraft is composed of several millions of parts and requires thousands of
persons to assemble. A four-lane highway bridge is another example of complexity.
The first version of Word for Windows, a word processor released by Microsoft in
1989, required 55 person-years, resulted into 249,000 lines of source code, and was
delivered 4 years late. Aircraft and highway bridges are usually delivered on time and
within budget, whereas software is often not. Discuss what are, in your opinion, the
differences between developing an aircraft, a bridge, and a word processor that would
cause this situation.
24
References
References
[Babich, 1986] W. Babich, Software Configuration Management, Addison-Wesley, Reading, MA,
1986.
[Booch, 1994] G. Booch, Object-Oriented Analysis and Design with Applications, 2nd ed.
Benjamin/Cummings, Redwood City, CA, 1994.
[Brooks, 1995] F. P. Brooks, The Mythical Man Month: Anniversary Edition: Essays on Software
Engineering, Addison-Wesley, Reading, MA, 1995.
[Bruegge, 1992] B. Bruegge, “Teaching an industry-oriented software engineering course,” Software
Engineering Education, SEI Conference, Lecture Notes in Computer Sciences,
Vol. 640, pp. 65–87, Springer-Verlag, October 1992.
[Bruegge & Coyne, 1993] B. Bruegge & R. Coyne, “Model-based software engineering in larger scale project
courses,” IFIP Transactions on Computer Science and Technology, Vol. A-40,
pp. 273–287, Elsevier Science, Netherlands, 1993.
[Bruegge & Coyne, 1994] B. Bruegge & R. Coyne, “Teaching iterative object-oriented development: Lessons
and directions,” in J. L. Diaz-Herrera (ed.), 7th Conference on Software Engineering
Education, Lecture Notes in Computer Science, Vol. 750, pp. 413–427, Springer-
Verlag, 1994.
[Coyne et al., 1995] R. Coyne, B. Bruegge, A. Dutoit, & D. Rothenberger, “Teaching more comprehensive
model-based software engineering: Experience with Objectory’s use case approach,”
in L. Ibraham (ed.), 8th Conference on Software Engineering Education, Lecture
Notes in Computer Science, pp. 339–374, Springer-Verlag, April 1995.
[De Marco, 1978] T. De Marco, Structured Analysis and System Specification. Yourdon, New York,
1978.
[D’Souza & Wills, 1999] D. F. D’Souza & A. C. Wills, Objects, Components, and Frameworks with UML: The
Catalysis Approach, Addison-Wesley, Reading, MA, 1999.
[IEEE Std. 610.12-1990] IEEE Standard Computer Dictionary: A Compilation of IEEE Standard Computer
Glossaries, New York, NY, 1990.
[Jacobson et al., 1992] I. Jacobson, M. Christerson, P. Jonsson, & G. Overgaard, Object-Oriented Software
Engineering—A Use Case Driven Approach, Addison-Wesley, Reading, MA, 1992.
[Moran & Carroll, 1996] T. P. Moran & J. M. Carroll (eds.), Design Rationale: Concepts, Techniques, and Use,
Lawrence Erlbaum Associates, Mahwah, NJ, 1996.
[Neumann, 1995] P. G. Neumann, Computer-Related Risks, Addison-Wesley, Reading, MA, 1995.
[OMG, 2009] Object Management Group, OMG Unified Modeling Language Specification. Version
2.2, 2009. http://www.omg.org.
[Popper, 1992] K. Popper, Objective Knowledge: An Evolutionary Approach, Clarendon, Oxford,
1992.
[Pressman, 2009] R. S. Pressman, Software Engineering: A Practitioner’s Approach, 7th ed., McGraw-
Hill, 2009.
[Royce, 1998] W. Royce, Software Project Management: A Unified Framework, Addison-Wesley,
Reading, MA, 1998.
[Rumbaugh et al., 1991] J. Rumbaugh, M. Blaha, W. Premerlani, F. Eddy, & W. Lorensen, Object-Oriented
Modeling and Design, Prentice Hall, Englewood Cliffs, NJ, 1991.
[Simon, 1970] H. A. Simon, The Sciences of the Artificial, MIT Press, Cambridge, MA, 1970.
[Sommerville, 2006] I. Sommerville, Software Engineering, 8th ed., Addison-Wesley, Reading, MA, 2006.
[Spivey, 1989] J. M. Spivey, The Z Notation, A Reference Manual, Prentice Hall, Hertfordshire, UK
1989.
25
26
2
Modeling with UML
From Chapter 2 of Object-Oriented Software Engineering Using UML, Patterns, and Java, Third Edition.
Bernd Bruegge, Allen H. Dutoit. Copyright © 2010 by Pearson Education, Inc. All rights reserved.
27
Chapter 2 • Modeling with UML
2.1 Introduction
UML is a notation that resulted from the unification of OMT (Object Modeling Technique
[Rumbaugh et al., 1991]), Booch [Booch, 1994], and OOSE (Object-Oriented Software
Engineering [Jacobson et al., 1992]). UML has also been influenced by other object-oriented
notations, such as those introduced by Mellor and Shlaer [Mellor & Shlaer, 1998], Coad and
Yourdon [Coad et al., 1995], Wirfs-Brock [Wirfs-Brock et al., 1990], and Martin and Odell
[Martin & Odell, 1992].
The goal of UML is to provide a standard notation that can be used by all object-oriented
methods and to select and integrate the best elements of precursor notations. For example, UML
includes the use case diagrams introduced by OOSE and uses many features of the OMT class
diagrams. UML also includes new concepts that were not present in other major methods at the
time, such as extension mechanisms and a constraint language. UML has been designed for a
broad range of applications. Hence, it provides constructs for a broad range of systems and
activities (e.g., distributed systems, analysis, system design, deployment). System development
focuses on three different models of the system (see Figure 1-2):
• The functional model, represented in UML with use case diagrams, describes the
functionality of the system from the user’s point of view.
• The object model, represented in UML with class diagrams, describes the structure of
the system in terms of objects, attributes, associations, and operations. During
requirements and analysis, the object model starts as the analysis object model and
describes the application concepts relevant to the system. During system design, the
object model is refined into the system design object model and includes descriptions of
the subsystem interfaces. During object design, the object model is refined into the
object design model and includes detailed descriptions of solution objects.
• The dynamic model, represented in UML with interaction diagrams, state machine
diagrams, and activity diagrams, describes the internal behavior of the system.
Interaction diagrams describe behavior as a sequence of messages exchanged among a
set of objects, whereas state machine diagrams describe behavior in terms of states of
an individual object and the possible transitions between states. Activity diagrams
describe behavior in terms control and data flows.
In this chapter, we describe UML diagrams for representing these models. Introducing
these notations represents an interesting challenge: understanding the purpose of a notation
requires some familiarity with the activities that use it. However, it is necessary to understand
the notation before describing the activities. To address this issue, we introduce UML iteratively.
In the next section, we first provide an overview of the five basic notations of UML. In
Section 2.3, we introduce the fundamental ideas of modeling. In Section 2.4, we revisit the five
basic notations of UML in light of modeling concepts. In subsequent chapters, we discuss these
notations in even greater detail when we introduce the activities that use them.
28
An Overview of UML
SimpleWatch
ReadTime
SetTime
WatchUser WatchRepairPerson
ChangeBattery
Figure 2-1 A UML use case diagram describing the functionality of a simple watch. The WatchUser actor
may either consult the time on her watch (with the ReadTime use case) or set the time (with the SetTime use
case). However, only the WatchRepairPerson actor can change the battery of the watch (with the
ChangeBattery use case). Actors are represented with stick figures, use cases with ovals, and the boundary
of the system with a box enclosing the use cases.
29
Chapter 2 • Modeling with UML
SimpleWatch
1 1 1 1
2 1 2 1
PushButton Display Battery Time
Figure 2-2 A UML class diagram describing the elements of a simple watch.
30
An Overview of UML
pressButton2() incrementMinutes()
refresh()
pressButtons1And2() commitNewTime()
stopBlinking()
Figure 2-3 A UML sequence diagram for the Watch. The left-most column represents the timeline of the
WatchUser actor who initiates the use case. The other columns represent the timeline of the objects that
participate in this use case. Object names are underlined to denote that they are instances (as opposed to
classes). Labeled arrows are stimuli that an actor or an object sends to other objects.
State machine diagrams describe the dynamic behavior of an individual object as a number of
states and transitions between these states. A state represents a particular set of values for an
object. Given a state, a transition represents a future state the object can move to and the
conditions associated with the change of state. For example, Figure 2-4 is a state machine
diagram for the Watch. A small black circle initiates that BlinkHours is the initial state. A circle
surrounding a small black circle indicates that StopBlinking is a final state. Note that this
diagram represents different information than the sequence diagram of Figure 2-3. The sequence
diagram focuses on the messages exchanged between objects as a result of external events
created by actors. The state machine diagram focuses on the transitions between states as a result
of external events for an individual object.
An activity diagram describes the behavior of a system in terms of activities. Activities are
modeling elements that represent the execution of a set of operations. The execution of an
activity can be triggered by the completion of other activities, by the availability of objects, or by
external events. Activity diagrams are similar to flowchart diagrams in that they can be used to
represent control flow (i.e., the order in which operations occur) and data flow (i.e., the objects
that are exchanged among operations). For example, Figure 2-5 is an activity diagram
representing activities related to managing an Incident. Rounded rectangles represent
activities; arrows between activities represent control flow; thick bars represent the
31
Chapter 2 • Modeling with UML
button1&2Pressed button2Pressed
Increment
BlinkHours Hours
button1Pressed
button1&2Pressed button2Pressed
Increment
BlinkMinutes Minutes
button1Pressed
button1&2Pressed
button2Pressed
Increment
StopBlinking BlinkSeconds Seconds
Figure 2-4 A UML state machine diagram for SetTime use case of the Watch.
synchronization of the control flow. The activity diagram of Figure 2-5 depicts that the
AllocateResources, CoordinateResources, and DocumentIncident can be initiated only after
the OpenIncident activity has been completed. Similarly, the ArchiveIncident activity can be
initiated only after the completion of AllocateResources, Coordinate–Resources, and
DocumentIncident. These latter three activities, however, can occur concurrently.
This concludes our first walkthrough of the five basic notations of UML. Now, we go into
more detail: In Section 2.3, we introduce basic modeling concepts, including the definition of
Allocate
Resources
Document
Incident
Figure 2-5 An example of a UML activity diagram. Activity diagrams represent behavior in terms of
activities and their precedence constraints. The completion of an activity triggers an outgoing transition,
which in turn may initiate another activity.
32
Modeling Concepts
systems, models, types, and instances, abstraction, and falsification. In Sections 2.4.1–2.4.5, we
describe in detail use case diagrams, class diagrams, sequence diagrams, state machine
diagrams, and activity diagrams. We illustrate their use with a simple example. Section 2.4.6
describes miscellaneous constructs, such as packages and notes, that are used in all types of
diagrams. We use these five notations throughout the book to describe software systems, work
products, activities, and organizations. By the consistent and systematic use of a small set of
notations, we hope to provide the reader with an operational knowledge of UML.
33
Chapter 2 • Modeling with UML
details about the exterior of the plane can be ignored. Both the flight simulator and the scale
model are much less complex than the airplane they represent. Modeling allows us to deal with
complexity through a divide-and-conquer approach: For each type of problem we want to solve
(e.g., testing aerodynamic properties, training pilots), we build a model that only focuses on the
issues relevant to the problem. Generally, modeling focuses on building a model that is simple
enough for a person to grasp completely. A rule of thumb is that each entity should contain at
most 7 ± 2 parts [Miller, 1956].
Modeling also helps us deal with complexity by enabling us to incrementally refine simple
models into more detailed ones that are closer to reality. In software engineering, as in all
engineering disciplines, the model usually precedes the system. During analysis, we first build a
model of the environment and of the common functionality that the system must provide, at a
level that is understandable by the client. Then we refine this model, adding more details about
the forms that the system should display, the layout of the user interface, and the response of the
system to exceptional cases. The set of all models built during development is called the system
model. If we did not use models, but instead started coding the system right away, we would
have to specify all the details of the user interface before the client could provide us with
feedback. Thus we would lose much time and resources when the client then introduces
changes.
Unfortunately, even a model may become so complex that it is not easily understandable.
We can continue to use the divide-and-conquer method to refine a complex model into simpler
models. A view focuses on a subset of a model to make it understandable (Figure 2-6). For
example, all the blueprints necessary to construct an airplane constitute a model. Excerpts
necessary to explain the functioning of the fuel system constitute the fuel system view. Views
may overlap: a view of the airplane representing the electrical wiring also includes the wiring for
the fuel system.
Scale model
Electrical
All blueprints
Airplane
Fuel
Flight simulator
Figure 2-6 A model is an abstraction describing a subset of a system. A view depicts selected aspects of
a model. Views and models of a single system may overlap each other.
34
Modeling Concepts
Notations are graphical or textual rules for representing views. A UML class diagram is a
graphical view of the object model. In wiring diagrams, each connected line represents a
different wire or bundle of wires. In UML class diagrams, a rectangle with a title represents a
class. A line between two rectangles represents a relationship between the two corresponding
classes. Note that different notations can be used to represent the same view (Figure 2-7).
UML
1 *
Book Chapter
composed-of
Booch
N
Book Chapter
composed-of
Figure 2-7 Example of describing a model with two different notations. The model includes two classes,
Book and Chapter, with the relationship, Book is composed of Chapters. In UML, classes are depicted
by rectangles and aggregation associations by a line terminated with a diamond. In the Booch notation,
classes are depicted by clouds, and aggregation associations are depicted with a line terminated with a solid
circle.
In software engineering, there are many other notations for modeling systems. UML
describes a system in terms of classes, events, states, interactions, and activities. Data flow
diagrams [De Marco, 1978] depict how data is retrieved, processed, and stored. Z Schemes
[Spivey, 1992] represent the system in terms of invariants (conditions that never change) and in
terms of what is true before and after the execution of an operation. Each notation is tailored for
a different problem.
In the next sections, we focus in more detail on the process of modeling.
35
Exploring the Variety of Random
Documents with Different Content
thread when contraction takes place after the web comes through
the press rolls.
The feature which is aimed at, and which is most desirable in the
appearance of such goods, is a clean cut prominent rib at the rubber
line, and the avoidance of a flat paper-like look and feel of the web
generally. The prominence of the rib varies, of course, according to
the size of the rubber thread used, and the binder warp employed in
dividing the same, but even the very best of conditions may be
spoiled if proper care is not taken to get all the prominence of rib
possible. Use as fine a binder warp as is practicable, compensating
for any loss of weight or excess of contraction by using a heavier
gut, which again of itself helps to fill in the rubber cavity and thereby
lends additional prominence to the rib. All the weight possible should
be carried on the binder warp up to a point of safety, and care should
be taken to get a very easy, uniform delivery of the warp from the
beam so as to avoid any erratic jerky movement of the warp lever.
The warp beams which are used on this delicate type of work
should be well balanced and true to center, and the flanges free from
any irregularity which would in any way interfere with the easy and
uniform operation of the warp lever.
The gut, which weaves in with the rubber thread, is used for the
two-fold purpose of giving additional body to the fabric and of
regulating in a measure the length of stretch in the goods. The more
gut there is used, the less becomes the power of contraction of the
rubber warp, and the shorter the stretch produced.
Aside from the fineness and body of the goods, the element of
stretch largely governs the market value of the fabric, so that good
judgment and great care must be exercised in the assembling of the
different sizes of yarns used. Weft, binder and gut all play their part
in the governing of the stretch, as also does the number of picks put
in the goods. Any excess of weight on the binder warp also
materially reduces the stretch. In fact, any one of these features,
wrongly adjusted, may result in the difference between the profit and
loss.
In making the selvage of these goods a hard steel wire is used,
around which the filling passes at each pick. This wire, shown at W
in Fig. 6A, is highly tempered piano wire, of the very best quality
obtainable. Sharpened to a needle point at one end, with a loop
turned at the other end, it is fastened at the back of the loom by a
cord which has an adjustable slip knot, so as to be able easily and
quickly to regulate the length of wire running in the web. It is then
passed through a harness heddle eye on the rubber or gut shaft, and
through a reed space next outside the selvage rubber thread. The
constant wear of this wire on the reed dent makes it necessary to
have this dent of hardened steel so as to withstand the constant
wear of the wire, which is always being crowded against the dent by
the nipping action of the filling as it draws against the wire in the
process of weaving, and the repeated beat at the same place in the
dent at the weaving line. In any event, after a short time the dents in
the reed will be cut so that it becomes necessary to frequently
replace them with new ones, and for this reason it should be so
arranged that they can be easily and quickly removed from and
replaced in the reeds.
Cable Web
The most popular web now made up into men’s garters is what is
known as the cable web, shown at Fig. 9. With the pronounced
prominence of the two-dent rib, which gives it a character peculiarly
different from the plain web, it is well adapted to this class of goods.
Simple in appearance, it nevertheless requires special care to
manufacture, particularly when we remember that it is not unusual to
be required to make a finished stretch of not less than 100 per cent.
The harness draft and weave are shown at Fig. 9A. The construction
is as follows: Binder, 34 ends 80/2; Gut, 24 ends 20/2; Rubber, 18
ends 28s; Reed, 20 dent; Picks, 80 per inch; Stretch, 100 per cent.
The filling, floating across the wide spaces under which lie the
rubber threads in pairs, is very easily thrown out of place, the result
of which may be an unsightly seersucker appearance, as shown in
Fig. 10, which the process of finishing aggravates rather than
corrects.
Trouble may manifest itself by the filling over the ribs opening up
and allowing the gut threads to prick through. To prevent this
objectionable feature it is necessary to use a good quality of
moderately soft yarn for the gut, not necessarily of high grade stock,
but a yarn which is uniformly spun and not at all hard or wiry. As
these goods are being woven and on full stretch, the gut threads, of
course, are perfectly straight and accurate in line, but when
contraction takes place, to probably one-half the former length, these
heavy threads, which form probably about 25 per cent. of the weight
of the entire web, should bend or fold uniformly and dispose of
themselves in such a manner as not to appear in any way on the
face of the web, snugly housed away in the several pockets or
cavities. If the yarn composing these gut threads is spotty or
irregularly spun, this uniformity of fold inside the pockets will be
broken up and the appearance of the face of the goods is likely to be
marred by unsightly specks of cotton pricking through, which can be
both seen and felt.
Chapter IV.
Elaboration of Honeycomb Effects by Parti-Dyed and Printed Fillings
—Bandage and Surgical Webs Made with Plain and Covered
Rubber—Frill Web Woven on Cam Looms—Double Cloths—
Importance of Securing Balance Between Back and Face of Goods
Among the group of single cloth webs confined to the capacity of
plain looms, is what is commonly known as the honeycomb, shown
at Fig. 1 and Fig. 1A. This is generally made with silk, wood silk, or
schappe filling. The smooth filling floating over two cords gives the
web a smooth feel, there being no rib effect noticeable whatever,
making it well adapted for a fine trade. The warp lines are almost
entirely hidden by the filling, so that it is not practicable to introduce
any sharp stripe fancy effects, which can be done both in the plain
web and the cable. The honeycomb is thus confined to plain solid
colors or such elaboration as can be obtained from the filling.
Fancy effects are often secured by dyeing skein yarn in two or
more colors. Such yarns when woven in the goods produce
alternating effects at regular distances in different colors, such
distances being governed by the length of the dips and the width of
the goods. The effects which can be produced are quite varied. The
simplest way of accomplishing this is to use the regular 54-inch
skein, having white or some light shade as a base, and then dyeing
a given portion of the skein another color. This process is carried out
by hanging the skeins on sticks placed in a rack at the required
distance above the color liquor, and then lowering them into the vat
and dyeing the immersed part in the usual manner.
Where cotton is used for the filling and more elaborate effects are
desired, long reeled skeins are used, sometimes 108 or 216 inches,
which have been reeled on specially designed collapsible reels.
Such skeins are not practicable to handle in the dye house in the
manner already described. Sections of such skeins are wrapped in
heavy waterproof paper and tied tightly, so that the dye liquor cannot
penetrate that portion, and then the whole is put in the liquor, when
the exposed part only will be dyed.
Then again sometimes wood clamps are used, like that shown at
Fig. 2, having a recess into which part of the skein is laid after being
carefully folded. The two halves are clamped together tightly in such
a manner that the dye cannot penetrate the clamped part of the
skein while the part left outside the clamp is dyed when the whole is
immersed in the dye liquor.
Printed Filling
Another form of elaboration used in such goods is printing the
skein yarn used for the filling. This is done by using a machine
having a pair of fluted brass printing rolls, one of which is made to
open on a hinge like a gate so that a skein of yarn can be put around
it. This roller is then closed to its original position, so that with the
two rollers parallel and close together, and the skein of yarn hugged
tightly between them, the turning of the rollers imprints color on the
skein. The skein is then taken out and dryed before spooling.
Different sets of rolls are used so as to get fine and coarse effects
and various colors are used in printing.
Where plaid or printed fillings are used for the elaboration of webs
of the honeycomb type, it is not unusual to introduce a couple of
plain cords in the center of the web, or possibly on either side, so as
to break up the flatness of the weave. This opens up the opportunity
of using lines of a different color in the warp which properly arranged
will produce a plaid-like effect.
Fig. 1.—Honeycomb
Bandage Webs
There is quite a large demand for surgical and bandage webs, Fig.
3, in widths ranging from 2 to 4 inches. These webs are used for
binding the limbs and other purposes and are in the pure white or
natural yarns. They require to be made with a long soft easy stretch.
An open reed of about 12 dents per inch is employed. Four threads
are generally used for the binder, weaving two up and two down. The
goods are similar in construction to a regular lisle web, except that
the gut is omitted in order to get the easiest possible movement.
Fig. 3.—Bandage Webs; Fabric at Left Made with Plain Rubber; Web at Right
Made With Covered Rubber
The yarn is generally the same quality and size for both warp and
filling, and is usually a soft spun 2-20s. The side of rubber is
generally about 38 or 40, with 40 picks per inch and a finished
stretch of 100 per cent. The use such webs are put to, necessitating
as we have already said a soft and sluggish stretch, prevents the
use of a heavy rubber thread, the result being that when the
bandage is kept in close contact with the warm body, the life of the
fine rubber is of short duration.
This condition, and the open weave necessary to get the easy
stretch, have made it expedient to use in many of these goods
strands of rubber which have been covered with cotton threads
before weaving. This process not only prolongs the life of the web,
but allows for even more open weaving, the use of different weaves
than would be possible where the uncovered rubber thread is used,
and the production of a fabric more suitable for the purpose.
In order to get the soft easy stretch which is the most desirable
characteristic of a bandage web, and yet have the necessary width,
it is not unusual to introduce a seersucker effect, as shown in Fig. 4,
in sections of the web so as to reduce the strong elasticity of the
whole. In an ordinary cotton cloth the seersucker or crinkle effect is
usually produced by the use of a separate warp of heavier yarn than
the rest of the fabric, which warp must be weighted differently and
often a different weave is employed to emphasize the contrast in the
puckered seersucker effect.
In the elastic web all this special preparation is unnecessary.
Wherever the seersucker stripe is desired, strands of rubber are left
out which of course takes away from these portions that element
which contracts the other part of the web, and a seersucker effect is
the result. Such stripes are often used for the ornamentation of some
webs by having narrow sections introduced for border effects, or
running down the center, and in fact they may be employed in a
variety of ways, inasmuch as they lend themselves effectively to
different forms of coloring, in relief to the main fabric.
Fig. 6A.—Harness Draft and Weave for Fig. 6, Simplest Form of Double Cloth
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
ebooknice.com