0% found this document useful (0 votes)
8 views59 pages

Tut 07

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

Tut 07

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

COMP S356

Software Engineering
and Project Management
Presentation Outlines
 Review of last tutorial

OCL – Object Constraint Language

 Unit5:

Implementation and Testing

 Q&A
Overview of mapping
Mapping concepts
Source Target Type of transformation

Model Model Model transformation

Code Code Refactoring

Model Code Forward engineering

Code Model Reverse engineering


Model transformation
 Object
model to another object model with
improvements

Identify superclass by common attributes and
operations in some classes (see figure on next page)

 Renaming of classes or operations


Object design model before transformation

LeagueOwner Advertiser Player


+email:Address +email:Address +email:Address

Object design model after transformation

User
+email:Address

LeagueOwner Advertiser Player


Refactoring
 Transform program code to program code

Why?
• Improving readability and performance

Need to retain all observable system behavior

3 refactoring approaches:
• Pull Up Field
• Pull Up Constructor
• Pull Up Method
Pull Up Field
Before refactoring After refactoring

public class User {


private String email;
}

public class Player { public class Player extends User {


private String email; //...
//... }
}
public class LeagueOwner { public class LeagueOwner extends
private String eMail; User {
//... //...
} }
public class Advertiser {
private String email_address; public class Advertiser extends User {
//... //...
} }
Pull Up Constructor
Before refactoring After refactoring
public class User { public class User {
private String email; private String email;
} public User(String email) {
this.email = email;
}
}

public class Player extends User { public class Player extends User {
public Player(String email) { public Player(String email) {
this.email = email; super(email);
} }
} }

public class LeagueOwner extends User { public class LeagueOwner extends User {
public LeagueOwner(String email) { public LeagueOwner(String email) {
this.email = email; super(email);
} }
} }

public class Advertiser extends User { public class Advertiser extends User {
public Advertiser(String email) { public Advertiser(String email) {
this.email = email; super(email);
} }
} }
Pull Up Method
Before refactoring After refactoring
public class User { public class User {
private String email; private String email;
} public String getEmail( ) {
return email;
}
}

public class Player extends User { public class Player extends User {
public String getEmail( ) { …
return email; }
}
} public class LeagueOwner extends User {

public class LeagueOwner extends User { }
public String getEmail( ) {
return email; public class Advertiser extends User {
} …
} }

public class Advertiser extends User {


public String getEmail( ) {
return email;
}
}
Forward Engineering
1. Transformation of elements in a model to program code
2. Transformation towards the direction of program code

User LeagueOwner
+email:String +maxNumLeagues:int
+notify(msg:String)
Object design model before transformation

User LeagueOwner
+email:String +maxNumLeagues:int
+notify(msg:String)

Source code after transformation

public class User { public class LeagueOwner extends User {

private String email; private int maxNumLeagues;

public String getEmail() { public int getMaxNumLeagues() {


return email; return maxNumLeagues;
} }

public void setEmail(String value) { public void setMaxNumLeagues(int value) {


email = value; maxNumLeagues = value;
} }

public void notify(String msg) { /* Other methods omitted */


// .... }
}

/* Other methods omitted */


}
Reverse Engineering
 Transformation of program code back to a model

Why?
• We may need to maintain a software system without
accurate and up-to-date models.
• We may not the original developer of the part of the system.


Software tools can’t generate models accurately from
program code automatically.


Difference between reverse engineering and
reengineering
Transformation principles
 Prevent multiple transformations at the
same time.
 Retest the program after refactoring.
Mapping Activities
Mapping Activities
 Optimizing the object design model

Optimizing associations
• For quick access to an object

 Mapping association to code



using collections

 Mapping contracts to code



using exceptions / assertions

