Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 3 (Horstmann’s Book) Guidelines for Class Design Hwajung Lee.

Similar presentations


Presentation on theme: "Chapter 3 (Horstmann’s Book) Guidelines for Class Design Hwajung Lee."— Presentation transcript:

1 Chapter 3 (Horstmann’s Book) Guidelines for Class Design Hwajung Lee

2  Have “bottom up point of view”  Learn how to write a single class well.  The classes will  Be useful  Be reusable  Increased pride and satisfaction for you, the designer.

3  Customers: Programmers using the class  Criteria: (5Cs)  Cohesion  Completeness  Convenience  Clarity  Consistency

4  A class is an abstraction of a single concept. A class is cohesive if all of its methods are related to a single abstraction. Methods should be related to the single abstraction  Bad example: public class Mailbox { public addMessage(Message aMessage) {... } public Message getCurrentMessage() {... } public Message removeCurrentMessage() {... } public void processCommand(String command) {... }... }

5  A class interface should support all operations that are a part of the abstraction that the class represents.  Potentially bad example: Date start = new Date(); // do some work Date end = new Date(); //How many milliseconds have elapsed?  No such operation in Date class  Does it fall outside the responsibility?  After all, we have before, after, getTime

6  A class should be convenient to use. A good interface makes all tasks possible... and common tasks simple.  Bad example: Reading from System.in BufferedReader in = new BufferedReader (new InputStreamReader (System.in)); Name = in.readLine();  Why didn't System.in have a readLine method?

7  A class interface should be clear to understand to programmers. Confused programmers write buggy code  Bad example: Removing elements from LinkedList LinkedList countries = new LinkedList(); countries.add("A"); countries.add("B"); countries.add("C"); ListIterator iterator = countries.listIterator(); while (iterator.hasNext()) System.out.println(iterator.next());

8  Iterator between elements is like blinking cursor in a word processor. Thus, if X is added before B: ListIterator iterator = countries.listIterator(); // |ABC iterator.next(); // A|BC iterator.add("France"); // AX|BC  Then, to remove first two elements, you can't just "backspace." The remove() method does not remove element to the left of the iterator.  Will the following work? iterator.remove(); //A|BC iterator.remove(); //|BC

9  In fact, void remove() from API documentation says: Removes from the list the last element that was returned by next or previous. This call can only be made once per call to next or previous. It can be made only if add has not been called after the last call to next or previous. void remove() http://java.sun.com/j2se/1.5.0/docs/api/java/util/ListIterator.html#remove() http://java.sun.com/docs/books/tutorial/  Huh?

10  The operations in a class should be consistent with each other with respect to  names  parameters  return values  behavior  Bad example: new GregorianCalendar(year, month - 1, day)  Why is month 0-based?

11  Bad example:  String class s.equals(t) or s.equalsIgnoreCase(t)  But boolean regionMatches(int toffset, String other, int ooffset, int len) boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)  Why not regionMatchesIgnoreCase?

12  Cohesion  Completeness  Convenience  Clarity  Consistency

13  A method should only use objects that are  instance fields of its class  parameters  objects that it constructs with new  A method shouldn't use an object that is returned from a method call

14  Side effect: change to another object  Explicit parameters  Avoid side effects--they confuse users  Good example, no side effect: a.addAll(b); mutates a but not b * Note: Accessor is a getter and Mutator is a setter.

15  References to immutable objects can be freely shared. Don't share mutable references  Example: Class Employee {... public String getName() { return name; } public double getSalary() { return salary; } public Date getHireDate() { return hireDate; } private String name; private double salary; private Date hireDate; }

16  Pitfall: Employee harry =...; Date d = harry.getHireDate(); d.setTime(t); // changes Harry's state!!!

17  Remedy: Use clone public Date getHireDate() { return (Date)hireDate.clone(); }

18  Good idea to mark immutable instance fields as final private final int day;  final object reference can still refer to mutating object private final ArrayList elements;  elements can't refer to another array list  The contents of the array list can change

