0% found this document useful (0 votes)
15 views38 pages

SELecture 4

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

SELecture 4

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

Software Engineering

Lecture 4

Dr. Abdulmalek Alqobaty


Taiz University, 2024
Software Engineering

Low-Level
Design
Low-Level Design

This lecture covers the following:


How to use generalization and refinement to build inheritance
hierarchies
Warning signs of bad inheritance hierarchies
How to use composition to build new classes without inheritance
How normalization protects databases from anomalies
Rules for first, second, and third normal forms
Low-Level Design

Low-level Design
High-level design
paints an application’s structure in broad strokes.
identifies the system’s general environment (hardware, operating system,
network, and so on) and architecture (such as monolithic, client/server,
and service‐oriented).
identifies the system’s major components such as reporting modules,
databases, and top‐level classes.
should sketch out how the pieces of the system will interact.
Low-level design
fills in some of the gaps to provide extra detail that’s necessary before
developers can start writing code.
gives more specific guidance for how the parts of the system will work
and how they will work together.
refines the definitions of the database, the major classes, and the internal
and external interfaces.
In short, High-level design focuses on what. Low-level design
begins to focus on how.
Low-Level Design

As an analogy,
if you were building a highway system,
The high‐level design would determine what cities would be connected
by highways.
The low‐level design would indicate exactly where the highways would
be placed, where the ramps would be, and what elementary schools would
be surrounded by four‐lane traffic circles.
The border between high‐level and low‐level designs is often rather
fuzzy. Typically, after a piece of the system is added to the high‐level
design, team members continue working on that piece to develop its
low‐level design.
Low-Level Design

OO Design
The high‐level design should have identified the major types of classes
that the application will use. Now it’s time to refine that design to identify
the specific classes that program will need. The new classes should include
definitions of the properties, methods, and events they will provide for
the application to use.
In the following we explain how you can define the classes that an
application will use.
Identifying Classes
The high level design tells you that you should identify the main classes that
the application will use, but it doesn’t tell you how to do that. One way to
pick classes is to look for nouns in a description of the application’s
features.
For example, suppose you are writing an application called FreeWheeler
Automatic Driver (FAD) that automatically drives cars. Now consider the
sentence, “The program drives the car to the selected destination.” That
sentence contains three nouns: program, car, and destination.
OO Design

 The program probably doesn’t need to directly manipulate itself, so it’s


unlikely that you will need a Program class. It will almost certainly need to
work with cars and destinations, so you may need Car and Destination
classes.
 When you are studying possible classes, think about what sorts of
information the class needs (properties), what sorts of things it needs to
do (methods), and whether it needs to notify the program of changing
circumstances (events).
 For this example, the Car class is going to be fully loaded, providing all
sorts of properties (such as CurrentSpeed , currentDirection, and FuelLevel ),
methods (such as Accelerate , Decelerate, ActivateTurnSignal, and
HonkHorn ), and events (such as DriverPressedStart, FuelLevelLow, and
CollisionImminent).
 The Destination class is probably a lot simpler because it just represents
a specific location. In fact, it may be that the application needs only a single
instance of this class to record the current destination. Making only a
single instance of a class is a sign that perhaps the class isn’t
necessary.
Low-Level Design

Building Inheritance Hierarchies


After you define the application’s main classes, you need to add more
detail to represent variations on those classes.
For example, FreeWheeler is going to need a Car class to represent the
vehicle it is driving, but different vehicles have different characteristics. A
106‐horsepower Toyota Yaris handles differently than a 460‐horsepower
Chevrolet Corvette. It would be bad if the program told the Yaris to pull
out in front of a speeding tractor trailer, assuming it could go from 0 to 60
miles per hour in 3.7 seconds.
You can capture the differences between related classes by deriving a child
class from a parent class. In this example, you might derive the Yaris and
Corvette child classes from the Car parent class. Child classes
automatically inherit the properties, methods, and events defined by the
parent class.
You can derive multiple classes from a single parent class. For example,
you could derive Corvette , Edsel , and Pinto all from the Car class.
Low-Level Design

