Implementação de Classe e Auto-Relacionamento em C++ · requisitos e esse pré-requisito é uma...

15
Implementação de Classe e Auto-Relacionamento em C++ 1) Introdução Um modelo de Diagrama de Classes representa a estrutura definida para o armazenamento das informações dos elementos ou classes que irão trabalhar em conjunto para solucionar um problema ou desafio. Sendo esse diagrama um modelo conceitual, existe a necessidade de verificar a validade e completude desse modelo. Uma das formas de se fazer isso é por meio de implementação, ou geração de códigos em uma linguagem de programação Orientada a Objetos e realizações de testes de seu uso. Neste material, será analisado um modelo de uma classe que possui um relacionamento com ela mesmo. Quando isso ocorre, diz-se que há um Auto- Relacionamento. Como objeto de estudo, definine-se uma classe que representa o conceito Disciplina. Considera-se, neste exemplo, que uma Disciplina possa possuir ou não como pré-requisitos outras instâncias da Disciplina. Ou seja, ela se relaciona com ela mesmo por meio do conceito “pré-requisito”. Por exemplo, na Figura 1 a seguir, a disciplina EL65E possui como pré-requisito as disciplinas EL64E, EL64F e EL64G. A disciplina EL64E, por sua vez, possui como pré-requisito a disciplina FI64A. Como essa estrutura poderia ser representada em um Modelo Orientado a Objetos? Para responder a essa questão, este documento está divido em 5 Seções. Na Segunda Seção, apresenta-se o cartão CRC da classe Disciplina. Na Seção 3, a partir do cartão CRC, o modelo UML da classe é definido e apresentado. Nesse instante, destaca- se que novas responsabilidades que não foram definidas no cartão CRC foram criadas com a finalidade de orientar o programador de computador e também facilitar ou permitir o (re)uso da classe. A Seção 4 apresenta a implementação da classe Disciplina. Encerrando este documento, na Seção 5 um exercício é deixado para o aluno resolver. De maneira similar ao descrito anteriormente, o programador de computador deve ter a liberdade de definir ou personalizar a implementação. Ou seja, o programador de UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 1 Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++ ----------------------------------------------------------------------------------------------------------------------------------------------

Transcript of Implementação de Classe e Auto-Relacionamento em C++ · requisitos e esse pré-requisito é uma...

Implementação de Classe e Auto-Relacionamento em C++

1) Introdução

Um modelo de Diagrama de Classes representa a estrutura definida para o

armazenamento das informações dos elementos ou classes que irão trabalhar em

conjunto para solucionar um problema ou desafio. Sendo esse diagrama um modelo

conceitual, existe a necessidade de verificar a validade e completude desse modelo. Uma

das formas de se fazer isso é por meio de implementação, ou geração de códigos em

uma linguagem de programação Orientada a Objetos e realizações de testes de seu uso.

Neste material, será analisado um modelo de uma classe que possui um

relacionamento com ela mesmo. Quando isso ocorre, diz-se que há um Auto-

Relacionamento.

Como objeto de estudo, definine-se uma classe que representa o conceito

Disciplina. Considera-se, neste exemplo, que uma Disciplina possa possuir ou não como

pré-requisitos outras instâncias da Disciplina.

Ou seja, ela se relaciona com ela mesmo por meio do conceito “pré-requisito”. Por

exemplo, na Figura 1 a seguir, a disciplina EL65E possui como pré-requisito as disciplinas

EL64E, EL64F e EL64G. A disciplina EL64E, por sua vez, possui como pré-requisito a

disciplina FI64A.

Como essa estrutura poderia ser representada em um Modelo Orientado a

Objetos? Para responder a essa questão, este documento está divido em 5 Seções. Na

Segunda Seção, apresenta-se o cartão CRC da classe Disciplina. Na Seção 3, a partir do

cartão CRC, o modelo UML da classe é definido e apresentado. Nesse instante, destaca-

se que novas responsabilidades que não foram definidas no cartão CRC foram criadas

com a finalidade de orientar o programador de computador e também facilitar ou permitir o

(re)uso da classe. A Seção 4 apresenta a implementação da classe Disciplina. Encerrando

este documento, na Seção 5 um exercício é deixado para o aluno resolver.

De maneira similar ao descrito anteriormente, o programador de computador deve

ter a liberdade de definir ou personalizar a implementação. Ou seja, o programador de

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 1Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

