[go: up one dir, main page]

0% found this document useful (0 votes)
27 views7 pages

3.2 Component Level Design

The document discusses component-level design in software engineering. It defines what a component is, describes different types of components and views of components. It also discusses principles for designing class-based components, guidelines for component-level design, and concepts of cohesion and coupling in component design.

Uploaded by

jashtiyamini72
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views7 pages

3.2 Component Level Design

The document discusses component-level design in software engineering. It defines what a component is, describes different types of components and views of components. It also discusses principles for designing class-based components, guidelines for component-level design, and concepts of cohesion and coupling in component design.

Uploaded by

jashtiyamini72
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Component-level design

Component-level design occurs after the first iteration of architectural design has
been completed. At this stage, the overall data and program structure of the software has
been established. The intent is to translate the design model into operational software.
What Is A Component?

A component is a modular building block for computer software. More formally,


the OMG Unified Modeling Language Specification defines a component as “a modular,
deployable, and replaceable part of a system that encapsulates implementation and
exposes a set of interfaces.”
The true meaning of the term component will differ depending on the point of
view of the software engineer who uses it.
An Object-Oriented View
In the context of object-oriented software engineering, a component contains a set of
collaborating classes. Each class within a component has been fully elaborated to include
all attributes and operations that are relevant to its implementation. As part of the design
elaboration, all interfaces that enable the classes to communicate and collaborate with
other design classes must also be defined. To accomplish this, you begin with the
requirements model and elaborate analysis classes and infrastructure classes.
The Traditional View
In the context of traditional software engineering, a component is a functional
element of a program that incorporates processing logic, the internal data structures that
are required to implement the processing logic, and an interface that enables the
component to be invoked and data to be passed to it. A traditional component, also called
a module, resides within the software architecture and serves one of three important
roles:
(1) A control component that coordinates the invocation of all other problem
domain components,
(2) a problem domain component that implements a complete or partial function that
is required by the customer, or
(3) an infrastructure component that is responsible for functions that support the
processing required in the problem domain.
A Process-related View

• Emphasis is placed on building systems from existing components maintained in a


library rather than creating each component from scratch
• As the software architecture is formulated, components are selected from the library
and used to populate the architecture
• Because the components in the library have been created with reuse in mind, each
contains the following:
– A complete description of their interface
– The functions they perform
– The communication and collaboration they require

DESIGNING CLASS-BASED COMPONENTS

Basic Design Principles

Four basic design principles are applicable to component-level design and have been
widely adopted when object-oriented software engineering is applied.

The Open-Closed Principle (OCP). “A module [component] should be open for


extension but closed for modification” This statement seems to be a contradiction, but it
represents one of the most important characteristics of a good component-level design.
Stated simply, you should specify the component in a way that allows it to be extended
without the need to make internal modifications to the component itself.

The Liskov Substitution Principle (LSP). “Subclasses should be substitutable for their
base classes”. This design principle, originally proposed by Barbara Liskov, suggests that
a component that uses a base class should continue to function properly if a class derived
from the base class is passed to the component instead. LSP demands that any class
derived from a base class must honor any implied contract between the base class and
the components that use it. In the context of this discussion, a “contract” is a precondition
that must be true before the component uses a base class and a post condition that should
be true after the component uses a base class.

Dependency Inversion Principle (DIP). “Depend on abstractions. Do not depend on


concretions”. The more a component depends on other concrete components, the more
difficult it will be to extend.
The Interface Segregation Principle (ISP). “Many client-specific interfaces are better
than one general purpose interface”. ISP suggests that you should create a specialized
interface to serve each major category of clients. Only those operations that are relevant
to a particular category of clients should be specified in the interface for that client. If
multiple clients require the same operations, it should be specified in each of the
specialized interfaces.

The Release Reuse Equivalency Principle (REP). “The granule of reuse is the granule
of release”. When classes or components are designed for reuse, there is an implicit
contract that is established between the developer of the reusable entity and the people
who will use it. The developer commits to establish a release control system that supports
and maintains older versions of the entity while the users slowly upgrade to the most
current version. Rather than addressing each class individually, it is often advisable to
group reusable classes into packages that can be managed and controlled as newer
versions evolve.
The Common Closure Principle (CCP). “Classes that change together belong
together.” Classes should be packaged cohesively. That is, when classes are packaged as
part of a design, they should address the same functional or behavioral area. When some
characteristic of that area must change, it is likely that only those classes within the
package will require modification. This leads to more effective change control and
release management.
The Common Reuse Principle (CRP). “Classes that aren’t reused together should not
be grouped together”. When one or more classes within a package changes, the release
number of the package changes. All other classes or packages that rely on the package
that has been changed must now update to the most recent release of the package and be
tested to ensure that the new release operates without incident. If classes are not grouped
cohesively, it is possible that a class with no relationship to other classes within a package
is changed.

Component-Level Design Guidelines