Refinement
Refinement is the process of breaking a parent class into multiple
subclasses to capture some difference between objects in the class.
One danger to refinement is over-refinement, which happens when you
refine a class hierarchy unnecessarily, making too many classes that make
programming more complicated and confusing. People are naturally good
at categorizing objects. It takes only a few seconds of thought to break cars
into the classes shown in Figure 6-1 . The open arrowheads point from child
classes to their parent classes.
There are a couple hundred models of
car on the roads in the United States
alone. You could refine most of those
models with different options such as
different engine sizes, alloy wheels,
and seat warmers.
The resulting hierarchy would
contain many thousands (or millions)
FIGURE 6-1: People are naturally good at
of classes. Obviously, a hierarchy building inheritance hierarchies.
that large wouldn’t be useful.
Building Inheritance Hierarchies

There are two main problems here.


1.The classes are capturing data that isn’t relevant to the application.
2.The differences between cars could easily be represented by properties
instead of by different classes.
Similarly, a car’s model (Corvette, Edsel, and Mustang) is just a name for a
specific type of car. You may have some expectations based on the name,
but to the FreeWheeler program, those are just labels.
You can avoid these kinds of hierarchy problems if you focus on behavioral
differences between the different kinds of objects instead of looking at
differences in properties.
Building Inheritance Hierarchies

For example,
where there is a behavioral difference, consider transmission type.
To accelerate a car with automatic transmission to freeway speeds, you
simply stomp on the gas pedal until the car is going fast enough.
Bringing a manual transmission car up to speed is much more
complicated, requiring you to use the gas pedal, the clutch, and the gear
shift.
Both kinds of vehicles accelerate, but the details about how they do it
are different.
In object‐oriented terms, the Car class might have an Accelerate method
that makes the car accelerate. The A utomatic and Manual subclasses
would provide different implementations of the Accelerate method that
handle the appropriate details.
Building Inheritance Hierarchies
Figure 6-2 shows a revised inheritance hierarchy.

The first section under a class’s name lists its properties (just Acceleration
in this example). A subclass does not repeat items that it inherits without
modification from its parent class. In this example, the Automatic and
Manual classes inherit the Acceleration property.
The second section below a class’s name shows methods ( Accelerate in
this example). The method is italicized in the Car class to indicate that it is
not implemented there and must be overridden in the child classes.

FIGURE 6-2: This hierarchy


focuses on behavioral
differences between classes.
Low-Level Design
Generalization
Refinement (specialization) starts with a single class and creates child
classes to represent differences between objects. Generalization does
the opposite: It starts with several classes and creates a parent for them to
represent common features.
Consider the ClassyDraw application which is a drawing application some-
what similar to MS Paint, except it allows you to manipulate drawn objects.
The program represents drawn objects, so it needs classes such as
Rectangle , Ellipse , Polygon , Text , Line , Star , and Hypotrochoid .
For a concrete example, suppose the user clicks part of a drawing to select
a drawn object.
Classes such as Rectangle and Ellipse use different techniques to decide
whether you clicked their objects, but they both need a method to do
that. You could call this method ObjectIsAt and make it return true if
the object is at a specific clicked location.
The parent class, which I shall call Drawable , can define the ObjectIsAt
method. The child classes would then provide their own implementations.
Generalization

Figure 6-3 shows the drawing class inheritance


hierarchy.

FIGURE 6-3: Generalization creates the


Drawable parent class.

Just as you can go overboard with refinement to build an inheritance


hierarchy containing thousands of car classes, you can also get carried away
with generalization.
For example, suppose you are building a pet store inventory application.
You define a Customer class and an Employee class. They share some
properties such as Name, Address, and ZodiacSign , so you generalize them
by making a Person class to hold the common properties. Next, you define
various pet classes such as Dog, Cat , Gerbil , and Capybara .
You generalize them to make a Pet class. In a fit of inspiration, you
realize that people and pets are all animals! So you make an Animal class
to be a parent class for Person and Pet. They can even share some
properties such as Name .
Low-Level Design
Hierarchy Warning Signs
The following list gives some questions you can ask yourself
when trying to decide if you have an effective inheritance
hierarchy.

