IMPLEMENTATION Software Engineering Roadmap Chapter 7 Focus Identify

  • Slides: 61
Download presentation
IMPLEMENTATION

IMPLEMENTATION

Software Engineering Roadmap: Chapter 7 Focus Identify corporate practices Plan project Implement in parts

Software Engineering Roadmap: Chapter 7 Focus Identify corporate practices Plan project Implement in parts - use detailed designs - apply coding standards - created “implementation model” (USDP) Analyze requirements Maintain Integrate & test system Design Implement Test units Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

Introduction to implementation Focus is on good programming principles and guidelines.

Introduction to implementation Focus is on good programming principles and guidelines.

Road. Map for Unit Implementation 1. Define coding standards Architecture For each. . .

Road. Map for Unit Implementation 1. Define coding standards Architecture For each. . . framework package. . . application package: Requirements For each class: 2. Implement methods Detailed design 5. Release for integration -- see Ch. 9 - pseudocode? - flowcharts? 3. Inspect class 4. Perform unit testing & debugging -- see Ch. 8 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

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 review; compiling & repairing syntax defects; unit testing & repairing defects found in testing (debugging) 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 Prepare for Implementation – 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 Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

Using Reverse Engineering for Very Detailed Design SRS Commented source code SDD Architecture 1

Using Reverse Engineering for Very Detailed Design SRS Commented source code SDD Architecture 1 2 Detailed design Class hierarchy; method lists; pseudocode 3 reverse engineering Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

Unified Process Inception Elaboration Prelim. Iter. iterations #1 Requirements Analysis Design Implementation Test Jacobson

Unified Process Inception Elaboration Prelim. Iter. iterations #1 Requirements Analysis Design Implementation Test Jacobson et al: USDP Construction Iter. #n #n+1 …. . Iter. #m Transition Iter. …. . #m+1 Iter. #k