 Mapping object models to a persistent storage


schema / databases
Optimizing the object model
 Optimizing access paths
Tournament
name
start *
end sponsors *
acceptPlayer() Advertiser
removePlayer()
schedule()

matches
Match
*
start
status
playMove()
getScore() Traversal from Match to Advertiser could
be more efficient by direct associations
Optimizing the object model
 Optimizing access paths

Optimization of a ‘many’ association to a ‘one’
qualified association
Without qualification
1 * File
Directory
filename

With qualification
1 0..1
Directory filename File


How ? HashTable
Concept of Hash table

Reference: Wikipedia.org
Optimizing the object model
 Optimizing access paths

Look for attributes that are misplaced in the wrong
objects.

* *
Course Student
courseID : int studentID: int
name: String name: String
age : int
maxSize: int


How to fix the diagram above?
Optimizing the object model
 Collapsing objects: turning objects into attributes
Object design model before transformation

Person ID
number:String

Object design model after transformation

Person
ID:String
Optimizing the object model
 Delaying expensive computations
 Caching the result of computations

Reference: Wikipedia.org
Mapping association to collections
 Unidirectional one-to-one associations

1 1
class A class B

Class A { Class B {
B partner; // …
// … }
}
Object design model before transformation
1 1
Advertiser Account

Source code after transformation

public class Advertiser {


private Account account;

public Advertiser() {
account = new Account();
}

public Account getAccount() {


return account;
}
...
}
Mapping association to collections
 Bi-directional one-to-one associations

1 1
class A class B

Class A { Class B {
B partner; A partner;
// … // …
} }
Object design model before transformation
1 1
Advertiser Account

Source code after transformation


public class Advertiser { public class Account {

private Account account; private Advertiser owner;

public Advertiser() { public Account(Advertiser owner) {


account = new Account(this); this.owner = owner;
} }

public Account getAccount() { public Advertiser getOwner() {


return account; return owner;
} }
} }
Mapping association to collections
 One-to-many associations

Use of HashSet / TreeSet in java.util package

1 *
class A class B

Class A { Class B {
HashSet bs; // …
// … }
}
Object design model before transformation (uni-directional)
Advertiser 1 * Account

public class Advertiser { public class Account {


private Set accounts; …
}
public Advertiser() {
accounts = new HashSet();
}

public void addAccount(Account a) {


accounts.add(a);
}

public void removeAccount(Account a) {


accounts.remove(a);
}
}
java.util.Set
- add(element)
- remove(element)
Object design model before transformation (bi-directional, incomplete)
1 *
Advertiser Account

public class Advertiser { public class Account {


private Set accounts; private Advertiser owner;

public Advertiser() { public void setOwner(Advertiser newOwner){


accounts = new HashSet(); owner = newOwner;
} }
}
public void addAccount(Account a) {
accounts.add(a);
a.setOwner(this);
}

public void removeAccount(Account a) {


accounts.remove(a);
a.setOwner(null);
}
}
Object design model before transformation (bi-directional)
1 *
Advertiser Account

public class Advertiser { public class Account {


private Set accounts; private Advertiser owner;

public Advertiser() { public void setOwner(Advertiser newOwner){


accounts = new HashSet(); if (owner != newOwner) {
} Advertiser oldOwner = owner;
owner = newOwner;
public void addAccount(Account a) { if (newOwner != null)
accounts.add(a);
a.setOwner(this); newOwner.addAccount(this);
} if (oldOwner != null)

public void removeAccount(Account a) { oldOwner.removeAccount(this);


accounts.remove(a); }
a.setOwner(null); }
} }
}
 Retrieve account objects belonging to an advertisers

Iterator myIterator = accounts.iterator( ) ;

while (iterator.hasNext( ))
{
Account = (Account)iterator.next();
...
}
Mapping association to collections
 Many-to-many associations

Using List (ArrayList, LinkedList and Vector) provided by the
java.util package

* *
class A class B

Class A { Class B {
List bList; List aList;
// … // …
} }
Object design model before transformation
* *
Tournament Player

public class Tournament { public class Player {

private List players; private List tournaments;

public Tournament() { public Player() {


players = new ArrayList(); tournaments = new ArrayList();
} }

public void addPlayer(Player p) { public void addTournament(Tournament t) {


if (!players.contains(p)) { if (!tournaments.contains(t)) {
players.add(p); tournaments.add(t);
p.addTournament(this); t.addPlayer(this);
} }
} }
} }
java.util.List
- add(element)
- remove(element)
- contains(element)
Mapping association to collections
 Qualified associations

Using Map in java.util package

Object design model before transformation


* *
Game Player

Object design model before forward engineering


* 0..1
Game nickName Player
Object design model before forward engineering
* 0..1
Game nickName Player

public class Game {


private Map players;
public void addPlayer (String nickName, Player p) {
if (!players.containsKey( nickName )) {
players.put(nickName, p);
p.addGame(nickName, this);
}
}
}
public class Player {
private Map games;
public void addGame (String nickName, Game g) {
if (!games.containsKey( g )) {
games.put(g, nickName);
g.addPlayer(nickName, this);
java.util.Map }
- containsKey(key) }
- put(key, value) }
Mapping contracts to exceptions
 Defining an exception class

public class KnownPlayerException extends Exception {

public KnownPlayerException ( ) {
super( “Attempted to add a player already found in a
tournament” );
}

public KnownPlayerException ( Player p, Tournament t) {


super( “Attempted to add player : ” + p.name +
“ again in tournament : ” + t.name );
}

}
Mapping contracts to exceptions
 Throwing an exception


Declaration

public void addPlayer (Player p) throws KnownPlayerException {


. . .
}


Raise the exception
throw new KnownPlayerException (p, tournament);
Mapping contracts to exceptions
 Catching an exception

Try-catch block
try {
...
control.addPlayer( p );
...
} catch (KnownPlayerException e) {
ErrorConsole.log( e.getMessage( ) );
}


When exception occurs in try block, the
program will flow to the catch block directly.
public class TournamentControl {
private Tournament ;
public void addPlayer(Player p) throws KnownPlayerException {
if (tournament.isPlayerAccepted(p)) {
throw new KnownPlayerException(p, tournament);
}
//... Normal addPlayer behavior
}
}

public class TournamentForm {


private TournamentControl control;
private ArrayList players;
public void processPlayerApplications() {
// Go through all the players who applied for this tournament
for (Iterator iter = players.iterator(); iter.hasNext(); ) {
try {
Player p = (Player) iter.next( );
control.addPlayer( p );
} catch (KnownPlayerException e) {
// If an exception was caught, log it to the console, and
// proceed to the next player.
ErrorConsole.log(e.getMessage());
}
}
}
}
Mapping contracts to assertions
 An alternative to try-catch approach
 Example

assert user.getAge( ) >= 0;

assert user.getAge( ) >= 0:


“Age is invalid: ” + user.getAge();
Mapping object models to persistent storage schema
 Mapping classes and attributes

Map each class to a relational table

Attribute of class becomes a column on the table

User
+firstName:String
+login:String
+email:String

User table

firstName:text[25] login:text[8] email:text[32]


 Concept of primary key

Primary key
User table

firstName login email

alice am384 [email protected]

john js289 [email protected]

bob bd [email protected]

Candidate key Candidate key


 Concept of foreign key

Game table

ID Name Status Owner

tictactoe_001 Tic Tac Toe active am384

chichess_013 Chinese Chess active am384

tictactoe_182 Tic Tac Toe inactive js289

Foreign key
referencing
User table
(login field)
Mapping object models to persistent storage schema

 Mapping associations

Mapping 1-to-1 or 1-to-many associations with buried
association
1 *
GameOwner Game

GameOwner table Game table

login ... ID ... Owner


am384 Chess_001 am384

js289 Race_010 am384


Mapping object models to persistent storage schema

 Mapping associations

Mapping many-to-many associations with new
association table

* *
Tournament Player

Tournament table TournamentPlayerAssociation table Player table

id name ... tournament player login ...

23 novice 23 alice alice

24 expert 23 john john


Mapping object models to persistent storage schema

 Mapping inheritance relationships


Vertical mapping
• One table for each superclass and subclass


Horizontal mapping
• One table for every concrete class
 Vertical mapping
User

id
name

GameOwner Player

maxNumGames credits

User table

id name role

56 Zoe GameOwner

79 John Player

GameOwner table Player table


id maxNumGames id credits

56 12 79 126
 Horizontal mapping

User

id
name

GameOwner Player

maxNumGames credits

GameOwner table Player table


id name maxNumGames id name credits

56 Zoe 12 79 John 126


Testing
Testing
 Testing concepts

Faults, erroneous states and failures

Test cases
• Test case name (derive from use case name)
• Name/location of the program being tested
• Location of test scripts
• Test objective
• Input test data
• Pass/fail criteria
• Test procedure
Testing
 Testing concepts

Test stubs and drivers

calls (drives) calls

Test Driver Component being tested Test stub

calls (drives) calls

Match Tournament Advertiser


(Test driver) (Test stub)
Testing
 Type of testing activities

Inspection

Usability testing
• User friendly
• FURPS+
• Learnability, throughput, robustness

Unit testing
• Blackbox test, whitebox test
Testing
 Type of testing activities (con’t)

Equivalence testing / partitioning
• Minimize number of required test cases by dividing
the input data into a number of different classes
(categories)

Boundary testing

Path testing
• Need to cover all branches in a component at least
once
Testing
 Type of testing activities

State-based testing
• The test inputs need to cover all states and state-transitions
(which caused by a stimulus, operation or signal)

3.pressButtonsLAndR
1.
2. 6.
pressButtonL pressButtonL
pressButtonR MeasureTime pressButtonR
SetTime

4.after 2 min.

5.pressButtonsLAndR/beep

7.after 20 years 8.after 20 years


DeadBattery
Testing
 Type of testing activities

Polymorphism testing

Application NetworkConnection NetworkInterface


send() open()
receive() close()
setNetworkInterface() send()
receive()
LocationManager

Ethernet WaveLAN UMTS


open() open() open()
close() close() close()
send() send() send()
receive() receive() receive()
Testing
 Integration testing

Big bang testing

Bottom-up testing
• Need test driver to simulate the upper components

Top-down testing
• Need test stub to simulate the lower components

Sandwich testing / Mixed testing
Layer 1
User Interface (A)

Layer 2

Billing (B) Event Service (C) Learning (D)

Layer 3

Database (E) Network (F) Neural Network (G)

Top-Down: A, (A,B), (A,C), (A, D), (A,B,E,F), (A,D,G), (A,B,C,D,E,F,G)

Bottom-Up: E, F, G, (B,E,F), C, (D,G), (A,B,C,D,E,F,G)

Sandwich: A, E, F, G, (A,B,C,D), (D,G), (B,E,F), (A,B,C,D,E,F,G)


Using ArgoUML to draw statechart diagram with internal transitions
End of Tutorial

You might also like