Lecture Outline Principles of Computer Choosing and designing classes Science I UML Understanding side effects Prof. Nadeem Abdul Hamid Pre- and postconditions CSC 120 – Fall 2005 Static methods and fields Lecture Unit 1 - Designing Classes Scope rules Organizing classes using packages 1 2 CSC120 — Berry College — Fall 2005 Choosing Classes Choosing Classes (cont.) Class represents a single concept/abstraction from Actor classes (names end in -er , -or ) the problem domain Objects of these classes do some sort of work for you Name for the class should be a noun Scanner Random (better name: RandomNumberGenerator ) Concepts from mathematics Utility classes Point Rectangle No objects; just contain collection of static methods and constants Eclipse Math Abstractions of real-life entities Program starters BankAccount Contain only a main method CashRegister Actions are not classes: e.g. ComputePaycheck 3 4 Cohesion Coupling Criteria for analyzing quality of a public interface: A class depends on another if it uses objects of that cohesion and coupling class CashRegister depends on Coin (not vice versa) A class should represent a single concept Coupling : the amount of dependence classes have Cohesive: all its features relate to the concept that the class on each other represents Many classes of a program depend on each other: high Non-cohesive example (split into two classes): coupling public class CashRegister { Few dependencies between classes: low coupling public void enterPayment(int dollars, int quarters, int dimes, int nickels, int pennies) Which is better, high or low? . . . public static final double NICKEL_VALUE = 0.05; Hint: think about effect of interface changes public static final double DIME_VALUE = 0.1; public static final double QUARTER_VALUE = 0.25; . . . 5 6 1
UML Diagrams Consistency Another useful criterion for good design ‘Unified Modeling Language’ Follow consistent scheme for class/method Notation for object-oriented analysis and design names and parameters Class diagrams denote dependencies by dashed line with arrow pointing to class that Java standard library contains many is depended on inconsistencies JOptionPane.showInputDialog( prompt ) JOptionPane.showMessageDialog( null, message ) 7 8 Accessor/Mutator Methods Immutable Classes Accessor : does not change the state of the Contains only accessor methods, no mutator methods implicit parameter Example: String double balance = account.getBalance(); String name = "John Q. Public"; String uppercased = name.toUpperCase(); Mutator : modifies the object on which it is // name is not changed invoked Advantage of immutable classes account.deposit(1000); Safe to give out copies of references to objects – object cannot be modified unexpectedly 9 10 Side Effects Output Side Effects public void printBalance() { // Not recommended Side effect : any externally observable System.out.println( "The balance is now $" + balance ); modification of data } Mutator method modifies implicit parameter object Problems: Another kind of side effect: Message in English Depends on System.out public void transfer(double amount, BankAccount other) { balance = balance - amount; other.balance = other.balance + amount; Best to decouple input/output from actual work of // Modifies explicit parameter classes } Updating explicit parameter can be surprising – best to In general, try to minimize side effects beyond avoid modification of implicit parameter Another kind of side effect: output 11 12 2
Common Error: Trying to Modify Modifying Primitive Type Primitive Type Parameter Parameter has no Effect on Caller Scenario (doesn’t work): double savingsBalance = 1000; harrysChecking.transfer(500, savingsBalance); System.out.println(savingsBalance); . . . void transfer(double amount, double otherBalance) { balance = balance - amount; otherBalance = otherBalance + amount; } 13 14 Call-by-Value Example Call-by-Value / Call-by-Reference harrysChecking.transfer(500, savingsAccount); Call by value : Method parameters are copied into the parameter variables when a method starts Call by reference : Methods can modify parameters Java has call by value for both primitive types and object references A method can change state of object reference parameters, but cannot replace an object reference with another public class BankAccount { . . . public void transfer(double amount, BankAccount otherAccount) { balance = balance - amount; double newBalance = otherAccount.balance + amount; otherAccount = new BankAccount(newBalance); // Won't work } 15 } 16 Preconditions Checking Preconditions Precondition : Requirement that the caller of a Method may skip check of the precondition method must meet (puts full trust/responsibility on caller) If precondition is violated, method is not responsible for Efficient, but dangerous if there is a violation computing correct result Good idea to document preconditions so that May throw an exception (Ch. 15) callers don’t pass bad parameters Inefficient - has to check every time Typical uses of preconditions May use an assertion check To restrict/constrain parameters of a method To require that method is only called when object is in an Causes error if the assertion fails appropriate state /** After testing, can disable all assertion checks to Deposits money into this account. allow program to run at full speed @param amount the amount of money to deposit (Precondition: amount >= 0) */ public void deposit( double amount ) { . . . 17 18 3
Assertions Bad Way to Handle Violations public void deposit( double amount ) { assert condition ; Syntax: if ( amount < 0 ) return; balance = balance + amount; Logical condition in a program that you believe } should be true public void deposit( double amount ) { Doesn’t abort the program if precondition is assert amount >= 0; violated balance = balance + amount; } But hard to debug if something is going wrong – nothing to tell you cause of the By default, assertion checking is disabled when running Java programs problem To enable assertion checking: java -enableassertions MyProgramName Can use -ea ea as shortcut instead of -enableassertions 19 20 Postconditions Pre- and Postconditions Condition that is true after a method is Don’t document trivial postconditions that repeat the @return clause completed /** . . . @return the account balance If method is called according to its preconditions, (Postcondition: the return value equals the account balance then is must ensure that its postconditions hold . . . State conditions in terms of public interface, not Two kinds of postconditions private fields Return value is computed correctly amount <= getBalance() // not account <= balance Object is in a certain state after method call is completed Pre- and postconditions spell out a contract /** Deposits money into this account. between pieces of code (Postcondition: getBalance() >= 0) @param amount the amount of money to deposit (Precondition: amount >= 0) 21 22 */ Class Invariants Static Methods Statement about an object that is true after every In Java, every method must be defined within a constructor and is preserved by every mutator class (provide preconditions are met) Most methods operate on a particular instance of an object /** of that class (the ‘implicit parameter’) A bank account has a balance that can be Some methods are not invoked (called) on an object changed by deposits and withdrawals (Invariant: getBalance() >= 0) Example: Math.sqrt( x ) */ public class BankAccount { . . . Why? Method does some computation that only needs numbers Once you formulate a class invariant, check that the – numbers aren’t objects, so can’t call methods on them: methods preserve it x.sqrt() is not legal in Java ( x is a double ) 23 24 4
Recommend
More recommend