程序代写代做代考 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
Classes:
Detailed View vs. Compact View (1)


shows a selection of: ○ features (queries and/or commands)
Detailed view
○ contracts (class invariant and feature pre-post-conditions)
○ 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
○ 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)
Compact view
shows only the class name.
3 of 25
Why a Design Diagram?
● SOURCE CODE is not an appropriate form for communication.
● Use a DESIGN DIAGRAM showing selective sets of important: ○ clusters (i.e., packages)
○ classes
○ architectural relations [ generic vs. non-generic ]
○ features (queries and commands) [ client-supplier vs. inheritance ]
[ deferred vs. effective ]
[ deferred vs. effective vs. redefined ]
○ contracts
● Your design diagram is called an abstraction of your system:
[ precondition vs. postcondition vs. class invariant ]
○ Being selective on what to show, filtering out irrelevant details ○ Presenting contractual specification in a mathematical form
(e.g., ∀ instead of across . . . all . . . end). 2 of 25
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 FOO 4 of 25 Contracts: Mathematical vs. Programming 5 of 25 symbols (e.g., across ... all ..., across ... some ..., <=). ○ When presenting the detailed view of a class, you should include contracts of features which you judge as important. ○ Consider an array-based linear container: ARRAYED_CONTAINER+ 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 ● Atagshouldbeincludedforeachcontract. ● Usemathematicalsymbols(e.g.,∀,∃,≤)insteadofprogramming Deferred vs. Effective means unimplemented (≈ abstract in Java) means implemented Deferred Effective 7 of 25 Classes: Generic vs. Non-Generic ● A class is generic if it declares at least one type parameters. ○ Collection classes are generic: ARRAY[G], HASH TABLE[G, H], etc. ○ Type parameter(s) of a class may or may not be instantiated: HASH_TABLE[G, H] HASH_TABLE[STRING, INTEGER] HASH_TABLE[PERSON, INTEGER] ○ 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 Classes: Deferred vs. Effective ● A deferred class has at least one feature unimplemented. ○ A deferred class may only be used as a static type (for declaration), but cannot be used as a dynamic type. ○ 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. ○ An effective class may be used as both static and dynamic types. ○ 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). ○ The word “deferred” means a descendant class would later implement this feature. ○ 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 (3) ● A redefined feature re-implements some inherited effective feature. ● A descendant class may still later re-implement this feature. 11 of 25 class DATABASE_V2[G] inherit DATABASE_V1[G] feature -- Queries search (g: G): BOOLEAN -- Perform a binary search on the database. deferred end end Features: Deferred, Effective, Redefined (2) ● An effective feature implements some inherited deferred feature. ● A descendant class may still later re-implement this feature. 10 of 25 class DATABASE_V1[G] inherit DATABASE feature -- Queries search (g: G): BOOLEAN -- Perform a linear search on the database. deferred end end 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]* DATABASE_V1[G]+ DATABASE_V2[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) 13 of 25 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. 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] Class Relations: Inheritance (2) More examples (emphasizing different aspects of DATABASE): Inheritance Hierarchy Features being (Re-)Implemented DATABASE[G]* DATABASE_V1[G]+ DATABASE_V2[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 sorted_data: ∀i : 1 ≤ i < count : data[i] < data[i + 1] 15 of 25 Class Relations: Inheritance (1) ● An inheritance hierarchy is formed using red arrows. ○ Arrow’s origin indicates the child/descendant class. ○ 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: 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 client-supplier (CS) relation is a variable declaration . ○ A variable may be an attribute, a parameter, or a local variable. s1: SUPPLIER ● A green arrow is drawn between the two classes. ○ Arrow’s origin indicates the client class. ○ Arrow’s destination indicates the supplier class. ○ Above the label there should be a label indicating the supplier name (i.e., variable name). ○ In the case where supplier is an attribute, indicate after the label name if it is deferred (*), effective (+), or redefined (++). 16 of 25 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 ○ Attribute indicates two suppliers: STRING and ARRAY. data: ARRAY[STRING] ○ Parameters nn and n may have an arrow with label , pointing to the STRING class. ○ Local variable u may have an arrow with label , pointing to the 17 of 25UTILITIES class. nn, n u 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 ... 19 of 25 data+ n, nn u + ARRAY[STRING] + STRING + UTILITIES 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[...] u n, nn data: ARRAY[...] + STRING UTILITIES+ feature search+ (a: ARRAY[STRING]; n: STRING): BOOLEAN -- Does name `n` exist in array `a`? require ... ensure ... Class Relations: Client-Supplier (3.1) Known: The deferred class LIST has two effective descendants ARRAY LIST and LINKED LIST). ● DESIGN ONE: ● DESIGN TWO: Question: Which design is better? [ DESIGN TWO ] Rationale: Program to the interface, not the implementation. 20 of 25 class DATABASE_V1 feature {NONE} -- implementation imp: ARRAYED_LIST[PERSON] ... -- more features and contracts end class DATABASE_V2 feature {NONE} -- implementation imp: LIST[PERSON] ... -- more features and contracts end 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 DATABASE_V2+ feature -- some public features here feature -- { NONE } -- some implementation features here invariant -- some class invariant here 21 of 25 imp+: ARRAYED_LIST[...] imp+: LIST[...] + PERSON + PERSON 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+ * LIST[G] -- Insert new item `g` into the right slot of `data`. imp 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] 23 of 25 ++ ARRAYED_LIST[G] LINKED_LIST[G] 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 DATABASE_V2+ feature imp+ -- some public features here feature -- { NONE } -- some implementation features here invariant -- some class invariant here * ARRAYED_LIST[PERSON] * LIST[PERSON] ++ ARRAYED_LIST[PERSON] LINKED_LIST[PERSON] 22 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