7. UNIT IMPLEMENTATION. Plan project Integrate & test system Analyze requirements Design Maintain...
-
Upload
isaac-sims -
Category
Documents
-
view
217 -
download
1
Transcript of 7. UNIT IMPLEMENTATION. Plan project Integrate & test system Analyze requirements Design Maintain...
7. UNIT IMPLEMENTATION
Plan project
Integrate & test system
Analyze requirements
Design
Maintain
Test unitsImplement
Software Engineering Roadmap: Chapter 7 Focus
Identify corporate practices
Implement in parts - use detailed designs - apply coding standards - created “implementation model” (USDP)
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
“Implementation” Learning Goals
Be able to ...
• … specify standards
• ... select coding style
• … code with correctness justification
• … identify quality goals
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission. Graphics reproduced with permission from Corel.
1. Introduction to implementation
RoadMap for Unit Implementation
Detailed design- pseudocode?
- flowcharts?
For each (1)... framework package (2) ...application package ...
For each class ...
Requirements
2. Implement method-- see section SSS
1. Identify coding standards
RoadMap for Unit Implementation
Detailed design- pseudocode?
- flowcharts?
For each ... framework package ...application package:
Architecture
For each class:Requirements
2. Implement methods-- see section tbd
5. Releasefor inte-gration-- see chpt. 9
1. Define coding standards
4. Perform unit testing-- see chpt. 8
3. Inspect class-- see section tbd
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
1. Confirm the detailed designs you must implement– code only from a written design (part of the SDD)
2. Prepare to measure time spent, classified by:– residual detailed design; detailed design review; coding;
coding review; compiling & repairing syntax defects; unit testing (see chapter 7) & repairing defects found in testing
3. Prepare to record defects using a form– default: major (requ. unsatisfied), trivial, or neither – default: error, naming, environment, system, data, other
4. Understand required standards– for coding– for the personal documentation you must keep
• see the case study for an example
5. Estimate size and time based on your past data
6. Plan the work in segments of ± 100 LOC
Prepare forImplementation
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Using Reverse Engineering for Very Detailed Design
Architecture
Detailed design
SRS SDDCommented
sourcecode
Class hierarchy;method lists;pseudo-code
3reverseengi-
neering
21
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Unified Process
Inception Elaboration Construction Transition
Requirements
Analysis
Design
Implemen-tation
Test
Jacobson et al: USDP
Prelim.iterations
Iter.#1
Iter.#n
Iter.#n+1
Iter.#m
Iter.#m+1
Iter.#k
….. …..
USDP Implementation Model Constituents
Implementation subsystem
«file»
Area.java
Implementation modelDesign model
Area
«trace»
File Area.java implementsthe design class Area (there is a trace between them)
AnotherClass
Implementation component
USDP Implementation Model Constituents
Implementation subsystem
Implementation modelDesign model
«trace»
Same nominal interfaceprovided by design class and implementation component
«file»
Area.class
«compilation»
AnotherClass
«file»
readme.txt
«explain»
«file»
impl.jar«compress»
«file»
Area.java
Area
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
USDP Subsystem Interfaces
Implementation subsystemDenotes interfaceto the subsystem
USDP Subsystem Interfaces
Implementation subsystem
«file»
EncounterCast.java
Denotes interfaceto the subsystem
Denotes interfaceto the class
Indicates that EncounterCasthandles the package’s inteface
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Implement Code 1/2
1. Plan the structure and residual design for your code(complete missing detailed design, if any)
– note pre- and post-conditions
– note the time spent
2. Self-inspect your design and/or structure– note time spent, defect type, source (phase), severity
3. Type your code– do not compile yet
– try methods listed below
– apply required standards
– code in a manner that is easiest to verify• use formal methods if appropriate
See the code inspection checklist (figure tbd in section 6) for details commonly required for method & class construction.
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Implement Code 2/2
4. Self-inspect your code -- do not compile yet
– convince yourself that your code does the required job
• the compiler will never do this for you: it merely checks syntax!
– note time spent, defects found, type, source, severity
5. Compile your code
– repair syntax defects
– note time spent, defect type, source, severity , and LOC.
6. Test your code
– apply unit test methods in chapter 7
– note time spent, defects found, type, source, severity
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
General Principles in Programming Practice
1. TRY TO RE-USE FIRST
2. ENFORCE INTENTIONS
If your code is intended to be used in
particular ways only, write it so that the code
cannot be used in any other way.
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Applications of “Enforce Intentions”
• If a member is not intended to be used
by other functions, enforce this by
making it private or protected etc.
• Use qualifiers such as final and
abstract etc. to enforce intentions
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
“Think Globally, Program Locally”
Make all members ...
• … as local as possible
• … as invisible as possible attributes private: access them through more public accessor
functions if required. (Making attributes protected gives
objects of subclasses access to members of their base classes -- not usually what you want)
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Miscellaneous
• Avoid type inquiry
– e.g. if( x instanceof MyClass )
– virtual function feature instead
• Use Singleton design pattern if there
is to be only one instance of a class
– e.g. theEncounter
After Horstmann
Exceptions 1
• Catch only those exceptions that you know how to handle – or handle part & throw– outer scope can do so, e.g.,… myMethod(…) throws XYZException{ ...
calledFunction(); // throws XYZException …
}
• Be reasonable about exceptions callers must handle
After Horstmann
Exceptions 2 (Hortsmann)
• Don’t substitute the use of exceptions for
issue that should be the subject of testing
– e.g. null parameters (most of the time)
• Consider providing
– a version throwing exceptions, and
– a version which does not (different name)
• accompanied by corresponding test functions.
– e.g., pop empty stack
Exceptions 3 (Hortsmann)
• Don’t substitute the use of exceptions for issue
that should be the subject of testing
– e.g. null parameters (most of the time)
• Consider providing
– a version throwing exceptions, and
– a version which does not (different name)
• accompanied by corresponding test functions.
– e.g., pop empty stack
Implement Error Handling
1. Follow agreed-upon development process; inspect
2. Consider introducing classes to encapsulate legal parameter values – private constructor; factory functions to create
instances– catches many errors at compile-time
3. Where error handling is specified by requirements, implement as required– use exceptions if passing on error handling
responsibility
. . . . .Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Implement Error Handling
1. Follow agreed-upon development process; inspect 2. Consider introducing classes to encapsulate legal
parameter values – private constructor; factory functions to create instances– catches many errors at compile-time
3. Where error handling is specified by requirements, implement as required– use exceptions if passing on error handling responsibility
4. For applications that must never crash, anticipate all possible implementation defects (e.g., use defaults)– only if unknown performance better than none (unusual!)
5. Otherwise, follow a consistent policy for checking parameters– rely mostly on good design and development process
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
3. Programming standards
Names 1
• Use concatenated words
– e.g., cylinderLength
• Begin class names with capitals
• Variable names begin lower case
• Constants with capitals
– as in MAX_NAME_LENGTH
– use static final
– -- but consider method instead
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Names 2
• Data members of classes with an underscore – as in _timeOfDay
– or equivalent
– to distinguish them from other variables • since they are global to their object
• Use get…, set…., and is… for accessor methods
– as in getName(), setName(), isBox() • latter returns boolean
• additional getters and setters of collections– e.g., insertIntoName(), removeFromName().
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Names, ctd.
• Consider preceding with standard letters or combinations of letters – e.g., C….. for classes
• as in CCustomer etc.
– useful when the importance of knowing the types of names exceeds the awkwardness of strange-looking names.
– or place these type descriptors at the end
• And/or distinguish between instance variables, local variables and parameters– _length, length and aLength
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Documenting Methods 1
• what the method does
• why it does so
• what parameters it must be passed (use
@param tag)
• exceptions it throws (use @exception tag)
• reason for choice of visibility
• known bugs
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Documenting Methods 2
• test description, describing whether the method has been tested, and the location of its test script
• history of changes if you are not using a CM system
• example of how the method works
• pre- and postconditions
• special documentation on threaded and synchronized methods
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Attributes
• Description -- what it's used for
• All applicable invariants
– quantitative facts about the attribute,
– such as "1 < _age < 130"
– or " 36 < _length * _width < 193".
See www.ambysoft.com
Constants
Before designating a final variable,
be sure that it is, indeed, final.
You’re going to want to change
"final" quantities in most cases.
Consider using method instead.
See www.ambysoft.com
Constants
instead of ...protected static final MAX_CHARS_IN_NAME;
consider using ...protected final static int getMaxCharsInName()
{ return 20;
}
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Initializing Attributes
Attributes should be always be initialized, think of
private float _balance = 0;
Attribute may be an object of another class, as in
private Customer _customer;
Initializing Attributes
Attributes should be always be initialized, think of
private float _balance = 0;
Attribute may be an object of another class, as in
private Customer _customer;
-- Traditionally done using the constructor, as in
private Customer _customer =
new Customer( "Edward", "Jones" );
Problem is maintainability. When new attributes added
to Customer, all have to be updated. Also accessing
persistent storage unnecessarily.Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Use initialization when the value is first accessed. Supply MyClass with static getDefaultMyClass(). Attributes are declared without initialization, then assigned values the first time they are accessed.
In class Customer:….public static Customer getDefaultCustomer()// … reasons these values are chosen for the default{ return new Customer ( "John", "Doe", 0, 1000, -2000 );}
One Solution to Object Initialization 1/3
Account Customer
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
In class Account:
….
private float balanceI = -10;
private Customer customerI;
public Account( ….. )….
public float getBalance(){ return balanceI;}
One Solution to Object Initialization 2/3
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
public Customer getCustomer() // access customerI {
if( customerI == null ) // never accessed customerI = // initial value Customer.getDefaultCustomer();
return customerI; // current value }
public getDefaultAccount() // for users of Account { return new Account( -10, 3, “regular” );}
One Solution to Object Initialization 3/3
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
4. Provably correct programs
A Simple Correctness Framework
while( the variables don’t have the values required)
perform appropriate actions
/* Need only prove that this loop terminates to ensure that the variables have the values required */
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Invariants as Infrastructures 2. Count on invariant
to performremaining
design.
1. Invariant = infrastructure: “system for
supporting roadway”Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
// Define I: j <= n-1 < 100 & r = max{g[0], g[1], …, g[j]}
// After the following two commands, I is true:
int r = g[0];
int j = 0;
// This block keeps I true
while( j < n-1 )
{ if( g[ j+1 ] > r )
r = g[ j+1 ];
++j;
}
Provably Correct Program to Get Maximum of an
Array of Length n 1/2
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Provably Correct Program for Max of an Array 2/2
/* We have kept I invariant (true). Assuming that the loop terminates, we also know at this point that j < n-1 is no longer true, and so j >=n-1. Putting these together,
• j >=n-1, AND
• j <= n-1 (from statement I) AND
• k = max{ a[0], a[1], …, a[j] } (from statement I)
. . . . .
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
/* Assuming that the loop terminates (proved later), we know at this point that j < n-1 is no longer true. We have also kept I invariant (true). Putting these together,
• j < n-1 is false, AND
• j <= n-1 (from of statement I), AND
• r = max{ g[0], g[1], …, g[j] } (from statement I)
so that j = n-1 AND r = max{ g[0], g[1], …, g[n-1] }
-- which was our goal.
It remains only to prove that the while loop terminates. Because I is kept invariant, the quantity n-j is always positive: in addition, n-j diminishes by 1 on each iteration. The only way this can occur is if the loop terminates. */
Provably Correct Program for Max of
an Array 2/2
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Precondition:
xP and yP are both natural numbers
Post-condition: (restates definition of GCD)
1. gcd( xP, yP ) is a positive integer
2. gcd( xP, yP ) divides xP and yP
3. if z is any natural number dividing
both xP and yP, then z <= gcd( xP, yP )
Requirements for gcd(xP, yP) as Pre- and Postconditions
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
// Let I be the assertion "GCD( xP, yP ) = GCD( x, y )"
// Initialize the variables to make I true:
int x = xP;
int y = yP;
/* The loop below preserves I and results in x == y.
When it terminates (termination proof later):
GCD( xP, yP ) = GCD( x, y ) -- from the invariant
= GCD( x, x ) -- because x == y
= x
Report x as the result and our work will be done. */
Provably Correct Greatest Common Divisor Code for
gcd(xP, yP) 1/2
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
while( !( x == y) )
{ if( x > y )
x = x - y; // preserves I (property of GCD)
else // !( x == y) and !(x > y), thus x < y
y = y - x; // preserves I (same property used)
}
/* The quantity x + y diminishes by at least 1 on every iteration, but remains positive. Thus, the number of iterations must be finite. */
System.out.println( "Greatest common divisor of " +
xP + " and " + yP + " is " + x );
Provably Correct Greatest Common Divisor Code for
gcd(xP, yP) 2/2
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
For Many Applications …..
1. Devise a relationship I among the variables which is easy to establish, and a relationship r so that I AND r together yield the post-condition.
2. Write code that makes I true.3. Follow by code in the form:
while( !r ){ Perform operations that
- keep I invariant and - cause the loop to terminate }
4. Prove that the while loop terminates
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
5. Tools and environments for programming
C1. Is its (the class’) name appropriate? – consistent with the requirements and/or the design?
– sufficiently specialized / general?
C2. Could it be abstract (to be used only as a base)?
C3. Does its header describe its purpose?
C4. Does its header reference the requirements and/or design element to which it corresponds?
C5. Does it state the package to which it belongs?
C6. Is it as private as it can be?
C7. Should it be final (Java)
C8. Have the documentation standards been applied?– e.g., Javadoc
Inspect Code 1 of 5: Classes Overall
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
A1. Is it (the attribute) necessary?A2. Could it be static?
– Does every instance really need its own variable?
A3. Should it be final?– Does its value really change?
• Would a “getter” method alone be preferable (see section tbd)
A4. Are the naming conventions properly applied?A5. Is it as private as possible?A6. Are the attributes as independent as possible?A7. Is there a comprehensive initialization strategy?
– at declaration-time?– with constructor(s)?– using static{}?– Mix the above? How?
Inspect Code 2 of 5 :
Attributes
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
CO1. Is it (the constructor) necessary?
– Would a factory method be preferable?
• More flexible
• Extra function call per construction
CO2. Does it leverage existing constructors?
(a Java-only capability)
CO3. Does it initialize of all the attributes?
CO4. Is it as private as possible?
CO5. Does it execute the inherited constructor(s)
where necessary?
Inspect Code 3 of 5 : Constructors
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
MH1. Is the method appropriately named?– method name consistent with requirements &/or design?
MH2. Is it as private as possible?
MH3. Could it be static?
MH4. Should it be be final?
MH5. Does the header describe method’s purpose?
MH6. Does the method header reference the requirements and/or design section that it satisfies?
MH7. Does it state all necessary invariants? (section tbd)
MH8. Does it state all pre-conditions?
MH9. Does it state all post-conditions?
MH10.Does it apply documentation standards?MH11.Are the parameter types restricted? (see section tbd)
Inspect Code 4 of 5 : Method Headers
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
MB1. Is the algorithm consistent with the detailed design pseudocode and/or flowchart?
MB2. Does the code assume no more than the stated preconditions?
MB3. Does the code produce every one of the postconditions?
MB4. Does the code respect the required invariant?MB5. Does every loop terminate? MB6. Are required notational standards observed? MB7. Has every line been thoroughly checked?MB8. Are all braces balanced? MB9. Are illegal parameters considered? (see section tbd)
MB10. Does the code return the correct type? MB11. Is the code thoroughly commented?
Inspect Code 5 of 5 : Method Bodies
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Cyclotomic Complexity
1 int x = anX;
2 int y = aY;
3 while( !( x == y) ) {
4 if( x > y )
5 x = x - y;
else
6 y = y - x;
7 }
8 ...println( x );
1
2
3
74
5
y
y
6
C = E - N + 1
= 8 - 7 + 1
= 2
**
* : independent loop After Meyer
Severity Description
Major Requirement(s) not satisfied
Medium Neither major nor trivial
Trivial A defect which will not affect operation or maintenance
Defect severity classification using triage
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
/** * Requirement 3.2.P.3.1 Configurability of the player character quality values */public synchronized void adjustQuality
( String qualityP, float qualityValueP ) { float originalSumM = sumOfQualities(); // must remain invariant
try { //pc IF qualityP is not recognized, //pc Log error to log file & inform user qualities unchanged // Will need current value of qualityP float originalValueOfaQualityPM = qualValueP[ indexOf( qualityP )]; //pc IF qualityValueP out of bounds //pc Log error to log file & inform user qualities unchanged . . . . . . . . //pc ELSE //pc Set the stated quality to qualityValueP setQuality( qualityP, qualityValueP );
Original adjustChar() Source Code 1 of 3
Pseudocode not followed; severity medium; type data
Defect as above
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
// Compute factor by which rest of the qualities must change. // Example: if the original values were 1, 3, 5 (i.e. sum 9), and the first // is changed to 2, then 3 and 5 change from (9-1)/9 of the total to (9-2)/9 // of the total, so each should be multiplied by (9-2)/(9-1). We // will name the latter fraction "newProportion" float newProportionM = ( originalSumM - qualityValueP ) / ( originalSumM - originalValueOfQualityPM ); //pc Reduce the remaining qualities, retaining their mutual proportion, //pc making the sum of qualities unchanged for( int i = 0; i < qualityTypeS.length; ++i ) if( !qualityTypeS[i].equals( qualityP ) ) // omit aQuality qualValueS[i] = qualValueS[i]*newProportionM; //pc Set each quality whose value is less than tolerance to zero for( int i = 0; i < qualityTypeS.length; ++i ) if( qualValueI[i] < getTolerance() ) setQuality(qualityTypeS[i], (float)0.0 );
adjustChar() 2 of 3
Spelling error; severity trivial; type documentation
Unclear documentation; severity medium; type documentation; source detailed design
Division by zero possible; severity major; type computational
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
adjustChar() 3 of 3
//pc Restore the original sum, retaining the mutual proportion of all of
//pc the nonzero qualities
// For example, if the computed values are 5, 0.4, 3, 6 (sum14.4)
// and this is changed to 5, 0, 3, 6 , then the ultimate values
// will be 5*(14.4/14), 0, 3*(14.4/14), 6*(14.4/14).
newProportion = originalSum / sumOfQualities();
for( int j = 0; j < _qualityType.length; ++j )
_qualValue[j] = _qualValue[j]*newProportion;
}
catch( Exception e )
{ System.out.println
( "adjustQuality() in EncounterCharacter has bad parameter" );
}
}
Division by zero possible; severity major; type computational
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
• Source code• Personal defect log
• defects types • personal phase during which they were injected • personal phase during which they were removed. The personal phases are
1. Additional detailed design (if applicable)
2. Code (record defects injected and/or detected -- and repaired -- in source code detected before submission to the compiler)
3. Compile (record defects detected and repaired upon attempted compilation)
4. Unit test
Some unit testing could be performed by QA, which would not be part of this documentation
• Time logtime spent on additional detailed design, coding, compiling, & testing
• Engineering notebookincludes status of additional detailed design (if applicable) and code,incidents, noteworthy development issues
Personal Software Documentation
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
7. Summary of the implementation process
“Implementation” Chapter Summary
• Coding goals:1. correct
2. clear
• Apply programming standards
• Prove programs correct before compiling
• Track time spent
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Case Study
Encounter Implementation Model
Implementation modelDesign model
RolePlayingGame RolePlayingGame
FrameworkRPG.
«file» RPGame.java
«file» RPGame.class
RPGame
. . . . .
Encounter Models
Implementation modelDesign model
RolePlayingGame
GameState
RPGEvent
RolePlayingGame
FrameworkRPG.
«file» RPGame.java
«file» RPGame.class
RPGMouseEventListener
RPGame
«file» RPGEvent.java
«file» RPGEvent.class
«file» RPGame.java
«file» RPGame.class
«file» RP…..java
«file» RP…..class
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Date Number Type Phase InjectedPhase Removed
Repair Time (minutes)
6/14/99 142 Interface Personal detailed design
Personal code review
10
Description: omitted checks on name length in EncounterCharacter.
6/16/99 143 Documen-tation
Code Personal code review
4
Description: incorrect Javadoc description of EncounterCharacter.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . .
Time Recording Log (Humphrey)
Date Start Stop Interruptns. Time taken
Phase Comments
6/99 10:04 am
10:25 am
4 + 6 11 Detailed Design
Consulted with V.N.
6/99 1:20 pm
4:34 pm
15 + 20 159 Personal Code review
Defect 14
7/99 . . . .
This data is stored in Time_Recording_Log
package Encounter.EncounterCharacters;/* Class Name : EncounterCharacter * Date : 01/13/2000 * Copyright Notice : copyright (c) 1999-2000 by Eric J. Braude*/import java.awt.*;import java.io.*;import FrameworkRPG.Characters.*;import TestUtilities.*;
/** Base class for the characters of the Encounter game. SDD reference: 6.2.1* <p> Invariants: The values of qualValueI[] are >= 0* @author Eric Braude, Tom VanCourt* @version 0.2*/public class EncounterCharacter extends GameCharacter{/** Total quality points at initialization. */private static final float QUAL_TOTAL_INIT = 100.0f; Listing
page 1 of 13
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Listing page 2 of 13
// Symbols used when other classes refer to specific qualities.
/** Symbol for one of a character’s qualities */public static final String QUAL_CONCENTRATION = "concentration";
/** Symbol for one of a character’s qualities */public static final String QUAL_INTELLIGENCE = "intelligence";
/** Symbol for one of a character’s qualities */public static final String QUAL_PATIENCE = "patience";
/** Symbol for one of a character’s qualities */public static final String QUAL_STAMINA = "stamina";
/** Symbol for one of a character’s qualities */public static final String QUAL_STRENGTH = "strength";
/** Qualities that each Encounter character posesses <p>Req: 3.2.EC.1.2 */private static final String[] qualityTypeS = { QUAL_CONCENTRATION, QUAL_STAMINA,
QUAL_INTELLIGENCE, QUAL_PATIENCE, QUAL_STRENGTH
};
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
/* INSTANCE VARIABLES *//** Values of the qualities <p> Requirement 3.2.EC.1.2 */private float[] qualValueI = new float[ qualityTypeS.length ];
/** Name of the GIF file containing the character's image. * The character in this image is assumed to be facing left. * Select this character's height, relative to heights of other characters, by padding the top* and bottom with transparent pixels. No padding gives the tallest possible character.*/private String imageFileNameI = null;
/* CONSTRUCTORS */
/** Allocate initial total quality points equally among the qualities. * <p> Requirement: 3.2.EC.1.2 (quality value initialization)*/protected EncounterCharacter() { super();
for( int i = 0; i < qualityTypeS.length; ++i ) qualValueI[i] = QUAL_TOTAL_INIT / qualityTypeS.length;
}
Listing page 3 of 13Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
/** Construct a new character using the given name and image file. * <p> Requirement: 3.2.EC.1.1 (character naming)* @param nameP Printable name for the character.* @param imageFileP Filename, relative to document base, for character image.*/protected EncounterCharacter( String nameP, String imageFileP ) { this();
setName( nameP );imageFileNameI = imageFileP;
}
/** Construct a new character using the given name. * <p> Requirement: 3.2.EC.1.1 (character naming)* @param nameP Printable name for the character.*/protected EncounterCharacter( String nameP ) { this( nameP, null );}
Listing page 4 of 13
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
/* METHODS */
/** Requirement 3.2.EC.3.2: "Configurability of Encounter character quality values." * Synchronization holds qualityValueI constant even with other threads running.* <p> SDD reference: 6.1.2.1.1* <p> Invariants: see the class invariants* <p> Preconditions: qualityP is in qualityTypesS[] * AND qualityValueP >= 0 * AND qualityValueP <= the sum of the quality values * <p> Postconditions: qualityP has the value qualityValueP * AND the remaining quality values are in the same proportion as prior to invocation, * except that values less than some tolerance are zero.* @param qualityP Quality whose value is to be adjusted.* @param qualityValueP The value to set this quality to. */public synchronized void adjustQuality( String qualityP, float qualityValueP ) { // Value of the quality to be changed
float qualityValueM = qualValueI[ indexOf( qualityP ) ];
// Save the sum of the valuesfloat originalSumM = sumOfQualities();
//pc Set the stated quality to the desired amount, adjusted to the threshold value.setQuality( qualityP, qualityValueP );
Listing page 5 of 13
“//pc” references the pseudocode
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
// pc If the caller adjusts the only non-zero quality value, // divide the adjustment amount equally among all other qualities.if( originalSumM == qualityValueM ){ float qualityDiffEach = (originalSumM - qualityValueP) / (qualityTypeS.length - 1) ;
for( int i = 0; i < qualityTypeS.length; ++i ) if( !qualityTypeS[i].equalsIgnoreCase( qualityP ) )
setQuality( qualityTypeS[i], qualityDiffEach );} else {
/* Compute factor ("proportionM") by which all other qualities must change. * Example: if the values were 1,3,5 (i.e. sum 9), and the first quality is changed
* from 1 to 2, then “3” and “5” change from 8/9 of the total to 7/9* of the total, so each should be multiplied by 7/8, i.e., by (9-2)/(9-1). */float proportionM = (originalSumM - qualityValueP) / (originalSumM - qualityValueM);
//pc Adjust the remaining qualities, retaining their mutual proportionfor( int i = 0; i < qualityTypeS.length; ++i )
if( !qualityTypeS[i].equalsIgnoreCase( qualityP ) ) setQuality( qualityTypeS[i], qualValueI[i] * proportionM );
}}
Listing page 6 of 13Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
/** Get a copy of the list of names of quality values. * @return working copies of name strings representing qualities. */public static String[] getQualityTypes(){
String [] returnListM = new String[ qualityTypeS.length ]; // Copy the string array.
for( int i = 0; i < qualityTypeS.length; i++ ) // Copy each string. returnListM[i] = new String( qualityTypeS[i] );
return returnListM; // Return the copy. }
/** Returns the value of the specified quality. * <p>Precondition: qualityP is a valid member of qualityTypeS[]* @param qualityP The quality we want the value for.* @return The value of the specified quality. */public float getQualityValue( String qualityP ) {
return qualValueI[ indexOf( qualityP ) ]; } Listing page 7 of 13
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
/** Quality values below this threshold are set to zero to avoid having the game* go on for an indeterminate amount of time. * <p>Requirement: e.g. 3.2.EC.1.2 (lower limit on non-zero quality values)* @return Tolerance value*/static final float getTolerance() { return 0.5f;}
Listing page 8 of 13
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
/** Returns the index of the the specified quality. * <p> Precondition: qualityP is in qualityTypeS[], give or take capitalization.* @param qualityP The quality we are searching for.* @return The quality index.*/private static int indexOf( String qualityP ) { int returnIndexM = -1; // Default to "missing" value.
for( int i = 0; i < qualityTypeS.length; ++i ) // Search quality name table. if( qualityTypeS[ i ].equalsIgnoreCase( qualityP ) ) // Quality name match?
{ returnIndexM = i; // Note the index value. break;
}
return returnIndexM;}
/** Set default maximum allowable number of characters in names of characters.* <p>Requirement: 3.2.EC.1.1 (limit on character name length) * @return Maximum number of characters allowed in a character name*/protected int maxNumCharsInName() { return 15; }
Listing page 9 of 13
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
/** Set a quality value without regard to the values of other qualities.* Truncate any value below the threshold vlue down to zero.* Synchronization prevents changes to qualityValueI while other threads are using it.* <p>Requirements: 3.2.EC.2 (lower limit on non-zero quality values), * <p>Precondition: qualityP is a valid member of qualityTypeS[]* <p>Postcondition: Quality values are greater than tolerance or are 0.** @param qualityP The quality to set the value of.* @param valueP The value to set the quality to. */public synchronized void setQuality( String qualityP, float valueP ) {
if( valueP < getTolerance() )qualValueI[ indexOf( qualityP ) ] = 0.0f;
elsequalValueI[ indexOf( qualityP ) ] = valueP;
}
Listing page 10 of 13
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
/** Display the character* <p>Requirements: 2.1.2.1 (character displayed in game Area),* 3.2.PC.1 (character image seletion),* 3.2.PQ.1 (character image in quality update window)* @param compP UI component in which to draw the character* @param drawP Graphics context for doing the drawing.* @param posP Pixel coordinates within compP for the center of the image.* @param heightPixP Desired image height, in pixels.* @param faceLeftP <tt>true</tt> if character faces left, <tt>false if faces right.*/public void showCharacter(Component compP, Graphics drawP, Point posP,
int heightPixP, boolean faceLeftP) {
if( imageFileNameI == null){ // No image file name. Print the character name instead.
drawP.setColor(Color.magenta); // Normally a visible color. FontMetrics fm = drawP.getFontMetrics();
drawP.drawString( getName(), // Print the name, centeredposP.x - fm.stringWidth( getName() ) / 2, // at the character location.posP.y - fm.getHeight() / 2 );
}
Listing page 11 of 13Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
else { // File name was provided. Draw the image file.Image chImage = compP.getToolkit().getImage( imageFileNameI );int imageWidth = chImage.getWidth( compP ); // Raw size of the image. int imageHeight = chImage.getHeight( compP );int scaledWidth = imageWidth * heightPixP / imageHeight; // Scale width same as height.
// Assume that the normal image faces left. Decide whether to reverse the image.if( faceLeftP )
drawP.drawImage( chImage, // Draw the image as given,posP.x - scaledWidth/2, posP.y - heightPixP/2, // scaled and centered.posP.x + scaledWidth/2, posP.y + heightPixP/2,0, 0, imageWidth-1, imageHeight-1, compP );
elsedrawP.drawImage( chImage, // Draw the image reversed,
posP.x + scaledWidth/2, posP.y - heightPixP/2, // scaled and centered.posP.x - scaledWidth/2, posP.y + heightPixP/2,0, 0, imageWidth-1, imageHeight-1, compP );
}
} // End of showCharacter.
Listing page 12 of 13
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.
Listing page 13 of 13
/** Computes the sum of the quality values. * Synchronization makes sure that another thread won't change qualityValueI * while this thread is part-way through computing the total.*<p> Requirements: 3.2.EC.3.2 (proportions among quality values)* @return The sum of the player's qualities, a value 0 or greater. */public synchronized float sumOfQualities() {
float sumM = 0.0f;
for( int i = 0; i < qualityTypeS.length; ++i ) sumM += qualValueI[i];
return sumM;}
} // end of EncounterCharacter
Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.