computador implementa além dos métodos e atributos definidos no Diagrama de Classes

UML, novos métodos e atributos que ele/ela achar necessário.

Figura 1 - Grade parcial do Curso de Engenharia Industrial Elétrica da UTFPR, campus Curitiba adaptada para o exemplo investigado.

2)Representação Classe Disciplina O Cartão CRC apresentado na Figura 2, define os atributos ou “conhecimentos”

que um elemento da classe Disciplina deve possuir.

Figura 2 - CRC da Classe Disciplina

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 2Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

O cartão CRC representado na Figura 2 possui na área de Colaboradores, uma

própria instância da classe Disciplina. O Auto-Relacionamento ocorre quando é definido

como colaborador para uma classe, um exemplar da própria classe. Nesse caso, no canto

à direita do cartão CRC existe uma referência à própria classe do cartão, a classe

Disciplina. Isso acontece pois uma disciplina pode possuir nenhum, um ou vários pré-

requisitos e esse pré-requisito é uma outra instância da classe Disciplina.

3)Diagrama UML da Classe Disciplina A Figura 3, a seguir, apresenta o Diagrama de Classe da Classe Disciplina definida

no cartão CRC ilustrado na Figura 2. Alguns detalhes e considerações utilizadas nessa

representação merecem destaque, a saber:

• No diagrama UML, cada responsabilidade indicada no CRC, pode ser um atributo ou

um método.

• As responsabilidades Codigo, Nome, Quantidade de Aulas Teóricas, Quantidade de

Aulas Práticas e Quantidade de Aulas a Distância definidas no cartão CRC da Figura

2 foram representadas no diagrama da Figura 3.Os Anexos 6a), 6b), 6c) e 6d)

ilustram a associação entre as responsabilidades do cartão CRC e o Diagrama de

Classe.

• Cada atributo foi definido com o modificador de acesso private ou privado. Isso é

apenas uma recomendação: “atributos devem ser definidos com acesso private ou

protected”. Essa representação é indicada pelo sinal “-” que precede o atributo.

• Para cada atributo, métodos de acesso “geters” e “seters” de visibilidade pública

foram definidos. Por exemplo, os métodos públicos “+setNome(v: String) : void” e

“+getNome() : String” estão associados ao atributo Nome.

• A responsabilidade “pre-requisito”, por sua vez não foi representada de maneira

explícita no diagrama. De acordo com o diagrama, esse auto-relacionamento possui

a multiplicidade “0..*”. Essa multiplicidade significa que a quantidade de pré-

requisitos pode variar de instância de classe para instância de classe. O Anexo 6e)

ilustra a associação entre a representação do Auto-Relacionamento do Diagrama

UML e o cartão CRC.

• Cada linguagem de programação fornece ao programador um conjunto de opções

para representar o AUto-Relacionamento. Por exemplo, na linguagem C++, poder-

se-ia representar, por exemplo, com listas, vetores ou arrays esse conjunto de

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 3Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

elementos. Por outro lado, na linguagem Java, outras opções também estão

disponíveis. Para deixar o programador livre para definir qual será a forma de

implementação desse grupo de elementos, optou-se apenas por definir um método

de inclusão e outro de remoção de pré-requisito. Os métodos são

“addPreRequesitoNecessario(Disciplina)” e “removePreRequisitoNecessario

(Disciplina)”.

• As duas últimas responsabilidades definidas no cartão CRC “lista de quem sou pré-

requisito” e “lista pré-requisitos necessários” foram definidas como dois métodos no

diagrama de classes. Esses métodos são: listaPreRequisitosNecessarios() e

listaDeQuemSouPreRequisito().

• Três outros métodos foram definidos no diagrama de classes e que não foram

previstos no cartão CRC. Esses métodos são: i) “print( )”, ii) “equals(Disciplina)” e iii)

“clone( )”. O método “print( )” imprime as informações consideradas importantes do

conceito Disciplina. Por sua vez, o método “equals(Disciplina)”, verifica se duas

instâncias da classe disciplina podem ser consideradas iguais. O método “clone( )”

fornece uma cópia da instância.

• Dois construtores também foram definidos. Um deles, não recebe argumento algum

e o outro, recebe o código da disciplina e o seu respectivo nome.

• O Auto-Relacionamento denominado por “preRequisito” é representado por uma

