outline
play

Outline Design considerations CS1007: Object Oriented Design - PDF document

Outline Design considerations CS1007: Object Oriented Design Testing and Programming in Java Putting all together Lecture #7 Sept 27 Shlomo Hershkop shlomo@cs.columbia.edu Announcements From last Time Midterm date set


  1. Outline • Design considerations CS1007: Object Oriented Design • Testing and Programming in Java • Putting all together Lecture #7 Sept 27 Shlomo Hershkop shlomo@cs.columbia.edu Announcements From last Time • Midterm date set • Encapsulation allows us to divide objects – Will post review notes into logical parts and only present specific – Will be open book views of the object to outside manipulators – No computers • Division of work • Homework due tonight at midnight – Accessors • Meet in clic lab on Thursday (Fairchild building) from 1pm-3pm (will take less) – Mutators – Graded lab – Free to work outside of lab, but I will be there to answer questions 1

  2. Idea: Law of Demeter • Example: Mail system in chapter 2 • For real object oriented programming, Mailbox currentMailbox = should be minum of objects floating mailSystem.findMailbox(...); around between objects. • Breaks encapsulation – Using just methods to change objects • Suppose future version of MailSystem – More responsibilities per object, but cleaner uses a database overall design • Then it no longer has mailbox objects – A.K.A Law of Demeter • Common in larger systems • Karl Lieberherr: Law of Demeter Emphasis • The law: A method should only use objects that are • Some of the design choices come with experience – instance fields of its class – parameters – objects that it constructs with new • No “One size fits all solution” • Shouldn't use an object that is returned from a method call • Solution to balance decisions: • Remedy in mail system: Delegate mailbox methods to mail system mailSystem.getCurrentMessage(int mailboxNumber); – Documentation mailSystem.addMessage(int mailboxNumber, Message msg); – Will talk about it soon . . . • Rule of thumb, not a mathematical law 2

  3. Designing projects Quality of Class Interface • Will now talk about what goes into • Customers: Programmers using the class designing a set of classes • Criteria: • Remember – Cohesion – In general you will both give and be given only – Completeness class files. – Convenience – Along with the documentations (API) it is the – Clarity only to know – Consistency • What • How • Engineering activity: make tradeoffs • Why Cohesion Completeness • Class describes a single abstraction • Support operations that are well-defined on abstraction • Methods should be related to the single abstraction • Potentially bad example: Date • Bad example: public class Mailbox Date start = new Date(); { // do some work public addMessage(Message aMessage) { ... } Date end = new Date(); public Message getCurrentMessage() { ... } public Message removeCurrentMessage() { ... } public void processCommand(String command) { ... • How many milliseconds have elapsed? } ... • No such operation in Date class } • Does it fall outside the responsibility? • After all, we have before, after, getTime 3

  4. Convenience Be Clear • Confused programmers write buggy code • A good interface makes all tasks possible . . . and • Bad example: Removing elements from LinkedList common tasks simple • Reminder: Standard linked list class • Bad example: Reading from System.in before Java 5.0 LinkedList countries = new LinkedList(); countries.add("A"); BufferedReader in = new BufferedReader(new countries.add("B"); InputStreamReader(System.in)); countries.add("C"); • Iterate through list: • Why doesn't System.in have a readLine method? • After all, System.out has println. ListIterator iterator = countries.listIterator(); • Scanner class fixes inconvenience while (iterator.hasNext()) System.out.println(iterator.next()); Be Consistent • Iterator between elements • Related features of a class should have matching • Like blinking caret in word processor – names • add adds to the left of iterator (like word processor): – parameters • Add X before B: – return values ListIterator iterator = countries.listIterator(); // |ABC – behavior iterator.next(); // A|BC iterator.add("France"); // AX|BC • Bad example: • To remove first two elements, you can't just "backspace" • remove does not remove element to the left of iterator new GregorianCalendar(year, month - 1, day) • From API documentation: 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 • Why is month 0-based? not been called after the last call to next or previous. • Huh? 4

  5. Consistency Programming by Contract • Bad example: String class • Spell out responsibilities s.equals(t) vs. s.equalsIgnoreCase(t) • But – of caller – of implementer boolean regionMatches(int toffset, String other, int ooffset, int len) boolean regionMatches(boolean ignoreCase, int toffset, • Increase reliability String other, int ooffset, int len) • Increase efficiency • Why not regionMatchesIgnoreCase? • Very common problem in student code Preconditions • Excessive error checking is costly • Caller attempts to remove message from • Returning dummy values can complicate testing empty MessageQueue • Contract metaphor • What should happen? – Service provider must specify preconditions – If precondition is fulfilled, service provider must work • MessageQueue can declare this as an correctly error – Otherwise, service provider can do anything • When precondition fails, service provider may • MessageQueue can tolerate call and – throw exception return dummy value – return false answer – corrupt data • What is better? 5

  6. Preconditions Circular Array Implementation /** • Efficient implementation of bounded queue Remove message at head @return the message at the head • Avoids inefficient shifting of elements @precondition size() > 0 */ • Circular: head, tail indexes wrap around Message remove() { return elements.remove(0); } • What happens if precondition not fulfilled? HTML File • IndexOutOfBoundsException • Other implementation may have different behavior Problem with Array Circular Array 6

  7. Preconditions Java Assertion Command • Mechanism for warning programmers • In circular array implementation, failure of • Can be turned off after testing remove precondition corrupts queue! • Useful for warning programmers about precondition • Bounded queue needs precondition for add failure • Naive approach: • Syntax: @precondition size()< elements.length assert condition; • Precondition should be checkable by caller assert condition : explanation; • Better: @precondition size() < getCapacity() • Throws AssertionError if condition false and checking enabled Example Exceptions in contract public Message remove() /** { . . . @throws NoSuchElementException if queue is empty assert count > 0 : "violated precondition size() */ > 0"; public Message remove() Message r = elements[head]; { . . . if (count == 0) } throw new NoSuchElementException(); Message r = elements[head]; • During testing, run with . . . } java -enableassertions MyProg • Exception throw part of the contract • Caller can rely on behavior • Or shorter, java -ea • Exception throw not result of precondition violation • This method has no precondition 7

  8. Postconditions Class Invariants • Conditions that the service provider guarantees • Condition that is • Every method promises description, @return • Sometimes, can assert additional useful condition • Example: add method – true after every constructor – preserved by every method @postcondition size() > 0 (if it's true before the call, it's again true • Postcondition of one call can imply precondition of afterwards) another: q.add(m1); • Useful for checking validity of operations m2 = q.remove(); • Example: Circular array queue 0 <= head && head < elements.length • First check it's true for constructor – Sets head = 0 – Need precondition size > 0! • Check mutators. Start with add – Sets headnew = (headold + 1) % elements.length – We know headold > 0 (Why?) – % operator property: 0 <= headnew && headnew < elements.length • What's the use? Array accesses are correct! return elements[head]; 8

Recommend


More recommend