Is it tall and thin? In general, tall, thin inheritance hierarchies are
more confusing than shorter ones. Tall hierarchies make it hard for
developers to remember which class to use under different
circumstances.
Do you have a huge number of classes? Suppose your car sales
application needs to track make, model, year, color, engine, wheel size,
and motorized cup holders. If you try to use classes to represent every
possible combination, you’ll get a combinatorial explosion and
thousands of classes
Does a class have only a single subclass? If so, then you can
probably remove it and move whatever it was trying to represent into
the subclass.
Low-Level Design

Hierarchy Warning Signs


 If there a class at the bottom of the hierarchy that is never
instantiated? If the Car hierarchy has a HalfTrack class and the
program never makes an instance of that class, then you
probably don’t need the HalfTrack class.
 Do the classes all make common sense? If the Car hierarchy
contains a Helicopter class, there’s probably something wrong.
 Do classes represent differences in a property’s value
rather than in behavior or the presence of properties? A
simple sales program might not need separate classes to
represent notebooks and three‐hole punches because they are
both simple products that you sell one at a time.
Low-Level Design

Object Composition
 Inheritance is one way you can reuse code. A child class
inherits all of the code defined by its parent class, so you don’t
need to write it again. Another way to reuse code is object
composition, a technique that uses existing classes to build
more complex classes.
For example, suppose you define a Person class that has
FirstName, LastName, Address, and Phone properties. Now you
want to make a Company class that should include information
about a contact person.
You could make the Company class and give the Company class a
new property of type Person called ContactPerson . Now the
Company class gets the benefit of the code defined by the Person
class without the illogic and possible confusion of inheriting
from Person .
Low-Level Design

DATABASE DESIGN
 The most popular kind of databases that you can use to build an
application are relational databases. Relational databases are
simple, easy to use, and provide a good set of tools for
searching, combining data from different tables, sorting results,
and otherwise rearranging data.
 Like object‐oriented design, database design is too big a topic
to squeeze into a tiny portion here. However, there is room
here to cover a few of the most important concepts of database
design. You can find a book on database design for more
complete information.
 In the following we briefly explains what a relational database
is. Then we after that explain the first three forms of database
normalization and why they are important.
Low-Level Design

Relational Databases

 A relational database stores related data in tables . Each table


holds records that contain pieces of data that are related.
Sometimes records are called tuples to emphasize that they
contain a set of related values.
 The pieces of data in each record are called fields . Each field
has a name and a data type. All the values in different records
for a particular field have that data type.
 Figure 6-4 shows a small Customer table holding five records.
The table’s fields are CustomerId , FirstName , LastName ,
Street , City , State , and Zip. Because the representation shown
in Figure 6 -4 lays out the data in rows and columns, records are
often called rows and fields are often called columns .
Low-Level Design

Relational Databases

FIGURE 6-4: A table’s records are often called rows and its fields are often called columns.
Low-Level Design
Relational Databases
 A relational database stores related data in tables . Each table holds
records that contain pieces of data that are related. Sometimes records
are called tuples to emphasize that they contain a set of related values.
 The pieces of data in each record are called fields . Each field has a name
and a data type. All the values in different records for a particular field
have that data type.
 Figure 6-4 shows a small Customer table holding five records. The
table’s fields are CustomerId , FirstName , LastName , Street , City ,
State , and Zip. Because the representation shown in Figure 6 -4 lays out
the data in rows and columns, records are often called rows and fields
are often called columns .

FIGURE 6-4: A table’s records are often called rows and its fields are often called columns.
Low-Level Design

Relational Databases
The “relational” part of the term “relational database” comes from
relationships defined between the database’s tables. For example,
consider the Orders table shown in Figure 6-5 . The Customers table’s
CustomerId field and the Orders table’s CustomerId field form a
relationship between the two tables. To find a particular customer’s
orders, you can look up that customer’s CustomerId in the Customers
table in Figure 6-4 , and then find the corresponding Orders records.

FIGURE 6-5: The Customers table’s CustomerId column provides a link to the Orders table’s CustomerID column.
Low-Level Design

Relational Databases

 One particularly useful kind of relationship is a foreign key