linha que inicia e termina na própria classe. A multiplicidade desse relacionamento é

“0..*”. Essa multiplicidade informa que uma determinada instância da classe

Disciplina pode possuir nenhum, um pré-requisito ou vários.

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 4Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

Figura 3 - UML - Diagrama de Classe da Classe Disciplina

4.Implementação em C++

A definição da assinatura da classe é apresentada no arquivo Disciplina.h a seguir.

Algumas decisões realizadas necessitam ser exclarecidas, a saber:

• os atributos Nome e Codigo da Figura 3 foram definidos como elementos std::string.

• o Auto-Relacionamento é representado por elementos Vector. Nesse exemplo definiu-se

dois vetores ou vectors para armazenar as disciplinas que são pre-requisitos e também

de quais disciplinas a classe é pre-requisito.

• os métodos que irão fazer modificação nas instâncias de classes passadas como

parâmetros tiveram seus parâmetros definidos como ponteiros. Por exemplo: void addPreRequisitoNecessario(Disciplina *v);

• Alguns métodos que não foram definidos no Diagrama de Classes da Figura 3 foram

definidos durante a programação. Esses métodos são:

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 5Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

• vector<Disciplina> getPreRequisitos(); > definida com a finalidade de

mostrar como um método pode ter uma instância da classe vector de retorno.

• bool tenhoPreRequisitoNecessario(Disciplina v); > definido apenas

como método auxiliar para os outros métodos. Por não ter sido definido no Diagrama

de Classes, poderia ter sua visibilidade privada.

• bool souPreRequisito(Disciplina v); > definido apenas como método

auxiliar para os outros métodos. Por não ter sido definido no Diagrama de Classes,

poderia ter sua visibilidade privada.

4.1 Arquivo Disciplina.h

#include <string>

#include <vector>

using namespace std;

#pragma once

! class Disciplina {

! private:

! ! std::string Codigo;

! ! std::string Nome;

! ! int QuantidadeAulasTeoricas;

! ! int QuantidadeDeAulasPraticas;

! ! int QuantidadeDeAulasDistancia;

vector<Disciplina> preRequisitoNecessarios;

vector<Disciplina> deQuemSoupreRequisito;

! public:

! ! Disciplina(std::string v_codigo,std::string v_nome);

! ! Disciplina();

! ! void setQuantidadeAulasTeoricas(int v);

! ! void setQuantidadeAulasPraticas(int v);

! ! void setQuantidadeAulasDistancia(int v);

! ! int getQuantidadeAulasTeoricas();

! ! int getQuantidadeAulasPraticas();

! ! int getQuantidadeAulasDistancia();

! ! void setNome(std::string v);

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 6Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

! ! std::string getNome();

! ! void setCodigo(std::string v);

! ! std::string getCodigo();

void addPreRequisitoNecessario(Disciplina *v);

! void removePreRequisitoNecessario(Disciplina *v);

!vector<Disciplina> getPreRequisitos();

!bool tenhoPreRequisitoNecessario(Disciplina v);

!bool souPreRequisito(Disciplina v);

!void listaPreRequisitosNecessarios();

!void listaDeQuemSouPreRequisito();

!bool equals(Disciplina v);

!void print();

!Disciplina clone();

! };

// fim do arquivo h.

4.2 O Arquivo Disciplina.cpp

#include "Disciplina.h"#include <iostream>#include <ctype.h>

