CSCE 431 Lecture 12
Jump to navigation
Jump to search
« previous | Tuesday, February 25, 2014 | next »
Converting Models to Implementation
Conditions/Invariants must be checked upon entry into function
- most languages do not support contracts natively:
- usually a couple of
if
-statements at start to check parameters will suffice - Manual transformation from conditions to error detection.
Also possible to extract model from implementation (reverse engineering)
Transformations
Pull Up Field (Extract Base Class)
class Administrator {
private string Email;
}
class Advertiser {
private string Email;
}
class Member {
private string Email;
}
Converts to
class User {
protected string Email;
}
class Administrator extends User {}
class Advertiser extends User {}
class Member extends User {}
Design Optimization
Important part of design (requirements analysis might imply a non-optimal implementation)
Add redundant associations to minimize access cost
- What are most frequent operations?
- How often is a function/operation called?
Keep distributed information in sync
Collapse simple objects into attributes
beforeclass Person {
SocialSecurity ssn;
}
class SocialSecurity {
String number;
} |
afterclass Person {
String ssn;
} |
Associations
Unidirectional 1-1
public class Advertiser {
private Account account;
public Advertiser() {
account = new Account();
}
}
Bidirectional 1-1
public class Advertiser {
private Account account;
public Advertiser() {
account = new Account(this);
}
}
public class Account {
private Advertiser owner;
public Account(Advertiser owner) {
this.owner = owner;
}
}
Bidirectional 1-*
public class Advertiser {
private Set<Account> accounts;
public Advertiser() {
accounts = new HashSet<>();
}
public addAccount(Account a) {
accounts.add(a);
a.setOwner(this);
}
public removeAccount(account a) {
accounts.remove(a);
a.setOwner(null);
}
}
Bidirectional *-*
public class Advertiser {
private Set<Account> accounts;
public Advertiser() {
accounts = new HashSet<>();
}
public addAccount(Account a) {
if (!accounts.contains(a)) {
accounts.add(a);
a.addOwner(this);
}
}
}
public class Account {
private Set<Advertiser> owners;
public Account() {
owners = new HashSet<>();
}
public addOwner(Advertiser a) {
if (!owners.contains(a)) {
owners.add(a);
a.addAccount(a);
}
}
}
Note: The if statement gets around the owning/inverse problem
Bidirectional qualified
Allows "many-to-one" style references (by a unique qualifier/name) in a many-to-many type of relationship
public class League {
private Map players;
public void addPlayer(String nickName, Player p) {
if (!players.containsKey(nickName)) {
players.put(nickName, p);
p.addLeague(nickName, this);
}
}
}
public class Player {
private Map leagues;
public void addLeague(String nickName, League l) {
if (!leagues.containsKey(l)) {
leagues.put(l, nickName);
l.addPlayer(nickName, this);
}
}
}
Model-Driven Engineering
(See wikipedia:Model-Driven Engineering→)
Implementing a Contract
- Check each pre-condition at beginning of method; raise exception if precondition fails
- Check each post-condition at end of method; raise exception if postcondition fails;
- ...
This can slow code down.
- Omit checking code for private and protected methods; Assume that invariants and preconditions will be respected by developers
- Focus on components with longest life.
- Omit checking code for post-conditions and invariants for other components
Entity-Relationship Databases
- class mapped to table
- attribute mapped to column
- instance mapped to row of table.
- 1-1 association mapped to foreign key
- 1-* association mapped to foreign key
- *-* association mapped to join table
- no counterpart for methods