Upload
fernanda-bastos-coimbra
View
215
Download
2
Embed Size (px)
Citation preview
Especificação Formal de Software
Alexandre Mota([email protected])
Desenvolvendo o SistemaDocumento
deRequisitos
...
Problema Solução
Um Modelo
ClienteConta
Poupança
Banco
0..* 0..*
1 1
1..* 1..*
Mais Precisão... Para caracterizar melhor um
sistema, sem entrar em detalhes de implementação, fazemos uso de: Pré-condições Pós-condições Invariantes Propriedades
Pré-condição Pré-condições são associadas a
operações (métodos) Sua utilidade é caracterizar uma
condição (restrição) sobre a aplicabilidade da operação
Se a condição for válida, a execução da operação é garantida não gerar exceções
Pós-condição Pós-condições são associadas a
operações também Sua utilidade é descrever em que
condição o sistema irá estar após a realização com sucesso (terminação) da operação
Invariante Para modelos orientados a objetos, o
invariante é associado a classes Daí, denominar-se de invariante da classe Sua utilidade é estabelecer os limites
válidos sobre as instâncias (objetos) criadas por uma classe
Assim, devido ao invariante, nem todos as instâncias são possíveis de serem criadas ou de efetuarem certas operações que mudem seus atributos
Propriedades Todo sistema é esperado satisfazer
a propriedades desejáveis Ausência de deadlock, composições de
operações bem-sucedidas, etc. Portanto, para toda classe podemos
estabelecer quais propriedades ela deve satisfazer
Tais propriedades podem ser usadas posteriormente na fase de testes
Anotando um Modelo Um diagrama de classes UML pode
ser anotado com formalismos O padrão de UML é anotar seus
diagramas com OCL (Object Contraint Language)
OCL é uma linguagem que explora textualmente elementos de lógica de predicados e teoria dos conjuntos é substituído por implies é substituído por forall
Anotando um Modelo
ClienteConta
Poupança
Banco
0..* 0..*
1 1
idade: int
{idade>17}
1..* 1..*
Anotando um Modelo Infelizmente, OCL não possui
suporte de ferramentas para explorar as restrições estabelecidas
A única ferramenta para OCL atualmente é um verificador de sintaxe e de tipos (parcial)
Portanto, usaremos lógica de predicados e teoria dos conjuntos (Z) pois existem mais ferramentas
A Notação Tal qual OCL, nossa linguagem
também é bastante textual Assim,
é obtido através de \implies é conseguido com \forall
Essa linguagem é nada mais que uma codificação em LaTeX (versão LaTeX para os elementos gráficos de Z)
Tipos Pré-Definidos Em nossa notação, assumiremos
três tipos básicos pré-definidos Naturais (\nat)
0, 1, 2, 3, ... Inteiros (\num)
..., -3, -2, -1, 0, 1, 2, 3, ... Booleanos (Bool)
true, false
Construtores de Tipos Dispomos de vários tipos para
caracterizarmos os problemas Given sets (conjuntos genéricos) Free-types (tipos enumerados) Conjunto potência (das partes) Produto cartesiano Relações Funções Seqüências Bags
Hierarquia de Tipos
Conjuntos ( P)IGiven Sets Free-Types
Relações ()
Funções ()
Seqüências (seq) Bags (bag)
Tuplas (...)
Given Sets Usam-se given sets quando não se tem
interesse sobre a estrutura dos elementos de tais conjuntos
Elementos de given sets são meramente identificadores
Somente operações sobre conjuntos independentes de tipos podem ser aplicadas a given sets (, , , etc.)
Para criá-los em um diagrama, basta digitar seus nomes nos espaços referentes a tipos
Exemplo de Given Set
Clienteid: ID Given set ID
Free-Types São os conhecidos tipos enumerados
de linguagens de programação (apesar de mais versáteis)
Sua versatilidade advém do fato de podermos definir tipos recursivos (construtores)
Normalmente usados para caracterizar as mensagens que o sistema irá exibir
Free-Types<<enumeration>>
Mensagensokfalha
<<enumeration>>Nat
zerosucc \ldata Nat \rdata
Enumeração Simples
Enumeração Recursiva
Produto Cartesiano Quando se deseja formar tuplas de
elementos de tipos base Usa-se T1 \cross T2 \cross ... \cross Tn Seus elementos são identificados
como (A, 2, casa) ou (3, 4) As funções first e second aplicam-se
a 2-uplas ou pares first (1, 2) = 1 e second (1, 2) = 2
Produtos Cartesianos first (x, y) second (x, y)
Conjunto Potência Para usar o conjunto potência, basta
prefixar o tipo base com \power Exemplo:
\power \{0, 1\} = \{ \{\}, \{0\}, \{1\}, \{0, 1\}\}
O tipo potência deve ser usado quando instâncias são conjuntos em si
Conjuntos Potência # A A = B, A B x A, x A , A B, A B A B, A B, A \ B AA, AA
Relações O tipo relação é obtido através do
operador \rel entre dois tipos Pessoa \rel Endereço
Produz subconjuntos de produtos cartesianos
Usado para capturar dependência entre dois tipos base
Relações dom R, ran R R ; S, S R A R, R A A R, R A R~
R A
(| )|
Funções Funções são tipos especiais de
relações Assim, funções provém de relações
com acréscimos de restrições Tipo mais comum de função é a parcial
Pessoa \pfun Endereço Esse relacionamento indica que nem toda
pessoa tem endereço
Funções F G
Seqüências Seqüências são especializações de
funções São obtidas com o prefixo \seq sobre
o tipo base \seq Pessoa
Contrariamente a conjuntos, seqüências são empregadas quando se deseja capturar a ordem entre os elementos
Seqüências S1 S2 head S, tail S front S, last S rev S
(
Bags Bags são usados para capturar a
repetição de elementos através de freqüência (ocorrência)
Usa-se o operador \bag prefixado sobre o tipo base
Normalmente, bags são usados como armazenadores de quantidades (“estoques”)
Bags count B x x in B B1 B2, B1 B2 items S
+ -
Detalhando o Modelo: Banco
0..n 0..n
1 0..n
BancocadastrarremovercreditardebitargetSaldotransferir
PoupançarenderJuros
Contanumero: NUMsaldo: \natgetNumgetSaldocreditardebitar
Clienteid: IDnome: NOMEgetIdgetNome
clientescontas
dono
Detalhando as Classes Para cada classe do diagrama
anterior: Descrever a funcionalidade de cada
método através de: Pré-condição Pós-condição
Caracterizar o invariante da classe
Classe ClienteCliente- id: ID- nome: NOMEgetIdsetIdgetNomesetNome
getId() pré: pós: result! = id
setId(id: ID) pré: pós: id’ = id?
getNome() pré: pós: result! = nome
setNome(nome: NOME) pré: pós: nome’ = nome?
Classe ContaConta- num: NUM- saldo: INgetNum()setNum()getSaldo()setSaldo()creditar()debitar()
getNum() pré: pós: result! = num
setNum(num: NUM) pré: pós: num’ = num?
getSaldo() pré: pós: result! = saldo
setSaldo(saldo: IN) pré: pós: saldo’ = saldo?
Classe ContaConta- num: NUM- saldo: IN...creditar()debitar()
creditar(val: IN) pré: pós: saldo’ = saldo + val?
debitar(val: IN) pré: saldo val? pós: saldo’ = saldo - val?
Invariante Classe Banco
cl: clientes cl null cc: contas cc null c1,c2: contas | c1 c2
c1.getNum() c2.getNum() cl1,cl2: clientes | cl1 cl2
cl1.getId() cl2.getId()
Classe Banco
Banco
cadastrar()remover()creditar()debitar()transferir()
ATENÇÃO: Esta classe possui dois atributos implícitos nomeados de contas: IP Conta e clientes: IP Cliente, respectivamente
cadastrar(conta: Conta) pré: conta? null
cc:contas cc.getNum() conta? pós: contas´ = contas {conta?}
remover(conta: Conta) pré: conta? null
cc:contas cc.getNum() = conta? pós: contas´ = contas \ {conta?}
Desenvolvendo o Sistema
...
Problema Solução
O que eu desejo GARANTIR na minha solução???
Operadores em Propriedades Para estabelecer propriedades
entre operações, podemos usar , , , , , , \ (.../...) pre, ;
Propriedade sobre Conta É verdade que, para uma mesma
conta, creditar um valor e, em seguida, debitar o mesmo valor resultará no mesmo estado inicial da conta?
Como garantir isso? v, saldo, saldo’: IN
creditar(v) ; debitar(v) saldo’=saldo
Propriedade sobre Conta Como garantir que creditar é uma
operação comutativa? Ou seja, creditar um valor v1 e depois v2 é o mesmo que creditar o valor v2 e depois o v1.
Bibliografia Booch, G. et al. The Unified Modeling Language
User Guide Sommerville, I. Software Engineering Tepfenhart, W. et al. Practical Object-Oriented
Development with UML and Java Woodcock, J. et al. Using Z (
http://www.usingz.com/) Spivey, J.M. The Z Notation (
http://spivey.oriel.ox.ac.uk/~mike/zrm/) Kruchten, P. The Rational Unified Process: An
Introduction