void Disciplina::print() { std::cout << endl; for (int i = 0; i < 70; i++) std::cout << "="; std::cout <<endl;

std::cout << "Disciplina Codigo: "! << Disciplina::Codigo << std::endl << "Disciplina Nome: " << Disciplina::Nome << std::endl << "Disciplina Quantidade de Aulas Teoricas: " << Disciplina::QuantidadeAulasTeoricas << std::endl << "Disciplina Quantidade de Aulas Praticas: " << Disciplina::QuantidadeDeAulasPraticas << std::endl << "Disciplina Quantidade de Aulas a Distancia: " << Disciplina::QuantidadeDeAulasDistancia << std::endl << "Total das aulas: " << (Disciplina::QuantidadeAulasTeoricas + Disciplina::QuantidadeDeAulasDistancia + Disciplina::QuantidadeDeAulasPraticas) << std::endl ; Disciplina::listaPreRequisitosNecessarios(); Disciplina::listaDeQuemSouPreRequisito();}void Disciplina::listaPreRequisitosNecessarios(){ // lista dos pre-requisitos std::cout << "Quantidade de Pre-Requisitos Necessarios: " << Disciplina::preRequisitoNecessarios.size() << std::endl; if (Disciplina::preRequisitoNecessarios.size() > 0)

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 7Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

{ vector<Disciplina>::const_iterator i; for(i=Disciplina::preRequisitoNecessarios.begin() ; i!=Disciplina::preRequisitoNecessarios.end(); i++) { cout << "\t Codigo : " << (*i).Codigo << " \t Nome : " << (*i).Nome << std::endl; } }}void Disciplina::listaDeQuemSouPreRequisito(){ std::cout << "Quantidade de Disciplinas em que sou Pre-Requisito: " << Disciplina::deQuemSoupreRequisito.size() << std::endl; if (Disciplina::deQuemSoupreRequisito.size() > 0) { vector<Disciplina>::const_iterator i; for(i=Disciplina::deQuemSoupreRequisito.begin() ; i!=Disciplina::deQuemSoupreRequisito.end(); i++) { cout << "\t Codigo : " << (*i).Codigo << " \t Nome : " << (*i).Nome << std::endl; } }}

Disciplina::Disciplina(std::string v_codigo, std::string v_nome) {! setNome(v_nome); Disciplina::Codigo = v_codigo; Disciplina::QuantidadeAulasTeoricas=0; Disciplina::QuantidadeDeAulasDistancia=0; Disciplina::QuantidadeDeAulasPraticas=0;}

Disciplina::Disciplina() { Disciplina::QuantidadeAulasTeoricas=0; Disciplina::QuantidadeDeAulasDistancia=0; Disciplina::QuantidadeDeAulasPraticas=0;}

void Disciplina::setQuantidadeAulasTeoricas(int v) {! if ( v >= 0 ) Disciplina::QuantidadeAulasTeoricas = v;}

void Disciplina::setQuantidadeAulasPraticas(int v) {! if (v >=0 ) Disciplina::QuantidadeDeAulasPraticas = v;}

void Disciplina::setQuantidadeAulasDistancia(int v) {! if (v >= 0 ) Disciplina::QuantidadeDeAulasDistancia = v;}

int Disciplina::getQuantidadeAulasTeoricas() {return Disciplina::QuantidadeAulasTeoricas;}

int Disciplina::getQuantidadeAulasPraticas() {

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 8Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

return Disciplina::QuantidadeDeAulasPraticas;}

int Disciplina::getQuantidadeAulasDistancia() {! return Disciplina::QuantidadeDeAulasDistancia;}

void Disciplina::setNome(std::string v) { std::string aux = v; for (int i = 0; i < v.length() ; i++) aux[i] = toupper(v[i]); Disciplina::Nome = aux;}

std::string Disciplina::getNome() {! return Disciplina::Nome;}

void Disciplina::setCodigo(std::string v) {! Disciplina::Codigo = v;}

std::string Disciplina::getCodigo() {! return Disciplina::Codigo;}

void Disciplina::addPreRequisitoNecessario(Disciplina *v){

if (Disciplina::tenhoPreRequisitoNecessario(*v) == false) { Disciplina::preRequisitoNecessarios.push_back(*v); v->deQuemSoupreRequisito.push_back(*this); }}

void Disciplina::removePreRequisitoNecessario(Disciplina * v){ int j=0; vector<Disciplina>::const_iterator i; for(i=Disciplina::preRequisitoNecessarios.begin() ; i!=Disciplina::preRequisitoNecessarios.end(); i++) { if ( v->Codigo.compare(Disciplina(*i).Codigo) == 0 ) { Disciplina::preRequisitoNecessarios.erase (Disciplina::preRequisitoNecessarios.begin()+j); vector<Disciplina>::const_iterator k; int m=0; for (k = v->deQuemSoupreRequisito.begin() ; k != v->deQuemSoupreRequisito.end(); k++) { if (this->equals(Disciplina(*k))) {v->deQuemSoupreRequisito.erase(v->deQuemSoupreRequisito.begin()+m); break; } m++; } break;

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 9Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

} j++; }}

