organização de código em módulos · 2010. 8. 2. · dim0108.0 - conceitos e técnicas de...

30
DIM0108.0 - Conceitos e Técnicas de Programação Organização de código em módulos David Déharbe 1 Sunday, August 1, 2010

Upload: others

Post on 15-Sep-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Organização de código em módulos

David Déharbe

1

Sunday, August 1, 2010

Page 2: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Introdução

• O desenvolvimento modular promove a divisão de uma aplicação em unidades de software.

• Cada módulo pode ser desenvolvido e compilado isoladamente, facilitando o trabalho em equipe.

• Um desenvolvedor pode utilizar um módulo sem ter acesso ao código fonte do mesmo, apenas precisa da interface.‣ A interface comporta a declaração das definições (tipos, funções, exceções,

outros módulos) exportadas pelo módulo‣ A interface permite usar o módulo sem conhecer a implementação do

mesmo.‣ A implementação do módulo pode ser alterada sem os usuários perceberem.

• A programação modular facilita a organização e a manutenção do código de aplicações.

• OCaml possui um mecanismo rico de módulos que permite definir módulos aceitam módulos em parâmetro (não apresentado).

2

Sunday, August 1, 2010

Page 3: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Organização modular

• Cada módulo deve corresponder a alguma funcionalidade.• Por exemplo, a biblioteca padrão da linguagem Objective Caml é dividida em

módulos:‣ Printf: impressão formatada,‣ Scanf: leitura formatada,‣ List: listas genêricas,‣ Graphics: manipulação de gráficos,‣ etc.

• O conceito de tipo de dados abstrato é muito importante em computação:‣ corresponde a um tipo (genêrico ou não) de dados,‣ possui funções para manipular valores daquele tipo,‣ o usuário não precisa saber como são implementadas as funções para usá-las,‣ exemplo: array‣ um tipo abstrato de dados pode ser implementado através de um módulo

3

Sunday, August 1, 2010

Page 4: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Compilação separada

• Módulos são compilados individualmente. • Mas, não são programas

‣ não podem ser executados!‣ opção -c do compilador: não tente gerar programa executável‣ o resultado da compilação é um componente pré-compilado que pode ser

usado em outro programa.‣ esses componentes podem ser agrupados em bibliotecas.

• Para um programa usar um módulo, devemos usar o compilador com o nome dos componentes pré-compilados.‣ Exemplo:

✓ ocamlopt graphics.cmxa -o game_of_life game_of_life.ml‣ Indica que a biblioteca graphics.cmxa deve ser incluída para construir o

programa game_of_life:

4

Sunday, August 1, 2010

Page 5: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Linkedição

• Comportamento defaut do compilador✓ ocamlopt fonte.ml -o programa

‣ compila o código fonte no arquivo fonte.ml‣ "combina" com alguns elementos da biblioteca padrão do OCaml e gera o

programa executável no arquivo programa‣ compilação + linkedição

• Linkedição é a combinação de vários códigos objetos em um arquivo executável.‣ Exemplo de códigos objetos:

✓ bibliotecas: graphics.cmxa✓ aplicação do compilador sem fase de linkedição:

- ocamlopt fonte.ml -cgera o arquivo objeto fonte.cmo.

✓ podemos juntar vários arquivos objetos para formar um programa.5

Sunday, August 1, 2010

Page 6: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Ilustração: exemplo 1

6

fonte.ml fonte.o programa

Pervasives.cmxa

Compilação Linkedição

ocamlopt fonte.ml -o programa

Sunday, August 1, 2010

Page 7: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Ilustração: exemplo 2

7

fonte3.ml fonte3.o programa

pervasives.cmxa

Compilação Linkedição

ocamlopt graphics.cmxa fonte3.ml -o programa

graphics.cmxa

Sunday, August 1, 2010

Page 8: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Ilustração: exemplo 3

8

fonte2.ml fonte2.oCompilação

ocamlopt fonte2.ml -c

Sunday, August 1, 2010

Page 9: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Ilustração: exemplo 3

9

fonte4.ml fonte4.o programa

pervasives.cmxa

Compilação Linkedição

ocamlopt graphics.cmxa fonte2.cmo fonte4.ml -o programa

graphics.cmxafonte2.o

Sunday, August 1, 2010

Page 10: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Ilustração: exemplo 3 - revisitado

10

fonte4.ml fonte4.o programa

pervasives.cmxa

Compilação Linkedição

ocamlopt graphics.cmxa fonte2.ml fonte4.ml -o programa

graphics.cmxafonte2.ofonte2.mlCompilação

Sunday, August 1, 2010

