Object Based Design - PowerPoint PPT Presentation

object based design n.
Skip this Video
Loading SlideShow in 5 Seconds..
Object Based Design PowerPoint Presentation
Download Presentation
Object Based Design

play fullscreen
1 / 88
Object Based Design
Download Presentation
Download Presentation

Object Based Design

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Object Based Design • Identifying the Classes • Features Design • Const Correctness • Design by Contract • Some C++ Tips sd

  2. Steps in Object Based Design • Find the classes and name them • Characterize your classes • Domain: foundation/architectural/business/application • Nature: state/source/sink/view/helper/other • Kind: mutable/immutable • Assign responsibilities • Identify collaborators • Declare protocol • Define structure • Establish class invariant • Implement behaviour Good object-based design is first and foremost good modular design. sd

  3. “Find the classes, ” • Arguably, the easiest step! • Main heuristic: • Underline the nouns in the problem description text. • Catches: • Must have a good problem description first • Requirement and analysis phases • Not all nouns should be classes: • Items outside the problem boundary • “Abstract” nouns, which arise from natural language • Some nouns are just attributes • Annual-Interest, Month, Dimension, Gender, .. • Synonyms sd

  4. Nouns in Requirements Problem Reporting System Requirements [G. Booch. OODwA, ‘91, . p. 364] Software with a reputation of being full of errors has a short life, and thus it behooves every software development organization to keep track of error reports. The problem is compounded when an organization is responsible for multiple software products, each of which may have several different versions released to the field at any time. Errors in a program may be identified through any number of different sources: end users, field-support personnel, the test and integration team, quality-assurance personnel, and developers. Once identified, errors must first be qualified (is it an error in the software, a problem with documentation, or is it simply a misunderstanding by the user?), then assigned to a responsible party, and eventually resolved (fixed, deferred, or rejected as being not reproducible). An analysis of error reports can help software managers properly allocate developmental resources and track the maturity of a product. Our task is to develop a problemreporting system for a software development company. This system must support multiple software products as well as multiple versions of each product. Because the kinds of and versions of products will change over time, the system must be designed to support changing database requirements. ... Can you distinguish the real candidates and the attributes from the abstract nouns, external entities and synonyms? sd

  5. Candidate Classes #1/5 Tangible: Physical objects, or groups of objects, that are tangible. engine, invoice, vehicle Roles: A person who carries out some action or duty or plays a role. student, manager, committee-member. • Based on Shlaer & Mellor, Ross, Coad & Yourdon sd

  6. Candidate Classes #2/5 Events: things that happen, usually at a given state or time. Look especially for historical event which must be recorded. withdrawal, purchase, registration, meeting, wedding Interactions: exam, loan, meeting, intersection, wedding. sd

  7. Candidate Classes #3/5 Places & Locations: Areas set aside for people or things. Physical locations, offices, and other relevant sites.Organizational units: Groups to which users belong. Formally organized collections of people, resources, facilities, and capabilities having a defined mission, whose existence is largely independent of constituents: bank, branch, department, committee. sd

  8. Candidate Classes #4/5 Other Systems: External systems or devices with which the application interacts. Pulse monitor Phone switchboard Smart fax machine sd

  9. Candidate Classes #5/5 Concepts: non tangible principles or ideas. Citizenship, authorization, process Structure: “Kind of” and “Part of” relationships. Capture the relationship between objects as a class. sd

  10. “... and name them.” • Use capitalized identifiers (usually one word) for all class names. • Date, Time, Window, Array • Class names are typically nouns or pairs of nouns: • Student, VersionNumber, PortManager • Do not use verbs! • The following class names indicate design errors: • Parse, Draw, Move • Exception: classes describing operation in an interactive system. • er-named classes • Examples: • LexicalAnalyzer, Mover, Popper, Updater • Usually a design flaw. Especially in the following cases: • An er class with many routines • An er class with just one routine • Many unrelated er classes sd

  11. Item / Group Ambiguity • Source: the class/object confusion arises from the fact that the name of a group is also used for denoting a single item in it: • The cat in the hat. • Kishta is a cat. • Solutions • Use plurals for class names • Dates, Cats, ... • Use articles for naming objects (the Smalltalk convention): • theCat, aWindow, ... • Be smart and organized: • Capitalized names for classes • Meaningful lower case names for objects sd

  12. General Rules for Naming • Pronounceable Names • If you cannot pronounce it, you cannot use it! • Few words: • One word is best. • Separate multiple words by • Capitalization: BinaryTree • Underscore: Binary_Tree • Hyphen (COBOL style): Deposit-Slip • Do not invent abbreviations • Clarity should be favoured over brevity. • If you must, omit vowels and/or suffixes • msg, buff, ptr, ... • No nested digits. These are easily confused • 0/O • 1/I • 2/Z • 5/S sd

  13. “Characterize your classes: Domain.” • There is a ladder of domains from which classes are taken. • Domains are characterized by the extent to which its classes are applicable: • Problem Space • Application Domain • One program or application. • Business Domain • One industry or company. • Program Space • Architectural Domain • One implementation architecture. • Foundation Domain • Across all businesses and architectures. [Meilir Page-Jones, What Every Programmer Should Know about OOD, Chapter 9, Dorest ‘95] Low Reusability MediumReusability High Reusability sd

  14. Program Space Domains • Subdomains of the foundation domain: • Fundamental • Integer, Boolean, Character, String, Pointer, Class, ... • Structural • Stack, Queue, List, Binary-Tree, List, ... • Semantic (gives units to quantities) • Date, Time, MKS, CGS, Point, Line,... • Subdomains of the architectural domain: • Machine-communication • Port, Remote-Machine, File, Process, Thread, Keyboard, Mouse-Event, ... • Database • Transaction, Backup, Stream, ... • Human Interface • Window, View-Port, Dialogue-Box, Menu-Item, Command, Radio-Button, ... sd

  15. Problem Space Domains • Subdomains of the business domain: • Attribute • Money, Temperature, Colour, Balance, Address, Rank, ... • Role • Customer, Patient, Bank, Department, ... • Relationship • Member-In, Account-Ownership, ... • Subdomains of the application domain: • Event-Stimulus-Recognizer • Components that recognize external events • Event-Activity-Manager • Components that handle those events sd

  16. “Characterize your classes: Nature.” • Data Manager, Data or State: Classes used to store data. • Almost all classes. • Basic Principle: All data should be managed by a class. • Container: Sole purpose is to store objects of other classes. • Data Sinks: Classes that consume data • Output file, Port • Data Sources: Classes that generate data • RandomNumber, FibonacciSequence • Viewer: Used to display the data of other classes. • Helper, Facilitator, or Algorithm: Used for packaging abstract operations • Sorter, Parser, ... • Other: all the rest... sd

  17. “Characterize your classes: Kind.” • Data Managers are of two kinds: • Mutable: class whose objects may change their state during their life time. • Long life-time of objects. • Immutable Classes: class whose objects’ state can be determined only at construction. • Short life-time of objects. • Objects are dynamically created and destroyed to compensate for lack of state changes. • Immutable classes are sometimes easier to design. New instances are dynamically created if necessary Examples: • Integer, Date, String, Point, Rectangle • File-Name • Button, Transaction, Playing-Card • Deposit, Permission-Request sd

  18. “Set responsibilities.” • So far, all that our program has is: • The next step is to write “class comments”. This should describe the class responsibility. class X { }; class Y {}; ... // XXX... class X { }; // YYY... class Y {}; ... sd

  19. Responsibility • Each class must have a cohesive set of responsibilities. • There must be a clear separation of responsibilities among classes. • Responsibilities must be: • Short. • Describe what not how. • Include an active verb. • Common errors: • Too much responsibility. • No responsibility at all - false class. • Unrelated responsibilities. • Shared responsibility. sd

  20. “Identify collaborators.” • Collaborators (at first iteration no need to determine exact collaboration): • Providers: • Composition relationship: • Classes of instance variables. • Inheritance Relationship (later): • Base classes. • Other relationships: • Arguments to class methods. • Classes of Internal variables in methods. • Classes of global variables used in methods. • Users: • The users of a class C, are all classes to which C is a provider. • Set of collaborators should be small. sd

  21. Encumbrance Direction 1 Pen 4 Position 1 Colour 1 • Encumbrance of a class C: The number of direct and indirect class providers to C. • Example:Encumbrance tends to be correlated with position in the domain ladder. Deviations should be thoroughly checked. They may contain design flaws. Turtle 6 uses Real 0 Integer 0 sd

  22. CRC Cards Class Name Collaborators Responsibilities 4 in 6 in • CRC = Class + Responsibility + Collaboration. • Invented by Beck (89). • Used by a group of individuals in the simulation process. • Back of card is used for the implementation details. sd

  23. “Declare protocol.” • Start from responsibility description. • Kinds of features • Mutators • Accessors • Constructors • Destructors • Convertors • Design decisions: • Number of features • Kinds of arguments • Input/Output • Options/Real arguments • Number of arguments • Names of features sd

  24. External vs. Member Functions class Complex {public: Complex conjugate(void) { ... } }; #include "complex.h" Complex conjugate(Complex c) { ... } sd

  25. Kinds of Features: Mutators • Nicknames: modifiers, commands, operations, procedures, etc. • Naming: • verbs: insert, pop, activate, move, draw, scale, deposit, indent • verbs with adverb: quick_format, left_rotate, deep_copy • verbs with noun: add_color, insert_line, move_to_parent, set_submitter, trace_rays, start_heating, display_headers, ... • Do not append class name! • stack_pop • Operators names: • Utilize, not abuse familiarity with ordinary operator names. • Sub-classification: • High-level: Can be implemented by using only features in the class protocol. • Low-level: Not high level. • Essential • Atomic • Immutable classes should have no mutators. sd

  26. Kinds of Features: Inspectors • Nicknames: examiners, accessors, queries, functions, etc. • Ratio: 60%! (only 40% are mutators) • Measured in the Eiffel library (~700 classes, ~5500 features). • A result of two design techniques we will study later. • Naming: • substantive (noun): occurrences, size, area, summary_of_problem • noun with adjective: current_size, last_int, next_value • Naming Boolean inspectors: • descriptive adjectives, sometimes prefixed with “is”. • ready (not status), full, empty • is_sibling, is_last, is_leaf, is_root sd

  27. Implementing Inspectors in C++ class Heater {public: //... int temperature(void) const;}; • The const keyword after the function member signature effectively defines this as: const Heater * constthis; instead of Heater * constthis; • The abstract (client-visible) state of the object is not allowed to change. • The compiler isn't allowed to assume a byte-wise const, for the purpose of optimization since a non-const cast could exist. • However, with the new mutable keyword, a byte-wise constness can be assumed. sd

  28. No Side-Effects Principle • Implementation Guide-lines: • Mutators should be implemented as procedures (void function members). • Inspectors should be implemented as functions. • Rule: Do not make a design that mixes the two. • Counter-intuitive to C programmers who like to write: while ((c = getchar()) != EOF) { ... } sd

  29. Rationale for No-Side Effects Principle • Clear distinction between inspectors and mutators. • Exploiting reader’s background knowledge and understanding of mathematical functions. getchar() == '\n' || getchar() == '\t' || getchar() == ' ' is not at all the same as iswhite(getchar()) sd

  30. Kinds of Features: Constructors • Nicknames: creating routines, new messages. • Naming: • C++: class name • Eiffel: make • Smalltalk: new sd

  31. C++ Constructors Caution • Constructors with only one argument, implicitly define a conversion from the argument type to the class type. • To avoid this, use the new explicit keyword: • This will prevent the following two kinds of nonsense code: class Array {public: explicit Array(int len); //... }; Array v = 10; int sum(Array); ... int j = sum(5); sd

  32. Kinds of Features: Destructors • Nicknames: cast operators • Naming: • C++: ~class-name • Eiffel: no destructors • Smalltalk: no destructors • Don't bother with them now: • Destructors exist only in non garbage collecting systems. • Their purpose is most frequently to aid in memory management. • This is an implementation detail, which need not be considered at this stage of the design. sd

  33. Kinds of Features: Convertors. • Naming: • C++: operator Type • Eiffel: no convertors • Smalltalk: no convertors • The main purpose of convertors is to make an ADT complete. Their consideration could be put off to later. sd

  34. Number of Features in Eiffel Incremental size of classes in the Eiffel Library [Meyer ‘94] sd

  35. Observations on #Features • Ranges: • Small classes (0-10): • 60-80%. • Medium classes (11-20) • 15-20%. • Large classes (20-40) • 5-10%. • Very big classes (more than 40): • As much as 150 features. • Rare. • Averages: • 12.2 in base. • 6.7 in vision. • Rule of thumb: • 5-20 is good. • 80 is probably too much. sd

  36. Number of Methods (Smalltalk) • Observe the variety • Among projects • Among classes within project Object-Oriented Software Metrics [Lorenz & Kidd ‘95] sd

  37. Distribution of Method Numbers in Smalltalk Programs Object-Oriented Software Metrics [Lorenz & Kidd ‘95] sd

  38. How Big Should a Class be? • Each class has an absolute minimum, below which, the class is useless. • Atomic features are necessary. • Nevertheless, too low level atomic features would hinder redesign. • How much should we have beyond this? • Minimalist approach (Stroustrup). • Maximalist approach (Meyer). sd

  39. Minimalist Approach • Extreme: Do not add anything that can be expressed in terms of atomic features. • Add only the most important gizmos. • Rationale: • Cannot forecast the future: • It is easy to add a feature later. • It is difficult to remove a bad feature. • Easier to write and understand. • Unnecessary features may be an extra baggage. • More work to implement. • May never be necessary. • Greater effort to redesign. • Higher coupling. • Invest time in thinking, not implementing! • Appropriate for problem space classes. sd

  40. Shopping List Approach • Add all features: • that make an ADT complete. • that may be useful to a potential user. • that are not duplicate. • Rationale: • Not Invented Here is a result of minimalism. • In a well documented and consistent system, the effort of reading is much less than that of writing. Essential factors are: • Feature documentation. • Uniform naming convention. • Consistent style. • Grouping of features by categories. • Powerful indexing system. • Appropriate for reuse library and program-space classes. sd

  41. Input and Output Arguments • Arguments to methods are of three kinds: • Input • Output • Input and Output • Output Arguments: not common in good design. • If there is only one returned value, then the method could be made into a function that returns this value. • Two or more returned values are less common. They are usually an indication of bad design. • Input/Output Arguments: very rare. • Danger Signal: An argument which serves as input to a method , and is also changed by the same method, brings the suspicion: • Maybe the method should have been sent to this argument?(More on multi-methods later). • Typical case: • Several inputs • 0/1 outputs. sd

  42. Implementing Input Arguments Alternatives: Good: Pass by value: void print(String s) {/*...*/} Better: Pointer to a constant object: void print(const String* sptr) {/*...*/} Best: Constant reference: void print(const String& s) {/*...*/} Bad: Non-const reference: void print(String& s){/*...*/} Worse: Pointer to a non-const object: void print(String* sptr) {/*...*/} A constant String “forgets” all methods that can change it. sd

  43. Reference to Constant Object • If an argument should not be changed, then this demand must be: • obvious • enforced • Reference to constant object: C++ version of input only argument declaration. • Compile-time error occurs whenever print attempts to change s. • No run-time penalty: • Execution speed • Memory consumption • Information may be used (in special cases) by good optimizing compilers. sd

  44. Const Correctness • A program is constcorrect if and only if: • All immutable elements are declared as such. • No immutable element is mutated, or equivalently, the program compiles without any mutability related warning or error messages. Just another form of type safety used with all program elements: global variables, arguments to functions, functions return values, internal variables, data members, inspectors, etc. • Type safety requires you to annotate your code with type information which isn't absolutely necessary. • You, as a programmer, know a lot of important information about your program. Type safety and const correctness are structured ways to tell the compiler about this information. • In return you get: • More robust systems. • Fewer run-time errors. • More efficient programs. “const correctness” (just like type-checking) can be time consuming and tedious! sd

  45. When to do it? void print(const String& s) { ... int len = length(s); // Beware: length cannot modify s. ... } • Making an existing program const-correct is not easy: • const-correctness tends to spread very quickly. • Bottom-up approach is usually better than top-down. • It is better to start thinking about const-correctness in the design phase. sd

  46. const Objects • All members are const: struct Rect { int top, left, width, height; Rect *next; }; // ... const Rect r; r.top = 0; // error! r.next = &r; // error! r.next->top = 0; // OK Same as: const int top, left,... Only the nextpointeris const ! • Can only call const member functions. sd

  47. Initialization of const Objects • Done once in construction time: const Rect r1(20, 20, 100, 100); r1 = r2; // error! • Members must be initialized before constructor body. class Student { public: Student(int id): id(id) {} private: const int id; }; Which id is which? Can the compiler generate operator=? sd

  48. const Member Functions • this points to a const object: int Rect::diameter() const { top = 0; // error! r.next = this; // error! r.next->top = 0; // OK } • Members cannot be changed. • Cannot call other non-const member functions. • Specifically, assignment should be non-const. sd

  49. Pointers and const-ness p 1 2 • const refers to its left hand type: int one = 1; int two = 2; const int *p1 = &one; int const *p2 = &one; int * const p3 = &one; constint * const p4 = &one; QUIZ: Which of these statements compile successfully? p1 = &two; p2 = &two; p3 = &two; p4 = &two; *p1 = two; *p2 = two; *p3 = two; *p4 = two; sd

  50. Logical vs. Physical const-ness • Default behavior is not always sufficient: class Person { char *name; }; const Person p; p.name = "John Doe"; • Default behavior may be too strict: class Database { void get_data() const; int number_of_accesses; }; sd