bool Disciplina::equals(Disciplina v){ bool saida = false; if (Codigo.compare(v.Codigo) ==0 ) {if (Nome.compare(v.Nome) == 0 ) if (QuantidadeAulasTeoricas == v.QuantidadeAulasTeoricas) if (v.QuantidadeDeAulasDistancia== QuantidadeDeAulasDistancia) if (v.QuantidadeDeAulasPraticas == QuantidadeDeAulasPraticas) saida =true; } return saida;}

bool Disciplina::tenhoPreRequisitoNecessario(Disciplina v){ bool saida = false; vector<Disciplina>::const_iterator i; for(i=Disciplina::preRequisitoNecessarios.begin() ; i!=Disciplina::preRequisitoNecessarios.end(); i++) { if ( v.equals(Disciplina(*i))) {saida = true; break;} } return saida;}

vector<Disciplina> Disciplina::getPreRequisitos(){ return Disciplina::preRequisitoNecessarios;}

bool Disciplina::souPreRequisito(Disciplina v){ bool saida = false; vector<Disciplina>::const_iterator i; for(i=Disciplina::deQuemSoupreRequisito.begin() ; i!=Disciplina::deQuemSoupreRequisito.end(); i++) { if ( v.equals(Disciplina(*i)) ) {saida = true; break;} } return saida;}

Disciplina Disciplina::clone(){ Disciplina *saida = new Disciplina(); saida->Codigo = Codigo; saida->Nome = Nome; saida->QuantidadeAulasTeoricas = QuantidadeAulasTeoricas; saida->QuantidadeDeAulasDistancia = QuantidadeDeAulasDistancia; saida->QuantidadeDeAulasPraticas = QuantidadeDeAulasPraticas; saida->deQuemSoupreRequisito = deQuemSoupreRequisito; saida->preRequisitoNecessarios = preRequisitoNecessarios; return *saida;}

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 10Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

// fim do arquivo cpp

4.3 O Arquivo de teste main.cpp

/*

* File: main.cpp

* Author: robinsonnoronha

*

* Created on February 9, 2013, 5:25 PM

*/

#include <iostream>

#include <cstdlib>

#include "Disciplina.h"

using namespace std;

int main(int argc, char** argv) {

Disciplina MA61B("MA61B", "Matematica 1");

MA61B.setQuantidadeAulasTeoricas(90);

Disciplina MA61A("MA61A","Calculo 1"); MA61A.setQuantidadeAulasTeoricas(90);

Disciplina MA62A("MA62A","Calculo 2"); MA62A.setQuantidadeAulasTeoricas(60);

Disciplina FI63A("FI63A","Fisica 3"); FI63A.setQuantidadeAulasTeoricas(45);

FI63A.setQuantidadeAulasPraticas(60);

FI63A.addPreRequisitoNecessario(&MA61B);

FI63A.addPreRequisitoNecessario(&MA61A);

Disciplina FI64A("FI64A","Fisica 4"); FI64A.setQuantidadeAulasTeoricas(60);

FI64A.addPreRequisitoNecessario(&FI63A);

// exemplo de recebimento de pre-requesitos.

cout << "\n Pre-requesitos da Disciplina FI63A:\n";

vector <Disciplina> l = FI63A.getPreRequisitos();

cout << "\n Quantidade de Pre-Requisitos:" << l.size() << endl;

vector<Disciplina>::const_iterator i;

for(i=l.begin()

; i!=l.end(); i++)

{

(Disciplina(*i).print());

}

// exemplo do uso do Clone()

cout << "\n Clone:" <<endl;

Disciplina cloneFI63A = FI63A.clone();

FI63A.print();

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 11Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

return 0;}

4.4 Resultado da Execução.

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 12Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

5. Exercício

a) Implementar e testar a classe Pessoa e o Auto-Relacionamento “casada_com”.

b) A Classe Pessoa do exercício 5 foi modificada. , para o Exercício 5b).

Além do Auto-relacionamento “cada_com” com multiplicidade “0..1”, um novo Auto-Relacionamento deve ser implementado. Esse novo Auto-Relacionamento é denominado “amizadeCom” e possui multiplicidade “0..*”.

Modificar a classe Pessoa implementada no exercício 5a) de tal forma que ela represente esse novo Diagrama de Classe.

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 13Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

6. Anexos

a)

b)

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 14Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------

c)

d)

e)

UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 15Prof. Robinson Vida Noronha Tema: Implementação de Classe e Auto-Relacionamentos em C++----------------------------------------------------------------------------------------------------------------------------------------------