Page 11: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Exemplo: os números racionais

• Nesta aula, iremos prover um módulo para representar e manipular números racionais.

• Este módulo será compilado isoladamente, e não será executável: proverá funcionalidade para outros programas.

• Nosso módulo poderá ser usado por programas clientes que precisam fazer cálculos com números racionais.

• O nosso módulo será um fornecedor da funcionalidade: representação e manipulação de números racionais.

‣ Do que precisamos para representar os números racionais?‣ Quais operações deveriamos prover para manipular números racionais?

11

Sunday, August 1, 2010

Page 12: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

OCaml: arquivos e módulos

• Cada arquivo de programa (ou unidade de compilação) é um módulo.• Os nomes declarados em um módulo formam a interface ou assinatura daquele

módulo:‣ tipos,‣ funções,‣ exceções,‣ sub-módulos.

• O nome do arquivo (minúsculas) é um nome do módulo (capitalizado).

• Para declarar os tipos e funções definidas no arquivo, a assinatura do módulo é definida em um arquivo de interface (extensão .mli).‣ O arquivo rational.mli contem a declaração da assinatura do módulo

Rational.‣ O arquivo rational.ml contem a definição do módulo Rational.

12

Sunday, August 1, 2010

Page 13: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

O arquivo interface: rational.mli

• O arquivo rational.mli contem as declarações que queremos.‣ Compilar com ocamlc -c rational.mli‣ gera o arquivo rational.cmi

13

type t

exception Null_denominator

val create: int -> int -> tval to_string: t -> stringval numerator: t -> intval denominator: t -> intval (+|) : t -> t -> tval (-|) : t -> t -> tval (*|) : t -> t -> tval (/|) : t -> t -> tval (~-|) : t -> t

val (=|) : t -> t -> boolval (<>|) : t -> t -> boolval (<|) : t -> t -> boolval (>|) : t -> t -> boolval (<=|) : t -> t -> boolval (>=|) : t -> t -> bool

val zero : tval one : t

Sunday, August 1, 2010

Page 14: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

O arquivo interface: rational.mli

• O arquivo rational.mli contem as declarações que queremos.‣ Compilar com ocamlc -c rational.mli‣ gera o arquivo rational.cmi

13

type t

exception Null_denominator

val create: int -> int -> tval to_string: t -> stringval numerator: t -> intval denominator: t -> intval (+|) : t -> t -> tval (-|) : t -> t -> tval (*|) : t -> t -> tval (/|) : t -> t -> tval (~-|) : t -> t

val (=|) : t -> t -> boolval (<>|) : t -> t -> boolval (<|) : t -> t -> boolval (>|) : t -> t -> boolval (<=|) : t -> t -> boolval (>=|) : t -> t -> bool

val zero : tval one : t

Sunday, August 1, 2010

Page 15: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Exemplo de uso da interface

• Um programa testrat.ml cria números racionais:

14

let _ = let r1 : Rational.t = Rational.create 2 3 and r2 : Rational.t = Rational.create 3 4and s : Rational.t ref = ref Rational.zero in s := Rational.(+|) r1 r2; print_string ( (Rational.to_string r1) ^ " + " ^ (Rational.to_string r2) ^ " = " ^ (Rational.to_string !s) ^ "\n")

Sunday, August 1, 2010

Page 16: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Exemplo de uso da interface

• Um programa testrat.ml cria números racionais:

14

open Rational

let _ = let r1 : t = create 2 3 and r2 : t = create 3 4and s : t ref = ref zero in s := r1 +| r2; print_string ( (to_string r1) ^ " + " ^ (to_string r2) ^ " = " ^ (to_string !s) ^ "\n" )

Sunday, August 1, 2010

Page 17: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Exemplo de uso da interface

• Compilar com ocamlopt -c testrat.ml• Gera o arquivo testrat.o

‣ Obs. 1 Pode se compilar o código do cliente sem ter definido o componente!‣ Obs. 2 Não pode se gerar o programa sem ter definido o componente...

15

