Métodos Formais em Engenharia de Software 3c

Slides:



Advertisements
Apresentações semelhantes
PHP Orientado a Objetos Análise e Desenvolvimento de Sistemas Prof
Advertisements

PROGRAMAÇÃO ORIENTADA A OBJETOS EM C++ Professor: Dilvan Moreira.
Modelagem Orientada a Objetos com UML Cursos para a CTI - IME/USP Dairton Bassi, Hugo Corbucci e Mariana Bravo Departamento de Ciência.
UNIVERSIDADE FEDERAL DE GOIÁS INSTITUTO DE INFORMÁTICA Sistemas Distribuídos Ciência da Computação 2o. Semestre / 2006 Prof. Fábio M. Costa
Classes Objetos Atributos Métodos Coletor de Lixo (Garbage Collector ) Confraria do Java Nivelamento. Caroline, Marcelo e Luiz 12/05/2007.
Linguagem de Programação – Aula 04 Prof. Me. Ronnison Reges Vidal
Métodos Formais em Engenharia de Software Especificação Baseada em Modelos em VDM++ (5ª parte) João Pascoal Faria
Polimorfismo e suas aplicações em C++.
Métodos Formais em Engenharia de Software Especificação Baseada em Modelos em VDM++ (2ª parte) João Pascoal Faria
Projecto de bases de dados relacionais:
Complementos de Engenharia de Software A linguagem VDM++ (1ª parte - Estrutura geral duma especificação; importação de.
Métodos Formais em Engenharia de Software Utilização da Ferramenta VDMTools Lite João Pascoal Faria
(baseado em slides de ex-alunos)
Introdução OO.
Complementos de Engenharia de Software A linguagem VDM++ (2ª parte - Operadores e expressões; definição de invariantes,
Análise e Projeto de Sistemas II
Programação Orientada a Objetos
MEI / LEIC Engenharia de Requisitos de Sistemas de Software Estudo de Casos - Caso da Colocação de Professores João Pascoal Faria Novembro de 2004.
Métodos Formais em Engenharia de Software Especificação Baseada em Modelos em VDM++ (4ª parte) João Pascoal Faria
Métodos Formais em Engenharia de Software Utilização da Ferramenta VDMTools Lite João Pascoal Faria
Teste e Qualidade de Software Teste baseado em modelos – exemplo da biblioteca João Pascoal Faria
Complementos de Engenharia de Software A linguagem VDM++ (4ª parte – Funções avançadas) João Pascoal Faria
Métodos Formais em Engenharia de Software Especificação Algébrica em CafeOBJ (3ª parte) João Pascoal Faria
Nataniel Vieira Endereçamento IP Nataniel Vieira
TQS - Teste e Qualidade de Software (Software Testing and Quality) Análise de cobertura de testes com a ferramenta Coverlipse.
João Pascoal Faria TQS - Teste e Qualidade de Software (Software Testing and Quality) Análise de cobertura de código com.
TQS - Teste e Qualidade de Software (Software Testing and Quality) Introdução a testes unitários automatizados com JUnit.
PROGRAMAÇÃO ORIENTADA A OBJETO - JAVA
3.1 Classes e Objetos Em um programa orientado a objetos normalmente existem vários objetos de um mesmo tipo. Por exemplo, um programa de controle de.
Tema 4 - Modelagem ER: Técnicas e Ferramentas
Introdução à Linguagem JavaScript
TQS - Teste e Qualidade de Software (Software Testing and Quality) Caso de estudo: Problema da procura duma string num.
FUNDAMENTO DE PROGRAMAÇÃO
POO - Classes Dilvan Moreira.
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas
Projeto de PLP (2006.1) Extensão da Linguagem OO1
Java: Interfaces Alcides Calsavara.
Estrutura de dados Pilhas e filas
Singleton e Template Method
Programador/a de Informática
Criação e manipulação de objetos
Programação Orientada a Objetos
Complementos de Engenharia de Software A linguagem VDM++ (3ª parte – instruções; aplicação à descrição de algoritmos e.
BANCO DE DADOS Araújo Lima Out / 2017 Araújo.
Programação Orientada a Objetos
Modelagem de Banco de Dados através do ERwin

TQS - Teste e Qualidade de Software (Software Testing and Quality) Teste baseado em modelos (visuais e formais): exemplo.
BANCO DE DADOS I.
TQS - Teste e Qualidade de Software (Software Testing and Quality) Discussão de Exercícios de Teste Baseado em Modelos.
Técnicas de Programação
MER – Modelo de Entidade Relacionamento
Programação Orientada a Objetos*
Rosemary Silveira Filgueiras Melo
3.2 Sobrecarga de Métodos (Overloading)
Rosemary Silveira Filgueiras Melo
Programação Orientada a Objetos
3.1.7 Variáveis de Classe e Instância
Programação Orientada a Objetos
Laboratório I Mateus Raeder.
Access Bd TransTic.
Curso básico de PHP. 1 Vantagens: Gratuito Multiplataforma Estável Rapidez Comunicação.
Módulo III Capítulo 2: SQLite
Aula Prática Objeto-Relacional Monitoria GDI
Arquitetura e padrões de software
Compilação de Linguagens OO
Modelagem de Banco de Dados
Introdução ao Modelo Relacional Capítulo 2 - Database System Concepts – 6ª. Ed - Silberschatz et al Curso: Ciência da Computação Disciplina: Banco de Dados.
Programação de Computadores II
Sistemas de Informação
Transcrição da apresentação:

jpf@fe.up.pt www.fe.up.pt/~jpf Métodos Formais em Engenharia de Software 3c. Especificação Baseada em Modelos em VDM++ (3ª parte) João Pascoal Faria jpf@fe.up.pt www.fe.up.pt/~jpf

Índice Definição de consultas tirando partido de operadores sobre conjuntos Acesso ao conjunto de instâncias duma classe a partir duma variável estática * Integridade referencial ao remover objectos Acesso ao conjunto de instâncias duma classe a partir dum objecto raiz Mapeamentos (maps) Modelação de associações qualificadas Modelação de generalizações Herança de invariantes * Enfraquecimento de pré-condições e fortalecimento de pós-condições Herança múltipla Resumo de mapeamento de UML para VDM++

Definição de consultas tirando partido de operadores sobre conjuntos Obter todos os ascendentes de uma pessoa: public GetAscendentes() res : set of Pessoa == return (if pai = nil then {} else {pai} union pai.GetAscendentes()) union (if mae = nil then {} else {mae} union mae.GetAscendentes()); Obter todos os descendentes de uma pessoa: public GetDescendentes() res : set of Pessoa == return GetFilhos() union dunion {f.GetDescendentes() | f in set GetFilhos()}; Obter todos os irmãos (e meios-irmãos) de uma pessoa: public GetIrmaos() res : set of Pessoa == return ((if pai = nil then {} else pai.GetFilhos()) union (if mae = nil then {} else mae.GetFilhos())) \ {self}; public GetDescendentes() res : set of Pessoa == ( dcl aux : set Of Pessoa := {}; dcl f : Pessoa; for f in set GetFilhos do aux := aux union {f} union f.GetDescendentes(); return aux ); ( dcl aux : set Of Pessoa := {}; dcl f : Pessoa; for f in set GetFilhos do aux := aux union {f} union f.GetDescendentes(); return aux ); Ver VDM/RegistoCivil_v2.zip

Acesso ao conjunto de instâncias duma classe a partir duma variável estática A referência de uma pessoa para os seus filhos é redundante, pois estes podem obter-se a partir das referências (dos filhos) para o pai e a mãe Mas, para isso, precisamos de ter acesso ao conjunto de instâncias da classe Pessoa Limitação: Em VDM++ não existe acesso automático ao conjunto de instâncias de uma classe O mesmo se passa nas linguagens de programação OO convencionais Em bases de dados relacionais e em OCL temos acesso automaticamente ao conjunto de instâncias (em OCL com classe.allInstances) Uma solução possível é guardar o conjunto de instâncias duma classe numa variável estática que é actualizada pelos construtores (e destrutores ?)

Acesso ao conjunto de instâncias duma classe a partir duma variável estática Pessoa … - pessoas: set of Pessoa Em UML, sublinhado significa estático (static) … + GetPessoas(): set of Pessoa + GetFilhos(): set of Pessoa

Acesso ao conjunto de instâncias duma classe a partir duma variável estática class Pessoa … instance variables … private static pessoas : set of Pessoa := { }; operations public Pessoa( … ) res : Pessoa == ( … ; pessoas := pessoas union {self}; … ) pre … ; public static GetPessoas() res : set of Pessoa == return pessoas; -- Ilustra como obter filhos a partir do conjunto de todas -- as instâncias e das referências para pai e mãe public GetFIlhos() res : set of Pessoa == return { f | f in set pessoas & f.GetPai() = self or f.GetMae() = self }; end Pessoa Construção de conjunto em compreensão Ver VDM/RegistoCivil_v2.zip

* Integridade referencial ao remover objectos * - Saltar numa 1ª leitura! * Integridade referencial ao remover objectos Se existir uma operação para remover uma pessoa (do conjunto de pessoas registadas na variável estática “pessoas”), é preciso alguma cautela para preservar a integridade das várias referências entre objectos (integridade referencial) Problema semelhante coloca-se em bases de dados relacionais, com restrições de integridade referencial (foreign key constraints) Nota: Em VDM++, não existe uma operação para eliminar explicitamente um objecto, o que podemos fazer é deixar de o referenciar ou removê-lo de um conjunto (de referências) O objecto existe enquanto for referenciado O mesmo se passa nas linguagens de programação OO de alto nível, como Java e C# (mas não C++ e na linguagem de acções de UML) Se por um lado isto é útil, por outro lado pode causar problemas, pois o objecto pode continuar a ser usado por quem tenha mantido uma referência para ele Mas é melhor esquecer este problema de “baixo nível” …

* Integridade referencial ao remover objectos Conceptualmente, a integridade referencial que queremos preservar ao remover pessoas (e não só) pode ser expressa pelo seguinte invariante: -- o conjunto de pessoas deve ser fechado pelas associações -- pai/mae/conjuge/exConjuges inv forall p in set pessoas & (p.pai <> nil => p.pai in set pessoas) and (p.mae <> nil => p.mae in set pessoas) and (p.conjuge <> nil => p.conjuge in set pessoas) and (elems p.exConjuges subset pessoas); Recomendação: esquecer este invariante de “baixo nível”, pois tem a ver com questões de “codificação” e não com o domínio do problema

* Integridade referencial ao remover objectos Algumas opções sobre como preservar a integridade referencial: Impedir a remoção se existirem objectos que referenciam o objecto a remover Formalizado por pré-condição Corresponde a “on delete restrict” em BDRs Pode ser demasiado restritivo, mas é o comportamento por defeito mais seguro Anular de alguma forma as referências para o objecto, antes de o remover Corresponde a “on delete set null” em BDRs Só é possível com associações para 0 ou 1, ou 0 ou mais Se for possível, é geralmente a melhor opção Eliminar os objectos que referenciam o objecto a remover, antes de o remover Corresponde a “on delete cascade” em BDRs Pode ser demasiado desastroso Soluções mistas, específicas do domínio em causa

* Integridade referencial ao remover objectos Exemplo da 1ª opção na classe Pessoa public Remover() == pessoas := pessoas \ {self} pre not exists p in set pessoas & p.pai = self or p.mae = self or p.conjuge = self or self in set elems p.exConjuges; Exemplo da 2ª opção na classe Pessoa public Remover() == ( for all p in set pessoas do if p.pai = self then p.SetPai(nil); if p.mae = self then p.SetMae(nil); if p.conjuge = self then p.SetConjuge(nil); if self in set elems p.exConjuges then p.RemoveExConjuge(self) ); pessoas := pessoas \ {self} ); Operações auxiliares a definir (não se pode fazer obj_ref.inst_var := valor) instrução “for all”, não confundir com expressão “forall”

Acesso ao conjunto de instâncias duma classe a partir dum objecto raiz Outra solução para ter acesso ao conjunto de instâncias de uma classe, e que escala para o caso de várias classes, é ter um “objecto raiz” a partir do qual se pode navegar para os restantes objectos do sistema (de uma ou mais classes) Na maioria dos sistemas acabamos por precisar de um objecto raiz para guardar alguns dados gerais Exemplo numa biblioteca: classe Biblioteca com referências para Publicação, Sócio e Empréstimo (tratado nas aulas práticas) Exemplo no sistema de registo civil: ver a seguir

Acesso ao conjunto de instâncias duma classe a partir dum objecto raiz classe só com uma instância (singleton) (o objecto raiz do sistema) RegistoCivil 1 + RegistaPessoa(p: Pessoa) + GetPessoas(): set of Pessoa + GetFilhos(p: Pessoa): set of Pessoa Todas as pessoas estão registadas 1 navegação do objecto raiz para as instâncias de Pessoa * -pessoas Pessoa

Acesso ao conjunto de instâncias duma classe a partir dum objecto raiz class RegistoCivil instance variables private pessoas : set of Pessoa := { }; operations public RegistaPessoa(p : Pessoa) == pessoas := pessoas union {p} pre not p in set pessoas; public GetPessoas() res : set of Pessoa == return pessoas; public GetFIlhos(p: Pessoa) res : set of Pessoa == return { f | f in set pessoas & f.GetPai() = p or f.GetMae() = p } pre p in set pessoas; end RegistoCivil regista uma instância de Pessoa previamente criada

* Acesso ao conjunto de instâncias duma classe a partir dum objecto raiz O modelo anterior em VDM++ não garante duas restrições do modelo UML: Podem existir instâncias de “Pessoa” que não estão registadas em “RegistoCivil” (violando multiplicidade 1 num dos extremos da associação) (2) Podem existir múltiplas instâncias de “RegistoCivil” (violando multiplicidade 1 da classe) Em consequência disso, uma pessoa registada em “RegistoCivil” pode ter pessoas relacionadas (pai, mãe, cônjuge, ex-conjuges) que não estão registadas ou estão registadas numa instância diferente de “RegistoCivil” É o mesmo problema de integridade referencial que já apareceu na solução com uma variável estática, ao introduzir a operação de remover pessoa Em consequência disso, por exemplo “GetFilhos” só dá efectivamente os filhos registados na mesma instância de “RegistoCivil” Abordagem recomendada: ignorar estas questões de “codificação”, e pressupor que o modelo é “bem utilizado” No arranque do sistema, deve-se criar uma instância única de “RegistoCivil” Cada nova instância de “Pessoa” deve ser imediatamente registada em “RegistoCivil”

* Acesso ao conjunto de instâncias duma classe a partir dum objecto raiz Se fizermos questão (não recomendado), podemos impor (de forma pouco declarativa) as multiplicidades indicadas no diagrama UML Para garantir que a classe “RegistoCivil” tem exactamente uma instância (padrão singleton, http://en.wikipedia.org/wiki/Singleton_pattern): class RegistoCivil instance variables private static uniqueInstance : RegistoCivil := new RegistoCivil(); operations -- construtor privado, para impedir criação de objectos fora da classe private RegistoCivil() res: RegistoCivil == return self; -- acesso público à única instância da classe (criada internamente) public static GetUniqueInstance() res: RegistoCivil == return uniqueInstance; end RegistoCivil

* Acesso ao conjunto de instâncias duma classe a partir dum objecto raiz Para garantir que todas as instâncias de Pessoa estão associadas à única instância de RegistoCivil: class Pessoa operations public Pessoa(…) … ( …; RegistoCivil`GetUniqueInstance().RegistaPessoa(self); … ) pre …; end Pessoa Também podemos passar a operação GetFilhos para a classe Pessoa: class Pessoa operations public GetFilhos() res : set of Pessoa == return { f | f in set RegistoCivil`GetUniqueInstance().GetPessoas() & f.GetPai() = self or f.GetMae() = self } end Pessoa Ver VDM/RegistoCivil_v3.zip

Mapeamentos (maps) Um mapeamento (map) é uma função finita definida em extensão Faz corresponder a cada elemento (chave) de um conjunto A, ou de um subconjunto de A, um elemento (valor) doutro conjunto B Sintaxe: map A to B ou inmap A to B (mapeamento injectivo) A e B são tipos de dados quaisquer Cada elemento de um mapeamento é designado maplet e representa-se em ASCII na forma chave |-> valor Domínio: Conjunto de elementos de A que têm um valor correspondente em B Contra-domínio (range): Conjunto de elementos de B que correspondem a alguma chave de A

Mapeamentos (maps) Construtores: Por enumeração: {a1 |-> b1, a2 |-> b2, ..., an |-> bn} Constructs a mapping of the enumerated maplets. The empty map will be written as {|->}. Em compreensão: {ed |-> er | bd1, ..., bdn & P} constructs a mapping by evaluating the expressions ed and er on all the possible bindings for which the predicate P evaluates to true bd1, ..., bdn are bindings of free identifiers from the expressions ed and er to sets or types

Mapeamentos (maps) (fonte: langmanpp_a4.pdf)

Mapeamentos (maps)

Mapeamentos (maps)

Mapeamentos (maps)

Mapeamentos (maps)

Mapeamentos (maps)

Mapeamentos (maps)

Modelação de associações qualificadas RegistoCivil 1 + RegistaPessoa(p: Pessoa, bi: nat) + ProcuraPessoa(bi: nat) : [Pessoa] + RegistaPessoa(p: Pessoa, bi: nat) + GetPessoa(bi: nat) : [Pessoa] bi : nat Qualificador: atributo(s) usado(s) para navegar de “RegistoCivil” para Pessoa (chave de navegação) 1 A cada número de bi corresponde 0 (no caso de nº não atribuído) ou 1 pessoa 0..1 - pessoas Associação qualificada Pessoa

Modelação de associações qualificadas Associações qualificadas são modeladas através de mapeamentos (map) ou mapeamentos injectivos (inmap), conforme a multiplicidade class RegistoCivil types public BI = nat; instance variables private pessoas : inmap BI to Pessoa := { |-> } ; operations public RegistaPessoa(bi: BI, p : Pessoa) == pessoas := pessoas munion { bi |-> p } pre not bi in set dom pessoas and not p in set rng pessoas ; public GetPessoa(bi: BI) res : [Pessoa] == return if bi in set dom pessoas then pessoas(bi) else nil; end RegistoCivil mapeamento vazio Ver VDM/RegistoCivil_v4.zip

Modelação de generalizações Pessoa # sexo : Sexo Homem Mulher {sexo = <Masculino>} {sexo = <Feminino>} class Pessoa instance variables protected sexo : Sexo; end Pessoa class Homem is subclass of Pessoa inv sexo = <Masculino> ; end Homem class Mulher is subclass of Pessoa inv sexo = <Feminino> ; end Homem

Herança de invariantes A subclasse herda os invariantes da super-classe, podendo acrescentar outros (fortalecendo o conjunto de invariantes) class Homem is subclass of Pessoa inv sexo = <Masculino> ; end Homem

* Enfraquecimento de pré-condições e fortalecimento de pós-condições Ao redefinir uma operação herdada da superclasse, não se deve violar o contracto (pré-condição e pós-condição) estabelecido na super-classe A pré-condição pode ser enfraquecida (relaxada) na subclasse, mas não fortalecida (não pode ser mais restritiva) qualquer chamada que se prometia ser válida na pré-condição da superclasse, deve continuar a ser aceite na pré-condição da subclasse pre_op_superclass => pre_op_subclass A pós-condição pode ser fortalecida na subclasse, mas não enfraquecida a operação na subclasse deve continuar a garantir os efeitos prometidos na superclasse, podendo acrescentar outros efeitos post_op_subclass => post_op_superclass

* Enfraquecimento de pré-condições e fortalecimento de pós-condições class Figura types public Ponto :: x : real y : real; instance variables protected centro : Ponto; operations public Resize(factor: real) == is subclass responsibility pre factor > 0.0 post centro = centro~; end Figura class Circulo is subclass of Figura instance variables private raio : real; inv raio > 0; operations public Circulo(c: Ponto, r: real) res:Circulo == ( raio := r; centro := c; return self ) pre r > 0; public Resize(factor: real) == raio := raio * abs(factor) pre factor <> 0.0 post centro = centro~ and raio = raio~ * abs(factor); end Circulo abstracta pre_Figura`Resize(…) post_Figura`Resize(…)   pre_Circulo`Resize(…) post_Circulo`Resize(…)

TrabalhadorEstudante Herança múltipla Em VDM++, uma classe pode herdar (ser subclasse) de mais do que uma superclasse Pessoa Trabalhador Estudante TrabalhadorEstudante class TrabalhadorEstudante is subclass of Trabalhador, Estudante end TrabalhadorEstudante

Resumo de mapeamento de UML para VDM++ C2 r5 r3 C5 C1 C3 * q : Q 1 r4 r6 r7 C4 C6 {ordered} 0..1 0..1 * C7 class C1 is subclass of C2 instance variables r3 : C3; r4 : [C4]; r5 : set of C5; r6 : seq of C6; r7 : map Q to C7; end C1 seq1 se for para 1..* inmap se for de 0..1

Referências e leituras adicionais Manual de VDM++ (langmanpp_a4.pdf) Manual de VDMTools (usermanpp_a4.pdf) Modelling Systems: Practical Tools and Techniques in Software Development, John Fitzgerald and Peter Gorm Larsen, Cambridge University Press, 1998.  (existe na biblioteca da FEUP) Validated Designs for Object-oriented Systems. John Fitzgerald, Peter Gorm Larsen, Paul Mukherjee, Nico Plat and Marcel Verhoef. ISBN: 1-85233-881-4. Springer Verlag, New York. 2005. Specification of Software Systems, V.S. Alagar and K. Periyasamy, ISBN: 0-387-98430-5, Springer, 1998.