Lösungsvorschlag Software Architecture Endterm 2005

Aus VISki
Wechseln zu: Navigation, Suche

Link zur Prüfung

1. Software Quality Principles

Quelle für Definitionen: Modularity-Slides 2004 (!) (in den 2005-07ern Slides ist IMHO nichts darüber zu finden, aber kann ja fast nicht sein. -> TODO: Besser suchen. :D)

1.1. Correctness vs. Robustness

Correctness: The ability of a software system to perform according to specification, in cases defined by the specification.

Robustness: The ability of a software system to react in a reasonable manner to cases not covered by the specification.

Example: Consider a console application which adds two integers, therefore expecting two parameters. If the program does just do that when receiving exactly two parameters, it is correct. If it just prints an error message when erroneously receiving three of them, it is robust. If it crashes the whole console application, deleting all files in the current folder, it is still correct but not robust at all.

1.2. External Quality Factors

  • CORRECTNESS
  • ROBUSTNESS
  • INTEGRITY
  • EASE OF USE
  • REUSABILITY
  • EXTENDIBILITY
  • PORTABILITY
  • EFFICIENCY
  • MAINTAINABILITY

Take four of them.

1.3. Principles

Principle: Information Hiding Principle

Explanation of Advantage: If a module changes and the changes apply only to its secret elements. Then the clients will not be affected. So it's no problem to change some hidden implementation.

In addition, the client can get a very simple interface and doesn't get confused by the complex interior mechanisms, which makes the module user-friendly.

Clients cannot modify attributes, possibly invalidating the module's status at runtime. Example: Clients cannot add/remove elements from an "internal" data structure used by the module.

2. Design by Contract

2.1. True or False

  • F, not (very) separately from the software element. Vague definition. Could be T as well.
  • T, the precondition binds the client: it defines the conditions under which a call to the routine is legitimage, it is a obligation for the client and a benefit for the supplier
  • F, not before object creation
  • F, this is only true for class invariants
  • T, rule of thumb: "ensure then" indicates an AND, "require else" indicated an OR
  • F, the supplier has to guarantee that the postcondition holds.
  • F, invariants are anded (see slide 69)
  • F, the exception will be triggered in the caller if the rescue clause does not reestablish the invariant and does not have a retry statement.

2.2. Class completion

(18 Zeilen ausgefüllt. Punktezahl suggeriert eigentlich 20 Zeilen, vielleicht findet noch jemand was?) (Vorschlag: invariant für die Einhaltung der oberen Grenzen für Wasser und Kaffee.) (Kommentar: Ich finde man sollte make nicht full machen, empty wäre logischer für den Benutzer. Also mit 0 initialisieren statt refill aufrufen. Ist aber vermutlich Ansichtssache.)

make is
  do
    refill_coffee
    refill_water
  ensure
    water_full: coffee_in_container = container_capacity
    water_full: water_in_tank = tank_capacity
  end
refill_coffee is
  require
    not_full: coffee_in_container < container_capacity
  do
    coffee_in_container := container_capacity
  ensure
    is_full: coffee_in_container = container_capacity
  end
refill_water is
  require
    not_full: water_in_tank < tank_capacity
  do
    water_in_tank := tank_capacity
  ensure
    is_full: water_in_tank = tank_capacity
  end
brew_coffee is
  require
    enough_coffee: coffee_in_container >= coffee_units
    enough_water: water_in_tank >= coffee_water
  do
    ...
  ensure
    coffee_deduced: coffee_in_container = old coffee_in_container - coffee_units
    water_deduced: water_in_tank = old water_in_tank - coffee_water
  end
brew_espresso is
  require
    enough_coffee: coffee_in_container >= espresso_units
    enough_water: water_in_tank >= espresso_water
  do
    ...
  ensure
    coffee_deduced: coffee_in_container = old coffee_in_container - espresso_units
    water_deduced: water_in_tank = old coffee_in_container - espresso_water
  end
invariant
  coffee_not_negative: coffee_in_container >= 0
  water_not_negative: water_in_tank >= 0
  water_not_overfull: water_in_tank <= tank_capacity
  coffee_not_overfull: coffee_in_container <= container_capacity

3. Inheritance

3.1. Polymorphic assignments

F, F, T, T, T, F

3.2. Implementations

Question.png

Zu dieser Aufgabe waren Unklarheiten vorhanden, die nun gelöst sind. Mehr Details dazu finden sich auf der zugehörigen Diskussionsseite dieses Themas.


class MOVIE inherit
  RENTABLE redefine output end
output is
  do
    Precursor
    io.put_string(director + "%N")
  end

...

class DVD_MOVIE inherit
  MOVIE redefine output end
output is
  do
    io.put_string(id.out + "%N")
    io.put_string(title + "%N")
    io.put_string(code.out + "%N")
  end

3.3. Dynamic binding

3
Spiderman 2
Sam Raimi
2
Hero
Yimou Zhang
1
House of Flying Daggers
1

4. Adding good contracts to an existing design pattern

HANDLER[G] -- G represents a request

feature {NONE} -- Initialization

  make(a_successor: like next) is
    do
    ensure
      next_set: next = a_successor
    end

feature -- Access
  next: HANDLER[G]
    -- Successor in the chain of responsibility