localhost: david$ ocamlc.opt testrat.ml -clocalhost: david$ ocamlc.opt testrat.ml rational.mli -o testratFile "rational.mli", line 1, characters 0-1:Error: Error while linking testrat.cmo:Reference to undefined global `Rational'

Sunday, August 1, 2010

Page 18: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

• O arquivo com as definições é um arquivo texto com código OCaml tal como foi praticado desde o início da disciplina.

‣ Questão que o fornecedor (nós) tem que se fazer:

‣ Como iremos representar os números racionais?✓ Isso nos indica como o tipo t deve ser definido

‣ Como iremos representar os valores constantes zero e one?‣ Como iremos calcular o resultado das operações declaradas na interface?

✓ Isso nos indica como as definições devem ser feitas.

Definição do módulo Rational

16

Sunday, August 1, 2010

Page 19: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Exemplo de definição de módulo

• Arquivo rational.ml:‣ vai ser definido o mínimo possível para poder executar o programa teste...‣ sempre tentar definir funções a partir de funções existentes.

17

type t = { num : int ; den : int }exception Null_denominatorlet create : int -> int -> t = fun (n : int) (d : int) -> if d = 0 then raise Null_denominator; { num = n ; den = d}let numerator : t -> int = fun (r : t) -> r.numlet denominator : t -> int = fun (r : t) -> r.denlet zero : t = create 0 1let one : t = create 1 1let to_string : t -> string = fun (r : t) -> "[" ^ (numerator r) ^ ":" ^ (denominator r) ^ "]"let (+|) : t -> t -> t = fun (r1 : t) (r2 : t) -> create (numerator r1 * denominator r2 + numerator r2 * denominator r1) (denominator r1 * denominator r2)

Sunday, August 1, 2010

Page 20: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Compilação da implementação do módulo

• Compilar com ocamlc -c rational.ml• Gera o arquivo rational.cmo

‣ Obs. Não se pode compilar enquanto todos os valores não foram definidos!

18

localhost: david$ ocamlc.opt rational.ml -cFile "rational.ml", line 1, characters 0-1:Error: The implementation rational.ml does not match the interface rational.cmi: The field `>=|' is required but not provided The field `<=|' is required but not provided The field `>|' is required but not provided The field `<|' is required but not provided The field `<>|' is required but not provided The field `=|' is required but not provided The field `~-|' is required but not provided The field `/|' is required but not provided The field `*|' is required but not provided The field `-|' is required but not provided

Sunday, August 1, 2010

Page 21: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Resto da definição de módulo (provisória)

• Eu estou muito ansioso para saber se funciona...• Quero testar as funcionalidades mais simples antes de trabalhar nas demais.

19

let (-|) : t -> t -> t = fun (r1 : t) (r2 : t) -> raise Not_implementedlet ( *|) : t -> t -> t = fun (r1 : t) (r2 : t) -> raise Not_implementedlet (/|) : t -> t -> t = fun (r1 : t) (r2 : t) -> raise Not_implementedlet (~-|) : t -> t -> t = fun (r1 : t) (r2 : t) -> raise Not_implementedlet (=|) : t -> t -> bool = fun (r1 : t) (r2 : t) -> raise Not_implementedlet (<>|) : t -> t -> bool = fun (r1 : t) (r2 : t) -> raise Not_implementedlet (<|) : t -> t -> bool = fun (r1 : t) (r2 : t) -> raise Not_implementedlet (<=|) : t -> t -> bool = fun (r1 : t) (r2 : t) -> raise Not_implementedlet (>|) : t -> t -> bool = fun (r1 : t) (r2 : t) -> raise Not_implementedlet (>=|) : t -> t -> bool = fun (r1 : t) (r2 : t) -> raise Not_implemented

Sunday, August 1, 2010

Page 22: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Resto da definição de módulo (provisória)

• Eu estou muito ansioso para saber se funciona...• Quero testar as funcionalidades mais simples antes de trabalhar nas demais.

19

let undef_combine : t -> t -> t = fun (r1 : t) (r2 : t) -> raise Not_implementedlet undef_compare : t -> t -> bool = fun (r1 : t) (r2 : t) -> raise Not_implemented

let (-|) : t -> t -> t = undef_combinelet ( *|) : t -> t -> t = undef_combinelet (/|) : t -> t -> t = undef_combinelet (~-|) : t -> t -> t = undef_combinelet (=|) : t -> t -> bool = undef_comparelet (<>|) : t -> t -> bool = undef_comparelet (<|) : t -> t -> bool = undef_comparelet (<=|) : t -> t -> bool = undef_comparelet (>|) : t -> t -> bool = undef_comparelet (>=|) : t -> t -> bool = undef_compare

Sunday, August 1, 2010

Page 23: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Geração do programa de teste

• Uma vez feitas todas as definições que correspondem à interface, iremos compilar essas definições‣ ocamlc.opt rational.ml -c

• Combinamos a implementação do módulo e o programa de teste para gerar um programa executável:‣ Compilar com ocamlc.opt testrat.cmo rational.cmo -o testrat‣ testrat é o nome do programa gerado;‣ Nos argumentos de ocamlc.opt, rational.cmo deve preceder testrat.cmo:

arquivo dos componentes devem vir antes do arquivo do código principal.

