程序代写代做代考 database Java C Drawing a Design Diagram

Drawing a Design Diagram
using the Business Object Notation (BON)
EECS3311 A: Software Design Fall 2019
CHEN-WEI WANG

Why a Design Diagram?
SOURCE CODE is not an appropriate form for communication. Use a DESIGN DIAGRAM showing selective sets of important:
X clusters X classes
X architectural relations
X features (queries and commands)
(i.e., packages)
[ deferred vs. effective ] [ generic vs. non-generic ]
[ client-supplier vs. inheritance ]
X contracts
[ deferred vs. effective vs. redefined ]
[ precondition vs. postcondition vs. class invariant ]
Your design diagram is called an abstraction of your system:
X Being selective on what to show, filtering out irrelevant details
X Presenting contractual specification in a mathematical form (e.g., ¦ instead of across . . . all . . . end).
2 of 25

Classes:
Detailed View vs. Compact View (1)
shows a selection of: X features (queries and/or commands)
X contracts (class invariant and feature pre-post-conditions)
X Use the detailed view if readers of your design diagram should
know such details of a class.
e.g., Classes critical to your design or implementation
shows only the class name.
X Use the compact view if readers should not be bothered with such details of a class.
e.g., Minor “helper” classes of your design or implementation e.g., Library classes (e.g., ARRAY, LINKED LIST, HASH TABLE)
3 of 25
Detailed view
Compact view