19  Spell out responsibilities  of caller  of implementer  Increase reliability  Increase efficiency

20  We will look through the ideas on  Preconditions  Postconditions  Exceptions in the Contract  Class Invariants  Assertions

21  A precondition of a method  is a condition that must be fulfilled before the method may be called.  Is a condition that the method caller must fulfill.

22  Why do we need to define preconditions?  Excessive error checking is costly  Returning dummy values can complicate testing  Contract metaphor  Service provider must specify preconditions ▪ If precondition is fulfilled, service provider must work correctly. Otherwise, service provider can do anything  When precondition fails, service provider may  throw exception  return false answer  corrupt data

23  Example: /** Remove message at head @return the message at the head @precondition size() > 0 */ Message removeFirst() { return (Message)elements.remove(0); }

24  (Ex) What should happen if a programmer attempts to remove a message from an empty queue?  What is better? ▪ MessageQueue can declare this as an error ▪ MessageQueue can tolerate call and return dummy value

25  A postcondition of a method  is a condition that holds after the method has completed  is a conditions that the service provider (the method developer) guarantees  In Java doc, you can use @return or @postcondition to represent a postcondition. Example: add() method @postcondition size() > 0  Postcondition of one call can imply precondition of another: q.add(m1); m2 = q.remove();

26  Exception throw is not an error. It is a part of the contract  Example: /**... @throws IllegalArgumentException if queue is empty */ public Message removeFirst() { if (count == 0) throw new IllegalArgumentException(); Message r = elements[head];... }

27  A class invariant is a logical condition that is  true after every constructor  preserved by every mutator (if it's true before the call, it's again true afterwards)  Useful for checking validity of operations

28  Example: Circular array queue (Ch2/mail/MessageQueue.java)Ch2/mail/MessageQueue.java 0 <= head && head < elements.length  First check it's true for constructor ▪ Sets head = 0 ▪ Need precondition size() >= 0  Check mutators. Start with removeFirst() ▪ Sets head new = (head old + 1) % elements.length ▪ We know head old + 1> 0 (Why?)  % operator property: 0 <= head new && head new < elements.length  What's the use of a class invariant?  Every array access of the form element[head] is legal!

29  An assertions:  is a condition that a programmer expects to be true  is a mechanism for warning programmers ▪ Useful for warning programmers about precondition failure  can be turned off after testing  Syntax: assert condition; assert condition : explanation;  Throws AssertionError if condition false and checking enabled

30  Example: public Message removeFirst() { assert count > 0 : "violated precondition size() > 0"; Message r = elements[head];... }  How to execute the assertion: During testing, run with java -enableassertions MyProg or Java -ea MyProg

31  Unit test = test of a single class  How to test?  Design test cases during implementation  Run tests after every implementation change  When you find a bug, add a test case that catches it  Download the JUnit tool  http://junit.sourceforge.net/ http://junit.sourceforge.net/  http://junit.sourceforge.net/doc/faq/faq.htm http://junit.sourceforge.net/doc/faq/faq.htm

32

33  Test class name = tested class name + Test  A name of a test method starts with test  Example: import junit.framework.*; public class DayTest extends TestCase { public void testAdd() {... } public void testDaysBetween() {... }... }

34  Each test case ends with assertion. Test framework catches assertion failures  Example: public void testAdd() { Day d1 = new Day(1970, 1, 1); int n = 1000; Day d2 = d1.addDays(n); assert d2.daysFrom(d1) == n; }

35  Day.java Day.java  DayTest.java DayTest.java  Compiling javac –classpath.:junit.jar DayTest.java  Run java –classpath.:junit.jar –ea junit.swingui.TestRunner DayTest

36

37  public: a field, method, or class that is accessible to every class.  protected: a field, method, or class that is accessible to the class itself, subclasses, and all classes in the same package or directory.  private: a field or method that is accessible only to the class in which it is defined. Note that a class can not be declared private as a whole.


Download ppt "Chapter 3 (Horstmann’s Book) Guidelines for Class Design Hwajung Lee."

Similar presentations


Ads by Google