Ambler suggests the following guidelines:
Components. Naming conventions should be established for components that are
specified as part of the architectural model and then refined and elaborated as part of the
component-level model. Architectural component names should be drawn from the
problem domain and should have meaning to all stakeholders who view the architectural
model.
Interfaces. Interfaces provide important information about communication and
collaboration. Ambler recommends that (1) lollipop representation of an interface
should be used in lieu of the more formal UML box and dashed arrow approach, when
diagrams grow complex; (2) for consistency, interfaces should flow from the left-hand
side of the component box; (3) only those interfaces that are relevant to the component
under consideration should be shown, even if other interfaces are available.

Cohesion
cohesion is the “single-mindedness” of a component. Lethbridge and Laganiére define a
number
of different types of cohesion
Functional. Exhibited primarily by operations, this level of cohesion occurs when a
component performs a targeted computation and then returns a result.

Layer. Exhibited by packages, components, and classes, this type of cohesion occurs
when a higher layer accesses the services of a lower layer, but lower layers do not access
higher layers.
Communicational. All operations that access the same data are defined within one class.
In general, such classes focus solely on the data in question, accessing and storing it.

Coupling

Coupling is a qualitative measure of the degree to which classes are connected to one
another. As classes (and components) become more interdependent, coupling increases.
An important objective in component-level design is to keep coupling as low as is
possible.
Class coupling can manifest itself in a variety of ways. Lethbridge and Laganiére define
the following coupling categories:
Content coupling. Occurs when one component “surreptitiously modifies data that is
internal to another component”.
Common coupling. Occurs when a number of components all make use of a global
variable. Although this is sometimes necessary, common coupling can lead to
uncontrolled error propagation and unforeseen side effects when changes are made.
Control coupling. Occurs when operation A() invokes operation B() and passes a control
flag to
B. The control flag then “directs” logical flow within B. The problem with this form of
coupling is that an unrelated change in B can result in the necessity to change the meaning
of the control flag that A passes. If this is overlooked, an error will result.
Stamp coupling. Occurs when ClassB is declared as a type for an argument of an
operation of ClassA. Because ClassB is now a part of the definition of ClassA, modifying
the system becomes more complex.
Data coupling. Occurs when operations pass long strings of data arguments. The
“bandwidth” of communication between classes and components grows and the
complexity of the interface increases. Testing and maintenance are more difficult.
Routine call coupling. Occurs when one operation invokes another. This level of
coupling is common and is often quite necessary. However, it does increase the
connectedness of a system.
Type use coupling. Occurs when component A uses a data type defined in component
B. If the type definition changes, every component that uses the definition must also
change.
Inclusion or import coupling. Occurs when component A imports or includes a package
or the content of component B.

External coupling. Occurs when a component communicates or collaborates with


infrastructure components. Although this type of coupling is necessary, it should be
limited to a small number of components or classes within a system.
Software must communicate internally and externally. Therefore, coupling is
a fact of life. However, the designer should work to reduce coupling whenever
possible.

CONDUCTING COMPONENT-LEVEL DESIGN

The following steps represent a typical task set for component-level design, when it is
applied for an object-oriented system.
Step 1. Identify all design classes that correspond to the problem domain. Using the
requirements and architectural model, each analysis class and architectural component is
elaborated.
Step 2. Identify all design classes that correspond to the infrastructure domain.
These classes are not described in the requirements model and are often missing from the
architecture model, but they must be described at this point.

Step 3. Elaborate all design classes that are not acquired as reusable components.
Elaboration requires that all interfaces, attributes, and operations necessary to implement
the class be described in detail. Design heuristics (e.g., component cohesion and
coupling) must be considered as this task is conducted.

Step 3a. Specify message details when classes or components collaborate. The
requirements model makes use of a collaboration diagram to show how analysis classes
collaborate with one another. As component-level design proceeds, it is sometimes useful
to show the details of these collaborations by specifying the structure of messages that
are passed between objects within a system. Although this design activity is optional, it
can be used as a precursor to the specification of interfaces that show how components
within the system communicate and collaborate.
Step 3c. Elaborate attributes and define data types and data structures required to
implement them. In general, data structures and types used to define attributes are
defined within the context of the programming language that is to be

Step 3d. Describe processing flow within each operation in detail. This may be
accomplished using a programming language-based pseudocode or with a UML activity
diagram. Each

software component is elaborated through a number of iterations that apply the stepwise
refinement concept.
Step 4. Describe persistent data sources (databases and files) and identify the classes
required to manage them. Databases and files normally transcend the design description
of an individual component. In most cases, these persistent data stores are initially
specified as part of architectural design. However, as design elaboration proceeds, it is
often useful to provide additional detail about the structure and organization of these
persistent data sources.

Step 5. Develop and elaborate behavioural representations for a class or component.


UML state diagrams were used as part of the requirements model to represent the
externally observable behaviour of the system and the more localized behavior of
individual analysis classes. During component-level design, it is sometimes necessary to
model the behaviour of a design class.

Step 6. Elaborate deployment diagrams to provide additional implementation


detail. Deployment diagrams are used as part of architectural design and are represented
in descriptor form. In this form, major system functions (often represented as subsystems)
are represented within the context of the computing environment that will house them.
During component-level design, deployment diagrams can be elaborated to represent the
location of key packages of components.
Step 7. Refactor every component-level design representation and always consider
alternatives. The first component-level model you create will not be as complete,
consistent, or accurate as the nth iteration you apply to the model.

You might also like