Soluciones a los casos de estudio del Tema 2.2 Ingeniería del Software II R. Corchuelo Índice ♦ La interfaz IQueue ♦ La nueva IBankAccount ♦ La interfaz Iterator Índice ♦ La interfaz IQueue ♦ La nueva IBankAccount ♦ La interfaz Iterator La interfaz IQueue interface IQueue { Object first(); void append(Object obj); void delete(); int size(); } Contrato sencillo contract QueueSem on IQueue { @query first, size @inv size() >= 0 @init size() == 0 result first() { @pre size() > 0 # EmptyQueueException } …sigue… Contrato sencillo …continuación… append(obj) { @pos size() == size()@pre + 1 @pos (size()@pre == 0 ==> first() == obj) @pos (size()@pre > 0 ==> first() == first()@pre) } delete() { @pre size() > 0 # EmptyQueueException @pos size() == size()@pre - 1 } } Un modelo necesitamos interface QueueMod { // Devuelve el objeto que se encuentra en la posición // i-ésima de la cola. El elemento en la cabeza de la cola // está en la posición 1, el siguiente en la 2 y el elemento // al final de la cola está en la posición size() Object at(int i); } Un contrato más completo contract QueueSem on IQueue with QueueMod { @query first, size @inv size() >= 0 @init size() == 0 result first() { @pre size() > 0 # EmptyQueueException @pos result == at(1) } …sigue… Un contrato más completo …continuación… append(obj) { @pos size() == size()@pre + 1 @pos at(size()) == obj @pos forall int i in {1..size()@pre} · at(i) == at(i)@pre } delete() { @pre size() > 0 # EmptyQueueException @pos size() == size()@pre – 1 @pos forall int i in {1..size()} · at(i) == at(i + 1)@pre } } Índice ♦ La interfaz IQueue ♦ La nueva IBankAccount ♦ La interfaz Iterator La nueva IBankAccount interface IBankAccount { void payIn(float amt); void withdraw(float amt); float getBalance(); void setOverdraftLimit(float limit); float getOverdraftLimit(); } Un contrato sencillo contract BankAccountSem on IBankAccount { @query getBalance, getOverdraftLimit @inv getOverdraftLimit() >= 0 @inv -getOverdraftLimit() <= getBalance() @init getBalance() == 0 && getOverdraftLimit() == 0 payIn(amt) { @pre amt > 0 @pos getBalance() == getBalance@pre + amt @pos getOverdraftLimit() == getOverdraftLimit()@pre } …sigue… Un contrato sencillo …continuación… withdraw(amt) { @pre amt > 0 @pre –getOverdraftLimit() <= getBalance() – amt @pos getBalance() == getBalance()@pre - amt @pos getOverdraftLimit() == getOverdraftLimit()@pre } setOverdraftLimit(limit) { @pre limit >= 0 @pre –lim <= getBalance() @pos getOverdraftLimit() == limit @pos getBalance() == getBalance()@pre } } Un contrato con modelo interface BankAccountMod { Record getRecord(int i); int getNoRecords(); } contract IBankAccountSem on IBankAccount with BankAccountMod { … result getBalance() { @pre true @pos result == sum(i = 1..getNoRecords(), getRecord(i).getAmount()) … } Cómo acabamos este contrato ¡Completar este contrato será la pregunta del examen! Índice ♦ La interfaz IQueue ♦ La nueva IBankAccount ♦ La interfaz Iterator La interfaz Iterator interface Iterator { bool hasNext(); Object next(); } // Este es el idiom habitual de uso de iteradores Data data; Item itm; Iterator itr; data = …crear la estructura… itr = data.iterator(); while (itr.hasNext()) { itm = (Item)itr.Next(); …procesar itm… } Un contrato sencillo contract IteratorSem on Iterator { @query hasNext result next() { @pre hasNext() } } Un posible modelo interface IteratorMod { Object at(int i); int size(); int pos(); } Un contrato con modelo contract IteratorSem on Iterator with IteratorMod { @query hasNext @init pos() == 1 result hasNext() { @pos result <==> (pos() < size() + 1) } result { @pre @pos @pos @pos @pos } } next() pos() <= size() pos() == pos()@pre + 1 result == at(pos()@pre) size() == size()@pre forall int i in {1..size()} · at(i) == at(i)@pre ¡Gracias! Plantea tus sugerencias y dudas en el foro de la asignatura Directorio: mailman/listinfo/isw2-dist Servidor: http://listas.us.es