relationship. A foreign key is a set of one or more fields in one
table with values that uniquely define a record in another table.
For example, in the Orders table shown in Figure 6-5 , the
CustomerId field uniquely identifies a record in the
Customers table. In other words, it tells you which customer
placed the order. There may be multiple records in the Orders
table with the same CustomerId (a single customer can place
multiple orders), but there can be only one record in the
Customers table that has a particular CustomerId value.
Low-Level Design

Relational Databases
Building a relational database is easy, but unless you design the database
properly, you may encounter unexpected problems. Those problems may
be that:
Duplicate data can waste space and make updating values slow.
You may be unable to delete one piece of data without also deleting
another unrelated piece of data.
An otherwise unnecessary piece of data may need to exist so that you
can represent some other data.
The database may not allow multiple values when you need them.
The database‐speak euphemism for these kinds of problems is anomalies.
Database normalization is a process of rearranging a database to put it
into a standard (normal) form that prevents these kinds of anomalies.
There are seven levels of database normalization that deal with increasingly
obscure kinds of anomalies. The following sections describe the first three
levels of normalization, which handle the worst kinds of database problems.
Low-Level Design

First Normal Form


First normal form (1NF ) basically says the table can be placed
meaningfully in a relational database. It means the table has a sensible,
down‐to‐earth. Relational database products tend to enforce most of the
1NF rules automatically, so if you don’t do anything too weird, your
database will be in 1NF with little extra work.
The official requirements for a table to be in 1NF are:
1.Each column must have a unique name.
2.The order of the rows and columns doesn’t matter.
3.Each column must have a single data type.
4.No two rows can contain identical values.
5.Each column must contain a single value.
6.Columns cannot contain repeating groups. That means you can’t have
two columns that represent the same thing.
Low-Level Design

First Normal Form


Now consider the signup sheet shown in Table 6-1. It violates Rule 1 through
4.
TABLE 6-1: Weapons Training Signup Sheet
Low-Level Design

First Normal Form


Here is how you can put this signup sheet into 1NF.
Rule 1 - The signup sheet has two columns named Weapon. You can fix that by
changing their names to Weapon1 and Weapon2.
Rule 2 - The order of the rows in the signup sheet determines the order in
which you’ll call campers for their tutorials, so the ordering of rows is
important.
Rule 3 - The Weapon1 column holds two kinds of values: weapon or
“Everything”. The value “Everything” will be replaced with multiple records
that list all the possible weapon values.
Rule 4 - The current design doesn’t contain any duplicate rows.
Rule 5 - Right now each column contains a single value.
Rule 6 - This rule says a table cannot contain repeating groups. That means
you can’t have two columns that represent the same thing. This means a bit
more than two columns don’t have the same data type .
Low-Level Design

First Normal Form

TABLE 6-4: Signup Sheet with Explicitly Listed Weapons


Low-Level Design

Another Way
Another way to look at this is to ask yourself whether the record “Sharon
Simmons, Broadsword, Bow” and the rearranged record “Sharon
Simmons, Bow, Broadsword” would have the same meaning. If yes even if
you switch the values of the two fields, then those fields form a repeating
group.
The way to fix this problem
is to pull the repeated data
out into a new table. Use
fields in the original table
to link to the new one.
Figure 6-6 shows the new
design. The Tutorials and
TutorialWeapons tables are
linked by their Time fields.

FIGURE 6-6: This design is in first


1NF. Lines connect related records.
Low-Level Design

Second Normal Form


A table is in second normal form ( 2NF ) if it satisfies these rules:
1. It is in 1NF.
2. All non-key fields depend on all key fields.
A key is a set of one or more fields that uniquely identifies a record. Any table
in 1NF must have a key because of Rule 4. That means there must be a way to pick
fields to guarantee uniqueness, even if the key must include all field.
For example of a table that is not in 2NF, suppose you want to schedule games for
campers at the fantasy adventure camp. Table 6-5 lists the scheduled games
TABLE 6-5: Camp Games Schedule Sheet
Second Normal Form

