CONCEPTS OF SOFTWARE
ENGINEERING
Programming
Dr. Abdul Karim ABED
Definition
XP Coding can be in Java, C, PHP etc. depending on
the purpose, user preferences, programmer
preferences, existing legacy code etc.
It works well with Java for a few reasons.
XP and Java
Most important is the speed with which Java compiles.
XP relies on test-first development in which programmers
write tests for code before they write the code.
For each new feature, you should write a test and then
watch the test run and fail. You should then add the
feature, compile, and watch the test run successfully. This
implies that you must write a little code, compile, and run
the tests frequently, perhaps dozens of times each day.
Because Java compiles quickly, it is well suited to the test-
first approach.
XP and Java
The second reason Java is a good choice for XP
development is Java's wealth of tools supporting
unit testing and continuous integration. JUnit,
provides a lightweight framework for writing
automated unit tests.
Ant, the premier build tool for Java, makes
continuous integration possible even when working
with large development teams.
XP and Java
Java's power and simplicity also make it a good
language when writing code using XP. Java's
relatively easy syntax makes it easier to maintain
code written by other team members, which is
important for XP's concepts of pair programming,
refactoring, and collective code ownership
UML and Java Code
6
UML is a modeling language that most developers
employed during design phase.
UML provides various types of diagrams used for
specifying both the structure and the behavior of
systems. During the development process.
Models specified by these diagrams are eventually
transformed into corresponding code.
UML and Java Code
7
We documented our OOAD (object-oriented analysis
and design) with UML diagrams. However, each
object identified in an OOAD must eventually be
implemented in some programming language.
Object-oriented programming works much better
when it is used together with an object-oriented
analysis and design process
UML and Java Code
8
Many professionals consider Java as the
implementation language of choice for object-
oriented development.
UML and Java may be languages for software
development, but they exist in different planes of
reality. UML occupies the visual world, whereas
Java is textual in nature.
UML and Java Code
9
Why UML and Java
When modeling elements, our goal is to sketch the
application's framework with a keen eye toward using
sound object-oriented principles. For this reason,
UML, as an object-oriented notation, is a nice fit for
any project using Java as its implementation language.
Java was built from the ground up with the necessary
"object plumbing" to benefit from the design elements
of UML models
UML and Java Code
10
UML ⇒ Java (Forward Engineering)
Implement code based on design written in UML
Java ⇒ UML (Reverse Engineering)
Create UML to document design of existing
UML and Java Code
11
UML Class Diagrams and Java Code
Different representation of same information
Name, state, behavior of class
Relationships between classes
Should be able to derive one from the other
Class Diagrams
12
• Class
Class Diagrams
13
Association
Multiplicity
Class Diagrams
14
• Inheritance
• interface
Class Diagrams
15
Abstract classes
Class Diagrams
Composition
Inner Classes
16
Sequence Diagram
17
Sequence diagram is used to show interaction
between the classes
It is a powerful way to communicate the flow of
messages in an object oriented application.
A sequence diagram shows a set of interaction
objects and the sequence of message exchanged
among them
Sequence Diagram
18
Creation of Object
Sequence Diagram
19
Destruction of object
Sequence Diagram
20
Sequence Diagram
Order price
anOrder anOrderEntry aProduct
calculate
Price
getQuantity
See how the
calculatePrice getProduct
method in
Order calls one
of its own getPricingDetails
methods
calc
Price OrderEntry
product : Product
Code in Order quantity : int
int quantity = entry.getQuantity(); + getProduct: Product
Product prod = entry.getProduct(); + getQuantity : int
double cost = prod.getPricingDetails();
double entryCost = this.calculatePrice(quantity, cost);
Sequence Diagram
One of the great fallacies of software development
in the 1990s was the notion that developers should
draw sequence diagrams for all methods before
writing the code. This always proves to be a very
expensive waste of time. Don’t do it
Sequence diagrams should be kept as simple as
possible, and any message that is insignificant need
not be shown
Code Quality
To code in XP, Everything we write must:
1- Run all tests;
2-Express every idea that we need to express
3- Say everything once and only once;
4- Have the minimum number of classes and methods
consistent with the above.
Code Quality
Run all the test
It’s most important that the code does what it has to
do. In XP there is only one way to know whether the
code does what it has to do: there must be a test. A
feature does not exist unless there is a test for it.
The code we release must run ALL the tests. It’s not
sufficient that the tests for OUR code run- all the tests
in the entire system still run whenever you release.
This ensure that changes we make don’t impact other
people in surprising ways.
Code Quality
Express every idea
As we write code, we are thinking. As we go along.
At the end of coding, the program should clearly
express all of the ideas. let every idea be expressed
explicitly in the code
Code Quality
Say everything once and only once
Whenever code is duplicated, get rid of it. Because
it makes program smaller, there is a chance for one
of duplicates to get fixed and the other one
forgotten. And duplicate code makes more code to
read and understand.
Code Quality
Minimize number of classes and methods
When all these things are done, if there are classes
or methods we don’t need, remove them.
Refactoring
?What it Refactoring
Refactoring is the technique of improving code
without changing functionality. Refactoring is an
ongoing process of simplification that applies to
.code, design, testing, and XP itself
Refactoring
Here is a simple refactoring. Suppose you have this
code:
public class Person {
private String firstName;
public void setFirst(String n) {
this.firstName = n; }
}
Refactoring
This code can be improved by picking a better
argument name, changing n to firstName:
public class Person {
private String firstName;
public void setFirst(String firstName)
{ this.firstName = firstName; }
}
Refactoring
The code can be improved even further by
renaming the method to setFirstName( ):
public class Person {
private String firstName;
public void setFirstName(String firstName)
{ this.firstName = firstName; }
}
Refactoring
Why should refactoring be done?
1) Refactoring Improves the Design of Software. -
Without refactoring, the design of the program will
decay. As people change code - changes to realize
short-term goals or changes made without a full
comprehension of the design of the code - the code
loses its structure.
Refactoring
2) Refactoring makes software easier to
understand. - There are users of your code. The
computer, the writer, and the updater. The most
important is the updater. Who cares if the compiler
takes a few more cycles to compile your code. If it
takes someone 3 weeks to update your code that is
a problem.
Refactoring
3) Refactoring helps you find bugs. - Part of
refactoring code is understanding the code and
putting that understanding back into the code. In
that process a clarification takes place. In that
clarification bugs will be found.
Refactoring
35
4) Refactoring Helps You Program Faster: A good
design is essential to maintaining speed in software
development. Refactoring helps you develop
software more rapidly, because it stops the design
of the system from decaying. It can even improve a
design.
Refactoring
Characteristics of Refactoring
Source to source transformation
Remain inside the same language, e.g., Java to
Java
Does not change the programs behaviour
Originally designed for object-oriented languages,
but can also be applied to non-object oriented
language features, i.e., functions
Refactoring
"code smells," which means that there are
indicators that point to bad code.
Refactoring has these simple steps:
Refactoring
38
Code Smells
Indicators that something may be wrong in the
code
Can occur both in production code and test code
Code Smells
1- Duplicated Code
If you see the same code structure in more than one place,
you can be sure that your program will be better if you find
a way to unify them
The simplest duplicated code problem is when you have
the same expression in two methods of the same class
Perform Extract Method and invoke the code from both places
Another common duplication problem is having the same
expression in two sibling subclasses
Perform Pull Up method
Refactoring
40
Extract Method
Extract Method is used when you have a code
fragment that can be grouped together. That code is
extracted and turned into a method whose name
will clearly explain the purpose of the method.
Extract Method
void printOwing(double amount)
{ printBanner();
//print details
System.out.println ("name:" + _name);
System.out.println ("amount" + amount);
}
Extract Method
void printReceipt (double a)
{ --------
//print details
System.out.println ("name:" + _n);
System.out.println ("amount" + a);
}
Extract Method
void printOwing(double amount)
{ printBanner();
printDetails(amount);
}
void printReceipt (double a)
{ printBanner();
printDetails(a);
}
void printDetails (double amount) {
System.out.println ("name:" + _name);
System.out.println ("amount" + amount); }
Refactoring
44
Pull Up Method
If you find methods in different subclasses that
have identical results, then you can use Pull Up
Method to move them to the superclass.
Eliminating this duplicate behavior will make the
code easier to maintain and understand
Pull Up Method
Pull Up Method
46
Pull Up Method
Code Smells
2- Long Method
The longer a procedure is the more difficult it is to
understand
Nearly all of the time all you have to do to shorten
a method is Extract Method.
As rule of thumb “more than 1 screen is too long”
Extract Method
49
Code Smells
3- Large Class
When a class is trying to do too much, it often
shows up as too many instance variables. When
a class has too many instance variables,
duplicated code cannot be far behind.
A class with too much code is also a breeding
ground for duplication
In both cases Extract Class and Extract Subclass
will work
Refactoring
Extract Class
If you find that you have one class that is doing
work that should really be done by two, use Extract
Class. You will create a new class and move the
relevant methods and attributes from the old class
into the new one.
Extract Class
Refactoring
53
Extract Subclass
Used when a class has some behavior used for
some instances and not for others
Make a subclass that inherits the common
functionality
Extract Subclass
Code Smells
4- Long Parameter List
Long parameter lists are hard to understand,
because they inconsistent and difficult to use
because you are forever changing them as you
need more data
Use Replace Parameter with Method when you
can get the data in one parameter by making a
request of an object you already know about
Refactoring
56
Replace Parameter with Method
An object invokes a method, then passes the result
as a parameter for a method.
The receiver can also invoke this method.
Replace Parameter with Explicit Methods
void setValue (String name, int value) {
{ if (name.equals("height"))
;height = value_
;return
}
{if (name.equals("width"))
;width = value_
;return
}
Replace Parameter with Explicit Methods
void setHeight(int arg) {
;height = arg_
}
void setWidth (int arg) {
;width = arg_
}
Code Smells
5- Feature Envy
A classic smell is a method that seems more
interested in a class other in the one that it is in
For example methods that make extensive use of
another class may belong in another class. Consider
moving this method to the class it is so envious of.
The method clearly wants to be elsewhere, so use
Move Method to get it there
Refactoring
60
Move Method
Create a new method with a similar body in the
class it uses most
Move Method
class Project {
Person[ ] participants;
}
class Person {
int id;
boolean participate(Project p) {
for(int i=0; i<p.participants.length; i++)
{ if (p.participants[i].id == id) return(true);
}
return(false);
}}
... if (x.participate(p)) ...
Move Method
class Project {
Person[ ] participants;
boolean participate(Person x)
{ for(int i=0; i<participants.length; i++) {
if (participants[i].id == x.id) return(true);
} return(false);
}}
class Person { int id;
}
... if (p.participate(x)) ...
Code Smells
6- Switch Statements
Most times when you see a switch statement you
should consider polymorphism
Often the switch statement switches on a type
code. You want the method or class that hosts the
type code value
Use Extract Method to extract the switch statement
and then Move Method to get it into the class
where the polymorphism is needed. Use Replace
conditional with polymorphism
Refactroing
64
Replace conditional with polymorphism
Move each leg of the conditional to an overriding
method in a subclass.
Replace conditional with polymorphism
{ )( Double getSpeed
{ switch (_type)
:case EUROPEAN
;)(return getBaseSpeed
:case AFRICAN
– )(return getBaseSpeed
;getLoadFactor() * _numCoconuts
:case NORWEGIAN_BLUE
return (_isNailed) ? 0
;getBaseSpeed(_voltage) :
}
}
Replace conditional with polymorphism
Replace conditional with polymorphism
class EmployeeType
... int payAmount(Employee emp)
{ switch (getTypeCode())
{
case ENGINEER:
return emp.getMonthlySalary();
case SALESMAN:
return emp.getMonthlySalary() + emp.getCommission();
case MANAGER:
return emp.getMonthlySalary() + emp.getBonus();
default: throw new RuntimeException("Incorrect Employee"); } }
Replace conditional with polymorphism
Replace conditional with polymorphism
class Engineer...
int payAmount(Employee emp) {
return emp.getMonthlySalary(); }
class Salesman...
int payAmount(Employee emp)
{ return emp.getMonthlySalary() + emp.getCommission(); }
class Manager...
int payAmount(Employee emp)
{ return emp.getMonthlySalary() + emp.getBonus(); }
and then declare the superclass method abstract:
class EmployeeType...
abstract int payAmount(Employee emp);
Bad Smells
7- Lazy Class
Each class you create costs money and time to
maintain and understand
A class that is not carrying its weight should be
eliminated
If you have subclasses that are not doing enough
try to use Collapse Hierarchy and nearly useless
components should be subjected to Inline Class
Refactoring
71
Collapse Hierarchy
A superclass and subclass are not very different.
Refactoring
72
Inline Class
Inline Class is the reverse of Extract Class. Use
Inline Class if a class is no longer pulling its weight
and shouldn’t be around any more. Often this is the
result of refactoring that moves other
responsibilities out of the class so there is little left
Bad Smells
73
8- Dead Code
Blocks of unused or commented out code in your
project? Don’t just leave it there just incase you
need it, test to make sure you don’t need it now
and get rid of it. If you don’t you’re only going to
make another developer spend a long time
looking at it and scratching their head trying to
work out what it is there for. Ruthlessly delete
code that isn't being used.
Bad Smells
9- Magic Number
Replace Magic Number with Symbolic Constant
Create a constant, name it after the meaning, and
replace the number with it
Refectory
static double ConvertPoundsToKilos( double
pounds ) { return pounds / 2.2 ; }
static final double KILO_CONVERSION_FACTOR
= 2.2;
static double ConvertPoundsToKilos( double
pounds ) { return pounds /
KILO_CONVERSION_FACTOR ; }