Implement Code 1/2 1. Plan the structure and residual design for your code (complete

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 See the code inspection checklist (in section 6) for details commonly required for method & class construction. – apply required standards – code in a manner that is easiest to verify • use formal methods (assertions of invariances) if appropriate 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

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 and debug – 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 EXISING CODE FIRST – Use

General Principles in Programming Practice 1. TRY TO RE-USE EXISING CODE FIRST – Use existing GUI components, Java. Beans 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

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

“Think Globally, Program Locally” Make all members. . . • … as local as possible • … as invisible as possible · Make attributes private: · Access them through more public accessor functions if required · Include examples in code/doc · List methods alphabetically Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

Exceptions 1 (Hortsmann) • Catch only those exceptions that you know how to handle

Exceptions 1 (Hortsmann) • Catch only those exceptions that you know how to handle – or handle part & throw – outer scope can do so, e. g. , … my. Method(…) throws XYZException {. . . called. Function(); // throws XYZException … } • Be reasonable about what exceptions callers can handle After Horstmann

Exceptions 2 (Hortsmann) • Don’t substitute the use of exceptions for issues that should

Exceptions 2 (Hortsmann) • Don’t substitute the use of exceptions for issues 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

3. Programming standards

3. Programming standards

Names 1 • Use concatenated words – e. g. , cylinder. Length • Begin

Names 1 • Use concatenated words – e. g. , cylinder. Length • 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.

 • Mark attributes of a class with an underscore – as in _time.

• Mark attributes of a class with an underscore – as in _time. Of. Day Names 2 – 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 get. Name(), set. Name(), is. Box() • latter returns boolean • additional getters and setters of collections – e. g. , insert. Into. Name(), remove. From. Name(). Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

 • Consider preceding with standard letters or combinations of letters – e. g.

• Consider preceding with standard letters or combinations of letters – e. g. , C…. . for classes Names, ctd. • 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 a. Length 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 •

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

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

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

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

Constants instead of. . . protected static final MAX_CHARS_IN_NAME; consider using. . . protected final static int get. Max. Chars. In. Name() { return 20; } Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

Exercise • Within your groups list some basic coding standards / conventions that you

Exercise • Within your groups list some basic coding standards / conventions that you will adhere to. • Consider: • 1: – Document code as you write it – Avoid long methods – keep short for testing, understanding – Keep comments concise – No temp variables – all vars should have good names

2: – Ensure understanding of requirements – if not from written req. then ask

2: – Ensure understanding of requirements – if not from written req. then ask someone (be certain) – Use packages for group based relative cohesion – Test new code ASAP before moving on • 3: – Write java docs (summary of functonality, vars passed in, passed back) before writing code – Define classes and basic skeleton (method stubs) – Run through logic on paper (write / draw is think) – Implement simplest code first

RR: – Give an example along with comments – Use variable naming conventions “_”

RR: – Give an example along with comments – Use variable naming conventions “_” for global vars – Put rep of type in variable • “C’’ - class • “p” - pointer – Debugging – if in doubt, print it out

Exercise • Within your groups list some basic coding standards / conventions that you

Exercise • Within your groups list some basic coding standards / conventions that you will adhere to. • Consider: – Use standard naming conventions “activate. Robot”, “_length”, “alength” – Using switch statements rather than if-then-else chain – Value should not be hardcode – get/setters for accessible variables instead of public variables – Comments should reflect design which in turn reflects requirements

Exercise • Within your groups list some basic coding standards / conventions that you

Exercise • Within your groups list some basic coding standards / conventions that you will adhere to. • Consider: – Naming – classes, attributes, data structures, constants, methods – Default values and initialization – Calling sequences – Error / Exception handling – Comments – minimum requirements – Code structure – use of indentation, braces{ } – Use of white space for readability – Placing instance variables at the top or bottom of classes – Explicit parameter passing (no wild cards *)

Initializing Attributes should be always be initialized, think of private float _balance = 0;

Initializing 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.

One Solution to Object Initialization 1/3 Use initialization when the value is first accessed.

One Solution to Object Initialization 1/3 Use initialization when the value is first accessed. Supply My. Class with static get. Default. My. Class(). Attributes are declared without initialization, then assigned values the first time they are accessed. In class Customer: Account Customer …. public static Customer get. Default. Customer() // … reasons these values are chosen for the default { return new Customer ( "John", "Doe", 0, 1000, -2000 ); } Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

One Solution to Object Initialization 2/3 In class Account: …. private float balance. I

One Solution to Object Initialization 2/3 In class Account: …. private float balance. I = -10; private Customer customer. I; public Account( …. . )…. public float get. Balance() { return balance. I; } Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

One Solution to Object Initialization 3/3 public Customer get. Customer() // access customer. I

One Solution to Object Initialization 3/3 public Customer get. Customer() // access customer. I { if( customer. I == null ) // never accessed customer. I = // initial value Customer. get. Default. Customer(); return customer. I; // current value } public get. Default. Account() // for users of Account { return new Account( -10, 3, “regular” ); } Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

5. Tools and environments for programming

5. Tools and environments for programming

Inspect Code 1 of 5: Classes Overall C 1. Is its (the class’) name

Inspect Code 1 of 5: Classes Overall C 1. Is its (the class’) name appropriate? – consistent with the requirements and/or the design? – sufficiently specialized / general? C 2. Could it be abstract (to be used only as a base)? C 3. Does its header describe its purpose? C 4. Does its header reference the requirements and/or design element to which it corresponds? C 5. Does it state the package to which it belongs? C 6. Is it as private as it can be? C 7. Should it be final (Java) C 8. Have the documentation standards been applied? – e. g. , Javadoc Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

A 1. Is it (the attribute) necessary? A 2. Could it be static? –

A 1. Is it (the attribute) necessary? A 2. Could it be static? – Does every instance really need its variable? A 3. Should it be final? Inspect Code own 2 of 5 : Attributes – Does its value really change? • Would a “getter” method alone be preferable (see section tbd) A 4. A 5. A 6. A 7. – – Are the naming conventions properly applied? Is it as private as possible? Are the attributes as independent as possible? Is there a comprehensive initialization strategy? at declaration-time? with constructor(s)? using static{}? Mix the above? How? Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

Inspect Code 3 of 5 : Constructors CO 1. Is it (the constructor) necessary?

Inspect Code 3 of 5 : Constructors CO 1. Is it (the constructor) necessary? – Would a factory method be preferable? • More flexible • Extra function call per construction CO 2. Does it leverage existing constructors? (a Java-only capability) CO 3. Does it initialize of all the attributes? CO 4. Is it as private as possible? CO 5. Does it execute the inherited constructor(s) where necessary? Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

MH 1. Is the method appropriately named? – method name consistent with requirements &/or

MH 1. Is the method appropriately named? – method name consistent with requirements &/or design? MH 2. Is it as private as possible? MH 3. Could it be static? Inspect Code 4 of 5 : MH 4. Should it be be final? Method Headers MH 5. Does the header describe method’s purpose? MH 6. Does the method header reference the requirements and/or design section that it satisfies? MH 7. Does it state all necessary invariants? (section tbd) MH 8. Does it state all pre-conditions? MH 9. Does it state all post-conditions? MH 10. Does it apply documentation standards? MH 11. Are the parameter types restricted? (see section tbd) Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

MB 1. Is the algorithm consistent with the detailed design pseudocode and/or flowchart? MB

MB 1. Is the algorithm consistent with the detailed design pseudocode and/or flowchart? MB 2. Does the code assume no more than the stated preconditions? Inspect Code 5 of 5 : MB 3. Does the code produce every Method Bodies one of the postconditions? MB 4. Does the code respect the required invariant? MB 5. Does every loop terminate? MB 6. Are required notational standards observed? MB 7. Has every line been thoroughly checked? MB 8. Are all braces balanced? MB 9. Are illegal parameters considered? (see section tbd) MB 10. Does the code return the correct type? MB 11. Is the code thoroughly commented? Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

Defect severity classification using triage Severity Description Major Requirement(s) not satisfied Medium Neither major

Defect severity classification using triage Severity Description Major Requirement(s) not satisfied Medium Neither major nor trivial Trivial A defect which will not affect operation or maintenance Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

Original adjust. Char() Source Code 1 of 3 /** * Requirement 3. 2. P.

Original adjust. Char() Source Code 1 of 3 /** * Requirement 3. 2. P. 3. 1 Configurability of the player character quality values */ public synchronized void adjust. Quality ( String quality. P, float quality. Value. P ) { float original. Sum. M = sum. Of. Qualities(); // must remain invariant Pseudocode not followed; severity medium; type data try { //pc IF quality. P is not recognized, //pc Log error to log file & inform user qualities unchanged // Will need current value of quality. P float original. Value. Ofa. Quality. PM = qual. Value. P[ index. Of( quality. P )]; Defect as above //pc IF quality. Value. P out of bounds //pc Log error to log file & inform user qualities unchanged. . . . //pc ELSE //pc Set the stated quality to quality. Value. P set. Quality( quality. P, quality. Value. P ); 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 by change. Division zero

// Compute factor by which rest of the qualities must by change. Division zero possible; // Example: if the original values were 1, 3, severity 5 (i. e. summajor; 9), andtype the first // is changed to 2, then 3 and 5 change fromcomputational (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 "new. Proportion" float new. Proportion. M = adjust. Char() 2 of 3 ( original. Sum. M - quality. Value. P ) / ( original. Sum. M - original. Value. Of. Quality. PM ); Spelling error; severity Reduce the remaining qualities, retaining their mutual proportion, trivial; type documentation //pc making the sum of qualities unchanged for( int i = 0; i < quality. Type. S. length; ++i ) if( !quality. Type. S[i]. equals( quality. P ) ) // omit a. Quality qual. Value. S[i] = qual. Value. S[i]*new. Proportion. M; //pc Set each quality whose value is less than tolerance to zero for( int i = 0; i < quality. Type. S. length; ++i ) Unclear documentation; severity medium; if( qual. Value. I[i] < get. Tolerance() ) type documentation; source detailed design set. Quality(quality. Type. S[i], (float)0. 0 ); Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

adjust. Char() 3 of 3 //pc Restore the original sum, retaining the mutual proportion

adjust. Char() 3 of 3 //pc Restore the original sum, retaining the mutual proportion of all of //pc the nonzero qualities Division by zero possible; // For example, if the computed values are 5, 0. 4, 3, 6 (sum 14. 4) severity major; type // and this is changed to 5, 0, 3, 6 , then the ultimate values computational // will be 5*(14. 4/14), 0, 3*(14. 4/14), 6*(14. 4/14). new. Proportion = original. Sum / sum. Of. Qualities(); for( int j = 0; j < _quality. Type. length; ++j ) _qual. Value[j] = _qual. Value[j]*new. Proportion; } catch( Exception e ) { System. out. println ( "adjust. Quality() in Encounter. Character has bad parameter" ); } } Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

 • Source code • Personal defect log Personal Software Documentation • defects types

• Source code • Personal defect log Personal Software Documentation • 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 log time spent on additional detailed design, coding, compiling, & testing • Engineering notebook includes status of additional detailed design (if applicable) and code, incidents, noteworthy development issues Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

Case Study

Case Study

Encounter Implementation Model Design model Role. Playing. Game Framework. RPG. Implementation model Role. Playing.

Encounter Implementation Model Design model Role. Playing. Game Framework. RPG. Implementation model Role. Playing. Game «file» RPGame. java RPGame . . . «file» RPGame. class

Encounter Models Design model Framework. RPG. Implementation model Role. Playing. Game «file» RPGame. java

Encounter Models Design model Framework. RPG. Implementation model Role. Playing. Game «file» RPGame. java «file» RPGame. class RPGEvent «file» RPGEvent. java «file» RPGEvent. class Game. State «file» RPGame. java «file» RPGame. class «file» RP…. . java «file» RP…. . class RPGame RPGMouse. Event. Listener Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

Date Number Type Phase Injected Phase Removed 6/14/99 142 Interface Personal detailed design Personal

Date Number Type Phase Injected Phase Removed 6/14/99 142 Interface Personal detailed design Personal code review Repair Time (minutes) 10 Description: omitted checks on name length in Encounter. Character. 6/16/99 143 Documentation Code Personal code review 4 Description: incorrect Javadoc description of Encounter. Character. . . Time. . Recording (Humphrey). . Log. . . . .

Date Start Stop Interruptns. Time taken Phase Comments 6/99 10: 04 am 10: 25

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 This data is stored in Time_Recording_Log 7/99 . .

package Encounter. Characters; /* Class Name : Encounter. Character * Date : 01/13/2000 *

package Encounter. Characters; /* Class Name : Encounter. Character * Date : 01/13/2000 * Copyright Notice : copyright (c) 1999 -2000 by Eric J. Braude */ import java. awt. *; import java. io. *; import Framework. RPG. Characters. *; import Test. Utilities. *; /** Base class for the characters of the Encounter game. SDD reference: 6. 2. 1 * <p> Invariants: The values of qual. Value. I[] are >= 0 * @author Eric Braude, Tom Van. Court * @version 0. 2 */ public class Encounter. Character extends Game. Character { /** Total quality points at initialization. */ private static final float QUAL_TOTAL_INIT = 100. 0 f; Listing page 1 of 13 Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

// Symbols used when other classes refer to specific qualities. /** Symbol for one

// 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"; Listing page 2 of 13 /** 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[] quality. Type. S = { 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.

/* INSTANCE VARIABLES */ /** Values of the qualities <p> Requirement 3. 2. EC. 1. 2 */ private float[] qual. Value. I = new float[ quality. Type. S. 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 image. File. Name. I = null; /* CONSTRUCTORS */ /** Allocate initial total quality points equally among the qualities. * <p> Requirement: 3. 2. EC. 1. 2 (quality value initialization) */ protected Encounter. Character() { super(); for( int i = 0; i < quality. Type. S. length; ++i ) qual. Value. I[i] = QUAL_TOTAL_INIT / quality. Type. S. length; } Listing page 3 of 13 Adapted 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>

/** Construct a new character using the given name and image file. * <p> Requirement: 3. 2. EC. 1. 1 (character naming) * @param name. P Printable name for the character. * @param image. File. P Filename, relative to document base, for character image. */ protected Encounter. Character( String name. P, String image. File. P ) { this(); set. Name( name. P ); image. File. Name. I = image. File. P; } /** Construct a new character using the given name. * <p> Requirement: 3. 2. EC. 1. 1 (character naming) * @param name. P Printable name for the character. */ protected Encounter. Character( String name. P ) { this( name. P, 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

/* METHODS */ /** Requirement 3. 2. EC. 3. 2: "Configurability of Encounter character quality values. " * Synchronization holds quality. Value. I constant even with other threads running. * <p> SDD reference: 6. 1. 2. 1. 1 * <p> Invariants: see the class invariants “//pc” references the pseudocode * <p> Preconditions: quality. P is in quality. Types. S[] * AND quality. Value. P >= 0 * AND quality. Value. P <= the sum of the quality values * <p> Postconditions: quality. P has the value quality. Value. P * AND the remaining quality values are in the same proportion as prior to invocation, * except that values less than some tolerance are zero. * @param quality. P Quality whose value is to be adjusted. * @param quality. Value. P The value to set this quality to. */ public synchronized void adjust. Quality( String quality. P, float quality. Value. P ) { // Value of the quality to be changed float quality. Value. M = qual. Value. I[ index. Of( quality. P ) ]; // Save the sum of the values float original. Sum. M = sum. Of. Qualities(); Listing page 5 of 13 //pc Set the stated quality to the desired amount, adjusted to the threshold value. set. Quality( quality. P, quality. Value. P ); 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

// pc If the caller adjusts the only non-zero quality value, // divide the adjustment amount equally among all other qualities. if( original. Sum. M == quality. Value. M ) { float quality. Diff. Each = (original. Sum. M - quality. Value. P) / (quality. Type. S. length - 1) ; for( int i = 0; i < quality. Type. S. length; ++i ) if( !quality. Type. S[i]. equals. Ignore. Case( quality. P ) ) set. Quality( quality. Type. S[i], quality. Diff. Each ); } else { /* Compute factor ("proportion. M") 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 proportion. M = (original. Sum. M - quality. Value. P) / (original. Sum. M quality. Value. M); //pc Adjust the remaining qualities, retaining their mutual proportion for( int i = 0; i < quality. Type. S. length; ++i ) if( !quality. Type. S[i]. equals. Ignore. Case( quality. P ) ) set. Quality( quality. Type. S[i], qual. Value. I[i] * proportion. M ); } } Listing page 6 of 13 Adapted 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

/** Get a copy of the list of names of quality values. * @return working copies of name strings representing qualities. */ public static String[] get. Quality. Types() { String [] return. List. M = new String[ quality. Type. S. length ]; // Copy the string array. for( int i = 0; i < quality. Type. S. length; i++ ) return. List. M[i] = new String( quality. Type. S[i] ); return. List. M; // Copy each string. // Return the copy. } /** Returns the value of the specified quality. * <p>Precondition: quality. P is a valid member of quality. Type. S[] * @param quality. P The quality we want the value for. * @return The value of the specified quality. */ public float get. Quality. Value( String quality. P ) { return qual. Value. I[ index. Of( quality. P ) ]; } 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

/** 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 get. Tolerance() { return 0. 5 f; } 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 specified quality. * <p> Precondition: quality. P is

/** Returns the index of the specified quality. * <p> Precondition: quality. P is in quality. Type. S[], give or take capitalization. * @param quality. P The quality we are searching for. * @return The quality index. */ private static int index. Of( String quality. P ) { int return. Index. M = -1; // Default to "missing" value. for( int i = 0; i < quality. Type. S. length; ++i ) // Search quality name table. if( quality. Type. S[ i ]. equals. Ignore. Case( quality. P ) ) // Quality name match? { return. Index. M = i; // Note the index value. break; } return. Index. M; } /** 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 max. Num. Chars. In. Name() Adapted from Softwareint Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission. Listing page 9 of 13

/** Set a quality value without regard to the values of other qualities. *

/** 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 quality. Value. I while other threads are using it. * <p>Requirements: 3. 2. EC. 2 (lower limit on non-zero quality values), * <p>Precondition: quality. P is a valid member of quality. Type. S[] * <p>Postcondition: Quality values are greater than tolerance or are 0. * * @param quality. P The quality to set the value of. * @param value. P The value to set the quality to. */ public synchronized void set. Quality( String quality. P, float value. P ) { if( value. P < get. Tolerance() ) qual. Value. I[ index. Of( quality. P ) ] = 0. 0 f; else qual. Value. I[ index. Of( quality. P ) ] = value. P; } 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 (character displayed in game Area), *

/** Display the character * <p>Requirements: 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 comp. P UI component in which to draw the character * @param draw. P Graphics context for doing the drawing. * @param pos. P Pixel coordinates within comp. P for the center of the image. * @param height. Pix. P Desired image height, in pixels. * @param face. Left. P <tt>true</tt> if character faces left, <tt>false if faces right. */ public void show. Character(Component comp. P, Graphics draw. P, Point pos. P, int height. Pix. P, boolean face. Left. P) { if( image. File. Name. I == null) { // No image file name. Print the character name instead. draw. P. set. Color(Color. magenta); // Normally a visible color. Font. Metrics fm = draw. P. get. Font. Metrics(); draw. P. draw. String( get. Name(), // Print the name, centered pos. P. x - fm. string. Width( get. Name() ) / 2, // at the character location. pos. P. y - fm. get. Height() / 2 ); } Listing page 11 of 13 Adapted 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 ch. Image

else { // File name was provided. Draw the image file. Image ch. Image = comp. P. get. Toolkit(). get. Image( image. File. Name. I ); int image. Width = ch. Image. get. Width( comp. P ); // Raw size of the image. int image. Height = ch. Image. get. Height( comp. P ); int scaled. Width = image. Width * height. Pix. P / image. Height; // Scale width same as height. // Assume that the normal image faces left. Decide whether to reverse the image. if( face. Left. P ) draw. P. draw. Image( ch. Image, // Draw the image as given, pos. P. x - scaled. Width/2, pos. P. y - height. Pix. P/2, // scaled and centered. pos. P. x + scaled. Width/2, pos. P. y + height. Pix. P/2, 0, 0, image. Width-1, image. Height-1, comp. P ); else draw. P. draw. Image( ch. Image, // Draw the image reversed, pos. P. x + scaled. Width/2, pos. P. y - height. Pix. P/2, // scaled and centered. pos. P. x - scaled. Width/2, pos. P. y + height. Pix. P/2, 0, 0, image. Width-1, image. Height-1, comp. P ); } } // End of show. Character. Listing page 12 of 13 Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.

/** Computes the sum of the quality values. * Synchronization makes sure that another

/** Computes the sum of the quality values. * Synchronization makes sure that another thread won't change quality. Value. I * 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 sum. Of. Qualities() { float sum. M = 0. 0 f; for( int i = 0; i < quality. Type. S. length; ++i ) sum. M += qual. Value. I[i]; return sum. M; } } // end of Encounter. Character Listing page 13 of 13 Adapted from Software Engineering: An Object-Oriented Perspective by Eric J. Braude (Wiley 2001), with permission.