Ooad Unit II
Ooad Unit II
State Modelling: Events, States, Transitions and Conditions, State diagrams, State
diagram behaviour. Need, purpose Advanced object and class concepts, Use Case
Modelling: Actor Identification, Actor Classification, Actor Generalization, Use Cases
Identification, Communication, Uses/Include and Extend Associations, writing a
Formal Use Cases, Use Case realizations. Need, purpose
Events
An event is an occurrence at a point in time, such as user depresses left button or
flight 123 departs from Chicago. Events often correspond to verbs in the past tense
(power turned on, alarm set) or to the onset of some condition (paper tray becomes
empty, temperature becomes lower than freezing). By definition, an event happens
instantaneously with regard to the time scale of an application. Of course, nothing
is really instantaneous; an event is simply an occurrence that an application
considers atomic and fleeting. The time at which an event occurs is an implicit
attribute of the event. Temporal phenomena that occur over an interval of time are
properly modeled with a state. One event may logically precede or follow another, or
the two events may be unrelated. Flight 123 must depart Chicago before it can arrive
in San Francisco; the two events are causally related. Flight 123 may depart before
or after flight 456 departs Rome; the two events are causally unrelated. Two events
that are causally unrelated are said to be concurrent; they have no effect on each
other. If the communications delay between two locations exceeds the
difference in event times, then the events must be concurrent because they cannot
influence each other. Even if the physical locations of two events are not distant, we
consider the events concurrent if they do not affect each other. In modeling a system
we do not try to establish an ordering between concurrent events because they can
occur in any order.
Events include error conditions as well as normal occurrences. For example, motor
jammed, transaction aborted, and timeout are typical error events. There is nothing
different about an error event; only our interpretation makes it an “error.” The term
event is often used ambiguously. Sometimes it refers to an instance, at other times
to a class. In practice, this ambiguity is usually not a problem and the precise
meaning is apparent from the context. If necessary, you can say event occurrence or
event type to be precise. There are several kinds of events. The most common are the
signal event, the change event, and the time event.
Signal Event
A signal is an explicit one-way transmission of information from one object to
another. It is different from a subroutine call that returns a value. An object sending
a signal to another object may expect a reply, but the reply is a separate signal under
the control of the second object, which may or may not choose to send it.
A signal event is the event of sending or receiving a signal. Usually we are more
concerned
about the receipt of a signal, because it causes effects in the receiving object. Note
the difference between signal and signal event—a signal is a message between objects
while a signal event is an occurrence in time. Every signal transmission is a unique
occurrence, but we group them into signal classes and give each signal class a name
to indicate common structure and behavior. For example, UA flight 123 departs from
Chicago on January 10, 1991 is an instance of signal class Flight- Departure. Some
signals are simple occurrences, but most signal classes have attributes indicating
the values they convey. For example, as Figure 5.1 shows, FlightDeparture has
attributes airline, flightNumber, city, and date. The UML notation is the keyword
signal in guillemets («») above the signal class name in the top section of a box. The
second section lists the signal attributes
States
A state is an abstraction of the values and links of an object. Sets of values and links
are grouped together into a state according to the gross behavior of objects. For
example, the state of a bank is either solvent or insolvent, depending on whether its
assets exceed its liabilities. States often correspond to verbs with a suffix of “ing”
(Waiting, Dialing) or the duration of some condition (Powered, BelowFreezing).
Figure 5.4 shows the UML notation for a state—a rounded box containing an optional
state name. Our convention is to list the state name in boldface, center the name
near the top of the box, and capitalize the first letter.
In defining states, we ignore attributes that do not affect the behavior of the object,
and lump together in a single state all combinations of values and links with the
same response to events. Of course, every attribute has some effect on behavior or it
would be meaningless, but often some attributes do not affect the sequence of control
and you can regard them as simple parameter values within a state. Recall that the
purpose of modeling is to focus on qualities that are relevant to the solution of an
application problem and abstract away those that are irrelevant. The three UML
models (class, state, and interaction) present different views of a system for which
the particular choice of attributes and values are not equally important. For example,
except for leading 0s and 1s, the exact digits dialed do not affect the control of the
phone line, so we can summarize them all with state Dialing and track the phone
number as a parameter. Sometimes, all possible values of an attribute are important,
but usually only when the number of possible values is small.
The objects in a class have a finite number of possible states—one or possibly some
larger number. Each object can only be in one state at a time. Objects may parade
through one or more states during their lifetime. At a given moment of time, the
various objects for a class can exist in a multitude of states.
A state specifies the response of an object to input events. All events are ignored in
a state, except those for which behavior is explicitly prescribed. The response may
include the invocation of behavior or a change of state. For example, if a digit is dialed
in state Dial tone, the phone line drops the dial tone and enters state Dialing; if the
receiver is replaced in state Dial tone, the phone line goes dead and enters state Idle.
There is a certain symmetry between events and states as Figure 5.5 illustrates.
Events represent points in time; states represent intervals of time. A state
corresponds to the interval between two events received by an object. For example,
after the receiver is lifted and before the first digit is dialed, the phone line is in state
Dial tone. The state of an object depends on past events, which in most cases are
eventually hidden by subsequent events. For example,
events that happened before the phone is hung up do not affect future behavior; the
Idle state “forgets” events received prior to the receipt of the hang up signal.
Both events and states depend on the level of abstraction. For example, a travel agent
planning an itinerary would treat each segment of a journey as a single event; a flight
status board in an airport would distinguish departures and arrivals; an air traffic
control system would break each flight into many geographical legs.
You can characterize a state in various ways, as Figure 5.6 shows for the state Alarm
ringing on a watch. The state has a suggestive name and a natural-language
description of its purpose. The event sequence that leads to the state consists of
setting the alarm, doing anything that doesn’t clear the alarm, and then having the
target time occur. A declarative condition for the state is given in terms of parameters,
such as current and target time; the alarm stops ringing after 20 seconds. Finally, a
stimulus-response table shows the effect of events current time and button pushed,
including the response that occurs and the next state. The different descriptions of
a state may overlap.
The UML notation for a transition is a line from the origin state to the target state.
An
arrowhead points to the target state. The line may consist of several line segments.
An event
may label the transition and be followed by an optional guard condition in square
brackets.
By convention, we usually confine line segments to a rectilinear grid. We italicize the
event
name and show the condition in normal font.
State Diagram
A state diagram is a graph whose nodes are states and whose directed arcs are
transitions
between states. A state diagram specifies the state sequences caused by event
sequences.
State names must be unique within the scope of a state diagram. All objects in a
class execute
the state diagram for that class, which models their common behavior. You can
implement
state diagrams by direct interpretation or by converting the semantics into equivalent
programming code.
The state model consists of multiple state diagrams, one state diagram for each
class with important temporal behavior. The state diagrams must match on their
interfaces events and guard conditions. The individual state diagrams interact by
passing events and through the side effects of guard conditions. Some events and
guard conditions appear in a single state diagram; others appear in multiple state
diagrams for the purpose of coordination.This chapter covers only individual state
diagrams; Chapter 6 discusses state models of interacting diagrams.
A class with more than one state has important temporal behavior. Similarly, a class
is temporally important if it has a single state with multiple responses to events. You
can represent state diagrams with a single state in a simple nongraphical form—a
stimulus–response table listing events and guard conditions and the ensuing
behavior.
One-shot State Diagrams
State diagrams can represent continuous loops or one-shot life cycles. The diagram
for the phone line is a continuous loop. In describing ordinary usage of the phone,
we do not know or care how the loop is started. (If we were describing installation of
new lines, the initial state would be important.)
One-shot state diagrams represent objects with finite lives and have initial and final
states. The initial state is entered on creation of an object; entry of the final state
implies destruction of the object. Figure 5.9 shows a simplified life cycle of a chess
game with a default initial state (solid circle) and a default final state (bull’s eye).
As an alternate notation, you can indicate initial and final states via entry and exit
points.
In Figure 5.10 the start entry point leads to white’s first turn, and the chess game
eventually ends with one of three possible outcomes. Entry points (hollow circles)
and exit points (circles enclosing an “x”) appear on the state diagram’s perimeter and
may be named.
Summary of Basic State Diagram Notation
Figure 5.11 summarizes the basic UML syntax for state diagrams.
The notation “do /” denotes a do-activity that may be performed for all or part of the
duration that an object is in a state. A do-activity may be interrupted by an event
that is received during its execution; such an event may or may not cause a transition
out of the state containing the do-activity. For example, a robot moving a part may
encounter resistance, causing it to cease moving. Entry and Exit Activities
As an alternative to showing activities on transitions, you can bind activities to entry
or to exit from a state. There is no difference in expressive power between the two
notations, but frequently all transitions into a state perform the same activity, in
which case it is more concise to attach the activity to the state.
For example, Figure 5.14 shows the control of a garage door opener. The user
generates depress events with a pushbutton to open and close the door. Each event
reverses the direction of the door, but for safety the door must open fully before it
can be closed. The control generates motor up and motor down activities for the
motor. The motor generates door open and door closed events when the motion has
been completed. Both transitions entering state Opening cause the door to open.
Figure 5.15 shows the same model using activities on entry to states. An entry
activity is shown inside the state box following the keyword entry and a “/” character.
Whenever the state is entered, by any incoming transition, the entry activity is
performed. An entry activity is equivalent to attaching the activity to every incoming
transition. If an incoming transition already has an activity, its activity is performed
first exit activity is shown inside the state box following the keyword exit and a “/”
character.
Whenever the state is exited, by any outgoing transition, the exit activity is performed
first. If a state has multiple activities, they are performed in the following order:
activities on the incoming transition, entry activities, do-activities, exit activities,
activities on the outgoing transition. Events that cause transitions out of the state
can interrupt do-activities. If a doactivity is interrupted, the exit activity is still
performed.
In general, any event can occur within a state and cause an activity to be performed.
Entry and exit are only two examples of events that can occur. As Figure 5.16 shows,
there is a difference between an event within a state and a self-transition; only the
self-transition causes the entry and exit activities to be executed.
Completion Transition
Often the sole purpose of a state is to perform a sequential activity. When the activity
is completed, a transition to another state fires. An arrow without an event name
indicates an automatic transition that fires when the activity associated with the
source state is completed. Such unlabeled transitions are called completion
transitions because they are triggered by the completion of activity in the source
state.
A guard condition is tested only once, when the event occurs. If a state has one or
more completion transitions, but none of the guard conditions are satisfied, then the
state remains active and may become “stuck”—the completion event does not occur
a second time, therefore no completion transition will fire later to change the state.
If a state has completion transitions leaving it, normally the guard conditions should
cover every possible outcome. You can use the special condition else to apply if all
the other conditions are false. Do not use a guard condition on a completion
transition to model waiting for a change of value. Instead model the waiting as a
change event.
When constructing a model, you should carefully note enumerations, because they
often occur and are important to users. Enumerations are also significant for an
implementation you may display the possible values with a pick list and you must
restrict data to the legitimate values.
Do not use a generalization to capture the values of an enumerated attribute. An
enumeration is merely a list of values; generalization is a means for structuring the
description of objects. You should introduce generalization only when at least one
subclass has significant attributes, operations, or associations that do not apply to
the superclass. As Figure 4.2 shows, you should not introduce a generalization for
Card, because most games do not differentiate the behavior of spades, clubs, hearts,
and diamonds.
In the UML an enumeration is a data type. You can declare an enumeration by listing
the keyword enumeration in guillemets («») above the enumeration name in the top
section of a box. The second section lists the enumeration values.Multiplicity
Multiplicity is a constraint on the cardinality of a set. Chapter 3 explained
multiplicity for associations. Multiplicity also applies to attributes.It is often helpful
to specify multiplicity for an attribute, especially for database applications.
Multiplicity for an attribute specifies the number of possible values for each
instantiation of an attribute. The most common specifications are a mandatory single
value [1], an optional single value [0..1], and many [*]. Multiplicity specifies whether
an attribute is mandatory or optional (in database terminology whether an attribute
can be null). Multiplicity also indicates if an attribute is single valued or can be a
collection. If not specified, an attribute is assumed to be a mandatory single value
([1]). In Figure 4.3 a person has one name, one or more addresses, zero or more
phone numbers, and one birthdate.
Scope
Chapter 3 presented features for individual objects. This is the default usage, but
there can also be features for an entire class. The scope indicates if a feature applies
to an object or a class. An underline distinguishes features with class scope (static)
from those with object scope. Our convention is to list attributes and operations with
class scope at the top of the attribute and operation boxes, respectively.
It is acceptable to use an attribute with class scope to hold the extent of a class (the
set of objects for a class)—this is common with OO databases. Otherwise, you should
avoid attributes with class scope because they can lead to an inferior model. It is
better to model groups explicitly and assign attributes to them. For example, the
upper model in Figure 4.4 shows a simple model of phone mail. Each message has
an owner mailbox, date recorded, time recorded, priority, message contents, and a
flag indicating if it has been received. A message may have a mailbox as the source
or it may be from an external call. Each mailbox has a phone number, password,
and recorded greeting. For the PhoneMessage class we can store the maximum
duration for a message and the maximum days a message will be retained. For
the PhoneMailbox class we can store the maximum number of messages that can be
stored. The upper model is inferior, however, because the maximum duration,
maximum days retained, and maximum message count have a single value for the
entire phone mail system. In the lower model these limits can vary for different kinds
of users, yielding a more flexible and extensible phone mail system.
In contrast to attributes, it is acceptable to define operations of class scope. The most
common use of class-scoped operations is to create new instances of a class.
Sometimes it is convenient to define class-scoped operations to provide summary
data. You should be careful with the use of class-scoped operations for distributed
applications.
Visibility
Visibility refers to the ability of a method to reference a feature from another class
and has the possible values of public, protected, private, and package. The precise
meaning depends on the programming language. (See Chapter 18 for details.) Any
method can freely access public features. Only methods of the containing class and
its descendants via inheritance can access protected features. (Protected features
also have package accessibility in Java.) Only methods of the containing class can
access private features. Methods of classes defined in the same package as the target
class can access package features.
The UML denotes visibility with a prefix. The character “+” precedes public features.
The character “#” precedes protected features. The character “-” precedes private
features. And the character “~” precedes package features. The lack of a prefix reveals
no information about visibility.
There are several issues to consider when choosing visibility.
■ Comprehension. You must understand all public features to understand the
capabilities of a class. In contrast, you can ignore private, protected, and package
features—they are merely an implementation convenience.
■ Extensibility. Many classes can depend on public methods, so it can be highly
disruptive to change their signature (number of arguments, types of arguments, type
of return 0value). Since fewer classes depend on private, protected, and package
methods, there is more latitude to change them.
■ Context. Private, protected, and package methods may rely on preconditions or
state information created by other methods in the class. Applied out of context, a
private method may calculate incorrect results or cause the object to fail.
a button to indicate a selection; the vending machine dispenses the beverage and
issues change, if necessary.
Some use cases have a fixed sequence of messages. More often, however, the message
sequence may have some variations. For example, a customer can deposit a variable
number of coins in the buy a beverage use case. Depending on the money inserted
and the item selected, the machine may, or may not, return change. You can
represent such variability by showing several examples of distinct behavior
sequences. Typically you should first define a mainline behavior sequence, then
define optional subsequences, repetitions, and other variations.
Error conditions are also part of a use case. For example, if the customer selects a
beverage whose supply is exhausted, the vending machine displays a warning
message. Similarly, the vending transaction can be cancelled. For example, the
customer can push the coin return on the vending machine at any time before a
selection has been accepted; the machine returns the coins, and the behavior
sequence for the use case is complete. From the user’s point of view, some kinds of
behavior may be thought of as errors. The designer, however,
should plan for all possible behavior sequences. From the system’s point of view,
user errors or resource failures are just additional kinds of behavior that a robust
system can accommodate. A use case brings together all of the behavior relevant to
a slice of system functionality. This includes normal mainline behavior, variations
on normal behavior, exception conditions, error conditions, and cancellations of a
request. Figure 7.2 explains the buy a beverage use case in detail. Grouping normal
and abnormal behavior under a single use case helps to ensure that all the
consequences of an interaction are considered together. In a complete model, the use
cases partition the functionality of the system. They should preferably all be at a
comparable level of abstraction. For example, the use cases make telephone call and
record voice mail message are at comparable levels. The use case set external speaker
volume to high is too narrow. It would be better as set speaker volume (with the
volume level selection as part of the use case) or maybe even just set telephone
parameters, under which we might group setting volume, display pad settings,
setting the clock, and so on.
denotes a use case. A “stick man” icon denotes an actor, with the name being placed
below or adjacent to the icon. Solid lines connect use cases to participating actors.
In the figure, the actor Repair technician participates in two use cases, the others in
one each. Multiple actors can participate in a use case, even though the example has
only one actor per use case.
Guidelines for Use Case Models
Use cases identify the functionality of a system and organize it according to the
perspective of users. In contrast, traditional requirements lists can include
functionality that is vague to users, as well as overlook supporting functionality,
such as initialization and termination. Use cases describe complete transactions and
are therefore less likely to omit necessary steps. There is still a place for traditional
requirements lists in describing global constraints and other nonlocalized
functionality, such as mean time to failure and overall throughput, but you should
capture most user interactions with use cases. The main purpose of a system is
almost always found in the use cases, with requirements lists supplying additional
implementation constraints. Here are some guidelines for constructing use case
models.
■ First determine the system boundary. It is impossible to identify use cases or
actors if the system boundary is unclear.
■ Ensure that actors are focused. Each actor should have a single, coherent
purpose. If a real-world object embodies multiple purposes, capture them with
separate actors. For example, the owner of a personal computer may install software,
set up a database, and send email. These functions differ greatly in their impact on
the computer system and the potential for system damage. They might be broken
into three actors: system admin-istrator, database administrator, and computer
user. Remember that an actor is defined with respect to a system, not as a free-
standing concept.
■ Each use case must provide value to users. A use case should represent a
complete transaction that provides value to users and should not be defined too
narrowly. For example, dial a telephone number is not a good use case for a telephone
system. It does not represent a complete transaction of value by itself; it is merely
part of the use case make telephone call. The latter use case involves placing the call,
talking, and terminating the call. By dealing with complete use cases, we focus on
the purpose of the functionality provided by the system, rather than jumping into
implementation decisions. The details come later. Often there is more than one way
to implement desired functionality.
■ Relate use cases and actors. Every use case should have at least one actor, and
every actor should participate in at least one use case. A use case may involve several
actors, and an actor may participate in several use cases.
■ Remember that use cases are informal. It is important not to be obsessed by
formalism in specifying use cases. They are not intended as a formal mechanism but
as a way to identify and organize system functionality from a user-centered point of
view. It is acceptable if use cases are a bit loose at first. Detail can come later as use
cases are expanded and mapped into implementations.
■ Use cases can be structured. For many applications, the individual use cases are
completely distinct. For large systems, use cases can be built out of smaller
fragments using relationships (see Chapter 8).
Realizing use case
Use cases define the required behavior, but they do not define its realization. That is
the purpose of design—to choose among the options and prepare for implementation.
Each choice has advantages and disadvantages. It is not sufficient merely to deliver
the behavior, although that is a primary goal. You must also consider the
consequences of each choice on performance, reliability, ease of future enhancement,
and many other “ilities”. Design is the process of realizing functionality while
balancing conflicting needs. Use cases define system-level behavior. During design
you must invent new operations and new objects that provide this behavior. Then,
in turn, you must define each of these new operations in terms of lower-level
operations involving more objects. Eventually you can implement operations directly
in terms of existing operations. Inventing the right intermediate operations is what
we have called “bridging the gap.” To start, list the responsibilities of a use case or
operation. A responsibility is something
that an object knows or something it must do [Wirfs-Brock-90]. A responsibility is
not a precise concept; it is meant to get the thought process going. For example, in
an online theatre ticket system, making a reservation has the responsibility of finding
unoccupied seats to the desired show, marking the seats as occupied, obtaining
payment from the customer, arranging delivery of the tickets, and crediting payment
to the proper account. The theater system itself must track which seats are occupied,
know the prices of various seats, and so on.
Each operation will have various responsibilities. Some of these may be shared by
other operations, and others may be reused in the future. Group the responsibilities
into clusters and try to make each cluster coherent. That is, each cluster should
consist of related responsibilities that can be serviced by a single lower-level
operation. Sometimes, if the responsibilities are broad and independent, each
responsibility is in its own cluster. Now define an operation for each responsibility
cluster. Define the operation so that is
not restricted to special circumstances, but don’t make it so general that it is
unfocused. The goal is to anticipate future uses of the new operation. If the operation
can be used in several different places in the current design, you probably don’t have
to make it more general, except to cover the existing uses. Finally, assign the new
lower-level operations to classes. If there is no good class to hold an operation, you
may need to invent a new lower-level class.
ATM example. One of the use cases from Chapter 13 is process transaction. Recall
that a Transaction is a set of Updates and that the logic varies according to
withdrawal, deposit, and transfer.
■ Withdrawal. A withdrawal involves a number of responsibilities: get amount from
customer, verify that amount is covered by the account balance, verify that amount
is within the bank’s policies, verify that ATM has sufficient cash, disburse funds,
debit bank account, and post entry on the customer’s receipt. Note that some of these
responsibilities must be performed within the context of a database transaction. A
database transaction ensures all-or-nothing behavior—all operations within the
scope of a transaction happen or none of the operations happen. For example, the
disbursement of funds and debiting of the bank account must both happen together.
■ Deposit. A deposit involves several responsibilities: get amount from customer,
accept funds envelope from customer, time-stamp envelope, credit bank account,
and post entry on the customer’s receipt. Some of these responsibilities must also be
performed within the context of a database transaction.
■ Transfer. Responsibilities include: get source account, get target account, get
amount, verify that source account covers amount, verify that the amount is within
the bank’s policies, debit the source account, credit the target account, and post an
entry on the customer’s receipt. Once again some of the responsibilities must happen
within a database transaction.
Actor Identification
Actor identification in a use case involves determining the entities (people, systems,
or devices) that interact with the system being designed. Actors represent roles that
participate in the system's functionality and are external to the system.
Steps to Identify Actors in a Use Case:
1. Understand the System Scope:
o Clearly define the boundaries of the system and what it is intended to
do.
2. Identify Stakeholders:
o Determine all the people or systems that have an interest in or need
from the system.
3. Ask Key Questions:
o Who will use the system? (Primary Actors)
o Who will provide inputs to the system?
o Who will receive outputs from the system?
o Are there external systems that interact with this system?
o Are there devices or hardware that need to interact with the system?
4. Categorize Actors:
o Primary Actors: Directly interact with the system to achieve their goals
(e.g., a user logging into a system).
o Secondary Actors: Support the system in achieving its goals but are
not directly involved in the primary workflow (e.g., a database server or
an authentication service).
5. Check for Generalization:
o If multiple actors share common behavior or goals, consider abstracting
them into a generalized actor.
6. Validate the Identified Actors:
o Review with stakeholders to ensure all relevant actors are included.
Actor Classification
Actors can be classified into the following categories:
1. Primary Actors
• Definition: Entities that initiate interaction with the system to achieve their
goals.
• Purpose: Drive the main use cases; their goals are directly addressed by the
system.
• Examples:
o A Customer placing an order in an e-commerce application.
o An Employee applying for leave in an HR system.
2. Secondary Actors
• Definition: Entities that support the system in achieving the goals of primary
actors. They don't directly trigger the system's operations but provide services
or perform background tasks.
• Purpose: Facilitate the functionality required by the primary actors.
• Examples:
o A Payment Gateway processing payments in an online store.
o A Database Server storing transaction records.
3. Human Actors
• Definition: People interacting with the system.
• Purpose: Represent real-world users or stakeholders.
• Examples:
o A Student registering for courses in an academic portal.
o A Manager approving leave requests.
4. System Actors
• Definition: External systems or software interacting with the system being
designed.
• Purpose: Collaborate with the system to perform tasks or exchange data.
• Examples:
o A Third-Party API validating credit card details.
o An External Accounting System generating financial reports.
5. Device Actors
• Definition: Hardware devices interacting with the system.
• Purpose: Serve as interfaces or data sources for the system.
• Examples:
o A Barcode Scanner used in inventory management.
o A Smart Sensor collecting environmental data.
6. Organizational Actors
• Definition: Departments, organizations, or groups that interact with the
system.
• Purpose: Represent institutional entities rather than individual users.
• Examples:
o A Logistics Department using a delivery management system.
o A Regulatory Authority auditing system operations.
Actor Generalization
in use case modeling is the process of identifying common roles, responsibilities, or
behaviors among actors and creating a generalized actor to represent shared
functionality. It uses inheritance to model relationships between actors, making
diagrams simpler and avoiding redundancy.
Purpose of Actor Generalization
1. Avoid Redundancy: Combine common behaviors shared by multiple actors.
2. Simplify Models: Reduce complexity by grouping similar actors under a
generalized parent actor.
3. Enhance Flexibility: Allow for easy modification or extension of use cases by
defining shared and specific behaviors.