20

localhost: david$ ocamlc.opt testrat.cmo rational.cmo -o testratFile "_none_", line 1, characters 0-1:Error: Error while linking testrat.cmo:Reference to undefined global `Rational'localhost: david$ ocamlc.opt rational.cmo testrat.cmo -o testratlocalhost: david$ /testrat[2:3] + [3:4] = [17:12]

Sunday, August 1, 2010

Page 24: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Exercícios

• Enriquece o módulo Rational:‣ Define as demais funções.

• Cria programas clientes que testam cada função.

21

Sunday, August 1, 2010

Page 25: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Manutenção e evolução de módulo

• Representação reduzida dos racionais:‣ maior eficiência nas operações de comparação, ‣ diminuição dos casos de transbordamento.

22

Sunday, August 1, 2010

Page 26: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Manutenção e evolução de módulo

• Representação reduzida dos racionais:‣ maior eficiência nas operações de comparação, ‣ diminuição dos casos de transbordamento.

22

(* maior divisor comum *)let mdc : int -> int -> int =(n: int) (m: int) -> let big : int ref = ref (max n m) and small = ref (min n m) in while !big mod !small <> 0 do let tmp = !big mod !small in big := !small; small := tmp done; !smalllet create : int -> int -> t = fun (n : int) (d : int) -> if n = 0 then raise Null_denominator; if d = 0 then { num = 0; d = 1} else let m = mdc (abs n) (abs m) in let n' = (abs n) / m and d' = (abs d) / m in if n >= 0 & d > 0 or n < 0 && d < 0 then { num = n'; den = d' } else { num = ~- n'; den = d' }

Sunday, August 1, 2010

Page 27: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Manutenção e evolução de módulo

• Representação reduzida dos racionais:‣ maior eficiência nas operações de comparação, ‣ diminuição dos casos de transbordamento.

22

(* maior divisor comum *)let mdc : int -> int -> int =(n: int) (m: int) -> let big : int ref = ref (max n m) and small = ref (min n m) in while !big mod !small <> 0 do let tmp = !big mod !small in big := !small; small := tmp done; !smalllet create : int -> int -> t = fun (n : int) (d : int) -> if n = 0 then raise Null_denominator; if d = 0 then { num = 0; d = 1} else let m = mdc (abs n) (abs m) in let n' = (abs n) / m and d' = (abs d) / m in if n >= 0 & d > 0 or n < 0 && d < 0 then { num = n'; den = d' } else { num = ~- n'; den = d' }

Sunday, August 1, 2010

Page 28: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Conclusões: muitas vantagens!

• Programas usam componentes pré-existentes;• Existe a necessidade de criar novos componentes para novos tipos de

aplicações;• O conceito de módulo permite prover componentes de software

‣ interface: todos os valores (tipos, exceções, funções) providos pelo componente

‣ implementação: definição dos valores• O cliente não precisa saber como o módulo foi implementado

‣ o cliente apenas tem que conhecer a interface do módulo• Componentes/módulos podem ser reaproveitados em diversos programas.

‣ Existe um mercado para componentes de software.• Uma vez definida a interface, pode se trabalhar de forma independente na

definição do módulo e na implementação do cliente‣ facilita o desenvolvimento em equipe.

23

Sunday, August 1, 2010

Page 29: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Conclusões: e tem muito mais...

• Foi apresentada uma parte da linguagem de módulos da linguagem OCaml.‣ Útil para a noção de Tipo Abstrato de Dados (TAD) usada na disciplina

AED1.‣ Funtores tem módulos em parâmetro e geram novos módulos

✓ cálculo matricial- parâmetro: tipo numérico, operações de soma e multiplicação, valor zero

- resultado: cálculo matricial sobre o tipo t.

• A programação orientada a objetos também permite alcançar benefícios da programação modular.‣ Também há construções para orientação a objetos em OCaml...

• Programing in the large: considere a programação modular como recurso.

24

Sunday, August 1, 2010

Page 30: Organização de código em módulos · 2010. 8. 2. · DIM0108.0 - Conceitos e Técnicas de Programação Introdução • O desenvolvimento modular promove a divisão de uma aplicação

DIM0108.0 - Conceitos e Técnicas de Programação

Módulos e o projeto de calculadora

• Módulo para pilhas:‣ quais funções deve prover‣ qual tipo essas funções devem ter

• Módulo para números‣ quais funções deve prover‣ qual tipo essas funções devem ter

• Defina a interface desses módulos

• Defina uma implementação para estes módulos

• Implemente uma versão parcial do programa e que use estes módulos.

25

Sunday, August 1, 2010