The table’s primary key is Time+Game. It cannot have two instances of the
same game at the same time (because you don’t have enough equipment or
counselors), so the combination of Time+Game uniquely identifies the rows.
Even though this table is in 1NF, it suffers from the following anomalies:
Update anomalies - If you modify the Duration or MaximumPlayers value in
one row, other rows containing the same game will be out of sync.
Deletion anomalies - Suppose you want to cancel the Middle Earth
Hold’em Poker game at 4:00, so you delete that record. Then you have lost
all the information about that game. You no longer know that it takes 90
minutes and has a maximum of 10 players.
Insertion anomalies - You cannot add information about a new game
without scheduling it for play. For example, suppose Banshee Bingo takes
45 minutes and has a maximum of 30 players. You can’t add that information
to the database without scheduling a game.
The problem with this table is that it’s trying to do too much. It’s trying
to store information about both games (duration and maximum players) and
the schedule.
Second Normal Form
The reason it breaks the 2NF rules is that some non-key fields do not
depend on all the key fields. Recall that this table’s key fields are Time and
Game . A game’s duration and maximum number of players depends only on
the Game and not on the Time. For example, Water Wizzards lasts for 120
minutes whether you play at 1:00, 4:00, or midnight.
To fix this table, move the data that doesn’t depend on the entire key into a new
table. Use the key fields that the data does depend on to link to the original
table. Figure 6-7 shows the new design. Here the ScheduledGames table holds
schedule information and the Games table holds information specific to the
games.

F IGURE 6-7: Moving the data that doesn’t depend on all the table’s key fields puts this table in 2NF.
Low-Level Design

Third Normal Form

A table is in third normal form (3NF ) if:


1. It is in 2NF.
2. It contains no transitive dependencies.
A transitive dependency is when a non-key field’s value depends
on another non-key field’s value.
For example, suppose the fantasy adventure camp has a library.
(So campers have something to read after they get injured playing
the games.) Posted in the library is the following list of the
counselors’ favorite books, as in Table 6-6 .
Low-Level Design

Third Normal Form


TABLE 6-6: Counselors’ Favorite Books
Third Normal Form

This table’s key is the Counselor field.


If you run through the 1NF rules, you’ll see that this table is in 1NF. The
table has only a single key field, so a non-key field cannot depend on only
some of the key fields. That means the table is also in 2NF.
When posted on the wall of the library, this list is fine. Inside a database,
however, it suffers from the following anomalies:
Update anomalies - If you change the Pages value for Becky’s row
(Dealing with Dragons ), it will be inconsistent with Noah’s row (also
Dealing with Dragons ). Also if Luke changes his favorite book to Majestrum:
A Tale of Hengis Hapthorn , the table loses the data it has about The Color of
Magic.
Deletion anomalies - If J.C. quits being a counselor to become a
professional wrestler and you remove his record from the table, you lose the
information about Gil’s All Fright Diner.
Insertion anomalies - You cannot add information about a new book
unless it’s someone’s favorite. Conversely, you can’t add information about a
person unless he declares a favorite book.
Third Normal Form
 The problem is that some non-key fields depend on other
non-key fields. In this example, the Author and Pages fields
depend on the FavoriteBook field. For example, any record with
FavoriteBook. The Last Dragonslayer has Author Jasper Fforde
and Pages 306 no matter whose favorite it is.
 You can fix this problem by keeping only enough
information to identify the dependent data and moving the
rest of those fields into a new table. In this example, you
would keep the FavoriteBook field in the original table and
move its dependent values Author and Pages into a new table.
(Figure 6-8)
Third Normal Form

FIGURE 6-8: Moving non-key fields that depend on other non-key fields into a separate table
puts this table in 3NF.
Low-Level Design

Higher Levels of Normalization


 Higher levels of normalization include Boyce‐Codd normal form (BCNF),
fourth normal form (4NF), fifth normal form (5NF), and Domain/Key
Normal Form (DKNF). Some of these later levels of normalization are
fairly technical and confusing, so I won’t cover them here. See a book on
database design for details.
 Many database designs stop at 3NF because it handles most kinds of
database anomalies without a huge amount of effort. In fact, with a little
practice, you can design database tables in 3NF from the beginning,
so you don’t need to spend several steps normalizing them.
 More complete levels of normalization can also lead to confusing
database designs that may make using the database harder and less
intuitive, possibly giving rise to extra bugs and sometimes reduced
performance.

You might also like