Classes:
Detailed View vs. Compact View (2)
Detailed View
FOO
feature — { A, B, C }
— features exported to classes A, B, and C
feature — { NONE } — private features
invariant
inv_1: 0 < balance < 1,000,000 Compact View 4 of 25 FOO Contracts: Mathematical vs. Programming X When presenting the detailed view of a class, you should include contracts of features which you judge as important. X Consider an array-based linear container: ARRAYED_CONTAINER+ 5 of 25 feature -- Queries count+: INTEGER -- Number of items stored in the container feature -- Commands assign_at+ (i: INTEGER; s: STRING) -- Change the value at position 'i' to 's'. require valid_index: 1 ≤ i ≤ count ensure size_unchanged: imp.count = (old imp.twin).count item_assigned: imp[i] ~ s others_unchanged: ∀j : 1 ≤ j ≤ imp.count : j ≠ i ⇒imp[j] ~ (old imp.twin) [j] feature -- { NONE } imp+: ARRAY[STRING] -- Implementation of an arrayed-container invariant consistency: imp.count = count A tag should be included for each contract. Use mathematical symbols (e.g., ¦, §, à) instead of programming symbols (e.g., across ... all ..., across ... some ..., <=). Classes: Generic vs. Non-Generic A class is generic if it declares at least one type parameters. X Collection classes are generic: ARRAY[G], HASH TABLE[G, H], etc. X Type parameter(s) of a class may or may not be instantiated: HASH_TABLE[G, H] HASH_TABLE[STRING, INTEGER] HASH_TABLE[PERSON, INTEGER] X If necessary, present a generic class in the detailed form: DATABASE[G] feature -- some public features here feature -- { NONE } -- imp: ARRAY[G] invariant -- some class invariant here DATABASE[STRING] feature -- some public features here feature -- { NONE } -- imp: ARRAY[STRING] invariant -- some class invariant here DATABASE[PERSON] feature -- some public features here feature -- { NONE } -- imp: ARRAY[PERSON] invariant -- some class invariant here A class is non-generic if it declares no type parameters. 6 of 25 Deferred vs. Effective Deferred Effective 7 of 25 means unimplemented ( abstract in Java) means implemented Classes: Deferred vs. Effective A deferred class has at least one feature unimplemented. X A deferred class may only be used as a static type (for declaration), but cannot be used as a dynamic type. X e.g., By declaring list: LIST[INTEGER] (where LIST is a deferred class), it is invalid to write: create list.make create {LIST[INTEGER]} list.make An effective class has all features implemented. X An effective class may be used as both static and dynamic types. X e.g., By declaring list: LIST[INTEGER], it is valid to write: create {LINKED LIST[INTEGER]} list.make create {ARRAYED LIST[INTEGER]} list.make where LINKED LIST and ARRAYED LIST are both effective descendants of LIST. 8 of 25 Features: Deferred, Effective, Redefined (1) A deferred feature is declared with its header only (i.e., name, parameters, return type). X The word “deferred” means a descendant class would later implement this feature. X The resident class of the deferred feature must also be deferred. deferred class DATABASE[G] feature -- Queries search (g: G): BOOLEAN -- Does item ‘g‘ exist in database? deferred end end 9 of 25 Features: Deferred, Effective, Redefined (2) An effective feature implements some inherited deferred feature. class DATABASE_V1[G] inherit DATABASE feature -- Queries search (g: G): BOOLEAN -- Perform a linear search on the database. deferred end end A descendant class may still later re-implement this feature. 10 of 25 Features: Deferred, Effective, Redefined (3) A redefined feature re-implements some inherited effective feature. class DATABASE_V2[G] inherit DATABASE_V1[G] feature -- Queries search (g: G): BOOLEAN -- Perform a binary search on the database. deferred end end A descendant class may still later re-implement this feature. 11 of 25 Classes: Deferred vs. Effective (2.1) Append a star * to the name of a deferred class or feature. Append a plus + to the name of an effective class or feature. Append two pluses ++ to the name of a redefined feature. Deferred or effective classes may be in the compact form: LIST[G]* LIST[LIST[PERSON]]* DATABASE[G]* LINKED_LIST[G]+ LINKED_LIST[INTEGER]+ DATABASE_V1[G]+ ARRAYED_LIST[G]+ ARRAYED_LIST[G]+ DATABASE_V2[G]+ 12 of 25 Classes: Deferred vs. Effective (2.2) Append a star * to the name of a deferred class or feature. Append a plus + to the name of an effective class or feature. Append two pluses ++ to the name of a redefined feature. Deferred or effective classes may be in the detailed form: DATABASE[G]* feature {NONE} -- Implementation data: ARRAY[G] feature -- Commands add_item* (g: G) -- Add new item `g` into database. require non_existing_item: ¬ exists (g) ensure size_incremented: count = old count + 1 item_added: exists (g) feature -- Queries count+: INTEGER -- Number of items stored in database ensure correct_result: Result = data.count exists* (g: G): BOOLEAN -- Does item `g` exist in database? ensure correct_result: Result = (∃i : 1 ≤ i ≤ count : data[i] ~ g) DATABASE_V1[G]+ feature {NONE} -- Implementation data: ARRAY[G] feature -- Commands add_item+ (g: G) -- Append new item `g` into end of `data`. feature -- Queries count+: INTEGER -- Number of items stored in database exists+ (g: G): BOOLEAN -- Perform a linear search on `data` array. DATABASE_V2[G]+ feature {NONE} -- Implementation data: ARRAY[G] feature -- Commands add_item++ (g: G) -- Insert new item `g` into the right slot of `data`. feature -- Queries count+: INTEGER -- Number of items stored in database exists++ (g: G): BOOLEAN -- Perform a binary search on `data` array. invariant sorted_data: ∀i : 1 ≤ i < count : data[i] < data[i + 1] 13 of 25 Class Relations: Inheritance (1) An inheritance hierarchy is formed using red arrows. X Arrow’s origin indicates the child/descendant class. X Arrow’s destination indicates the parent/ancestor class. You may choose to present each class in an inheritance hierarchy in either the detailed form or the compact form: * LIST[G] MY_LIST_INTERFACE[G]* feature -- some public features here feature -- { NONE } -- some implementation features here invariant -- some class invariant here ++ MY_LIST_IMP_ONE[G]+ MY_LIST_IMP_TWO[G]+ 14 of 25 Class Relations: Inheritance (2) More examples (emphasizing different aspects of DATABASE): Inheritance Hierarchy Features being (Re-)Implemented DATABASE[G]* DATABASE[G]* feature {NONE} -- Implementation data: ARRAY[G] feature -- Commands add_item* (g: G) -- Add new item `g` into database. require non_existing_item: ¬ exists (g) ensure size_incremented: count = old count + 1 item_added: exists (g) feature -- Queries count+: INTEGER -- Number of items stored in database ensure correct_result: Result = data.count exists* (g: G): BOOLEAN -- Does item `g` exist in database? ensure correct_result: Result = (∃i : 1 ≤ i ≤ count : data[i] ~ g) DATABASE_V1[G]+ DATABASE_V2[G]+ feature {NONE} -- Implementation data: ARRAY[G] feature -- Commands add_item++ (g: G) -- Insert new item `g` into the right slot of `data`. feature -- Queries count+: INTEGER -- Number of items stored in database exists++ (g: G): BOOLEAN -- Perform a binary search on `data` array. invariant DATABASE_V1[G]+ 15 of 25 DATABASE_V2[G]+ sorted_data: ∀i : 1 ≤ i < count : data[i] < data[i + 1] Class Relations: Client-Supplier (1) A exists between two classes: one (the client) uses the service of another (the supplier). Programmatically, there is CS relation if in class CLIENT there is a variable declaration . X A variable may be an attribute, a parameter, or a local variable. A green arrow is drawn between the two classes. X Arrow’s origin indicates the client class. X Arrow’s destination indicates the supplier class. X Above the label there should be a label indicating the supplier name (i.e., variable name). X In the case where supplier is an attribute, indicate after the label name if it is deferred (*), effective (+), or redefined (++). 16 of 25 client-supplier (CS) relation s1: SUPPLIER Class Relations: Client-Supplier (2.1) class DATABASE feature {NONE} -- implementation data: ARRAY[STRING] feature -- Commands add_name (nn: STRING) -- Add name ‘nn‘ to database. require ... do ... ensure ... end name_exists (n: STRING): BOOLEAN -- Does name ‘n‘ exist in database? require ... local u: UTILITIES do ... ensure ... end invariant ... end class UTILITIES feature -- Queries search (a: ARRAY[STRING]; n: STRING): BOOLEAN -- Does name ‘n‘ exist in array ‘a‘? require ... do ... ensure ... end end X Attribute indicates two suppliers: STRING and ARRAY. X Parameters nn and n may have an arrow with label , pointing to the STRING class. X Local variable u may have an arrow with label , pointing to the UTILITIES class. 17 of 25 data: ARRAY[STRING] nn, n u Class Relations: Client-Supplier (2.2.1) If STRING is to be emphasized, label is , where . . . denotes the supplier class STRING being pointed to. 18 of 25 DATABASE+ feature add_name+ (nn: STRING) -- Add name `nn` into database. require ... ensure ... name_exists+ (n: STRING): BOOLEAN -- Does name `n` exist? require ... ensure ... invariant ... data+: ARRAY[...] n, nn data: ARRAY[...] + STRING u UTILITIES+ feature search+ (a: ARRAY[STRING]; n: STRING): BOOLEAN -- Does name `n` exist in array `a`? require ... ensure ... Class Relations: Client-Supplier (2.2.2) If ARRAY is to be emphasized, label is . The supplier’s name should be complete: ARRAY[STRING] data DATABASE+ feature add_name+ (nn: STRING) -- Add name `nn` into database. require ... ensure ... name_exists+ (n: STRING): BOOLEAN -- Does name `n` exist? require ... ensure ... invariant ... data+ n, nn u + ARRAY[STRING] + STRING + UTILITIES 19 of 25 Class Relations: Client-Supplier (3.1) Known: The deferred class LIST has two effective descendants ARRAY LIST and LINKED LIST). DESIGN ONE: class DATABASE_V1 feature {NONE} -- implementation imp: ARRAYED_LIST[PERSON] ... -- more features and contracts end DESIGN TWO: class DATABASE_V2 feature {NONE} -- implementation imp: LIST[PERSON] ... -- more features and contracts end Question: Which design is better? [ DESIGN TWO ] Rationale: Program to the interface, not the implementation. 20 of 25 Class Relations: Client-Supplier (3.2.1) We may focus on the PERSON supplier class, which may not help judge which design is better. DATABASE_V1+ feature -- some public features here feature -- { NONE } -- some implementation features here invariant -- some class invariant here imp+: ARRAYED_LIST[...] + PERSON DATABASE_V2+ feature -- some public features here feature -- { NONE } -- some implementation features here invariant -- some class invariant here imp+: LIST[...] + PERSON 21 of 25 Class Relations: Client-Supplier (3.2.2) Alternatively, we may focus on the LIST supplier class, which in this case helps us judge which design is better. DATABASE_V1+ feature imp+ -- some public features here feature -- { NONE } -- some implementation features here invariant -- some class invariant here * ARRAYED_LIST[PERSON] DATABASE_V2+ feature imp+ -- some public features here feature -- { NONE } -- some implementation features here invariant -- some class invariant here * LIST[PERSON] ++ ARRAYED_LIST[PERSON] LINKED_LIST[PERSON] 22 of 25 Clusters: Grouping Classes Use clusters to group classes into logical units. model DATABASE[G]* DATABASE_V1[G]+ DATABASE[G]+ feature -- Commands add_item++ (g: G) tests db DATABASE_TESTS+ -- Insert new item `g` into the right slot of `data`. imp * LIST[G] base-library feature -- Queries count+: INTEGER -- Number of items stored in database exists++ (g: G): BOOLEAN -- Perform a binary search on `data` array. invariant sorted_data: ∀i : 1 ≤ i < count : data[i] < data[i + 1] ++ ARRAYED_LIST[G] LINKED_LIST[G] 23 of 25 Index (1) Why a Design Diagram? Classes: Detailed View vs. Compact View (1) Classes: Detailed View vs. Compact View (2) Contracts: Mathematical vs. Programming Classes: Generic vs. Non-Generic Deferred vs. Effective Classes: Deferred vs. Effective Features: Deferred, Effective, Redefined (1) Features: Deferred, Effective, Redefined (2) Features: Deferred, Effective, Redefined (3) Classes: Deferred vs. Effective (2.1) Classes: Deferred vs. Effective (2.2) 24 of 25 Index (2) Class Relations: Inheritance (1) Class Relations: Inheritance (2) Class Relations: Client-Supplier (1) Class Relations: Client-Supplier (2.1) Class Relations: Client-Supplier (2.2.1) Class Relations: Client-Supplier (2.2.2) Class Relations: Client-Supplier (3.1) Class Relations: Client-Supplier (3.2.1) Class Relations: Client-Supplier (3.2.2) Clusters: Grouping Classes 25 of 25