feature -- Status report

  can_handle(a_request: G):BOOLEAN is
      -- Can current handle `a_request'?
    deferred
    end

  handled: BOOLEAN
      -- Has request been handled?

feature -- Element change

  set_next(a_successor: like next) is
      -- Set `next' to `a_successor'.
    do
    ensure
      next_set: next = a_successor
    end

feature --Basic operation

  handle(a_request: G) is
      -- Handle `a_request' if `can_handle' otherwise forward it to `next'.
      -- If `next' is void, set `handled' to False.
    do
    ensure
      handled_if_possible: can_handle(a_request) implies handled
      propagated_if_unhandled_and_not_last: (not can_handle(a_request) and next /= Void) implies (handled = next.handled)
      unhandled_if_cant_handle_and_last: (not can_handle(a_request) and next = Void) implies not handled
    end

feature {NONE} -- Implementation

  do_handle(a_request: G) is
      -- Handle `a_request'.
    require
      can_handle_request: can_handle(a_request)
    deferred
    end

end

5. Genericity

5.1. Two Lists

Question.png

Zu dieser Aufgabe waren Unklarheiten vorhanden, die nun gelöst sind. Mehr Details dazu finden sich auf der zugehörigen Diskussionsseite dieses Themas.

  • L1
  • L1,L2
  • L1,L2
  • L1

5.2. Fill in the types

Question.png

Dem Autor des Lösungsvorschlags stellt sich eine Unklarheit betreffend der Prüfungsfrage oder deren Lösung:
Ich bin nicht sicher ob man im HASH_TABLE auch 'like item' verwenden kann weil item ein Argument braucht --PeeDee 14:36, 17. Jun 2007 (CEST)
Hilf mit, die Qualität dieser Seite zu verbessern, indem du eine eindeutige Lösung einfügst oder auf der Diskussionsseite dieses Themas deine Meinung äusserst.

HASH_TABLE

feature
  has_item (v: G): BOOLEAN
  item (k: H): G
    require
      valid_key: valid_key (k)
      valid_key (k: H): BOOLEAN
  put (v: G; k: H)
    require
      valid_key: valid_key (k)
    ensure
      associated: item (k) = v

LIST

feature
  has (v: like item): BOOLEAN
  item: G
    require
      not_off: not off
      count: INTEGER
  is_empty: BOOLEAN
  off: BOOLEAN
  force (v: like item)
    ensure
      new_count: count = old count + 1
      item_inserted: has (v)
  append (s: like Current)
    require
      argument_not_void: s /= Void
    ensure
      new_count: count >= old count

5.3. Type checking

  • Y
  • N (list.item is STRING, expected is INTEGER)
  • Y
  • N (has is BOOLEAN, expected is STRING)
  • N (item is INTEGER, expected is STRING)

6. Abstract Data Types

6.1 Terminology

Question.png

Zu dieser Aufgabe waren Unklarheiten vorhanden, die nun gelöst sind. Mehr Details dazu finden sich auf der zugehörigen Diskussionsseite dieses Themas.

  • F, types are required as well. Furthermore, axioms and preconditions also express some semantics.
  • T
  • T
  • T
  • T
  • F, total functions are always defined.


6.2 Write an ADT

Question.png

Zu dieser Aufgabe waren Unklarheiten vorhanden, die nun gelöst sind. Mehr Details dazu finden sich auf der zugehörigen Diskussionsseite dieses Themas.

TYPES

ARRAY[G]

FUNCTIONS






PRECONDITIONS

make(l, u: INTEGER) require l <= u
item(a: ARRAY[G], i: INTEGER) require lower(a) <= i and upper (a) >= i
put(a: ARRAY[G], i: INTEGER, v: G) require lower(a) <= i and upper(a) >= i

AXIOMS

Question.png

Zu dieser Aufgabe waren Unklarheiten vorhanden, die nun gelöst sind. Mehr Details dazu finden sich auf der zugehörigen Diskussionsseite dieses Themas.

For any a: ARRAY[G], v: G, i: INTEGER

item(make(l,u),i) = default_value
item(put(a,v,i),j)
  = v                               iff i=j
  = item(a,j)                       iff i/=j
lower(make(l,u)) = l
lower(put(a,v,i)) = lower(a)
upper(make(l,u)) = u
upper(put(a,v,i)) = upper(a)

Nicht notwendig für sufficient completeness:

put(put(a,v,i),v',i')
  = put(a,v',i')                    iff i=i'
  = put(put(a,v',i'),v,i)           iff i/=i'

6.3 Sufficient completeness

Question.png

Zu dieser Aufgabe waren Unklarheiten vorhanden, die nun gelöst sind. Mehr Details dazu finden sich auf der zugehörigen Diskussionsseite dieses Themas.

Zu zeigen:

item(a,i), lower(a) und upper(a) können alle auf eine Form gebracht werden, die kein ARRAY[G] enthält.

Mithilfe der Axiome sollen wir das für alle möglichen Werte von a und i (a:ARRAY[G], i:INTEGER, beide erfüllen die Preconditions des jeweiligen Features) zeigen können. Mögliche Werte für a sind make(j,k) oder put(a, v, i). (Mögliche Werte für i trivial)