Vous êtes sur la page 1sur 696

Ap

da Pro
a
em 21

Tony Sintes

Traduo

Joo Eduardo Nbrcga Torlcllo


Revisl10 Tcn ic(l

Ana Fernanda Gomes Ascencio


Bacharel em Cincia da Computao pela

pue-sp

Especialista cm Si stema de Infonnao pela UFSCAR c mestre cm computao pela UFROS

I
r

PEARSON

Makron
Books
So Paulo

Brasil Argentina Colmbia Costa Rica Chile Espanha


Guatemala Mxico Peru Porto Rico Venezuela

@ 2002 by Pearson Education do Brasil

Ttulo Original:
Object Oriented Programming in 21 Dias
2002 by Sams Publishing
Todos os direitos reservados
Editora: Gislia do Carmo Cosia
Gerente de Produo: Silas Camargo
Produtora Editorial: Sandra Cristina Pedri
Reviso: Jorge Abdalla Neto
Capa: Marcelo da Silva Franozo, sobre o projeto original

Editorao Efetr6nica: ERJ Informtica LIda.

Dados de Catalogao na Publicao


Sintes, Tony
Aprenda Programao Orientada a Objetos em 21 Dias
Traduo: Joo Eduardo Nbrega TorteUo
Reviso Tcnica: Ana Fernanda Gomes Ascencio
So Paulo: Pearson Education do Brasil, 2002
Titulo Original: Object Oriented
Programming in 21 Dias

ISBN: 85.346.1461-X
,

Indice para Catlogo Sistemtico


1. Programao Orientada a Objelos

2002
Direitos exclusivos para a lngua portuguesa cedidos
Pearson Education do Brasil,
uma empresa do grupo Pearson Educalion
Av. Ermano Marchetti, 1435
CEP 05038-00 1 - Lapa - So Paulo - SP
Tel: (11) 3613- 1222 Fax: ( 11) 3611-0444
e-mail : vendas@pearsoned.com

Sobre o autor
TONY SINTES traba lha com tecno logias orientadas a objetos h sele anos. Nesse tempo, Tony
fez parte de muitos trabal hos de desenvo lvimento orientados a objetos de larga escala. Alualme nte, Tony trabalha na Firsl C lass Consult ing, uma empresa que fundou para ajudar as grandes
empresas a integrar se us diversos s istemas em uma estrutura unificada. Antes de in iciar a First
C lass Consulting, Tony trabalhou na BroadVision como consultor snior, onde ajudou a construir alguns dos maiores sites Web do mundo . Atualmente, as principais responsabilidades de

Tony so como a rquiteto, lder tcnico e mentor da equipe, ajudando a construir as habilidades
em desenvo lvedores menos experientes.

Tony um autor tcnico ampl amente reconhecido, cujos trabalhos tm apa rec ido naJavaWorld,
Dr. Dobb 's JOllrnol, LinuxWorld, JavaOne Today e Silicon Prairie, onde co-autor de uma coluna mensal altamente respeitada sobre programao orientada a objetos. Atuahne nte, Tony escreve a coluna mensa l de perguntas e respostas daJavaWorld. Voe pode entrar em contato com
ele no endereo styoop@flrslclasscommlling.nel.

Agradecimentos
Escrever um livro um processo como nenhum outro. A quantidade de pessoas que colaboram

em um livro, e que so necessrias para produzir a cpia final que voc est le ndo agora, s implesmente espantoso. Gostaria de estender minha gratido equ ipe inteira de ed itoriais da Sams.
Sem seu trabalho rduo, este livro s implesmente no existiria.
Pel o nome, gostaria de agradecer a Michael Stephens, Carol Ackerman, Tiffany Taylore George
Nedeff. A liderana e toques sutis de Caro l foram o que realmente fi zeram este li vro prosseguir
at sua concluso. A capac idade de Tiffany de estruturar e encadear o material tcnico, clara e

conci samente, simplesmente espan tosa. No apenas as edies de Tiffany tornaram este livro
mai s leg ve l, mas acho que seu trabalho me ensi nou algumas lies valiosas sobre redao tcnica. Tambm gostaria de agradecer a William Brown. Wi ll iam entrou em contato comigo a respeito
do projeto STY oor, no incio de agosto de 2000. Confiar tal projeto a um a utor relativamente
desconhecido era arriscado e agradeo a William por me dar a chance de esc rever este li vro.
Agradeo especia lmente aos edi tores tcnicos, Mark Cashman e Ric hard Ba ld win, que garantiram que o material apresentado fosse tecnicamente bom. Agradeo a vocs pela awao tcnica.
Aos me us colegas, mu ito obrigado. Gostaria de estender os agradec imentos espec iai s a David
Kim e Michael Hall . Eu comecei este livro enquanto estava na BroadVis ion e gostaria de agradecer a David Kim por me permit ir aquel as frias de pnico, quando os prazos de entrega comearam a se aprox imar. Ta mbm gostaria de agradecer a Michael Han, por SlIas id ias tc nicas e por
escrever o apndice sobre Java deste livro.
Por (lltimo, mas no menos importante, tenho o privilg io de agradecer minha maravilhosa esposa, Amy, por se u apoio firme , revi sl'lo e pacincia. Agradeo ainda minha ramlia e amigos,
que ofereceram seu apoio e que o uviram minhas reclamaes.

Diga-nos o que voc acha!


Como leitor deste livro, voc nosso c rt ico e co laborador mais importante. Valorizamos sua
opini o e queremos saber o que estamos fazendo correta mente. o que poderamos fa zer melhor,
sobre quais reas voc gostaria de nos ver publi cando e qua lquer outra sugesto importante que

deseje passar para ns.


Receberemos com satis fao seus comentrios. Voc pode e nviar um fax, e-ma il ou esc rever difeiamen te, para que possamos saber o q ue gostou ou no neste livro - assim como o que podemos fazer para tornar nossos livros melhores.
Por favor, entenda que no podemos ajud-lo em prob lemas tcnicos relacionados ao assunto

deste livro e que, dev ido ao grande volume de correspondncia que recebemos, no possamos
responder a todas as mensagens.
Q uando voc escrever, cert ifique-se de incluir o tlul o e o a utor deste livro, assi m como seu
nome e n(nnero de tele fone ou fax. Examinarem os seus come ntrios c uidadosamente e os compartilharemos com os aulores e editores que trabalharam no livro.

Fax: (1 1) 36 11 -9686
Fone: ( 11 ) 3613- 12 13
Endereo elelrnico: clientes@ma kron.com.br
Endereo postal: Pearson Education do Brasi l Lida
Rua Emlio Goe ld i, 747 - Lapa
So Paulo - SP - CEPo05065-110

Sumrio

Introduo
XXIII
Sobre os exemplos' .. ............ ......... .. . . ... . .. . XX IV
O que voc prec isa saber para usar este livro' ... ... .... .. . .. . ..... XX IV
SEMANA 1
Dia 1

Definindo 00

Introduo programao orientada a objetos

3
Programai'lo orientada a objelos em um contexto histrico' . .. ..... . ....... 4
Precursores da POO .................................. ... .... ... 4
Programao orientada a objetos' . .... .................. .. . ..... . . 6
Uma estratgia de POO para software usando objetos ...... . ..... . ...... 6
O que uma classe?' ............................. ... . .. . .... .. 8

Reunindo tudo: classes e objetos' ............................... 9


Fa7..endo os objetos trabalhar ' ............................. . ..... . I I
Re lacionamentos de objeto ................................ . .... 13
Como a programao orientada a objetos fundamenta o passado ' ......... 14
Vantagens e objetivos da 00 .................... ................ . . 14
Natural' ........................... . ........................ 15
Confi vel ' .................. ..... . .. . . .. .......... .. ..... 15
Reuti lizvel ' .... . ...... . ................................. 15
Manuten vel ' ......... .. . ... . ................ . ... .. . . ...... 16
Extensvel ........ . . . .. .... . . .. ... . . . .. . .. . . .. .. .. .... 16
Oportuno' ........ . . . ... . . . .. .. ..... ............... ...... . .. 16
Armadilhas ................................................... 16
Armad ilha I : pensar na POO simplesmen te como uma li ng uagem ... .. . . .. 17
Armadilha 2: medo da reutili zao' . . . .. .. ........................ 17
Armadilha 3: pen sar na 00 como uma so luo para tudo ' . . . . ........... 17
Armadilha 4: programao egosta' . . . . ................. . . . . . . .... 18
A prx ima semana' ... . . ... . . . ... . ................... .. . ..... 18
Resumo ' . .. ....................... . . ......... .. . ..... . ..... 18
Pergu ntas e respostas' ...... . . . ......... . .... ................ 19
Workshop ............... ..... .......... . ..... .......... 19
Teste' ................ ' ..... .................. .. ... .. ..... 19
Exerccios ................. .... .. . .. . ................. . ..... 20
Dia 2

Encapsulamento: aprenda a manter os detalhes consigo mesmo


21
Encapsulamento: o prim eiro pilar ' ................................ 22
Um exemplo de interface e implementao' ................. . . .. . . .. 24

Aprenda Progra m ao Orientada a Obj eto s em 21 Dia s

Pblico, privado e protegido' ................................... 25


Por que voce deve encapsul ar? ....... ................... .. ..... . 25
Abstrao: aprendendo a pensar e programar de forma abstraia ' .... . ........ 26
O que abstrao? ............................................ 26
Dois exemp los de abstrao .................. ................... 27
Abslrao eficaz' ............................................. 28
Guardando seus segredos atravs da ocuhao da imp lemen tao' ........ . .. 29
Protegendo seu objeto atravs do TAO (Abslract Data Type - Tipo
Abstraio de Dados)- ...................................... . .... 30
O que um tipo? . .. . . .. .. . . . .. . . . ......................... . .. 30
Um exemplo de TAO . ........................ 33
Protegendo outros de se us segredos, atravs da ocultao da impl emen tao' . 34
Um exemplo real de ocultao da implementao ................ . . . . . 36
Diviso da respon sabil idade : preocupando-se com seu prprio negcio' ....... 37
Dicas e armadilhas do encapsulamento' ........................ . . .. . . 41
Dicas e armadilhas da abstrao .. . . . . .. .. .................. . . . .. . 41
Dicas e armadi lhas do TAD .... ............. 43
Dicas da ocultao da implementao' . ........................... . 43
Como o encapsulamento atende os objet ivos da programao orien tada
a objetos ................................................... 44
Advertnc ias ............ . ..................................... 45
R eSUI110 . . . . . . . . . . . . . 45
Perguntas e respostas ..... . . ................................ 45
Workshop .............. . ................................. 46
Teste .. .................................... . ............ 46
Exerccios .............. . .... .. .............. .. . . . . . ..... 47
Dia 3

Encapsu lamento: hora de escrever algum cdigo

49

Laboratrio I : config urando o ambiente Java' . . ................ . ...... 49


Exposio do problema' ....................... ... . ..... .. ..... 50
Laboratrio 2; c lasses bsicas' .... .. . . . ...... .. . . .. . . .. . ... .... .. 50
Expos io do problema' ...... . .... .. . . . .. . , .. " . .. . .... .. ..... 53
So lues e discusso' ............. .. . ............ .. .. . ....... 54
Laboratrio 3: o encapsu lamento ' .. .... . .. . ................. .... . . 56
Exposio do problema ' ........................................ 57
Sol ues e discusso' ................................... .. ..... 57
Laboratrio 4: estudo de caso - os pacotes de pri mitivas Java (opc ional ) ..... 62
Ex posio do problema ' ........................................ 66
Sol ues e discusso .......................................... 66
Perguntas e respostas ............. . ........... . ..... .......... 67
Workshop ... . . . ......... . .................... , ... . .... 68
Teste' ................ ............ .... ..... ......... 68
Exercidos ............ . ..... . .... . .. .... .. .... .. .... ..... 69

Sumrio

Dia 4

Herana: obtendo algo para nada

o que herana?

7'

. . ....... . .. . ...................... . .. . . ...... 71


Por q ue herana? . . . .. . ............ . .. ... . ........... . . .. ... . .. 74
" um" versus " tem um": aprendendo quando usar herana ' ...... ....... 75
Aprendendo a navegar na teia emaran hada da herana ' .. . . . .. .... .. . .... 77
Mecnica da herana ... . . ......... . . . . ............ ... . .. . .. 79
Mtodos e atributos sobrepostos' ... .. .. . .......... . ..... . . .. . . . .. 8 1
Novos mtodos e atributos . . ........... ... ..... .. . ... . . .. .. . 84
Mtodos e atributos recursivos .... .. .. . . ... .. ........ . . . . ..... 84
T ipos de herana .. . .. . ... .... . . . . ..... . ... ...... .. . . ... . . . . .. 84
Herana para impl ementao' .. ... .. . . .. ... ... . .... . . . . . . . . .... 85
Prob lemas da herana da implementao' .. . . . . .... .. . . . . . . . .. . .... 85
Herana para d iferena' . .. .... .. . ...... . ... . . ... . ... . ........ 86
Especializao' ...... . .. .... .. . . . .. .. .... . . .. . . . .... ... . .... 87
Herana para substituio de tipo ....... .. . . ..... . . . .. ........ 90
Dicas para a herana eficaz ' .. .... .. . . . .... . . .. ... . . .... .... . .. . 92
Resurno ..... . .. . ... . . ...... . . ... . . ... .... . . . ... . ..... .. ... .. 94
Como a herana atende aos objetivos da 00 .. ... . .. . . .... ... . . ... . . .. . 94
Perguntas e respostas .. ....... . ....... . . .. . . . . . .... . . . . .. . .. . 96
Workshop . ............... . . . ............. . ..... . ..... . ...... 96
Teste' ......... . . . . ............ . . ..... ..... ..... .... .. 97
"
.......... . ..... . ................ . . . ...... ...... 97
E' xerclcl0s
Dia 5

Herana: hora de escrever algum cdigo

99

Laboratrio I: herana simples ' . . ......... .... .. ..... . ..... . ... . .. 99


Expos io do prob lema ' ......... ..... . ............... .. .. .. . . 100
So lues e di scusso ' ... . .. . .. . ...... . .... . .. .. . . . .... . ....... 101
Laboratrio 2: usando classes abstratas para herana planejada . ... . . .. . . .. . 102
Exposio do problema' . . .. . ..... . . .... .. .. .. . ...... .. . .. . .... 105
Solues e di scusso' ......................... . . ..... . . .. . . . . . 105
Laboratrio 3: conta em banco - praticando a herana simples' . .. . ....... 107
Urna conta genrica . ...... . . . .. .. ..... . ........ . . . .... . .. . .. 107
A conta poupana' ... . . . ........... . . .. . .. . .. .. . . .... .. . .... 107
Urna conta com vencimento programado' . .. .. .. .. .. . .. . . . . .... . . 107
Con ta com cheques' . . . . . . . .. . ..... .. .. .. . . . ..... . .... . . .. ... 107
Conta com cheque especial ' . . . . . . . ........ . . . . . ... . . . . . . .. .... 108
Exposio do problema' . .. . ..... . . .. .... . . . . . .. . . . . ... .. 108
Expos io estendida do problema' ...... . ..... . . . .. . ............. 110
Sol ues e discusso ' .... . . . ..... . ................. . .... . ..... I I I
Laboratrio 4: estudo de caso - " um ", " tem um" e j ava.uti l.Stack .... .... 1 17
Expos io do prob lema .. . ... . .. . ................. . ........... I 18
Solues e discusso' . ... . .. . ........ . ... ............. . . . . . . . . I 18
ResUlllo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Pergurllas e respostas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I 19

XII

Aprenda Progra mao Ori entada a Obj eto s em 2 1 Dia s

Workshop' ...... . .. . . . .. . . .. . . . . . .. .... 120


Teste' ....... ..................... . . . .. . .. . . ........ 120
.'
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
Exe rCIClOS
Dia 6

Polimorfismo: aprendendo a prever o futuro

121

Po linl orfi smo ....................... ....... . .. .. . . .. .. . .....


Po limorfismo de incl uso' ....... . .......... o
Po limorfi smo paramtrico' .. . . .. . . ..... . .............. . ........
Mtodos paramtricos' ....................................
Tipos paramtri cos ' . .. . . .. . ....... ............... .. .. . . . .

122
126
13 1
13 1
133

Sobreposio ............... .... ... . . . .... .... . .. .... 134


Sobrecarga' . . .. . . . .. .... .. . . .... . ... .. . . .. .... . . .. . . .. . . 135
Converso' .. . . . .. .... .... . .. .. .. ... .. .. .. . . . . . . ... . . . . 137

Poli morfis mo eficaz' . .. ..................... . .. . ............ . . .


Armadi lhas polim rficas ' . . .. .. . . . . . ........................ .. . . .
Armadilha I : mover comportamentos para cima na hierarquia ' ...... .. . . .
Armadil ha 2: sobrecarga de desempenho ' ..................... . ....
Armadil ha 3: vendas
Advertnc ias' ........ . . . .. .... .. . . . .. . .. . .. . .. .. .. . . .. . .. ....
Como o polimorfismo atende os objctivos
da 00 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ResunlO ..................................................
Perguntas e respostas .... . . .. . ..............................
Workshop' ............ . ..... . ..................... . . . . ....
Teste' .... ......... . .. .... .. .............. . . .... .. . . . ....
. '
ExerCICIOS ............ . . . .. . ............ . . . . ..... . ......
Dia 7

Polimorfis mo: hora de escrever algum cdigo


Laboratrio \: aplicando poli morfismo' .. .... . ... . . .. . . .. . . .. . . . . .
Exposio do problem a ............... . .... .. .. . ..............
Solues e discusso' .. . . .. . . . .... ................... ... .. . . . .

137
139
140
140
141
142
142
143
144
145
145
145

147
147
154
155

Laboratrio 2: conta de banco - aplicando po limorfismo em um exemplo


con hec ido' . . .................................... . .. . . .. ...... 156
Expos io do problema' . .. .. . . .. .. ................. ...... .. . . . 157
Solues e d iscusso' ....... . ................................. 159
Laboratrio 3: conta de banco - usando polimorfismo para escrever cdigo
prova do fut uro' .... . . . .. .. .... . .... .. .......................
Exposio do problema ' .......................................
Sol ues e d iscusso" ........................................
Laboratrio 4: estudo de caso - estruturas condic ionais Java e pol imorfismo'
Corrig indo uma estrutura condic ional .............................
Exposio do problema ' .. . ....................................
Solues e discusso ' .... . .... . ..... .. .. ... . .. . .. ... .. .. ...
Res Ulllo ..... ............... . . . .. .. . . . . . .. . .. . . ..... ......

160
162
163
165
167
169

17 1
172

Sumrio

XIII

Pergu ntas e respostas .... . . . . . .. .. . .. ... . . . .... .. .... ... ... 173
Workshop' ...... ....... . .. . . .. . .... . . .. . .. . . ........ 173
T este 173
Exerccios ........ .... .. . ............................. 173
SEMANA 1

Em reviso

174

SEMANA 2

Aprendendo a aplicar 00

175

Introduo UML

177

Introduo Unified Mode ling Language ...... .. .. .... ..... . ........


Modelando s uas c lasses .. . . .. . . . .. . ........................ . .
Notao bs ica de classe' .............. . .. . . .. ........ ........
Notao avanada de classe . . . . .. . ........................ .. . . .
Modelando suas c lasses de acordo com seus objeti vos .... . . . .. ... . .
Modelando um re lacionamento de c lasse' ......... . ..... .. .. .. , .. . ...
Dependncia' . ... .. . . . .. .. . . .. .. .................. .. ..... . .
Associao' ....... .......... . . .. . . .. .. . .............. . .
Agregao ' .................. ... ...... .... .. .. .......
Conl pos iO ........ . .... . .................. .. .......
General izao' ............ . . .. .. ............. . .. . .. . ....
Reun indo tudo ......... . .... ... .. .. . ... . . . .. ... .. .. . . ....
ResUlllo ............. ..... . .... .. . . .. ... .... . . . .. . . . . . ....
Perguntas e res postas ..... .. . . . . .... . . . . . . ..... . ..... . .......
Workshop' ............ .. ... . ...........................
Teste ' ................. . .. . ..... . .......................
,.
xerCICIOS
...... . ....... . ......................... .. .. . ...
E

177
179
179
181
18 1
183
183
184
186
187
188
189
190
191

Introduo AOO (Anlise Orientada a Objetosl

193

Dia 8

Dia 9

191
191
192

O processo de desenvolv imento de software " ..................... . . . . 194


O processo iterativo ' .... .. . .... .. . . ...... ............ ..... . . 195
Uma metodo logia de alto nvel ' ......................... . . . . .... 197
AOO (A nli se Orientada a Objetos)- .. .. . .. ................ . . . .... . . 198
Usando casos de estudo para descobrir o liSO do sistema ' . .... . . . . ...... 199
C ri e uma lista pre liminar de casos de uso ................ . . .. ...... 20 I
Construindo o modelo de domnio' . . .................. .... ...... 2 13
E agora?' .. ... ...... ................. ........ .... .......... 2 14
Resull'o ............ . . . ................................... 2 15
Perguntas e res postas ......... ... . . ............. . ... .. ..... 2 16
Workshop' ............. . . . . .. . .... ..... . .... .. . . . .. ...... 2 16
T este 2 16
Exerccios ............ .. ................................. 2 17
Dia 10 Introduo ao POO (Projeto Orientado a Objetos)
219
POO (Projeto Orientado a Objelos)' ............... . .. .. . . . .. ..... 220

XIV

Aprenda Progra mao Orientada a Obj eto s em 21 Dia s

Como voc apl ica roo (Projeto Orientado a Objeto)?' . . .. .. . . .. .. ...... 221
Passo I: gere uma lista inic ial de objetos ............ .. . . ......... 222
Passo 2: refine as responsabilidades de seus objetos ......... ......... 223
Passo 3: desenvolva os pontos de imerao ....................... 231
Passo 4: detal he os relacionamentos entre os objelos ........ . ...... . .. 232
Passo 5: construa seu modelo .. . .................... .. . . ..... 233
ReSUlllO .......... . ............................. . . . . ... 234
Perguntas e respostas ... . .... . ... . . . .. .. .. .. . ... . .... . . ..... 234
Workshop' .. .. . . ..... . . .. . . . . .. . . . . ... . . . . .. ..... ......... 235
Teste' ........... .. . . .. . .... . ....................... . . . . 235
Exercc ios ...................... . .. . ..................... 236
Dia 11 Reutilizando projetas atravs de padres de projeto

237

Reutili zao de projeto' ....................... .. .. ........... . . . 238


Padres de proj eto . . .. . . . .. ..... . . ...................... .. . . . 238
O nom e do padro' . ... .. .. . .. . .. . . .. .. . ..... . ..... ... .. . . . 23 9
O problelna ........... ... . ...... ..... . .... .... ... .. ....... 23 9
A soluo' ... .... . . . . .. . . . . ....... . . . .. .. . . .. . ... ....... 239
As conseqUnc ias' .. . . . . . . . . ... . . . .. . ... .. . .. . . .. . . .. . .. .... 239
Rea lidades do padro' ...... . . .. . ... . . . . . . ... ... .. .. . . .. ....... 240
Padres por exem plo' .......... .. .. .. ... .. .... .. .... . ....... 240
O padro Adapter' .... . ..... . .............. . .... . ....... 24 1
O padro Proxy ........ . ........................ . .... . .. 245
O padro Iterator ........... . .... .. .. . . .. ....... . ... ..... 247
Apossando-se de um padro ' .... . . .... . ..... . .. . .. . . . .. . . . .... 254
ReSUlno ....... . .. . .. . .. . . . . . .. . . .. .. . . . .. . . . ..... . ...... 255
Perguntas e respostas ........... . .... .. ..... .. .... . .... . ...... 255
Workshop ' ..... . ..... ... .............................. . . . . 256
Teste' ................ .. . . . . ...... ..................... 256
" los ................. . . . ... ... ... .. ..... . .. . . . . ...... 256
Exerc lc
Respostas do teste ' . . .. .... .. . . . .. . . . . . .... . ..... . . . . . . .. . . . . 259
Respostas dos exercc ios ' ..... . . . ... ... ... ... ... .. .. . . . . . . ...... 260
Dia 12 Padres avanados de projeto

263

Mais padres por exemplo' .. . .. . ............ . .. . . .. ..... .. ..... 263


O padro Abstracl Factol)' 264
O padro Sing leton ' . . . . .. . .. . ... ... .... . .. . . . . . . . .. . ..... 269
O padro Typesafe Enum ..... .. . ..... .. . .. . ..... . . . ... .. .... 275
Armad ilhas do padro' ..................................... 280
Resumo' ................ ........ ...... . ............... 281
Perguntas e respostas ..... ................ . ..... . .... .. ..... 28 1
Workshop' .............. . ................. . . . .. . . .. ..... 282
Teste ' ............. .. . . . . . . ... ... . . . ... . .. . .. ... .. .. .... 282
Exercfcios ..... . . . . . . ... . . . . . . .. . . . . . .. . .. . . ..... . . .. .. 282

Sumrio

Respostas do teste' .......... , , ........... . . . . . .... .... .. ...... 284


Respostas dos exercc ios' ..................... .. .. .. . . ......... 285
Dia 13 00 e programao da interface com o usurio

POO e a interface com o usurio' ........................... .. .....


A importncia das Uls desacop ladas .......................... . .....
Como desacoplar a UI usando o padro Mode l View Controller ... .........
o Inodelo' ............ ........ ... . .........................
o modo de visualizao' ......................................
O controlador ' .... . .. . . .. . ..............................
Problemas com o MVC ....... . ............ . .....
Uma nfase nos dados' . . .. . . . .... . ... .. . . .. .. . . ... . . . . . .
Acoplamento forte' . .... .... . .. .. . . . . .. . . .. . . ... . .. . . . .
Ineficincia' ............. .. .. .. .. .... . ... .. .. ........... ...
Resumo ' ...... . . . .. . . . ... .... ......................... . . . .
Perguntas e respostas .. ... .. .. . .. . .. . . .. .. . ...................
Workshop' .............. ......... ........... . ......... ... ..
Teste' ....... ... . .. . .. . .. . ..... . ...... . .... .. . ... .......
Exerccios ................................ .. .... . . .. . .. ....
Dia 14 Construindo software confivel atravs de testes

289
289
290
293
294
297
30 I
303
304
304
305
305
305
306
307
307
313

Testando software 003 14


Testes e o processo de desenvolvi mento de software iterat ivo' .... .. . . .... 3 14
Fonnas de teste' ...................................... . . . . .... 3 17
Teste de unidade ................................ .... . ...... 3 17
Teste de integrao' .............. .. .... .. ......... . ....... 3 18
Teste de sistema ' . . .... .. .......................... .. .. .... 318
Teste de regresso ... .................. ................... 3 19
Um gu ia para escrever cd igo confive l' ..... . .. ... .... . .... . . .... 3 19
Comb inando desenvolvimento e teste' .... .... . .. . . . ... .. . . . . . 3 19
Escrevendo cdigo excepc iona l ' .. . .. . . .. .. .. . . . .. . . . . .. ..... 335
Escrevendo documentao eficaz' ............ .. ................. 336
Resumo ' ........ . .. . . .. .... . ............................ . . 339
Perguntas e respostas .......... . .. . .......................... 339
Workshop' ....................... . ........................ 340
Teste 341
Exerccios .... ...... . ... . .. ... .. .... . . . . .. ... .... .. ..... 341
SEMANA 2

Em reviso

342

SEMANA 3

Reunindo tudo: um projeto 00 completo

345

Dia 15 Aprendendo a combinar teoria e processo

347

Jogo Vin le-e-u m' .................... . ...... . .... . ... . ... .... 347
Por qu vi nte-c-um? ................... - .... . . .. . . ... ...... 348

XVI

Aprenda Progra mao Ori entada a Obj eto s em 2 1 Dia s

Ded arao da viso' ............ .. .. . . ... . . . .... . . .. .. ......


Requis itos de sobreposio ' ....... . .... . . .. .. .. . . .........
Anlise inicial do jogo vinte-e-um ..................... .. .........
As regras do jogo vinte-e-um ............ .....................
Criando uma lista pre liminar de casos de uso' .......... .. ..........
Plancjando as iteraes ' ......... . ................ . .. ..... .....
Iterao I : jogo bs ico' .................... ... .. . . .... . . .. ..
Iterao 2: regras' ... ................ . . .. . ... . .. .. . . ... ..
Iterao 3: aposta' ................. . .. . . . .. . ..... .... . . ...
Iterao 4: interrace com o usurio ' . ..................... . . . .
Iterao 1: jogo bs ico .........................................
Anlise do jogo vinte-e-um' . . . . ......................... . . . .
Projeto do jogo vinte-e-u m .. . . . .... . .. . .. . ... . ... . ... . .
A implementao' ............ . .. . .. . . .. .. .. . .. . .. ... .....
Resumo ' ........... . . .. . .. . . .... . .. . .. . . .. . . . .. ...... . .
Perguntas e respostas .. . . . . .. . . .. . .............. . ....... .....
Workshop' ................. - .............................
Teste' ............. . .. . . - - ..... - ..... . ........... .... ....
Exerccios ................................... . ........ . ....

348
349
349
350
353
353
354
355
355
355
356
356
360
365
380
381
381
381
381

Dia 16 Iterao 2 do jogo vinte-e-um: adicionando regras


Regras do jogo vinte-e-um .....................................
Anlise das regras' ...... ..... ........................ . - ......
Projeto das regras' .......... . .................... ... .....
Implementao das regras' .... . . ... -o .
Teste' ......... . .. .......... .. . .... .. .. ... ..... . ......
ResUlno .......................... .. ................ . ......
Pergun tas e respostas ... .... ... ...... .................... . ...
Workshop ' ............... . .......... .....................

383
383
384
388
395
409
409
410
4 10

Teste 4 11
Exerccios ... . . . .. .. .... . . . .. .. ............ . . .. . . ... ....... 4 1 I
Dia 17 Iterao3dojogo vinte-e-um: adicionando aposta
413
Aposta no jogo vinte-c-um . .. .. . . .. .. . . . .. .. . ............ ....... 413
Anlise da aposta' ...... ........ ................ . ........... 4 14
Projeto da aposta .................. . ....... . . . ... . . . ...... 4 17
Impl ementao da aposta .. . ..... . ...... . . .. . .. . . . . .. . ..... 420
A implementao de Bank (Banco) ......... . .. ... ... ........... 421
Um pequeno teste: um objeto falsificado' ....................... 42 7
Resumo ' ..................... .... ....................... 428
Perguntas e respostas .......................................... 429
Workshop' .............. ..... ............. . . ... ... ...... 429
Teste' ..... ........ .. . . . . . . ... . . . ... . . . . .. . .. .. . .. ...... 429
Exercicios .... . . . . . . . ... ... . .. .. . . . . . .... . . . .. .. . ...... 429

Sum rio

XV II

Dia 18 Iterao 4 do jo go vinte-e-um: adicionando uma GUI


431
Apresentao do jogo vinte-e- um ' ....................... . ........ 431
Oti mizacs da linha de comando ...... ..... . ........... ......... 432
Anlise da GU I do jogo vinte-e-um ' ....................
433
Casos de uso da GUI .... ...... ........ . . . .. . . . . .. ... . .. . . 433
Modelos visua is de GU I .. ...... ..... .. .. .. .. . .. .. .. ..... 436
o

Projeto da GUI do jogo vinte-e-um 437


Cartes CRC da GU I ...................................... 437
Estnltura da GU I
Refazendo' .. . .................................. .... . . . . .
Diagrama de classes da GU I . . .... . ... ....... . ... . .. o
Imp lementao da GU I do jogo vinte-e-um . . ..... ... ... . . . . .....
Im plementando YCard, YDeck c Ca rdV icw .. ......... . .. . . . ... . . . .
Implementando Pl ayerVicw' .. . . .. . ..... . ......................
Implementando Opt ionYicw e OptionViewCont ro ller' ....... .. ... .. . .
Implementando G UIPlayer . .. . . .. . .. . ................. . .......

438
439
440
440
440
444
445
445
Reunindo ludo com BlackjackGUI 448
Resurl10 ...... ..... . .. . .. . ......... .. . . . . .. . . . .. .... ... .. 449
Perguntas e respostas .... ........ . .... . . .. . . .. . .. . . . . ..... 450
Workshop' ............ . . . ... . . .. ......... .. . ............. 450
Teste' .......... .. ........................... . ....... 450
. .
E' XCrcICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 1
Dia 19 Aplica ndo uma alternativa ao MVC
453
Uma GU I alternativa do jogo vinte-e-um 453
As camadas do PAC .... ... ....................... .. .. .. .. 454
A filosofia do PAC , .... ... . .. . ............................. 454
Quando usar o padro de projeto PAC ............................ 455
Ana lisando a GU I PAC do jogo vinte-c-um .... ................ .... . . . 455
Projetando a GU I PAC do jogo vinte-e-um ................. . . . ...... 455
Identificando os componentes da camada de apresentao' .... . . . . .. . . . . 456
Projetando os com ponentes da camada de abslrao' ................. 457
Projetando ri camada de con trole' ............................... 458
Usando o padro Faclory para evi tar erros comuns' ..... ..... . .... . . 458
Im plemen tando a GU I PAC do jogo vinte-e-um' .... . ..... . .......... 460
Implementando YCard e V Hand ................. . .. ... ... . .... 460
Implementando VBetting Player ................ . . . .. . ..... 462
Im plementando VBlackj ackDea ler' ...... . ..................... 464
Implementando GU IPlayer ................... .... ......... 465
Reun indo tudo com O Contro le' .................. ..... . .... 465
Resurl10 ...................................... .. ..... . ..... 468
Perguntas e respostas .. .... ...... ..... ..... . . . . . .. . . .. . .. . .. 468
Workshop' ............ . .... . . . .... .. ... ... ... . .. ... .. . ..... 468

XVII I

Aprend a Progra m ao Ori entada a Objetos em 21 Dia s

Teste ' ....... , , .. , . , ... , , , ... .. .. . .... . . . .... .. .. .. . ..... 468


Exercicios .......... ........... .... . . .. .. .. . . ......... 469
Dia 20 Oivertindo-se com o jogo vinte-e-um

471

Di vertindo-se com O polimorfismo" ............. .... . .... ....... 47 1


Criando um jogador ................ . .. . ... . .. .. . .. .. . ..... 471

O jogador segu ro' .............. .. . .. .. .... .. . ........... 472


Adicionando SafePlayer na GU I ...................... . ........
Aperfe ioamento' ........................................
POO e sim ulaes' .. . . ............... ................... . . ..
Os jogadores do jogo vinte-c-um ' .... .. .. . . . ............ . .....
Resurno .... .... . ............ .... . ... .. . . .. ... . . . .. . . ....
Perguntas e respostas .. .... .. . . . ....... . .. .. .. . . . . .... . . . .
Workshop' ......... .... . .. .. .... . ..... . .....................
Teste' ...... . . . .. . . . ... . . . .......... ............... .....
Exerccios ..... ......... . . .. . ..........................

472
473
474
474
479
480
480
480
480

Dia 21 O ltimo quilmetro


483
Amarrando as pontas ....... . ..... . ............................. 483

Refazendo o projeto do jogo vinte-eum para reut ilizao em ou tros


sistcnl as ............ .............. ......................... 484
Identificando as vantagens que a Poo tTouxe para o sistema do jogo
vi nteeum ................................................. 489
Rea lidades do setor e POO ..................................... 491
Resulllo .................... . . .. .. . ..... .... . ...... . ...... 49 1
Perguntas e respostas . ..... ...... ......................... . 491
Workshop' ............ . .................................. 492
Teste' ...... . .. .. . ... .. .. ...................... .. . .... 492
Exercc ios .... . .. .... .. . ............ . . .. .. .. .... ....... 492
SEMANA 3

Apndices

Em reviso

493
495

Apndice A Respostas
497
Dia 1 Respostas do teste ' . . ................. .. .. . . ...... .... .. . . 497
Respostas do teste' ............. . .......................... 497
Dia 2 Respostas do teste e dos exerccios' ......................... 499
Respostas do teste' ......................................... 499
Respostas dos exerccios' .......................... . ... ..... 50 I
Dia 3 Respostas do teste e dos exerc cios' ...... .. . ... . . ... .. ....... 50 1
Respostas do teste' .. .... ....... ........ ... . . .... ............ 50 I
Respostas dos exercic ios' .................................... 503
Dia 4 Respostas do teste e dos exerccios' ....................... . .. 505
Respostas do teste' ...... . .... . ............................. 505

Sumrio
Respostas dos exercicios' .... . .. . ... . .. .. . . . ..... . .......... 507
Dia 5 Respostas do teste' . . .............. . . .. .. .. . . ......... 508
Respostas do teste' ............... . ..... . ................... 508
Dia 6 Respostas do teste e dos exerccios' ......................... 508
Respostas do teste' ...... .. ......... . ... . .................... 508
Respostas dos exercic ios' ...... . ................... .. .. . ..... 5 10
Dia 7 Respostas do teste' .............. .. . .. ... . . . .. . .. . . . ... 5 11
Respostas do leste' ... . .... . .. . ..... . .. . .. . ... . .. .. . .. ..... 51 1
Dia 8 Respostas do teste e dos cxerccios' .... . .... . . . .. ..... ... .. . ... 5 12
Respostas do teste' .. .. . . .. . .... . ...................... . . . . 5 12
Respostas dos exerccios' ........... . .. . . . ................... 5 13
Dia 9 Respostas do teste e dos exerccios' ..... . ... .. .. ... . .. .. . . . . 5 15
Respostas do teste' .. .... .. . . . ......... .. . ... .. . . . . . . . . 5 15
Respostas dos exerccios' .............. . .. . . . .. . . .. .. ... .. . . . 5 17
Dia 10 Respostas do teste e dos exerccios' .... .. . .. . ... . . .... . . 5 17
Respostas do teste' .. . . . .. .. .... . .......... .... . . ...... ...... 5 17
Respostas dos exerccios' . ......... ........... ... ........... 5 19
Dia I I Respostas do teste e dos exerccios ' .. . ............ .. .. . .... 520
Respostas do teste' ............................ .. .... . ... . .... 520
Respostas dos exerccios' ............... . . .. . . . .. . . . . . . . . ..... 521
Dia 12 Respostas do teste e dos exercc ios .... .. . . . . ... . .. .. . . . ..... 523
Respostas do testc' .................... . . .. ..... . ..... . ....... 523
Respostas dos exerccios' . . .. . ............................. 524
Dia 13 Respostas do teste e dos exercc ios . . ..................... 528
Respostas do teste' . ....... ...... ......... . ..... .. ... . . ...... 528
Respostas dos exercc ios' ... . .. . .. . .. . ....... . .. .. . .. . . ..... 529
Dia 14 Respostas do teste e dos exerccios' .... . . . ... . . . . .. . . ...... 53 1
Respostas do teste' . . .. .... .. .......... ... .. .. . . ..... . .. . . .. 53 1
Respostas dos exercc ios' . .. . .... .. . . .. . ... . .. .... . ......... .. 532
Dia 15 Respostas do teste e dos exerccios' . .. . .. . .. ................ 533
Respostas do teste' .. .. ... .. . . ....... ............... ......... 533
Respostas dos exerccios' ... . . . ...... . .. .. .. ..... . ... . . . ...... 533
Dia 16 Respostas do leste e dos exerccios' .... . . . . . . . . . ... . . . .... ... 534
Respostas do teste' .. . . . .. .. . .. . .. ..... . .. . . . . . . . . .. . . .... . . . 534
Respostas dos exerccios' . .... .............. . .. . . .. ........... 534
Dia 17 Respostas do teste e dos exerccos ' .. . .............. ....... 53 6
Respostas do teste' .... . ........ . .... . .................... 536
Respostas dos exerccios' ................... . ..... . .... .. ..... 536
Dia 18 Respostas do teste e dos exerccios ' ....... . . . .... .... . .... 540
Respostas do teste' ...... . .......... . .... . . . . ... .... , .... 540
Respostas dos exerccios' .................. . .... .. ..... . ..... 540
Dia 19 Respostas do teste e dos exercc ios' . . ...... , ........... ..... 543
Respostas do teste' ....... . ................ . ..... . .......... 543

xx

Aprend a Programao Ori entada a Objetos em 21 Dia s

Respostas dos exercicios' .................. . . . .... . . ... . ......


Dia 20 Respostas do teste e dos exercc ios' .... . .. .. .. . . .........
Respostas do leste' ............... . .............. .. .........
Respostas dos exercc ios' ...................................
Dia 2 1 Respostas do teste e dos exercc ios' . . ... . .......... . ...... . ..
Respostas do leste ' ........... . ..... . ............. .. .. . .....
Respostas dos exerccios' ............... . . ... . . . . .... . . . ...

544
548
548
548
553
553
554

Apndice B Resumo do Java


555
O Java Developer's Kit: J2SE 1.3 SDK ............ . . . . . ... ... .. . . .. 555
Configurao do ambiente de desenvolvimento' ............... . . . . 556
Panorama das fe lTamen tas do S DK ..... . . .. . .... .. .. . .......... ... 557
Co mpilador Java: javac' .... . . . .. . .............. . .... ... .. . . . . 557
Interpretador Java : java ' .. . .. . . .. .. . . .. . . .. ........... . . . .. . . 558
Uti litrio de com pactao de arqui vos Java: jar . . . .. .... ... . . .... . 558
Documentao Java e o gerador de documentao: javadoc .... .. ... .. . . 559
Cercadinho Java: seu primeiro programa Java .. .... . ............... . . 560
Compi lando e executando ' ..................................... 561
Cri ando um arqui vo .jar . .... . .......... . . ............... ... 562
Gerando j avadoc' ........... . .... ...... . ..... . .. . .. . ....... 563
Mecnica da li nguagem Java' ... . .. .. . . .... . . .. .. .. . . . . . . .. ... 564
Classe Java simples ........ .... .. .. . .. .... . . ..... . .. ..... 564
Ti po de Dados ............ . .... . . ..... ..... . ..... . ....... 565
Varive is' ...... . .... . ... . .......................... . 566
Constantes ............ . ... . .. .. . . .. . ............ ....... 568
Operadores' .. . .. . ....... .. ................. .. .... . .. . ... 568
Estruturas condic iona is' . .. . . ..... . .. . . . ............... . .. . . . 570
Laos ou estruturas de repetio" . .. . .. . . .... .. ......... . ...... 57 1
C lasses e interfaces - blocos de construo da linguagem Java ' .... . .. . . . . 57 1
Usando classes j ex istentes' . . .. . .. . . .. . .... .. ................ 572
Cri ando suas prprias classes ....... ............... . .. . .. . ...... 572
Interfaces' . .... . .. . . .. . .. . .. . .... ...... . ............ . .. ... . 575

C lasses internas e classes internas annimas' .... . . .... . .... . .. , .... 577
Resulno ... . .. . .. . ........ .. ....... . .. . .. . .. . . . ... . . . . .... . . 579
Apndice C Referncia da UML
581
Refernc ia da UM L ............ . ... . . . .... . . ........... . .... . 581
Classes' .............. . .... . .......... .... ................ 581
Objeto ............... ..... . ...... .. . . . ............... 58 1
Visibilidade " ......... . ............... . ..... . .... .. ..... 581
Classes e mtodos abstralOs ' .... .. .............. . . .. .. .. . .... 582
Notas ...................... . . .. .. ... . ... . .. . . ... . . . .. .... 582
Esteretipos ' ............ . .... . .. ... . . . .... .... .. ... . .... . 583
Relacionamentos ' .... . . . .. ........... . ... . . . .. . . .. ..... . ..... 583

Sumrio

Dependncia ..... .... . . . . .. . . ..... .. ... .... .. . . . ... ...


Associao ' ...... . . . .. .. . . .. . .... . . . .. .. .. . . .........
Pa p is' ...... ... . . ..... . ............... .. ..... ... ... ...
Mu ltipl icidade ........... . .......... ...................
Agregao ........... ..... ... . ... . ....................
COln posio ........... ...... ... .. .......... . .. ..... .....
General izao' ................... .... ... . . .. .... . . .. ..
Diagram as de in lerao' ...... . .. . . . . ... .. .. . ... . .... . . ... ..
Diagramas de colaborao ............ . . .. . . .. .. . . ... .... . . ...
Diagramas de seqUncia' . .. . .... .. ..................... . . . .

583
584
584
584
585
585
585
586
586
586

Apndice O Bibliografia selecionada


587
An lise, projeto e metodologias' . . . .. . ....................... . . . . 587
Programal'lo com C++ . .... .. . . . .. .. . . .. .. .. . . .. .. . . .. .. . . 588
Padres de projeto ........ ............ .... . . . .. . . .. .. .. . .. ... 588
Principios e teoria gera l da 00 .. . . .. .. ............ . . .. . . . .... . . 588
Teoria " Hard Core" (mas no deixe isso assust- lo!) . . ............... 588
Programallo com Java' ................... ............ ........ 589
Miscelnea ' ........... ................ ..................... 589
Snl alltalk ................... . ..... ...... . ... ................. 589
Teste' .......................................... .... ........ 589
Apndice E Listagens do cdigo do jogo vinte-e-um
591
blackjack.core ..................... ................... . ...... 592
blackjack.core.lhreaded ..... . ................ ............ . ..... . 6 19
blackjack.exe .... ......................... ........ .. ..... 62 1
blackjack. players ........ . .. . ......... ........ . ... ........ 627
blackjack. ui ........... . .. .. .... . .. . ............... ... ...... 635
blac~ack.u i.mvc ...... . . . . . ... ... . . .... . . ... . .. .. .. ... ....... 636
blackjack. ui.pac ... . .. . .. .. . ... ... ... ... .. . . . .. . . . ... ....... 649
(ndice Remissivo

669

Introduo
Este livro adota uma estratgia prtica para e ns inar programao orienlada a objclos (POO). Em
vez de ensinar POO em um nve l acadmico, este li vro apresenta lies e exemplos acessveis e
amigveis, para pennitir que voc comece a aplicar POO imediatamente. Em vez de tenlar ensi-

nar cada detalhe terico, este li vro destaca os assuntos que voc precisa conhecer para poder
aplicar POO em seus proj etas dirios - e no perder seu tempo se degladiando em algum debate
terico.

o objetivo deste li vro fornecer a voc uma base slida sobre programao o rientada a objelos.
Aps 21 dias, voc dever ter lima boa idia dos concei tos bs icos da POO. Usando essa base,
voc pode comear a apli car co nceitos de POO em seus projetas dirios, assi m como cont inuar a
construir seus conhec imentos de 00, atravs de estudo adicional. Voc no aprender tudo a
respeito de POO em 21 dias - isso simplesmente no possvel. En tret8llto, possve l constru ir
uma base slida e comear com o p direito. Este livro o ajuda a fazer exatamente isso.
Dividimos este li vro em trs partes. A Semana I apresenta os trs princpios da POO (tambm
conhec idos como os trs pilares da POO). Esses trs princpios fonnam a base da teo ria da orientao a objetos. O entendimento desses trs princpios abso lutamente fundamen ta l para entender POO. As lies da semana esto divid idas entre apresentao da teoria e o fornec imento de
experincia prtica, atravs de laboratrios.
A Semana 2 apresenta o processo de desenvolvimento de software 00. Embora as lies do Captulo I, "llllroduo programao orientada a objetos", sejam im portantes, mand-lo programar se m qualquer outra instruo como dar a voc madeira, uma serra, um martelo e a lguns
pregos, e dizer para construir uma casa. A Semana 2 mostra como aplicar as ferramentas apresentadas nas Iies da Semana I.
A Semana 3 o conduz em um estudo de caso completo, de um jogo de cartas 00. Esse estudo
permitir que voc percorra um ciclo de desenvolvimento 00 inte iro, do inc io ao fim , assi m
como prat ique a escrita de algum cd igo. Esperamos que esse estudo de caso ajude a esc larecer a
teoria da 00 e torne as co isas mai s concretas.
Tambm existem vrios apndices no fina l do livro. De impo rtnc ia espec ial o "Resumo do
Java", no Apndice B, e a bibliografia selecionada, no Apndice D, O Apndice B serve como
um g uia exce lente para a linguagem de programao Java. A bibliogra fia mostra os rec ursos que
voc desejar consultar, quando conti nuar seus estudos de POO. Esses recursos certamente fo ram va liosos para escrever este livro.

Sobre os exemplos
Todos os exemplos de cdigo-fonte foram escritos em Java. A Iguma ex perincia em Java ajudar; entretanto, o Apndice B deve ajud-lo a ter ve locidade, caso voc esteja enferrujado ou mlnca tenha visto a linguagem antes. Desde que voc tenha algum conhec imento de programao,
os exemp los 5<10 os mai s acess veis. Os recursos e truques especia is do Java foram particularme nte evitados nos exemplos.

o que voc precisa saber para usar este livro


Este li vro presum e alguma experincia anterior em programao e no lenta ensinar programao bsica. Este livro pega o conhec ime nto que voc j tem e mostra como pode us-lo pa ra escrever so fi ware orientado a objclos. Ou escrever software orientado a objelos me lhor. Isso no
quer dizer que voc precisa ser um guru de programao para ler e enlender este livro - um curso de programao introdutrio ou simplesmente a leitura de um li vro de programao todo o
con hec imento que voc deve precisar.

Para poder tirar total prove ito dos exemplos e exerccios, voc tambm precisar de um computador com acesso Internet. A escolha do ambiente operacional e do editor fi cam completamente por conta de seu gosto pessoal. O nico requisi to que voc possa fazer download, instalar e
executar Java. O Apndice B o conduz pelo processo de obteno de um SDK Java.
Finalmente, voc precisa de determinao, dedicao e uma mente aberta. A programao orientada a objetos no fci l e voc demorar mais de 21 dias para dominar, mas aqui voc pode ter
um incio bom e slido.
O mundo maravilhoso da

roo est espera ....

SEMANA

Definindo 00
I Introduo programao orientada a objetos
2 Encapsulamento: aprenda a manter os detalhes

consIgo mesmo
3 Encapsulamento: hora de escrever algum cdigo
4 Herana: obtendo algo para nada

5 Herana: hora de escrever algum cd igo

6 Polimorfismo: aprendendo a prever o futuro


7 Polimorfismo: hora de escrever algum cdigo

Panorama
Os prximos sete dias fornecerdO a voc uma base slida sobre programao orientada a objelos.
O Dia I descreve os fu ndamentos da 00 (orientado a objetos). Voc aprende a respeito de orientao a objelos a parti r de uma perspectiva histrica e v como a 00 evolu iu a partir de linguagens de programao existentes. Voc tambm aprende a terminologia bsica, ass im como as
vantagens e armadi lhas da programao orientada a objetos.
Os dias 2, 4 e 6 apresentam os trs pitares da programao orientada a objelos: encapsulamenlo,
herana e polimOlfismo. Esses captul os no apenas expli cam os fundamentos da programao

orientada a obj elos, mas como e quando us-los, assi m como os erros a serem evitados.
Os dias 3, 5 e 7 fornecem laboratrios correspondentes a cada um dos trs pilares. Cada capitulo
de laboratrio fornece experincia prtica que lhe penn ite se fami liarizar-se com os pi lares apresentados nos dias 2, 4 e 6.
Aps concluir a primeira semana, voc dever ter um entend imento com pleto do qu constitui
um programa orientado a objetos. Voc deve poder identificar os trs pilares da 00 e aplic-los
em seu cd igo.
Testes e exerccios seguem a lio de cada dia, para ajud-lo a entender melhor os assuntos abordados. As respostas de cada pergunta dos testes e exerccios aparecem no Apndice A.

SEMANA

DIA
Introduo programao
orientada a objetos
Embora as linguagens orientadas a objetos j existam desde a dcada de 1960, os ltimos 10
anos tm vi sto um cresci mento sem paralelo no uso e na aceitao de tecnologias de objeto, por
todo o selar de software. Embora tenham comeado como algo secundrio, slIcessos recentes,
como Java, CORBA e C++, tm impulsionado as tcnicas orientadas a objetos (00) para novos
nveis de acei tao. Isso no por acaso. Aps anos presa nos meios acadmicos e tendo de lutar
uma rdua batalha contra as prticas entrincheiradas, a programao orientada a objetos (POO)
amadureceu at o ponto onde as pessoas so finalmente capazes de perceber as promessas que a
tcnica contm. No passado, voc tinha de convencer seu chefe a permit ir o uso de uma linguagem orientada a objetos. Hoje, muitas empresas obrigam seu uso. seguro dizer que as pessoas
esto finalmente ouvindo.
Se voc est lendo este livro, fina lmente foi convencido. Provavelmente algum com um nvel
intcnnedirio de experincia em programao. Se voc conhece C. Visual Basic ou FORTRAN,
j estava nas imediaes, mas decidi u que precisa dar uma sria olhada na programao orientada a objetos e torn-Ia parte de seu conjunto de habilidades.
Mesmo que voc tenha alguma experincia com uma linguagem orientada a objetos, este li vro
pode aj ud-lo a sol id ificar seu entendimento de 00. Mas no entre em pnico, caso voc no
esteja fa miliarizado com uma linguagem 00. Embora este livro use Java para ensinar conceitos de

Dia 1

00, um conhecimento prvio de Java no necessrio. Se voc fica r confuso ou predsar de um


lem brete da sintaxe, basta consultar o Apnd ice B, " Resumo do Java".
Se voc prec isa de 0 0 para se manter no mercado, termi nar seu projeto ma is recente ou satis
fazer sua pr pria curiosidade, ento veio ao lugar certo. Embora nenhum livro possa ensinar
tudo que h em re lao a ao, este li vro promete fornecer uma base sl ida em 00. Com essa
base, voc pode comear a praticar POO. E, mais im portante, a fundamentao fornece r a
base d urvel q ue voc precisa para con tinuar a aprender e, fin al mente, dominar esse parad ig
ma de programao.
Hoj e voc aprender

Programao orientada a objetos em um contexto hi strico

A base da programao ori entada a objetos

As vantagens e obj eti vos da programao orientada a objetos

As fa lc ias e armadilhas comuns associadas programao ori entada a objetos

Programao orientada a objetos em um


contexto histrico
Para entender o estado atual da POO. voc deve conhecer um pouco da histria da programao.
Ningum cOllcebeu a POO da noite para o dia. Em vez disso, a POO apenas outro estgio na
evoluo natural do desenvolv imento de soft ware. Com o passar do tempo, se tomou mais fc il
identifi car as prticas que funcionam e as que comprovadamente falh am. A POO com bina prti
cas com provadas e testadas o mais efi cientemente possvel.

00 a abreviatura de orientado a objelOs. 00 um lemlO gera l que incl ui qualquer


esti lo de desenvolvimento que seja baseado no conceito de 'objeto ' - urna entidade
que exibe caractersticas e comportamentos. Voc pode aplicar uma estratgia orientada a objetos
na programao, assim como na anlise e no projeto.

Novo TERMO

Voc tambm pode di zer que 00 um estado da mente, uma maneira de ver o mundo todo em
termos de objetos.
Simplesmente, a 00 contm tudo que pode ser denominado como ori entado a objetos. Voc vai
ver o tenno 00 muitas vezes neste livro.

Precursores da POO
Atualmente, quando usa um computador, voc tira proveito de 50 anos de refi namento. Antiga
mente, a programao era engenhosa: os programadores introduziam OS programas diretamente
na memria princi pal do computador, atravs de bancos de chaves (sw itches). Os programado-res escreviam seus programas em linguagem binria. Ta l programao cm linguagem binria

Introduo programao orientada a objetos

era extremamente propensa a erros e a falta de estrutura tornou a manuteno do cdigo praticamente impossvel. Alm disso. o cd igo da linguagem binria no era muito acessvel.
Quando os com putadores se tomaram mais comuns, linguagens de nvel mais alto e procedurais
comearam a aparecer; a primeira foi FORTRAN. Entretanto, linguagens procedurais posteriores, como ALGO L, tiveram mais inO uncia sobre a 00. As linguagens procedurais permitem ao
programador reduzir um programa em proced imentos refinados para processar dados. Esses
procedimentos refinados definem a estrutura global do programa. Chamadas seqi.lenciai s a esses
procedi mentos geram a execuo de um programa proced ural. O programa termi na quando acaba de chamar sua li sta de procedi mentos.
Esse paradigma apresentou diversas melhorias em relao Iinguagem binria, incluindo a adio de uma estrutura de apoio: o procedimento. As funes menores no so apenas mais fceis
de entender, mas tambm so mai s fceis de depurar. Por outro lado, a programao procedural
limita a reutilizao de cdigo. E, com muita freqncia, os programadores produziam cdigo
de espagueti - cd igo cujo caminho de execuo se assemelhava a uma ti gela de espagueti. Finalmente, a natureza voltada aos dados da programao procedural causou alguns problemas
prprios. Corno os dados e o procedimento so separados, no existe nenhum encapsulamento
dos dados. Isso ex ige que cada procedimento saiba como manipularcorretamente os dados. Infelizmente, um procedi mento com comportamento errneo poderia introduzi r erros se no manipulasse os dados corretamente. Uma mudana na representao dos dados ex igi a alteraes em
cada lugar que acessasse os dados. Assim, mesmo urna pequena alterao poderia levar a uma
cascata de alteraes, por todo o programa - em outras palavras, um pesadelo de manuteno.
A programao modular, com uma linguagem como Modula2, tenta mel horar algumas das defi cincias encontradas na programao procedural. A programao modu lar divide os programas
em vrios componentes ou mdulos constitui ntes. Ao contrrio da programao proccdural, que
separa dados e proced imentos, os mdulos combinam os dois. Um mdulo consiste em dados e
procedi mentos para manipu lar esses dados. Quando outras partes do programa precisam usar um
mdulo, elas simplesmente exercitam a interface do mdu lo. Como os mdu los ocultam todos
os dados internos do restante do programa, fcil introduzir a idia de estado: um md ulo contm informaes de estado que podem mudar a qual quer momento.
Novo

TERMO

o estado de um objeto o significado combinado das variveis irllemas do objeto.

Novo

TERMO

Uma varivel inferna um valor mantido dentro de um objeto.

Mas a programao Illodular sofre de duas deficincias prprias importantes. Os mdulos no


so extensveis, sign ificando que voc no pode fazer alteraes incrementa is cm um mdulo
sem abrir o cdigo a fo ra e faze r as alteraes diretamente. Voc tambm no pode basear um
mdulo em outro, a no ser atravs de delegao. E, embora um mdulo possa defin ir um ti po,
um mdulo no pode compart ilhar o tipo de oulro mdulo.

Dia 1

Nas linguagens modulares e procedurais, os dados estruturados e no estruturados tm um

'tipo'. O tipo mais fac ilmente pensado como o fonna lo da memria para os dados. As linguagens fortemente ti padas exigem que cada objeto tenha um tipo especfico e definido. Entretanto,
os tipos no podem ser estendidos para criar outro tipo, exceto atraves de um est ilo chamado
'agregao'. Por exemplo, em C, podemos ter dois tipos de dados relacionados:
typedef struct
{

'Int a;
int b;
} aBaseType;
typedef struct
{

aBaseType Base ;
i nt c;
} aDerivedType
Nesse exemplo, aDeri vedType baseado em aBaseType, mas uma est rutura de aDerivedType no
pode ser tratada di retamente como uma estrutura de aBaseType. Uma s pode faze r referncia ao
mem bro Base de uma estrutura aDeri vedType. Infel izmente, essa organizao lcva a cdigo que
possu i muitos blocos case e if7else, pois o aplicativo deve saber como manipular cada mdulo
que encontra .
Finalmente, a programao modu lar tambm um hbrido procedural que ainda div ide um programa em vrios proced imentos. Agora, em vez de atuar em dados brutos, esses procedimentos
manipulam mdulos.

Programao orientada a objetos


A roo d o prximo passo lg ico aps a programao modular, adicionando herana e polimorfismo ao mdulo. A roo estrutura um programa, dividindo-o em vrios objetos de alto nvel.
Cada objeto modela algum aspecto do problema que voc est tentando resolver. Escrever listas
seqUencia is de chamadas de procedimento para dirigir o flux o do programa no mais o foco da
programao sob a 00. Em vez disso, os objetos interagem entre si, para orientar o fluxo global
do programa. De certa forma , um programa 00 se torna uma si mulao viva do problema que
voc est tentando resolver.

Uma estratgia de POO para software usando objetos


Imagine que voc tivesse de desenvolver um programa 00 para implementar um carrinho de
compras on-l ine ou um tenninal de ponto de vendas. Um programa 00 conter os objetos item,
carrinho de compras, cupom e caixa. Cada um desses objetos vai interagir uns com os outros
para orientar o programa . Por exemplo, quando o caixa totalizar um pedido, ele veri ficar o preo de cada item.

Introduo programao orientada a objet os

Definir um programa em termos de objetos uma maneira profunda de ver o software. Os objelOS o obrigam a ver tudo, em nvel concei tuai, do que um objeto faz: seus comportamentos. Ver
um objelo a partir do nvel concei tua i um desvio da observao de como algo feito: a implementao. Essa menta lidade o obriga a pensarem seus programas em termos nat urais e reais. Em
vez de modelar seu programa como um conj unto de procedimentos e dados separados (termos
do mundo do computador), voc modela seu programa em objetos. Os objetos permitem que
voc modele seus programas nos substant ivos, verbos e adjet ivos do domnio de seu problema.
Novo TERMO
Novo TERMO

A implcmcnta(70 define como algo feito. Em tennos de programao, implcmcnla(jo o cdigo.

o dOll/inio o espao onde um prob lema reside. O domnio o conjunto de conceitos


que representam os aspectos im portantes do problema que voc est tentando resolver.

Quando recua e pensa nos termos do problema que est resolvendo. voc ev ita se emaranhar nos
detalhes da implementao. claro que alguns de seus objetos de alto nvel precisaro interagir
com o computador. Entretanto, o objeto isolar essas interaes do restante do sistema. (O Dia
2, "Encapsulamento: aprenda a manter os detalhes consigo mesmo", explorar melhor essas
vantagens.)

NOTA

Em term os do carri nho de compras, ocultao de implementaosign' ica que


o caixa no v dados brutos ao t otali zar um pedid o. O caixa no sabe procurar,
em certas posies de memria, nmeros de item e outra varivel para um cupom. Em vez disso, o caixa interage com objetos item. Ele sabe perguntar
quanto custa o item.

Neste ponto, voc pode definir ohjelo fo nnalmente:


Novo TERMO Um objelo uma construo de software que encapsu la estado c comportamento. Os
objetos permitem que voc modele seu software em lennos reais e abstraes.
Rigorosamente fa lando, um objeto urna instncia de lltna classe. A prx ima seo apresentar
o concei to de classe.
Assim como o mundo real constitudo de objetos, da mesma forma o o software orientado a
objelos. Em uma linguagem de programao 00 pura, tudo um objeto, desde os tipos mais bsicos, como inteiros e lgicos, at as instncias de classe mais complexas; nem todas as li nguagens
orientadas a objeto chegam a esse ponto. Em algumas (como o Java), primi tivas como int c fl oat,
no so tratadas como objetos.

Dia 1

o que uma classe?


Assi m como os objetos do mundo real, o mundo da POO agrupa os objelos pelos seus comportamentos e atributos comuns.
A biologia classifica todos os ces, gatos, elefantes e seres humanos como mamferos. Caraclerislicas comparti lhadas do a essas criaturas separadas um senso de comunidade. No mundo do software, as classes agnlp.1.1ll objetos relacionados da mesma maneira.
Uma classe define todas as caracterst icas com uns a um ti pode objeto. Especificamente, a classe
defi ne todos os atribulos e comportamentos expostos pelo objeto. A classe define a quais mensagens seus objelos respondem. Quando Ulll objetoquer exercer o comportamento de outro objeto,
ele no faz isso diretamente, mas pede ao outro obj eto para que se mude, normalmente baseado em
alguma informao adiciona l. FreqUentemente, isso referido como 'envio de uma mensagem' .
Novo TERMO Uma c/asse define os atributos e comportamen tos com uns compartilhados por um
tipo de objelo. Os objetos de certo tipo ou classificao compartil ham os mesmos
comportamen tos e atributos. As classes atuam de forma muito parecida com um cortador de mal
de ou biscoito. no sentido de que voc usa uma classe para criar ou instanciar objetos.
Novo TERMO Atributos so as caracteristicas de uma classe visiveis externamente. A cor dos olhos
e a cor dos cabelos so exemplos de atributos.
Um objeto pode expor um atribula fornecendo um link direto a alguma varivel interna ou retornando o valor atravs de um mtodo.
Novo TERMO ComporramelJ/o uma ao executada por um objeto quando passada uma mensagem ou em resposta a uma mudana de estado: algo que um objeto faz.
Um objelo pode exercer o comportamenlo de outro, executando uma operao sobre esse objeto.
Voc pode ver os termos chamada de mtodo, chamada de funo ou passar lili/a mensagem ,
usados em vez de executar uma operao. O que importante que cada urna dessas aes om ite o comportamento de um objcto.
Passagem de mensagem, operao, chamada de mtodo e chamada de funo: o qu voc usa, freqen temente depende de seus conceitos anteriores.

Pensar em termos de passagem de mensagem uma maneira muito orientada


a objetos de pensar. A passagem de mensagem dinmica. Conceituai mente,
ela separa a mensagem do objeto. Tal mentalidade pode ajudar a pensar a respeito das interaOes entre objetos.
linguagens como C++ e Java tm heranas procedurais, onde as chamadas de
funo so estticas. Como resultado, essas tinguagens freqentemente se referem a um objeto realizando uma chamada de mtodo a partir de outro objeto. Uma chamada de mtodo est fortemente acoptada ao objeto.
Este livro normalmente usar chamada de mtodo. devido sua forte ligao
com Java. Entretanto, podem existir ocasies em que o termo mensagem
usado indistintamente.

Introduo programao orientada a objetos

Reunindo tudo: classes e objetos


Pegue um objeto item, por exemplo. Um item tem uma descrio, id, preo unitrio, quantidade
e um desconto opcional. Um item saber calcular seu preo descamado.
No mundo da POO, voc diria que todos os objetos item so instncias da classe Item. Uma classe Item poderia ser como segue :

public class Item (


private
private
private
private
private

double
double
i nt
Stri ng
Stri ng

unit_pri ce i
discount; Iluma porcentagem de desconto que se ap l ic a ao preo
quantity ;
desc r i pt i on i
i d;

public Item( String id , Stri ng descri ption, int quantity , doub l e price ) {
this.id id;
th i s.description descript i on;
O) I
this.quantily quan t ity;

if( quan tity

>-

I
else {
l his.quantity O;

I
this.unit_price pri ce i

I
publi c double getAdju stedTotal() {
double tota l unit_price * quantity;
double total - discount total * discount;
double adj usted_to t al total - total_d isco unt;
return adjusted_total

II

apl ic a uma porce ntagem de desconto no preo


publ i c void setOiscount( double di scount ) I
if( dis count u 1. 00 ) {
this .discoun t discount;

I
else {
t his.discount 0.0 ;

Dia 1

I
publi C double getD1scount()
return discount:

I
publl c int getQuantityO
return quantity;

I
public vo 1d setQuantity( int quantity ) {
if( quantity >- O ) {
this.quantity z quantitYi

I
I
pub l ic String getProductIDO {
return idi

I
public String getDescription() (
return descriptionj

I
Mtodos como
public Item( String id, String descr1ption. 1nt quantity . double pr1ce )
so chamados COI1Slr/llo r es. Os construtores inicializam um objeto durarue sua criao.
so mtodos usados para inicializar objctos durante sua instanciao.
Voc chama a criao de objetos de il/Slallciat7o porque ela cria uma instncia do
objeto da classe.

Novo

TERMO

NOTA

COI/Slr/IIores

No construtor e por todo o exemplo Item, voc poda notar o uso de th i s. thi s
uma referncia que aponta para a instncia do objato. Cada objato tem sua
prpria referncia para si mesmo. A instncia usa essa referncia para acessar
suas prprias variveis e mtodos.

Mtodos como setDfscountO, getDescript1onO e getAdjustedTota l O so lodos comportamentos da classe I tem que retomam o u configuram atributos. Quando um caixa quer totali zar o
carrinho, e le simplesmente pega cada ite m e envia ao objeto a mensagem getAdj us tedT ota 1 O .

Introduo programao orientada a objet os

11

unit_price, di scou nt, quantity, description e id so todas variveis internas da classe Item.
Esses va lores compreendem o esladQ do objelo. O estado de um objeto pode variar com Otempo.
Por exemplo, ao fazer compras, um consumidor pode aplicar um cupom ao item. Aplicar um cupom ao item mudar o estado do item, pois isso mudar o valor de discount.
Os mtodos como getAdjustedTota 10 e getoiscountO so chamados de ace:"SQres, pois eles
pennitem que voc acesse os dados internos de um objeto. O acesso pode ser direto, como no
caso de getDiscount(). Por outro lado, o objeto pode realizar processamento antes de retornar
um valor, como no caso de getAdjustedTotal O.
Os ace.~.wres do acesso aos dados internos de um objeto. Entretanto, os (lcessores
ocultam o fato de os dados estarem em uma varive l, em uma combinao de varivei s ou serem calculados. Os aces:wres permitem que voc mude ou recupere o valor e tm 'efeitos colaterais' sobre o estado interno.

Novo

TERMO

Os mtodos como setDi scount() so chamados de l11ulanles, pois eles permitem que voc altere o estado interno do objeto. Um mutante pode processar sua entrada como qui ser, antes de alterar o estado interno do objeto. Pegue setD; scount () , por exemplo. setDi scount () garante que
o desconto no seja maior que 100%, antes de aplic- lo.
Novo

TERMO

Os

1II1I/(lI1les

pennitem que voc altere o estado interno de um objeto.

Ao serem executados, seus programas usam classes como a I tem para cdar ou instanciar os objetos que compem o aplicativo. Cada nova instncia uma duplicata da lt ima. Entretanto, uma
vez instanciada, a instncia transporta comportamentos e controla seu estado. Ento, o que inicia
sua vida como clone poderia se comportar de maneira muito diferente durante sua existncia.
Por exemplo, se voc criar dois objetos item a partirda mesma classe I tem, um objeto item poder ter um desconto de 10%, enquanto o segundo pode no ter desconto. Alguns itens tambm so
um pouco mais caros que outros. Um item poderia custar USS 1.000, enquanto outro poderia custar apenas US$I,98. Assim, embora o estado de um item possa variar com o passar do tempo, a
instnc ia ainda um objeto de Item. Considere o exemplo da biologia; um mamfero de cor cinza
to mamfero quanto outro de cor marrom.

Fazendo os objetos trabalhar


Considere o mtodo main() a seguir:
publiC static void main( String
II cria os itens
Item mil k ,e. Item(
Item yogu rt 'e. Item{
Item bread 00' Item(
Item soap ,e. Item(

[] al"9S ) I
"dairy-Oll", "I Gallon Hilk", 2, 2.50 );
"dairy-032", Peach Yogurt", 4,0.68 ) ;
"bakery-023" , "Sliced Bread" , 1,2.55 );
"household -21", "6 Pack Soap , 1,4.51 ) ;

Dia 1

II aplica cupons
milk.setOiscount( 0. 15 ).
II obtm preos ajustados
double milk_price milk.getAdjustedTotal();
doubl e yogurt_price yogurt.getAdjustedTotal();
doubl e bread_price z bread.getAdjustedTotal().
double soap_price a soap.getAdj ustedTotal().
I I imprime recibo
System.out.println( "Thank Vou For Vour Purchase." ).
$ystem. out.println( "Please Come Again!" ):
System . out.println( milk.getOescription()
+ "\t $" +
System.out.print l n( yogurt.getOescription() + "\t $" +
System.out.print l n( bread.getOescript ion() + ., \ t $" +
+ ., \ t $" +
System . out.println( soap.getOescr i pt ion()

milk_pri ce
yogurt_price
bread_price
soap_price

);
);
);
);

II calcu l a e imprime total


double total milk_price + yogurt_price + bread_price + soap_price.
System . out.p r intln( "Total Price \t $" + total );
}

Esse mtodo mostra como poderia ser um pequeno programa que usa objetos de Item. Primeiro, o
programa instancia quatro objetos de Item. Em um programa real, ele poderia criar esses itens
quando um usurio navegasse em um catlogo on-li ne ou quando um caixa percorre os amlazns.
Esse programa cria vrios itens, aplica descontos e, em segu ida, imprime um recibo. O programa
rea liza toda a imerao do objeto enviando vrias mensagens para os itens. Por exemplo, o programa apl ica um desconto de 15% no leite (milk), enviando a mensagem setDiscount () para o item.
O programa total iza os itens primeiro enviando a cada item a mensagem getAdjustedTotal O.
Finalmente, esse programa envia um recibo para a tela. A Figura 1.1 ilustra o exemplo de saida.
FIGURA 1.1

Imprimindo
I/m recibo.

im portante perceber que toda a programao foi feita em termos de objetos de Item e os comportamentos expostos pelos mtodos de I tem - os substantivos e verbos do domnio do carri nho
de compras.

Introduo programao o rientada a objetos

13

Relacionamentos de objeto

o modo como os objetos se relacionam um com ponente muito importante da POO. Os objetos
podem se relacionar de duas maneiras im portantes.
Primeiro, os objetos podem existi r independentemente uns dos outros. Dois objetos de Item p0dem aparecer no carrinho de compras si multaneamente. Se esses dois objetos separados prec isarem interagi r, eles interagiro passando mensagens um para o outro.
Novo TERMO Os objetos se comunicam uns com os outros atravs de mensagens. As mensagens
fazem com que um objeto realize algo.
' Passar uma mensagem' o meSmo que chamar um mlodo para mudar o estado do objeto ou
para exercer um com portamento.
Segundo, um objeto poderia conter outros objetos. Assim, como os objetos compem um programa em POO, eles podem compor outros objetos atravs da agregao. A partir do exemplo
Item, voc poderia notar que o objeto ite m contm muitos outros objetos. Por exemplo, o objeto
item tambm contm uma descrio e uma ido A descrio e a id so ambas objelos de Stri ng.
Cada um desses objetos tem uma interface que oferece mtodos e at ributos. Lembre-se de que,
na POO, tudo um objeto, mesmo as partes que compem um objclo!
A comunicao funciona da mesma maneira entre um objetoe os objetos que ele contm. Quando os objetos precisarem interagir, eles fa ro isso enviando mensagens uns para os outros.
As mensagens so um importante conceito de 00. Elas pennilem que os objetos permaneam
independentes. Quando um objeto envia uma mensagem para OUITO, geralmente ele no se preocupa com a maneira como o objetoescol he transportar o comportamento solici tado. objeto solic itante se preocupa apenas que o comportamento acontea.

Voc vai aprender mais a respeito de como os objetos se relacionam, na prxima semana.

A definio de objeto est aberta ao debate. Algumas pessoas no defi nem um


objeto como uma instncia de uma classe. Em vez disso, elas definem tudo em
termos de ser um objet o: a partir desse ponto de vista, uma classe um objeto
que cri a outros objetos. Tratar uma classe como um objeto importante para
conceitos como metaclasse.
Quando este livro encontrar uma discordncia na terminologia, escolheremos
u ma definio e ficaremos com ela. Muito freqentemente, a escolha ser
pragmtica. Aqui, optamos por usar a definio de objeto como instncia. Essa
a definio UML (Unified Modeling Language) e a mais encontrada no set or.
(Voc vai aprender mais a respeito de UMl posteriorm ente.) Infelizm ente, a
outra uma definio orientada a objetos mais pura. Entretanto, voc no a
encontrar muit o freqentemente e o conceito de m etaclasse est fora dos objetivos deste livro.

Dia 1

Como a programao orientada a objetos fundamenta o


passado
Assi m como outros paradigmas lentam acentuar as vantagens e corrigir as ralhas dos paradigmas
anteriores, a POO rundamenta a programao proced ural e mod ular.
A programao modular est rutura um programa em vrios mdulos. Do mesmo modo, a POO
d ivide um programa em vrios objetos interativos. Assim como os md ulos ocultam representaes de dados at rs de procedi mentos, os objetos encapsulam seu estado por trs de suas interraces. A POO empresta esse concei to de encapsulamento di retamente da programao modular. O
encapsul amento direre muit o da programao procedura l. A prog ramao procedu ral no encapsul a dados. Em vez d isso, os dados so abertos para todos os procedi mentos acessarem. Ao
contrrio da program ao procedural , a programao orientada a obj etos acopla rortemente
dados e com portamentos ao objeto. Voc va i aprender mais a respei to do encapsulam ento nos
dias2e3.
Em bora os objetos sejam conceitua lmente semelhantes aos mdulos, eles di rerem de vrias maneiras importantes. Primeiro, os mdulos no suportam extenso prontamente. A programao
orientada a objetos introduz o conceito de herana para elimi nar essa deficincia. A herana permite que voc estenda e mel hore suas classes raci lmenle. A herana tambm permite que voc
classi fi que suas classes. Voc vai aprender mais a respeito da herana no Dia 4, " Herana: obtendo algo para nada" e no Dia 5, " Herana: hora de escrever algum cd igo" .
A POO tambm acentua o concei to de polimorfi smo, q ue aj uda a construir programas fl exveis,
que no resistem mudana. O poli morfi smo acrescenla essa fl exibilidade limpando o sistema
de tipagem li mitado do mdu lo. Voc vai aprender mais a respeito do poli morfi smo no Dia 6,
" Polimorfismo: aprendendo a prever o ruturo" e no Dia 7, " Poli morfismo: hora de escrever algum cdigo".
A POO certamente no invento u o encapsulamento e o polimorfi smo. Em vez disso, a POO
combina esses conceitos em um s lugar. Peg ue a noo da POO de objetos e voc reun ir essas
tecno logias de uma maneira jamais reita.

Vantagens e objetivos da 00
A programao orientada a objetos define se is objeti vos sobrepostos para desenvolvimento de
software. A POO se esmera em produzir software que tenha as seguintes caractersticas:
1. Natura l

2. Confive l
3. Reut ilizvel
4. Manutenve l

Introduo programao orientada a objet os

15

5. Extensvel
6. Oportunos
Vamos ver como ela funciona para atender cada um desses obj etivos.

Natural
A POO produz software natural. Os programas naturais so mais intel igveis. Em vez de progra
mar em termos de regies de memria, voc pode programar usando a terminolog ia de seu pro-blema em particu lar. Voc no precisa se aprofundar nos detalhes do computador enquanto
projeta seu programa. Em vez de ajustar seus programas para a linguagem do mundo dos computadores, a 00 o libera para que expresse seu programa nos termos de se u problema.
A programao orientada a objetos pennite que voc modele um prob lema em um nvel funci onal e no em nvel de implementao. Voc no precisa saber como um so ftware func iona, para
us-lo: voc simplesmente se concentra no que ele faz.

Confivel
Para criar soft ware ti I, voc precisa criar software que seja to confivel quanto outros produtos, como geladeiras e televi ses. Quando fo i a ltima vez que seu microondas quebrou?
Programas orientados a objetos, bem projetados e cuidadosamente escritos so confiveis. A nat ureza modular dos objetos penn ile que voc faa alteraes em uma parte de seu programa, sem
a fetaroutras partes. Os objetos isolam oconhec imenlo ea responsabilidade de onde pertencem.
Uma maneira de aumentar a confiabilidade atravs de testes completos. A 00 aprimora os testes, permitindo que voc isole conheci mento e responsabilidade em um nico lugar. Tal isolamento pennite que voc teste e val ide cada componente independentemente. Uma vez que tenha
va lidado um componente, voc pode reutiliz-lo com confiana.

Reutilizvel
Um construtor inventa um novo tipo de tijo lo cada vez que constri um a casa? Um engenheiro
eletricista inventa um novo tipo de resistor cada vez que projeta um circuito? Ento, por que os
programadores continuam ' reinventando a roda?' Uma vez que um problema esteja resolvido,
voc deve reutili zar a soluo.
Voc pode reutili zar prontamente classes orientadas a objetos bem feitas. Assim como os mdulos, voc pode reutil izar objetos em muitos programas diferentes. Ao contrrio dos mdu los, a
POO introduz a herana para penni tir que voc estenda objetos ex istentes e o polimorfi smo,
para que voc possa escrever cdigo genrico.
A 00 no garante cdigo genrico. C riar classes bem feitas urna tarefa difici l que exige concentrao e ateno abstrao. Os programadores nem sempre acham isso fcil.

Dia 1

Atravs da POO, voc pode modelar idias gerais e usar essas idias gerais para reso lver problemas especficos. Embora voc v construi r objelos para resolver um problema especfico, freq entemente construi r esses objetos especficos usando partes genricas.

Manutenvel

o ciclo de vida de um programa no tennina quando voc o di stri bui. Em vez disso, voc deve
manter sua base de cdigo. Na verdade, entre 60% e 80% do tempo gasto trabalhando em um
programa para manuteno. O desenvolvi mento representa apenas 20% da eq uao!
Um cdigo orientado a objetos bem projetado manutenvel. Para corrigir um erro, voc simpl esmente corrige o problema em um lugar. Corno uma mudana na implem entao transparente, todos os outros objetos se benefici aro automaticamente do aprimoramento. A ling uagem
natural do cd igo deve permitir que outros desenvolvedores tambm o entendam.

Extensvel
Ass im como voc deve manter um programa, seus usurios exigem o acrscmo de nova fu ncionalidade em seu sistema. Quando voc construir uma biblioteca de objetos, tambm desejar estender a func ional idade de seus prprios objetos.
A POO trata dessas real idades. O soft ware no esttico. Ele deve crescer e mudar com o passar
do tempo, para permanecer til. A POO apresenta ao programador vrios recursos para estender
cd igo. Esses recursos incluem herana, polimorfismo, sobreposio, delegao e uma variedade de padres de projeto.

Oportuno
O ciclo de vida do projeto de software moderno freqentemente medido em semanas. A
POO ajuda nesses rpidos c iclos de desenvolvimento. A POO dim inui o tempo do ciclo de
desenvo lv imento, fornecendo software confivel, reutilizvel e facilmente extensve l.
O software nat ura l simplifica o projeto de sistemas complexos. Embora voc no possa ignorara
projeto cuidadoso, o software natural pode otim izar os ciclos de projeto, po is voc pode se concentrar no problema que est tentando resolvcr.
Quando voc divide um programa em vrios objetos, o desenvolvi mento de cada parte pode
ocorrer em paralelo. Vrios desenvolvedores podem trabalhar nas classes independentemente.
Tal desenvolvimento em para lelo leva a tempos de desenvolvimento menores.

Armadilhas
Quando voc aprende 00 pela primeira vez, existem quatro annadilhas que precisa evitar.

Introduo programao orientada a objetos

17

Armadilha 1: pensar na POO simplesmente como uma


linguagem
Freqentemente, as pessoas equ iparam linguagens orientadas a objetoscom a poo. O erro surge
ao supor que voc est programando de maneira orientada a objetos si mplesmente porque usa
uma linguagem orientada a objetos. Nada poderia estar mais distante da realidade.
A POO muito mais do que simp lesmente usar uma linguagem orientada a objetos ou conhecer
ceno conjunto de definics. Voc pode escrever cdigo horrivelm ente no orientado a obj etos
em uma linguagem orientada a objetos. A verdadeira POO um estado da mente que exige que
voc veja seus proble mas como um grupo de objetos e use encapsu lamento, herana e polimorfismo corretam ente.
Infeli zmente, muitas empresas e programadores supem que, se sim plesmente usa rem Lima linguagem orientada a objetos, se beneficiaro de todas as vantagens que a POO oferece . Quando
fa lham, elas tentam culpar a tecnologia e no o fato de que no trei naram seus funcionrios corretamente, ou que agarraram um conceito de programao popular sem entender realmente o que
ele sign ificava.

Armadilha 2: medo da reutilizao


Voc deve aprender a reutilizar cd igo. Aprender a reutilizar sem culpa freq Uentemerlle uma
das lies mais dificeis de aprender, quando voc escolhe a POO pela primeira vez. Trs problemas levam a essa dificu ldade.
Primeiro, os programadores gostam de criar. Se voc ol har a reutilizao de modo errado, ela parecer afastar algumas das alegrias da criao. Entretanto, voc precisa lembrar que est reutilizando panes para criar algo maior. Pode no parecer interessante reutilizar um componente, mas isso
permitir que voc construa algo ainda melhor.
Segundo, muitos programadores sofrem do sentimento de 'no escrito aq ui'- signi fi cando que
eles no confiam no softw are que no escreveram. Se um software bem testado e atende sua necessidade, voc deve reuli liz-Io. No rejeite um componente porque voc no o escreveu. Lembre-se de que reutilizar um componente o liberar para escrever outro software maravilhoso.

Armadilha 3: pensar na 00 como uma soluo para tudo


Embora a POO oferea muitas vantagens, ela no a soluo para tudo no mundo da programao. Existem ocasies em que voc no deve usar 00. Voc ainda precisa usar bom senso na escolha da fe rramenta correta para o trabalho a ser feito. Mais importante, a POO no garante o
sucesso de seu projeto. Seu projeto no ter sucesso automaticamente, apenas porque voc usa
uma li nguagem 00. O sucesso aparece somente com planejamento, projeto e cod ificao cuidadosos.

Dia 1

Armadilha 4: programao egosta


No seja egosta quando programar. Assim como voc deve aprender a reutil izar, tambm deve
aprender a com partil har o cd igo que cria. Compart ilhar significa que voc encorajar outros desenvo lvedores a usarem suas classes. Entretanto, compartilhar tambm signifi ca que voc tomar fc il para outros reutili zarem essas classes.
Lembre-se dos outros desenvolvedores quando voc programar. Faa interfaces limpas e inteligiveis. Mais importante, escreva a documentao. Documente suposies, parmetros de mtodos, documente o mximo que voc puder. As pessoas no reuti lizaro o que no podem
encontrar o u entender.

A prxima semana
Na prx ima semana, voc continuar s ua introduo a roo, aprendendo a respeito dos trs pi lares que fonnam a base da tcoria da POO: encapSlllamenlo, herana e polimorfismo.
Cada pilar ser dividido em duas lies. A primeira lio apresentar o pi lar e a teoria subjacente. A segunda lio fornecer experincia prtica com os conceitos apresentados no dia anterior.
Essa estratgia espelha a estratgia de preleo/laborat rio, usada com sucesso por muitas universidades e escolas.
Voc com pletar todos esses laboratrios usando a linguagem de programao Java da Sun Mi
crosystem. Voc pode obter gratuitamente todas as ferramen tas usadas neste livro, atravs da
World Wide Web. O Dia 3, assi m como o Apnd ice B, " Resumo do Java", no fi nal do livro, o
cond uziro na obteno e config urao de seu ambiente de desenvolvi mento.

NOTA

Por que Java 7


Existem dois m otivos para se usar Java como fer ramenta de ensino. Primei ro,
o Java o abstrai perfe itamente dos det alh es da m q uin a e do sist em a opera cional. Em vez de ter de se preocupar com alocao e desa locao de memria, voc pode simp lesmente se concentrar no aprendizado dos objetos.
Finalm ente, aprender boas prticas orientadas a o bjetos em Java prtico.
Voc pode pegar o conhecimento e fazer um trabalho. Al gumas li nguagens
silo mais orientadas a objetos do que o Java. Entretanto, f cil faze r o Java
fun cionar.

Resumo
Hoje, voc fez um passeio pela programao orientada a objetos. Voc comeou vendo a evoluo dos principa is paradigmas de programao e aprendeu alguns dos fundamentos da roo.
Agora, voc deve entender as idias conceitua is por trs da 00, como o que uma classe e como
os objetos se comunicam.

Introduo programao orientada a objet os

19

Definies so importantes, mas nunca devemos perder o rumo do que estamos tentando fazer
usando 00, nos atendo ao 'como' do que est ivennos fazendo. As seis vanlagens e objetivos resumem o que a programao orientada a objetos espera cumprir:
1. Natural

2. Confi vel
3. Reuti li zvel

4. Manuten vel
5. Extensvel
6. Oportuna

Voc nunca deve perder esses objetivos de vista.

Perguntas e respostas
P o q ue posso fer para dominar a POO?
R Li vros como este so um a boa maneira de comear em sua jornada para dominar a 00.
importante construir uma base slida; uma que voc possa desenvolver.
Uma vez que tenha uma base, voc precisa comear a praticar 00 ativamente. O verdadeirodomnio s vem com a experincia. Comece como um desenvolvedorem um projeto 00. Conhea profundamente o assunto. Quando voc se tornar mais fam il iarizado
com a 00, comece a se envolver na anlise e no projeto de seus trabalhos.
Tambm aj uda encontrar um mentor. Encontre algum que esteja desejoso de passar al gum tempo com partilhando sabedori a. Instruir-se com os outros a maneira me lhor e
mais rpida de aprender POO.
Finalmente, continue seu estudo pessoa l. Leia livros, artigos, participe de conferncias.
Voc sempre pode absorver mais informaes.

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entend imento. Veja as respostas no Apndice A, "Respostas".

Teste
I. o que programao procedural?
2. Qual vantagem a programao procedural tem cm relao programao no estruturada?
3. O que programao modu lar?

Dia 1

4. Quais vantagens a programao modul ar tem em relao programao procedural?

S. Liste uma deficincia da programao procedural e da programao modular.


6. O que programao orientada a objetos?
7. Quais so as seis vantagens e objetivos da programao orientada a objetos?
8. Ex pliq ue um dos obj etivos da programao orientada a objetos.
9. Defina os seguintes lermos:
Classe
Objeto
Comportamento
10. Como os obj etos se comunicam ent re si?
I I. O que um construtor?
12. O que um acessor?
13. O que um mutante?
14. O que thl S?

Exerccios
Alegre-se! Para hoj e, voc no tem exerccios escritos. Em vez disso, d um passeio.

SEMANA

DIA

Encapsulamento: aprenda a
manter os detalhes consigo
mesmo
Esperamos que o Dia I, " Introd uo programao orientada a objetos", tenha aguado seu interesse e que voc provavelmente tenha mui tas perguntas. Conforme voc pode imag inar, existe
muito mais na programao orientada a objetos do que algumas de fi nies simples. Ao adotar
uma estratgia de 00 para desenvolvimento de software , voc no pode sim plesmente sair programando. Em vez di sso, voc deve ler um planejamento cuidadoso e lima boa base nas importantes teorias ex istentes por trs da POO . Infelizmente, no h uma maneira prti ca de se tornar

um especialista em POO cm poucos anos, imagine em 21 dias! Em vez di sso, voc precisa voltar
e perguntar, "o que estou lentando fa zer?" Voc est tentando se tornar um especia lista terico
ou um profissional prtico? Voc sabe, preciso ser um pouco mai s prtico se quiser aprender
00 suficientemente para faze r seu trabalho. Felizmente, voc no precisa de um doutorado para
entendere apl icar 00 em seus projetas de soft ware eficientemente. O que voc precisa de uma
mente aberta e o desejo de aprender - ou desaprender, em muitos casos.
Hoje e no restante da semana, voc dar uma o lhada prtica nas teorias subjacentes a POO: as
ferra mentas de 00. Essas teorias devem lhe dar uma base suficiente para comear a experimen
tar a POO. Entretanto, o domnio no vir rapidamente. Assim como qualquer outra habilidade,
seus conheci mentos de POO me lhoraro e aumentaro apenas com estudo e prtica.

Dia 2

Hoje voc vai aprender:


Sobre os trs pilares da programao orientada a objetos
Como apl icar encapsulamento efi cazmente
Como programar de forma abstrata
Como os ti(X)s abstratos de dados formam a base do encapsulamento
A diferena entre interface e implementao
Sobre a importncia da responsabi lidade
Como o encapsulamento ati nge os objetivos da 00

Os trs pilares da programao orientada a


objetos
Para edi fi car seu entendimento c domnio de 00, voc deve primeiro ter uma base slida a partir
da qual possa expandi r sua com preenso. Primeiro, voc precisar identi ficar, definir e explorar
os conceitos bsicos da 00. Somente quando voc tiver uma boa base das teorias bsicas de 00
que poder aplic-la corretamente no software que escrever. Tal discusso o leva naturalmente
aos trs conceitos que devem estar presentes para que uma I inguagem seja considerada realmente orientada a objetos. Esses trs conceitos so freqe ntcmente referidos como os Irs pilares da
programao orientada a objetos.
Novo

TERMO

Os Irs pi/ares da programao orienlada a objetos si'lo: eI1CapSIlItl/lIeIllO, herana e


poIiIllOlfi:m/O.

Como a 1>00 baseada neles, os trs pilares so semelhantes a uma torre de bl ocos: remova o
bloco inferior e tudo mais vir abaixo. O encapsulamento, que voc abordar hoje, uma pea extremamente importante do quebra-cabea, pois ele forma a base da herana e do polimorfismo.

Encapsulamento: o primeiro pilar


Em vez de ver um programa como um a nica entidade grande e monolt ica, o encapsul amento
permite que voc o divida em vrias partes menores e independentes. Cada parte possui im plemetllai'lo e realiza seu trabal ho independentemente das outras partes. O encapsul amento mantm essa independncia, ocultando os detalhes internos ou seja, a im plementao de cada parte,
atravs de uma interface externa.
Encapsulamento a caracterstica da 00 de ocultar partes independentes da implementao. O encapsulamento penn ite que voc construa partes ocultas da implementao do soft ware, que at injam uma funcionalidade e ocultam os detalhes de im plementao
do mundo exterior.

Novo

TERMO

Encapsu lamento: aprenda a mante r os det alhes consigo mesmo

NOTA

23

Se voc no estiver famil iarizado com o termo encapsulamento, ta lvez reconhea os termos mdulo, componente ou bean. Voc pode usar esses termos
em vez de 'softwa re encapsulado'.

Uma vez encapsu lado, voc pode ver uma entidade d e software como lima caixa preta. Voc
sabe o que a caixa preta fa z, po is conhece sua interface externa. Conforme a Figura 2.1 ilustra,
voc si mplesmente envia mensagens para a caixa preta. Voc no se preocupa com o que acontece dentro da caixa; voc s6 se preocupa com o fa to d e que isso acontea.

FIGUR A 2 .1

Uma caixa preta.

INTERFACE

Men,egem

Mensage m

INTERFACE

Uma il/lelje/ce lista os servios forn ecidos por um componente . A interface um


contrato com O mundo exterior, que define exatamente o que uma entidade externa
pode fazer com o objeto. Uma interface o painel de controle do objcto.

NovO TERMO

Uma interface importante, pois ela d iz o que voc pode fazer com o componente. O mais interesse o q ue uma interface nAo informa: como o componente far seu trabalho. Em vez disso, a interface oculta a implementao do
mundo exterior. Isso li bera o componente para alteraes na sua implementao a qualquer momento. As mudanas na implementao no mudam o cdigo que usa a classe, desde q ue a interface permanea inalte rada. As alteraes
na interface necessitaro de mudanas no cdigo que exerce essa interface.

Dia 2

Talvez voc esteja familiari zado com o t ermo d e programao APl (Int erfa ce d e
Programa Aplica ti vo). Uma interface semel hante a APl para um objeto. A interface lista t odos os mtodos e argumentos que o objeto entende.

Novo

TERMO

A implementao define como um componente realmente fomece um servio. A im-

plementao defin e os detalhes internos do componente.

Um exemplo de interface e implementao


Consi dere a classe Log a seguir:
pub li c class Log {
public void debug( String message ) {
pri nt ( "DEBUG ". message ) i
}

publiC void info( String message ) {


print( "IN FO ", message }i
}

public void warn ing( Stri ng message ) {


pr i nt( "WARN ING ", message )i
}

public void er ror( Str ing message } I


print{ "ERROR ", message }i
}

pub lic void fatal( Stri ng message ) I


print( "FATAL ", message ) ;
System .exit( O ) i
}

private void print ( String message , Str ing severity ) {


Sys tem.ou t. println{ severity + ": " + message )j
}

A classe Log contm objctos para relatar mensagens de depurao, infonnativas, de aleT1a e de
erro, durante a execuo. A interface da classe Log constituda de todos os compoT1amentos di spon veis para o mundo exterior. Os eomponamentos disponveis para o mundo exterior so conhecidos como interface pblica. A interface pblica da classe l og inclui os seguintes mtodos:

public
public
publ i c
public
public

void
void
void
void
void

debug( St ring message )


i nfo( String message )
warn ing( String message )
er ror ( String message )
fatal ( String message )

Enca p sulamento: aprenda a manter os deta lhes con sigo m esm o

25

Tudo mais na de fin io da classe, alm dessas ci nco declaraes de mtodo, implementao.
Lembre-se de que a implementao define como algo fei to. Aqui, o 'como' o fa to de que log
imprime na tela. Entretanto, a interface oculta completamente o 'como'. Em vez disso, a interface define um contrato com o mundo exterior. Por exemplo, publ'i c vo'id debug ( String message )
uma maneira de dizer ao mundo exterior que, se voc passar uma Stri ng, ela reportar uma
mensagem de depurao.
O que importante notar o que a interface no diz. debug O no diz que impri mi r na tela. Em
vez disso, o que feito com a mensagem deixado para a implementao. A implementao p0deria escrever na tela, descarregar em um arquivo, gravar em um banco de dados ou enviar uma
mensagem para um cliente monitorado pela rede.

Pblico, privado e protegido


Voc pode ter notado que a interface pblica no incl ui
private void print( Stri ng message , String severity ).
Em vez disso, a classe log restringe o acesso a pri nt O .
O que aparece e o que no aparece na interfa ce pblica governado por diversas palavras-chave.
Cada li nguagem 00 define seu prprio conjunto de palavras-chave, mas fundamen talmente essas palavras-chave acabam tendo efeitos semelhantes.
A maioria das linguagens 00 suporta trs nveis de acesso:

Pblico - Garante o acesso a todos os objetos.


Protegido - Garante o acesso instncia, ou seja, para aquele objeto, e para todas as subclasses(mai s informacssobre subclasses no Dia4, "Herana: obtendo algo para nada").
Pri vado - Garante o acesso apenas para a instncia, ou seja, para aquele objeto.
O nve l de acesso que voc escolhe muito im portante para seu projeto. Todo comportamento
que voc queira tornar visvel para o mundo, precisa ter acesso pblico. Tudo que voc quiser
ocultar do mundo exterior precisa ter acesso protegido ou privado.

Por que voc deve encapsular?


Quando usado cuidadosamente, o encapsulamento transforma seus objetos em componentes
plugveis. Para que outro objeto use seu componente, ele s precisa saber como lIsar a interface
pbl ica do componente. Tal independncia tem trs vantagens importantes:

Independncia sign ifica que voc pode reutilizar o objeto em qualquer parte. Quando
voc encapsular corretamente seus objetos, eles no estaro vinculados a nenhum programa em particular. Em vez disso, voc pode us-los sempre que seu uso fize r sentido. Para
usar o objeto em qualquer lugar, voc simplesmente exerce sua interface.
O encapsulamento penn ite que voc tome transparentes as alteraes em seu objeto. Desde que voc no altere sua interface, todas as alteraes pennanecero transparentes para

Dia 2

aq ueles que estiverem usando o objeto. O encapsulamento penn ite que voc atualize seu
componente, fornea uma implementao mais eficiente ou corrija erros - tudo isso sem
ter de tocar nos outros objetos de seu programa. Os usurios de seu objeto se benefi c iaro
automaticamente de todas as alteraes que voc fi zer.

Usar um objeto encapsu lado no causara efeitos colaterais inesperados entre o objeto e o
restante do programa . Como o objeto tem implementao independente, ele no tera nenhuma oll1 ra interao com o restante do programa. alm de sua interface.

Agora, voc est em um ponto onde podemos falar sobre algumas generalidades a respeito do
encaps ulamento. Voc viu que o encapsulamento pennite escrever componentes de so ftware
com implementaes independentes. As trs caractersticas do encapsulamento eficaz so:

Abstrao

Ocultao da implementao

Divi so de responsabilidade

Vam os ver mais profundamente cada caracterstica, para aprender a melhor maneira de obter o
encapsulamento.

Abstrao: aprendendo a pensar e programar


de forma abstrata
,

Embora as linguagens 00 estimulem o encapsulamento, elas no o garantem. E fci l construir


cd igo dependente e frgil. O encapsu lamento efi caz vem apenas com um projeto cuidadoso.
abslrao e experincia. Um dos primeiros passos para o encapsulamento eficaz aprender
como abstrair software e os conceitos s ubjacentes eficientemente.

o que abstrao7
Abstrao o processo de simplificar um probl ema difici!. Quando comea a resolver um problema, voc no se preocupa com cada detalhe. Em vez disso, voc o simplifica, tratando apenas
dos detalhes pertinentes a uma soluo.
,

Imagine que voc tenha de escrever um simu lador de fluxo de trfego. E poss vel que voc modele classes para sinais de trnsito, veculos, cond ies da pista, auto-estradas, ruas de mo dupla, ruas de mo nica, condies climticas etc. Cada um desses elementos afetaria o fluxo do
trfego. Entretanto, voc no modelaria insetos e pssaros no sistema, mesmo que eles possam
aparecer em uma via real. Alm disso, voc omitiria tipos especficos de carros. Voc simplifica
o mundo real e inclui apenas as partes que realmente afetam a sim ulao. Um carro muito importante para a simulao, mas o fato de ser um Cadillac ou fazer com que o carro controle seu
nvel de combustvel suprfl uo para a simulao de trfego.
A abstrao tem duas vantagens. Primeiro, ela permite que voc resolva um problema faci lmente. Mais importante, a abstrao o ajuda a obter reuti lizao. Muitas vezes, os componentes de

Encapsulamento : aprenda a mante r os det alhes consigo m esm o

27

software so demasiadamente especializados. Essa especial izao, combinada com uma interdependncia desnecessria entre os componentes, torna diflci l reutilizar um cdigo existente em
outra parte. Quando possivel, voc deve se esrorar por criar objetos que possam resolver um domnio inteiro de problemas. A abstrao penni te que voc resolva um problema uma vez e depois use essa soluo por todo o domnio desse problema.

NOTA

Embora seja desejvel escrever cdigo abstrat o e evitar uma especializao


dem asiada, duro escrever cdigo abstrato, especial mente quando voc comea a praticar a POO.
Existe um a li nha tnue entre muita e pouca especializao. A linh a pOde ser
discernida apenas com a experincia. Entretanto, voc p recisa saber desse poderoso co nce ito.

Dois exemplos de abstrao


Considere dois exemplos.
Primeiro, imagine pessoas em fil a em um banco, esperando por um caixa. Assim que um caixa se
toma disponvel, a pri mei ra pessoa da fil a avana para a janela aberta. As pessoas sempre deixam a fil a na ordem de que o pri meiro a entrar o pri meiro a sai r (FI FO): essa ordem sempre
mantida.
FIG URA 2 .2

Uma fila em

Banco de 00

11111 IXII/co.

ENTRADA

IL _

Clie nte 1

Ce ixe 1

Cliente 2

C.iu 2

A
_ ~ I
~

Cliente 5

SAlDA

C. ix.3

Dia 2

Segundo, considere um estabelecimento de sanduches do tipofaslfood. Quando um novo sanduche fi ca pronto, ele colocado atrs do lti mo sanduche que est no escaninho; veja a Figura
2.3. Desse modo, o primeiro sanduche ret irado tambm o mais antigo. FIFO o esquema do
restaurante.

FIGURA 2 .3
Sandlliches fic(lndo
P"OIlfO.f.

Embora cada um desses exemplos seja especfico, voc pode encontrar uma descrio
genrica que funcione em cada situao. Em outras palavras, voc pode chegar a uma
abstrao.
Cada domnio um exemplo de fila do tipo primeiro a entrar, pri meiro a sair. No importa quais
tipos de elementos apaream na fil a. O que importa que os elementos entram no fina l da fil a e
saem dela a pan ir da fre nte, confonne ilustrado na Figura 2.4.

FIGURA 2 .4
UII/tI abSfra(((io de

ambos os domnios.

ENTRADA

Abstraindo os domnios, voc pode criar uma fila lima vez e reutiliz- Ia em qualquer problema
que modele um dom ni o onde exista uma ordenao FIFO de elementos.

Abstrao eficaz
Neste ponto, voc pode formular alg umas regras para a ahstrao eficaz:

Trate do caso geral e no do caso especifico.

Ao confrontar vrios problemas diferentes, procure o q ue for comum a todos. Tente ver
um conceito e no um caso especfico.

No se esquea de que voc tem um problema a resolver. A abstrao valiosa, mas no


descuide do problema na esperana de escrever cd igo abstrato.

A abstrao pode no estar prontamente aparente. A abstrao pode no saltar sua frente
na pri meira, segunda ou terceira vez que voc resolver um problema que est s ujeito a ser
abstrado.

Enca psulamento: aprenda a manter os deta lhes consigo mesmo

29

Prepare-se para a fa lha. quase impossve l escrever uma abstrao que funcione em todas as situaes. Voc ver por que, posterionnente ainda hoje.

AL ERTA

NeTA

No caia na paralisia da abstrao. Resolva os problemas que voc encontrar


primeiro. Veja a abstrao com o um bnus e no com o o objetivo final. Caso
contrrio, voc vai se deparar com a possibilidade de prazos fina is perdidos e
abstrao incorreta . Existem ocasies para abstrair e ocasies em que a abstrao no apropriada.
Uma boa regra ger~1 abstrair algo que voc tiver implementado trs vezes de
m aneira anloga. A medida que voc ganhar experincia, aprender a escolher a abstrao mais rapidamente.

Nem sempre voc pode reconhecer oportunidades para uma abstrao. Talvez
voc tenha de resolver um problema vrias vezes, antes que uma abstrao se
torne aparente. s vezes, diferentes situaes ajudam a encontrar uma abstrao efi caz e, mesmo ento, a abstrao pode precisar de alguma converso. A
abstrao pode demorar a amadurecer.

A abstrao pode tomar um componente encapsulado mais reutili zvel, pois ele est personalizado para um domino de problemas e no para um uso especfi co. Entretanto, h ma is coisas importantes quanto ao encapsulamento do que a simples reutilizao de componentes. O
encapsulamento tambm importante porocul tar os detalhes internos. O tipo abstrato de dados
um bom lugar para ver em seguida, na busca do encapsulamento eficaz.

Guardando seus segredos atravs da


ocultao da implementao
A abstrao apenas uma caracterst ica do encapsulamento eficaz. Voc pode escreve r cdigo
abstrato que no encapsu lado. Em vez di sso, voc tambm precisa ocultar as implementaes
internas de seus objetos.
A ocultao da impl ementao tem duas vantagens:

Ela protege seu objelo de seus usurios.

Ela protege os usurios de seu objeto do prprio objeto .

Vamos explorar a primeira vantagem -

proteo do objeto.

Dia 2

Protegendo seu objeto atravs do T AD (Abstract Data


Type - Tipo Abstrato de Dados)

Tipo Abstrato de Dados (TAD) no um conceito novo. Os TADs,junto com a prpria 00,
cresceu a partir da li nguagem de programao Si mula, introduzida em 1966. Na verdade, os
TADs so decididamente no 00; em vez disso, eles so um subconj unto da 00. Entretanto, os
TADs apresentam duas caracterst icas interessantes: ahstrao e tipo. essa idia de tipo que
importante, pois sem ela, voc no pode ter um verdadeiro encapsulamento.

NOTA

o verdadeiro encapsulamento imposto em nivel de lin guagem, atravs de


construes internas da linguagem. Qualquer outra fo rma de encapsulamento
simplesmente um acordo de cavalheiros, que fa cilmente malogrado. Os
programadores o contornaro porque podem fazer isso!

Um TAD um conj unto de dados e um conjunto de operaes sobre esses dados. Os


TAOs pernlitem que voc defina novos tipos na linguagem , ocultando dados internos e o estado, atrs de uma interface bem defin ida. Essa interface apresenta o TAO como uma
unica unidade atmica.

Novo TERMO

Os TA Os so uma maneira excelente de introduzir encapsulamento, pois eles o li beram de considerar o encapsulamento sem a bagagem extra da herana e do polimorfismo: voc pode se concentrar no encapsulamento. Os TAOs tambm pennitem que voc explore a noo de tipo. Uma
vez que o tipo seja entendido, fcil ver que a 00 oferece uma maneira natura l de estendcr uma
linguagem, defin indo tipos personalizados do usurio.

o que um tipo?
Quando programar, voc criar diversas vari veis e atribuir valores para elas. Os ti pos de fi nem
as di ferentes espcies de va lores que esto disponveis para seus programas. Voc usa tipos para
construir se u programa. Exemplos de alguns tipos comuns so inlegers (inteiros), longs (inteiros
longos) e fl oats (rea is). Essas defin ies de ti po informam exatamente quai s espcies de tipos esto disponvei s, o que os ti pos fa zem e o que voc pode fazer com eles.
Usaremos a seguinte definio de tipo:
Os tipos definem as diferen tes espcies de valores que voc pode usar em seus programas. Um tipo define o domn io a panir do qual seus valores vlidos podem ser extrados. Para inteiros posit ivos, so os nmeros sem panes fracionarias e que so maiores ou
iguais a O. Para tipos estruturados, a definio mais complexa. Alm do dom inio, a definio de
tipo inclu i quais operacs so vlidas no tipo e quais so seus resultados.

Novo TERMO

Enca psulamento: aprenda a manter os detalhes consigo mesmo

NOTA

31

a tratamento formal de tipo est fora dos objetivos de um livro sobre paa para
iniciantes.

Os tipos so unidades atmicas da computao. Isso signifi ca que um tipo uma unidade independente. Pegue o inteiro, por exemplo. Quando soma dois inteiros, voc no pensa sobre a adi o de bits individuais; voc pensa apenas a respeito da adio de dois numeroso Mesmo que os
bits representem o inteiro, a linguagem de programao apresenta o inteiro apenas como um nmcro para O programador.
Pegue o exemplo Item do Dia I. A criao da classe Itemadiciona um novo tipo em seu vocabulrio de programao. Em vez de pensar a respeito de uma id , uma descrio e um preo de produto
como entidades separadas, provavelmente regies desconectadas da memria ou variveis, voc
pensa simplesmente em termos de I tem. Assim, os tipos permitem representar estruturas complexas em um nvel mais simp les e mai s conceituai. Eles o protegem dos detalhes desnecessrios. Isso
o libera para trabalhar no nvel do problema, em vez de trabalhar no nvel da implementao.
Embora seja verdade quc um tipo protege o programador dos detalhes subjacentes, os tipos oferecem uma vantagem ainda mais importame. A definio de um tipo protege o tipo do programador. Uma defi nio de tipo garante que qualquer objeto que interaja com o tipo, o faa de maneira
correta, consistente e segura. As restries impostas por um tipo im pedem os objetos de terem uma
interao inconsistente, possivelmente destrutiva. A delarao de um tipo impede que o tipo seja
usado de maneira no projetada e arbitraria. Uma declarao de tipo garante o uso correio.
Sem uma definio clara das operaes pennitidas, um tipo poderia interagir com outro tipo da
maneira que quisesse. FreqUentemente, tal interao indefi nida pode ser destrutiva.
Pense novamente no Item do Dia I. Imagine que tivssemos alterado um pouco a definio de
I tem:
public class Unencapsulatedltem {

II
public double
public double
publ ic int
public String
pub l ic String

unft_pri ce ;
discount ;
!!lITI(I porcentagem de desconto a ser aplicada no preo
quantity;
description;
id;

I
Voc notar que Iodas as variveis internas agora esto publicamenlc di sponvci s. E se algum
escrevesse o programa a segui r, usando o novo Unencapsu l atedItem:
publ i c static void main( String {] args ) {
Unencapsulatedltem moni t or z
new UnencapsulatedItem( e l ectronics~012 .

Dia 2
"17\" SVGA Monitor ",
1

299 .00 ) ;
monitor .discount 1. 25 ;

II invlido, o desconto deve ser menor que 100%!

double pri ce mon itor.getAdj ustedTot al();


System.out. pr i nt ln( "Incorrect Tota l: $" + prlce ) ;
monitor.se tO lsco unt{ 1.25 );

II invl ido
I I entretanto , o configurador capturarli o erro

pr i ce monitor.get Ad justedTotal O;
System . out .println{ "Correct Total:$" + price ) ;
}

A Figura 2.5 mostra o que acontece quando voc executa o mtodo mainO.
2.5
Um 10/(// illwlido.
FIGURA

Abrindo o tipo Unencapsu 1a ted I tempara acesso liberado, outros podem chegar e deixar uma instncia de Une nca psu1ated I t emem um estado invlido. Nesse caso, ma i n () cria um Unencapsu 1atedltem e, em seguida, aplica diretamente um desconto invlido. O resultado um preo
negati vo ajustado!
Os TADs so ferramentas de encapsul amento valiosas, pois eles permitem que voc defina novos tipos da linguagem que so seguros de usar. Assim como novas palavras so acrescentadas
no idioma ingls a cada ano, um TAD permite que voc crie novas palavras de programao,
onde voc precisa expressar lima nova idia.
Uma vez defi nido, voc pode usar um novo tipo como qualquer outro. Assim como voc pode
passar um inteiro para um mtodo, tambm pode passar um TAO para um mtodo. Isso conhecido como sendo um objeto de primeira classe. Voc pode passar objetos de primeira classe
como parmetros.

Enca psulamento: aprenda a manter os deta lhes consigo mesmo

33

Novo

TERMO

Um objelO de primeira c/o.se aquele que pode ser usado cxatamcnte da mesma ma
neira que um tipo interno.

Novo

TERMO

Um objelo de segllnda c/asse um tipo deobjelO que voc pode definir, mas no ne
ccssariarncnte usar, como faria com um tipo interno.

Um exemplo de TAO
Vamos considerar o exemplo da fila abstrata apresentado anteriormente. Ao implementar uma
fila, voc di spe de vrias escolhas de implementao. Voc pode implementar a fila como uma
Iista encadeada, uma li sta duplamente encadeada, um vetor ou uma matriz. Entretanto, a imple
mentao subjacente no muda o comportam ento defin ido da fi la. Independentemente da impIe
mentao, os itens ainda entram e saem de acordo com a ordem FIFO.
A fila uma fo rte candidata para um TAO. Voc j viu que no precisa conhecer a im plementa
o subjacente para usar a fil a. Na verdade, voc no quer ter de se preocupar com a impl emen
tao. Se voc no transformar a fila em Ulll TAO, cada objeto que preci sa de uma fila precisar
rei mplementar a estrutura de dados. Cada objeto que quiser manipular os dados na fi la precisar
entender a implementao e entender como fazer para interagir com ela corretamente. Voc j
viu os perigos do uso no projetado!
Em vez disso, voc deve construi r a fila como um TAO. Um TAD de fi la bem encapsulado ga
rante acesso consistente e seguro aos dados.
Ao sentarse para projetar um TAO, voc precisa perguntarse o que o TAD faz. Neste caso, o
que voc pode fazer com uma fi la? Voc pode:
Colocar elementos na fil a: enqueue
Remover elementos da fi la: dequeue
Consultar o estado da fi la
Ver o elemento da frente sem remov lo: peek
Cada um dos mtodos se transfo rmar em uma entrada na interface pbl ica de Queue.
Voc tambm preci sa nomeara TAO. Neste caso, o nome do TAO Queue. O TAO definido
como segue:
pub li c inte rface Queue {
public vo i d enqueue( Object obj );
pub l i c Object dequeue();
pub l ic boolean i s Empty();
pub l ic Obj ect peek();

I
Note que a interface da fila no diz nada a respeito de como a fila contm seus dados internos.
Note tambm que a interface no fornece acesso li berado a qualquer dos dados internos. Todos
os detalhes fi cam ocultos.

Dia 2

Em vez disso, agora voc tem um novo tipo, uma fila. Agora, voc pode usar esse tipo em qualq uer um de seus programas.
Como se trata de um objeto de primeira classe, voc pode usara fi la como parmetro. Voc pode
tratar a abstrao como uma unidade, pois todas as partes so independentes. Isso poderoso;
pois permite ao programador ser mai s expressivo. Em vez de pensar em termos de ponteiros e
listas, o programador pode pensar em um nvel muito mais alto: em termos do problema a ser resolvido. Quando o programador d iz fila, a palavra inclui todos os detalhes de uma lista e de UIll
ponteiro, mas tambm permite que ele ignore esses deta lhes e pense em uma estrutura de dados
FIFO de a lto nivel.

Conforme voc ver. medida que continua r. um tipo pOderia ser compos to
de outros ti pos. atravs de restries. Embora isso oculte os det athes. t ambm
aumenta sua capacidade de se expre ssar. Os tipos que contm outros tipos podem abranger muitos conceitos.
Po r exemplo, quando voc programa e diz i nt. o significado muito simples;
voc simplesmente declarou um nico inteiro. Entret anto, quando voc diz
Queue, sua declarao muito mais expressiva. H muit o mais ocorrendo dentro de Queue do que dentro de int.

Vamos considerar a interface mais um pouco. Note que essa interface muito genrica. Em vez
de dizer que essa uma fil a de inteiros ou hamburgers, a interface simplesmente coloca e reti ra
objetos da fi la. Em Java, voc pode tratar todos os objetos como Objec t . Entretanto, cada linguagem fornece seu prprio mecanismo semel hante. Declarando os parmetros desse modo, voc
pode colocar qualquer objeto que queira na fila. Assim, essa defi nio torna o tipo Queue ltil em
muitas sit uaes diferentes.

ALERTA

As interfaces genricas tm seus prprios perigos. Uma Queue de inteiros muito


exata. Voc sabe que cada element o em Queue um intei ro. Entret anto, uma
Queue de ob jetos fraca m ente tipada . Quando voc extrai um elemento, pode
no saber qual seu tipo .

Para um encapsu lamento realmente efi caz, existem mai s algumas caractersticas que voc prec isar tratar. Tocamos no aspecto da ocultao da implementao. Mas, e quanto ao outro lado da
moeda - proteger os usurios de seus objetos?

Protegendo outros de seus segredos atravs da ocultao


da implementao
At aqui, voc vi u que uma interface pode ocultar a implementao subjacente de um obj eto.
Quando oculta a implementao atrs de uma interface, voc protege seu objeto de uso no pro-

Enca p sulamento: aprenda a manter os detalhes consigo mesmo

35

jetado ou destrutivo. Proteger seu objeto de uso no projetado uma vantagem da ocultao da
implementao. Entretanto, existe outro lado na histria: os usurios de seus objetos.
A ocullao da implementao leva a um projeto mais flex vel , pois ela impede que os usurios
de seus objetos se tomem fortemen te acoplados implementao subjacente dos objetos. Ento,
no apenas a ocultao da implementao protege seus objelos, como tambm protege aqueles
que usam seus objetos, esti mulando um cd igo fracamente acoptado.
Novo TERMO

o cdigofracamente acoplado independente da implementao de outros compo-

Novo TERMO

o cdigo fortemel1te acoplado fortemente vinculado implementao de outros

nentes.
componentes.

Voc poderia estar se perguntando, "para que serve cd igo fracamente acoplado?"
Quando um recurso aparece na interface pblica de um objeto, todo mundo que usa o recurso se
toma dependente do fato de ele existir. Se o recurso desaparecer repenti namente, voc preci sar
alterar o cdigo quc tiver se desenvolvido de forma dependente a esse comportamento ou atri buto.
Novo TERMO Cdigo dependeme dependente da existncia de detcnninado tipo. O cdigo dependente inevitvel. Entretanto, existem graus para a dependncia aceitvel e para
a superdependncia.
Existem graus para a dependncia. Voc no pode eliminar a dependncia totalmente. Entretanto, voc deve se esforar para min imizar a dependncia entre objetos. Nonnahnente, voc limita
tal dependncia programando uma interface bem defi nida. Os usurios s6 podem se tomar dependentes quanto ao que voc decide colocar na interface. Entretanto, se alguma implementao
do objeto se tornar partc da interface, os usurios do objelo podero se tornar dependentes dessa
implementao. Tal cdigo fortemente acoplado el imina sua li berdade de alterar a implementa~
o de seu objcto. Uma pequena alterao na implementao de seu objcto poderia necessitar de
uma cascata de alteraes por todos os usurios do objeto.

o encapsulamento e a ocultao da implem entao no so m gica. Se voc


precisar alterar uma interface, precisar atualizar o cdigo que dependente
da interface antiga. Ocult ando os deta lhes e escrevendo software para uma interface, voc cria software que fracamente acoplado.

o cd igo fonem ente acoplado anula o objetivo do encapsu lamento: criarobjelos independentes
e reutilizveis.

Dia 2

Um exemplo real de ocultao da implementao


Um exemplo concreto de ocu ltao da implementao esclarecer esta lio. Considere a seguinte defin io de classe:
publlc cl ass Customer {
II ... vrios mtodos de cliente
publlc I tem (} items;
Iles te array contm t odos os itens selecionados
}

Um Customer contm itens selecionados. Aqui, Customer torna o array I tem parte de sua interface externa:
publ1c static void main( String [] args ) {
Customer customer new Customer {) ;

II . . . seleciona alguns itens .. .


II preo dos itens
double total 0.0;
for( lnt 1 O; 1 < customer.items.length; i++) {
Item i tem customer.items[i] ;
total total + item.getAdjus tedTotal();
}
}

Esse mtodo main() pega um cliente, adiciona alguns itens e tota liza o pedido. Tudo funciona,
mas o que acontece se voc qu iser mudar a maneira corno um Customer contm itens? Suponha
que voc qu isesse introd uzi r uma classe Bas ket. Se voc mudar a implementao, precisar atualizar todo o cdigo que acessa diretamente o array Item.
Sem ocultao da implementao, voc perde sua liberdade de melhorar seus objetos. No exemplo
Cus temer, voc deve tomar o array Item privado. Fornea acesso aos itens atravs de acessores.

NeTA

A ocu ltao da implementao tem seus inconven ientes. Existem ocasies em


que voc poderia precisar saber um pouco mais do que a interface pode informar.
No mundo da programao, voc d eseja r uma caixa preta que funcione dentro de det erminada tolerncia o u que use a quantidade certa de preciso. Voc
poderia saber que precisa de inteiros de 64 bits, pois est tratando com nmeros m uito grandes. Ao definir sua interface, importante no apenas fornecer
uma interface, mas tambm documentar esses tipos de detalhes especificas
sobre a implementao. Entretanto, assim como em qualquer o utra parte da
interface pblica, uma vez que voc declara um comportamento, no pode aiterlo.

Encapsu lamento: aprenda a manter os deta lhes consigo mesmo

37

A ocuhao da implementao permite que voc escreva cd igo q ue independente e fracamente acoplado com outros componentes. O cdigo fracamente acoplado menos frg il e mais flexvel para alterar. Um cdigo flexive l facil ita a reuti lizao e o aprimoramento, pois as alteraes
em uma parte do sistema no afetar outras partes no relacionadas.

DI CA

Co mo voc obtm ocultao da implementao eficaz e cd igo fracamente


acoplad07
Aqui esto algumas dicas:
S permita acesso ao seu TAO atravs de uma interface baseada em mtodo. Tal interface garante que voc no exponha informaes sobre a implementao.
o

No fornea acesso involuntrio a estruturas de dados internas, retornan do ponteiros ou referncias acidentalmente. Aps algum obter uma referncia, a pessoa pode fazer tudo com ela.
Nunca fa a suposies sobre os outros tipos que voc usa. A no ser que
um comportamento aparea na interface ou na documentao, no con te
com ele.
Cuidado enquanto escrever dois tipos intimamente relacionados. No
programe acidentalmente em supOSies e dependncias.

Diviso da responsabilidade: preocupando-se


,
.
, .
com seu propno negocIo
A ocultao da implementao evol ui naturalmente para uma discusso sobre a diviso da responsabilidade. Na seo anterior, voc viu como poderia desacoplar cd igo ocultando detalhes
da implementao. A ocu ltao da implementao apenas um passo na direo da escrita de
cd igo fracamente acoplado.
Para ter realmenle cdigo fracamente acoplado, voc tambm deve ter uma di viso da responsabilidade correta. Di viso da responsabilidade correta signifi ca que cada objeto deve executar
uma funo - sua responsabilidade - e execut- la bem. A diviso da responsabilidade correta
tambm sign ifica que o objeto coesivo. Em outras pa lavras, no faz sent ido encapsul ar muitas
funes aleatrias e variveis. Elas precisam ter um forte vincu lo conceituaI entre si. Todas as
funes devem trabalhar no senti do de uma responsabil idade comum.

Dia 2

NOTA

A ocultao da implementao e a responsabilidade andam lado a lado. Sem


ocu ltao da implem entao, a responsabi lidade pode faltar em um objet o.
de responsabilidade do objeto saber como fazer seu trabalho. Se voc deixar a
implementao aberta para o mundo exteri or. um usuri o poder comear a
atuar diretamente na implem entao - dupl icando assim a responsabil idade.
Assim que dois objetos comeam a fazer a mesma tarefa, voc sabe que no
t em uma diviso da responsabilidade correta. Quando voc observar a exist ncia de lgica redundante, precisar refazer seu cdigo. Mas no se sinta
m al; refazer o trabalho um a part e esperada do ciclo de desenvolvimento 00.
A medida que seus projetos amadu recerem, voc encontrar muit as oportunidades para melhor-los.

Vamos considerar um exemplo rea l de div iso da responsabilidades: o relacionamento entre gerente e programador.
Imagine que seu gerente venha at voc, fornea as especificaes de sua parle em um projeto e,
em seguida, o deixe trabalhar. Ele sabe que voc tem um trabalho a faze r e que sabe como razero
melhor trabalho possvel.
Agora, imagine que seu chefe no to esperto. Ele explica o projeto e pelo que voc ser responsvel. Ele lhe garante que est l para facilitar seu trabal ho. Mas, quando voc comea, ele
puxa uma cadeira! Pelo resto do dia, seu chefe fica em cima de voc e fornece instrues passo a
passo, enquanto voc cod ifica.
Embora o exemplo seja um tania extremo, os programadores programam dessa maneira em seu
cd igo, o tempo todo. O encapsu lamento como o gerente efi ciente. Como no mundo real, conhecimento e responsabi lidade precisam ser delegados para aqueles que sabem como fazer o trabalho da melhor ronna possvel. Muitos programadores estruturam seu cdigo como um chefe
autoritrio trata seus funcionrios. Esse exem plo fac ilmente transportado para os termos da
programao. Vamos considerar um exemplo assi m:

public class Badltem {


private double unit _pricei
private double adjusted_pr1ce i
private double discounti
II uma porcentagem de desconto para aplicar no
II preo
private i nt
quantitY i
private String descriptioni
pri vate St ring i d i
publ ic Badltem( St ring id o String descri ption,
int quantity . doub l e pri ce ) {
this . id 1d i
this.descriptlon descriptioni
i l( quantity

>-

O) {

Encapsulamento: aprenda a manter os detalhes consigo mesmo

this.quantity quantity;
}

else {
this.quantity O;
}

this.unit_price

price;

public double getUnitPrice() {


return unit_price;
}

II aplica uma porcentagem de desconto no preo


public void setOiscount( double discount ) (
if( discount <- 1. 00 ) {
this.discou nt : discount ;
}
}

publiC double getOiscount() I


return discount;
}

publiC int getQuantity() (


return quantity;
)

public void setQuantity( int quantity ) {


th i s.quantity - quantity ;
}

publiC String getProductID() I


return id;
}

public String getDescription() {


return description;
}

publ i C double getAdjustedPrice() {


return adjusted_price ;
}

publ iC vo i d setAdjustedPrice( double pr ice) I


adjusted_price price;
}
}

39

Dia 2

BadItem no contm mais a responsabilidade de calcular o preo ajustado. Ento, como voc
gera um preo ajustado? Considere o mtodo mainO a seguir:
public static voi d ma i n( String [] args ) I
II cr i a os itens
BadItem milk = new BadItem( ~dairy-Ol1". "1 Gallon Milk

R
,

2, 2 .50 );

II

apl ica cupons


milk. set Oi scou nt( 0.15 ) ;

II

obtm os preos aju s tados


double milk_price
milk.getQuantity() * milk.getUnitPrice() ;
double milk_discount = milk.getDiscount() * milk_price ;
milk.setAdjustedPrice( milk_price - milk_discount );
System . out.println( "Y our milk costs : \t $" + milk.getAd j us tedPriceO )i

I
Agora, em vez de si mplesmente solici tar a Item seu preo ajustado, voc precisa se comportar
como o gerente ineficiente. Voc preci sa dizer ao objeto item o que fazer, passo a passo.
Ter de chamar varias funes para calcular o total ajustado, retira a res ponsabilidade do item e a
coloca nas mos do usurio. Retirar a responsabil idade dessa maneira to rui m quanto expor
implementaes internas. Voc acaba com responsabil idade duplicada por todo o seu cd igo.
Cada objeto que desejar calcular o total aj ustado precisar repeti r a lgica encontrada no mtodo
ma ioO.
Ao escrever s uas interfaces, voc preci sa certificar-se de que no esteja si mplesmente apresentando a implementao atravs de um conjunto de nomes diferente. Lembre da fila - voc no
quer mtodos chamados addObjec tToLi s tO , updateEndl i stPoi nterO etc. Esses tipos de comportamentos so es pecficos da implementao. Em vez disso. voc ocul ta a implementao,
atravs dos comportamentos enqueueO e dequeueO . de nvel mais alto ( mesmo que, internamente, voc possa atua li zar ponteiros c adicionar o objeto a uma li sta). Em te rmos de BadI tem,
voc no deseja r ter de chamar um mtodo ca 1culateAdjustedPri ce O, antes de poder recuperar o preo aj ustado atravs do mtodo getAdjustedPri ce (). Em vez d isso, getAdjustedPri ce ()
deve saber efetuar o clculo.
Quando voc tem objetos que no dividem corretamente a responsabil idade, acaba com cd igo
procedural , centrado nos dados. O mtodo mai n para calcular o preo aj ustado mui to procedural o Um mtodo maio que instrusse um obj eto Queue em cada passo de seu processo enqueue()
seria procedura l. Se voc simplesmente enviar uma mensagem para um objeto e confia r que ele
faa seu trabalho, esse o verdadeiro desenvolvimento orientado a objetos.
O encapsulamento esta completamente ligado ocultao de detal hes. A responsabilidade coloca o con hecimento de certos detalhes onde eles pertencem . importante que os objetos tenham
apenas uma o u um pequeno numero de responsabilidades. Se um objeto tiver responsabilidades

Encapsu lamento: aprenda a manter os deta lhes con sigo mesmo

41

demais, sua implementao se tomar mui to confusa e dificil de manter e estender. Para alterar
uma responsabil idade, voc correr o risco de alterar outro comportamento inadvertidamente, se
um objeto conti ver muitos comportamentos. Ele tam bm central izar mu ito conhecimento, que
estaria melhor espalhado. Quando um objeto fica grande demais, ele quase se toma um programa completo e cai nas armadi lhas procedurais. Como resultado, voc se depara com todos os
problemas que encontraria em um programa que no usasse nenhum encapsulamento.
Quando voc verifi car que um objeto executa mai s de uma responsabi lidade, precisar mover
essa responsabilidade para seu prprio obj eto.

A LE RTA

A ocultao da implementao apenas um passo para o encapsu lam ento efi ciente. Sem divises de responsabil idade corre tas, voc simplesmente acaba
com uma lista de procedimentos.

Neste ponto, voc pode melhorar a definio de encapsulamento.


NovO

TERMO

Encapsulamel1to efelil'o abstrao mais ocu ltao da implementao mais res-

ponsabilidade.

Retire a abstrao e voc ter um cd igo que no reutilizvel. Retire a ocultao da implementao e voc fi car com um cdigo fortemente acopladoe frgil. Retire a responsabilidade e voc ficar com um cd igo centrado nos dados, procedural, rortemente acoplado e descentralizado.
Sem todas as trs partes, voc no pode ter um encapsulamento efet ivo, mas a falta de responsabilidade o deixa com a pior situao de todas: programao procedural em um ambiente orientado a objetos.

Dicas e armad

do encapsulamento

Ao se aplicar encapsu lamerHo, existem vrias di cas a seguir e armadilhas a ev itar.

Dicas e armadilhas da abstrao


Ao escrever uma classe, voc pode ter problemas, se tentar trabalhar de forma abstrata demais.
impossvel escrever lima classe que satisfaa todos os usurios e cada situao. Imagine que
voc tivesse de escrever um objeto pessoa para um sistema de fo lha de pagamento de uma empresa. Esse objeto pessoa vai ser muito diferente de um objelo pessoa no simulador de nuxo de
trfego que discutimos anteriormente.

Dia 2

A abstrao pode ser perigosa. Mesmo que voc t enha abstraldo algum elem ento, ele poder no funci onar em todos os casos. muito difcil escrever
uma classe que sat isfaa as necessidades de todos os usuri os. No caia na fi xao da abstrao - resolva seus problemas prim eiro l

T udo se resume a faze r o s uficienle para resolver o problema imediato. Inclui r todos os detalhes
necessrios para o objeto pessoa funcionar nos dois contextos seria muito dispendioso. Isso pode
provocar lodos os problemas que voc viu hoje, devido responsabil idade embaralhada. Embora voc possa ligar seu objeto pessoa s duas situaes, ele no ser mais um objeto pessoa abstrato. Voc perde toda a simplificao que a abstrao oferece.

ALERTA

No coloqu e em uma classe mais do que o necessri o para re solver o problema. No tente resolver todos os problemas; re solva o problema imediato. Somente ento voc dever procurar meios de abstrair o que fez .

E claro que ex istem ocasies onde um problema complexo, como um clculo dificil ou uma simulao com plicada. Estamos falando de com plexidade do ponto de vista da responsabi lidade.
Quanto mais responsabilidades um objeto assume, mais complexo ele ser e mais dificil ser
mant-lo.

DIC A

Lembre-se de que ad icionar uma nova classe em seu sist ema o m esmo que
cri ar um novo tip o. Ter essa noo em m ente ajuda a f ocalizar o que voc est
realmente f azendo. Ao fa lar sobre seu problema, voc ver que estar falando
em term os dos objetos e das interaes e no de dados e mtodos.

Finalmente, a verdadeira abstrao s pode vir com o tempo.


A verdadeira abstrao norm almente nasce a part ir de usos reais c no do fato de um programador se sentar e decidi r criar um obj elo reuti lizve l. Como diz o ditado, a necessidade a me da
inveno. Os objetos funcionam da mesma maneira. Normalmente, voc no pode sentar-se e
escrever um objeto abstraIO realmente reutilizvel, logo na primeira vez. Em vez disso, os objetos reutilizveis nonnalmente so derivados de um cd igo amadurecido, que foi posto prova e
que enfrentou muitas alteraes.

A verdadeira abslrao tambm vem com a experincia . E um objelivo a ser buscado no domnio

da POO.

Enca p sulamento: aprenda a manter os deta lhe s con sigo m esm o

43

Dicas e armadilhas do TAO


A transformao de um TAD em uma classe especifica da linguagem. Entretanto, ex istem algumas consideraes independentes da li nguagem que voc pode faze r a respeito das classes.
A maioria das linguagens 00 fomece palavras-chave que o aj udam a defi nir classes encapsuladas. Primeiro, existe a prpria defin io de classe. A classe como o TAD, mas com alguns recursos importantes, que voc vcr nos prximos dias.
Dentro de uma classe, normalmente voc tem mtodos e varivei s internas-os dados. O acesso
a essas variveis e mtodos fomecido por funes de acesso. Tudo na interface do TAD deve
parecer fazer parte da interface pblica do objeto.

Os TADs no so diretament e anlogos classe da 00. El es no tm herana


e recursos de pOlimorfismo. A importncia desses recursos se t ornar evidente quando voc estudar o Dia 4 e o Dia 6, ~ Po l imorfismo : aprendendo a prever
o futuro ~ .

Dicas da ocultao da implementao


o que expor e o que ocultar em sua interface nem sempre fcil de decidir. Entretanto, podemos tecer algumas consideraes independentes da linguagem sobre o acesso. Apenas os mtodos que
voc pretende que outros usem devem estar na interface pblica. Os mtodos que apenas o tipo usar
devem estar ocul tos. No exemplo da fi la, dequeue () e enqueue() devem estar na interface pbl ica.
Entretanto, voc deve ocultar mtodos auxiliares, como updateFrontPointerO e addToLis tO .
Voc sempre deve ocultar as variveis internas, a no ser que elas sejam constantes. Achamos
que elas no devem estar apenas ocultas, mas tambm acessve is apenas para a prpria classe.
Voc vai expl orar esse conceito mais detidamente, no Dia 4. Abrir varivei s internas para acesso
externo expe sua implementao.

NeTA

Voc pode abrir variveis internas para uso extern o apenas se sua linguagem
tratar desses valores com o trata mtodos. O Delphi e o Borland C++ tratam de
variveis i ntern as dessa maneira.
Se usurios externos puderem acessar mtodos e va lores sem saber que esto
mexendo em um valor, ento estar corre to abrilos. Em t al linguagem, uma
varivel interna exposta seria igual a um mtodo que no recebe parmetros.
Infelizment e, no so m u itas linguagens 00 q ue Irata m valores e mt odos da
m esma maneira.

finalmente, no crie interfaces que apresentam apenas a representao interna com um nome di ferente. A interface deve apresentar comportamentos de alto nvel.

Dia 2

Como o encapsulamento atende os objetivos da


programao orientada a objetos

o Dia

I mostrou que o objetivo da programao orientada a objetos prod uzir softwa re:

I. Natural

2. Confive l
3. Reuti lizve l
4. Manutenivel

5. Extensvel
6. Oportuno

o encapsulamento atende cada um desses objetivos:

Natural: o encapsulamento permite que voc divida a responsabil idade da manei ra como
as pessoas pensam naturalmente. Atravs da abstrao, voc fica li vre para modelar o
problema em termos do prprio problema e no em termos de alguma implementao especfica. A abstrao permite que voc pense e programe no geral.
Confivel: isolando a responsabilidade e ocultando a implementao. voc pode validar
cada componente individual. Quando um componente for va lidado, voc poder us- lo
com confiana. Isso possi bili ta testes de unidade completos. Voc ainda precisa realizar
testes de integrao, para cert ifi car-se de que o software constru do funciona corretamente.
Reutil izvel: a abstrao fornece cdigo flexve l e utilizvel em mais de uma situao.
Manutenvel: o cd igo encapsu lado mais fcil de manter. Voc pode fazer qualquer al terao que queira na implementao de uma classe, sem dan ificar cdigo dependente.
Essas alteraes podem incluir mudanas na implementao, assim como a adi o de novos mtodos na interface. Apenas as alteraes que violam a sernmica da interface exigiro mudanas no cdigo dependente.
Extensivel: voc pode mudar implementaes sem danificar cd igo. Como resultado, voc
pode fazer melhorias de desempenho e mudar func ionalidade sem dani fi car o cdigo existente. Alm di sso, como a implementao fica oculta, o cd igo que usar o componente ser:l
atualizado automaticamente, para tirar proveito de todos os novos recursos que voc introduzir. Se voc fi zer tais alteraes, certifique-se de fazer os testes de unidade novamente!
Danificar um objeto pode ter um efeito de domin por todo o cdigo que use o objeto.
Oportuno: divid indo seu sofuvare em partes independentes, voc pode dividi r a tarefa de
criar as partes entre vrios desenvolvedores, acelerando assim o desenvolvi mento.

Uma vez que esses componentes estejam construidos e validados, eles no precisaro ser reconstruidos. Assim, o programador fica livre para reutil izar func ionalidade, sem ter de recri-Ia.

Enca p sulame nto: aprenda a m anter os deta lhes con sigo m esm o

45

Advertncias
Voc pode estar pensando, "mas eu no preciso de 00 para abstrair e encapsular meu cd igo".
Quer saber? Voc est certo - voc no precisa de 00 para ter cdigo encapsulado. Os prprios
TA Ds no so 00. Ebastante possvel ter encapsulamento em praticamente qualquer linguagem .
Entretanto, h um problema. Em outros tipos de li nguagens, voc freqente mente precisa criar
seus prprios mecanismos de encapsulamento. Como no existe nada na linguagem que o obrigue
a respeitar seus padres, voc precisa estar atento. Voc precisa se obrigar a seguir suas diretrizes.
Voc tambm ter de recriar suas diretrizes e seu mecanismo para cada programa que escrever.
Isso est bem para um desenvolvedor. Mas e para dois desenvo lvedores? Dez? Uma empresa inte ira? Quanto mais desenvolvedores so adicionados, mais difici l ter todos na mesma pgina.
Uma verdadeira linguagem 00 fornece um mecanismo para encapsulamento. Ela impe o mecanismo de um modo que voc no consegui ria sozinho. A li nguagem encapsula os detalhes do mecanismo de encapsulamento do usurio. Uma linguagem 00 fornece algumas palavras-chave. O
programador simplesmente usa as palavras-chave e a linguagem cuida de todos os detalhes.
Ao trabalhar com os recursos fornecidos pela linguagem, a linguagem apresenta a todos os programadores o mesmo mecan ismo consistente.

Resumo
Agora que voc entende de encapsulamento, pode comear a programar com objetos. Usando
encapsulamento, voc pode tirar prove ito das vantagens da abstrao, da ocultao da implementao e da responsabilidade em seu cdigo dirio.
Com a abstrao, voc pode escrever objetos que so tei s em vrias situaes. Se voc ocultar
corretamente a implementao de seu objeto, estar livre para faze r quaisquer mel horias que
queira em seu cdigo - a qualquer momento. Finalmente, se voc divid ir corretamente a responsabilidade entre seus objetos, evi tar lgica duplicada e cd igo procedural.
Se voc fec har este li vro agora e nunca mais consult-lo, ter aprendido novas hab il idades de
0 0 sufi cie ntes para escrever componentes independentes . Entretanto, a histria da 00 no termina com o encapsulamento. Cont inue a ler e voc aprender como tirar proveito de todos os recursos oferec idos pela POO.

Perguntas e respostas
P Como \'oc sabe quais mClodos d cvc incluir em um a inlerface?
,

R E si mples saber quais mtodos deve incl uir. Voc precisa incluir apenas os mtodos
que tornam o objeto ti l; os mtodos de que voc precisa para que ou tro objeto faa seu
trabalho.

Dia 2

Quando voc comear a escrever uma interface , desejar prod uzi r a menor interface q ue
ai nda satisfaa suas necessidades. Tome sua interface o mais si mples possvel. No incl ua mtodos que voc ' poderia ' prec isar. Voc pode adicion-los quando rea lmente
precisar de les.
Conhea certos tipos de mtodos de conven incia. Se voc fize r um obj eto conter outros
objetos, normal meme desejar evitar a criao de mtodos que si mplesmeme encaminham uma chamada de mtodo para um dos objetos conti dos.
Por exempl o, digamos que voc tenha um objeto ca rrinho de compras que contenha
itens. Voc no deve adicionar um mtodo de conveninc ia no carrinho, que consultar
um item para sabe r seu preo e retom-lo. Em vez disso, voc deve ter um mtodo que
permi ta obter o item. Quando voc tiver o item, poder solici tar o preo em si.
P Voc mencionou as palavras-chave publ i c, protected e private. Existem outros modificadores de acesso?

R Cada linguagem define seus modificadores de acesso de sua prpria maneira. Entretanto,
a maioria das linguagens 00 define esses trs nveis. A linguagem Java tambm tem um
modificador de acesso do pacote padro. Voc especifica esse nvel omi tindo um modificador. Esse nvel restringe o acesso a apenas as classes do mesmo pacote. I)ara mais informaes sobre pacotes, consulte o Apndice Bt "Resumo do Java".
P Os modificadores de acesso tambm tm o papel de mecanismo de segurana?

R No. Os modificadores de acesso s restringem o modo como OUlros objelos podem interagir com detenninado objeto. Os mod ificadores no tm nada a ver com a segurana do
computador.

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respostas no Apndice A, ' Respostas".

Teste
I. Como o encapsulamento at inge os objetivos da programao orientada a objetos?
2. Defina abstrao e d um exemplo demonstrando abstrao.
3. Defi na implementao.
4. De fin a interface.
5. Descreva a diferena ent re interface e implementao.
6. Por que a diviso clara da responsabil idade importante para o encapsulamento eficaz?

Enca p sulamento: aprenda a manter os deta lhes consigo mesmo

47

7. Defina tipo.
8. Defina TAO (Tipo Abstrato de Dados).
9. Como voc obtm ocultao da implementao efi caz e cdigo fracamente
acoplado?
10. Quais so alguns dos perigos inerentes abstrao?

Exerccios
,

I. Considere a estrutura de dados de pilha clssica. Urna pilha uma estrutura ,. Ult imo a
entrar, pri mei ro a sair" (LI FO). Ao contrrio de urna fi la FI FO, voc s pode ad icionar e
remover elementos a parti r da mesma extremidade de uma pilha . Assim como em um a
fila , urna pilha permite que voc verifique se e la est vazia e esco lha o prime iro elemento
que pode remover.
Defi na um TAO para a classe pilha.
2. Pegue o TAO de pil ha do Exercicio I e esboce uma implementao. Quando terminar,
defina uma segunda implementao.
3. Exam ine os exercicios I e 2. A interface q ue voc projetou no Exerccio I era adequada
para as duas implementaes formuladas no Exercicio 2? Se ass im foi, quai s vantagens a
interface forneceu? Caso contrrio, o que falto u na interface original?

SEMANA

DIA
Encapsulamento: hora de escrever
algum cdigo
Ontem, voc aprendeu tudo sobre encapsulamento. Ao in iciar as lies de hoje, voc dever ter
uma boa idia do que encapsu lamento, como aplic-lo efi cazmente e em qua is erros comuns
,
deve prestar ateno. Neste ponto, o que voc no tem experincia prtica COlU a tcnica. E claro que voc conhece a Icoria, mas nada melhor do que se aprofundar no cd igo. Para o restante
do d ia, voc completar vrios laboratrios que devero cimentar as lies do Dia 2.

Hoje voc aprender:

Como con fi gurar o amb iente Java


Sobre as classes bsicas

Como implementar o encapsulamento

A respeito do pacote de primitivas Java

laboratrio 1: configurando o ambiente Java


Voc usar a linguagem de programao Java para com pletar todos os laboratrios desta se
mana, assi m como o projeto fi nal. Para programar em Java, voc precisa obter uma verso do
Java 2. Para completar estes laboratrios, voc precisa ter pelo menos a verso 1.2 do SDK.

Dia 3

Se voc ainda no tem, ter de fazer download e instalar um kit de desenvolvimento agora. Existem mu itos kits de desenvolvimento diferentes disponveis. Entretanto, voc pode obter facilmente a verso mai s recente, a parti r do endereo http: //www.javasoft. com/ j2se/ .
A Sun s uporta trs platafonnas pri ncipais: Solaris, Linux e Wi ndows. Quando este livro estava

sendo produzido, a verso mais recente da Sun era Java 2 SOK, Standard Edi tion, v 1.3.
A IBM tambm o ferece vrios kits de desenvo lvimento, no endereo
http ://www.i bm.com/java/jdk/index.html.
Alm das plataformas suportadas pela Sun, a IBM tambm fornece suporte a vrias plataformas,
como OS/2, AS/400 e A IX .
Cada kit de desenvo lvimento vem com instrues de instalao adequadas. Siga essas instrues
para instalar o kit em sua mqui na de desenvo lvimento. Voc tambm pode cons ultar o Apnd ice B, " Resumo do Java", para obter mai s ajuda.
Voc tambm pode optar por usar um popular IDE Java , como Forte, JBuilderoll Visual Age for
Java. Estes exem plos e laboratrios tambm funci onaro nesses ambientes.
Este livro pressupe uma fam il iaridade bsica com programao, mas voc no precisa de um
conhecimento profundo de Java para completar estes laboratrios. Se voc precisar de alguma
ajuda para conhe<::er os fundamentos da linguagem Java, consulte o Apndice B.

Exposio do problema
Na verdade, voc precisa do boi antes do carro. Antes de poder programar, voc precisa obter e
configurar um am biente de desenvolvimento Java. Se voc ai nda no fez isso, obtenha um kit de
desenvolvi mento Java e siga os passos de li neados no Apndice B para installo. Uma vez instalado, o apndice o conduzi r na configurao do caminho das classes, ass im como na compilao e execuo de seu primeiro programa Java. Quando voc concluir este labof'cltrio, saber se
s ua in stalao de Java fun ciona. Voc tambm saber tudo q ue precisa para compilar e executar
seus programas Java.

laboratrio 2: classes bsicas


muito importante que voc se recorde das lies dos dias 1 e 2, enquanto escreve s uas primeiras classes.
No Dia I, voc aprendeu alguns fu ndamentos sobre classes e objetos. O Dia 2 mostrou como
voc podc se benefi ciar do encapsulamento para produzir objetos bem definidos.
A biblioteca de classes Java contm um rico conjunto de estruturas de dados clssicas, como listas e tabelas hashi ng. Considere a classe OoubleKey da Listagem 3.1.

Enca psulamento: hora de escrever algum cdigo

LISTAGEM 3 .1

51

OoubleKey.java

public class OoubleKey {


private String keyl , key2:

II

um construtor sem argumentos


public DoubleKeyD (
keyl "key l ";
key2 "key2":

II

um construtor com argumentos


public DoubleKey( String keyl , Str ing key2 ) {
this.keyl keyl:
this.key2 key2;

II

acessor
pub l ic String getKeylO (
return keyl :

II

mutante
public void setKeyl( St r ing keyl ) {
th i s . keyl keyl :

II

acessor
public String getKey2() {
return key2 :

II

mu tante
public void setKey2( St ring key2 ) {
this.key2 = key2:

II

igua l e cdigo hashi ng omitidos por brevidade

I
Quando coloca um objeto em qualquer implementao de java .ut; 1 .Map. voc pode especificar
qualquer objeto como chave para esse objeto. Quando precisa recuperar um objeto, voc simplesmente usa a chave para recuperar o valor. Ooubl eKey permite que voc use hashing em duas
chaves Stri ng, em vez de em uma.

Dia 3

Voc notar que Ooubl eKey tem dois construtores:


public OoubleKey() I
keyl "keyl-j
key2 "key2 M ;
J

public OoubleKey( String keyl . String key2 ) {


this.key l = keyl;
this . key2 key2 i
J

Os construtores aparecem em duas formas: aqueles sem argumentos (construtores lI oargs) e


aq ueles com argumentos.
Novo TERMO Conslr Ufores l10args so construtores que no recebem nenhum argumento.

NOTA

Construtor noarg u m termo Java. O equivalente em C++ construtorpedro.

Os construtores sem argumento instanciam um objeto COm valor padro. enquanto aqueles que
aceitam argumentos usam os argumentos para in icializar o estado interno dos objetos.
pub 1i c Ooub 1eKey () um exemplo de construtor noarg. enquanto pub 1i c Ooub 1eKey ( Stri ng
key l. String key2 ) aceita argumentos.
Confonne o Dia 1 ensinou, mtodos como public St ring getKeyl O e publ ic Stri ng get Key20
so conhecidos como acessorcs, pois eles pcnn item que voc acesse os valores internos do objeto.

O mundo Java reconhece dois tipos de acessores: de con figurao e de obteno. Os de con figurao permitem que voc con fi g ure u ma varivel d e instncia. enquanto os de obteno permitem que voc leia uma varivel de
instncia.
A Sun Microsyst em s desenvolveu uma conveno de atribuio de nomes em
torno de acessores de configurao e de obt eno, conheci da com o JavaBean
Design Patterns. JavaBeans uma maneira padronizada de escrever se us
componentes. Se seus componentes obedecem a esse padro, voc pode conect-Ias em qualquer IDE compatvel com JavaBean. Tal IDE poderia permitir
a construo visual de seus programas, usando os beans.
As convenes de atribuio Java so simples. A conveno JavaBean para
atribuio d e nomes para acessores de obt eno e de configurao :
public void set<VariableNome>( <type> value )
publ1c <type> get<VariableName>()
o nde <type> o tipo da varivel de instncia e <VariableName> o nome da
vari vel de inst ncia.

Enca ps ulamento : ho ra de escrever algum cdigo

53

Tome como exemplo u m objeto Pessoa. Um objeto Pessoa tem um nome. Os


acessores de obteno e de config urao do nome poderiam ter o seguint e
fo rmato:
pub l ic void setName( String name )
publi c String getName()

Finalmente, voc chama mtodos como publ ic void setKey l ( String keyl ) e publ ic void
setKey2( String key2 ) de mutantes, pois eles permitem alterar o estado interno do objeto.
Doub1 eKey demonstra o uso correto do encapsulamento. Empregando uma interface bem definida, DoubleKey oc ulta sua implementao do mundo exterior. Doubl eKey tambm bastante abstrata. Voc pode reutili zar Doub l eKey onde precisar usar hash ing com duas chaves String.
Finalmente, Doub l eKey di vide corretam ente a responsabilidade, fornecendo apenas os mtodos
necessrios para atuar como uma chave.

Exposio do problema
No Di a 2, voc viu um Banco 00. No Banco 00, os clientes entram em uma fi la, enquanto esperam por um caixa. Mas no se preocupe, voc no vai escrever uma classe Queue. A linguagem
Java tem bastante suporte interno para estruturas de dados clssicas. Em vez disso, voc vai programar uma classe de conta - a linguagem Java ainda deixa o programador com alguns trabalhos a fazer.
Seja essa uma conta corrente, uma conta poupana ou uma conta de mercado financeiro, todas
elas tm algumas caracteristicas compartilhadas. Todas as contas tm um saldo. Uma conta tam bm permitir que voc depos ite valores, saque valores e consulte o saldo.
Hoje, voc vai escrever uma classe de conta. O Laboratrio 2 vem completo, com uma classe
Te 11 er. A classe Te 11 er tem um mtodo ma in () que voc usar para testar a impl ementao de
sua conta.
A classe l eller espera uma interface pblica especfica. Aqui esto as regras:

Voc deve chamar a classe conta de Account.


A classe deve ter os dois construtores a seguir:
pub 1i c Account ()
pub1; c Aceount( double in Hial_deposH )
O construtor noargs configurar o sa ldo inicial como 0.00. O segundo construtorconfigurar o saldo inicial como i nitlal_deposit .

A classe deve ter os trs mtodos a seguir. O pri mei ro mtodo credita na conta o va lor de
funds:
publlc vo"id depositFunds( double funds )
O mtodo seguinte debita na conta o valor de funds:

Dia 3

publ ic doub l e withdrawFunds( doub l e fun ds )


Entretanto, wi thdrawFund s () no deve permiti r um saque a descoberto. Em vez disso, se
funds for maior que o saldo, apenas debita o resto do saldo. wi thdrawFunds() deve retornar a real quant idade sacada da conta.

O terceiro mtodo recupera o saldo corrente da conta:


pu bll c double ge tBalan ee ()
Alm dessas regras, voc pode adicionar quaisquer outros mtodos que possa considerar tei s.
Entretanto, certifique-se de implementar cada um dos mtodos exatamente como listado anteriormente. Caso contrrio, o ca ixa no poder fazer seu trabalho!
Uma vez que voc lenha terminado de escrever a classe Aceoun t , ce rtifique-se de compi lar as
classes Account e Te 11er. Uma vez fei to isso, execute o ma i n de Te 11er, d igitando ja '.Ia Te 11 er.
Se voc fe z seu trabalho corretam ente, dever ver a sada ilustrada na Figura 3.1.

FIGURA 3 .1

A M/ida correia
de rel/er.

A prxima seo discuti r as solues do Laboratrio 2. No prossiga at concluir o Laboratri o 21

Solues e discusso
A Li stagem 3.2 apresenta uma possvel implementao de Accoun t.

Enca psulamento: hora de escrever algum cdigo

LISTAGEM 3.2

55

Account .java

public class Account {

II dados privados
private double ba lancei

II const rutor
public Account( double in it_deposit ) {
balance init_depos iti

I
publi C Account() {
II n!o precisa fazer nada.

balance ter O como padro

II deposita dinhe iro na conta


publ ic void deposltFunds( double amount ) {
balance balance + amount ;

II consu l ta o sal do
pub l ic double get8a l ance() I
return balance:

II saca fundos da conta


publi c double withdrawFunds( double amount ) I
if(amount > balance)1
amount balance i

II ajusta o valor

I
balance balance - amount i
return amounti

I
I
A classe Account ilustra os conceitos importantes existentes por trs do encapsulamento.
Account bastante abstrata. Ela funcionar como a base para muitos tipos diferen tes de contas. A

classe Account ocu lta sua implementao atrs de uma interface bem definida. Finalmente, a
classe Account mostra uma divi so correta de responsabilidades, pois contm todo o conhecimento de como debi tar e cred itar no saldo da conta. O conhecimento de como executar essas tarefas no 'vaza' para fora do objeto.

Dia 3

Entretanto, Accounl no perreita; ainda h espao para melhoria. Por questo de brevidade,
essa soluo de cl asse Accounl pula a validao do argumento. alm da verificao de saque a
descoberto si mples. Para usar no mundo real, voc precisaria incluir cdigo para validar todos os
parmetros dos mtodos.

laboratrio 3: o encapsulamento
o Di a 2 abordou trs caractersticas do encapsulamento eficaz:
Abstrao
Ocu ltao da implementao
Diviso da responsabilidade
Cada caracterstica urna habi lidade importante a ser domi nada, enq uanto voc projeta e escreve suas classes. Voc precisa aplicar todas as trs caractersticas pam ter objetos bem encapsulados.
Vamos apli car essas trs caractersticas em um jogo de cartas.
Primeiro, vamos aplicar a abstrao. Lembre-se de no abusar da abstrao. Voc ai nda tem um
problema para resolver e no pode resolver todos os problemas. Assim , voc deve pri meiro tentar resolver os problemas que conhece!
O qu voc pode dizer genericamente a respeito de jogos de carta jogados com um baralho de
pq uer padro?
Um bom lugar para comear no prprio mao de cartas. Um baralho padro contm 52 cartas.
Voc pode embaralhar um mao, assim como escolher uma carta do baral ho, em qualq uer posi o. Do mesmo modo, voc pode retomar uma carta para qualquer posio no mao. Qualquer outra
extrao apenas uma especial izao da escolha de uma carta a partir de qualquer parte do mao.
O que voc pode dizer a respeito das cartas em si?
Todas as cartas compartilham lim a estrutura comum. Cada carta tem um naipe: ouros, copas, espadas ou paus. Cada carta tambm tcm um valor: 2 a 10, va lete, dama, rei ou s. A nica direrena de uma carta para outra o valor desses dois atributos.
Levado a um extremo, voc poderia tentar descrever cada tipo de mao de cartas, sejam elas cartas de beise bol ou de tar. Novamente, quando voc comea a abstrair, precisa cert ificar-se de
no abstrair em dem asia.
E quanto a ocultao da implementao?
A no ser que voc roube enquanto joga baralho, nunca ver o que est no mao, at receber uma
carta. Voc tambm no insere cartas que no fazem parte do baral ho.
Final mente, e quanto responsabilidade?

Enca psulamento : ho ra de escrever algum cdigo

57

No mundo real, as cartas em si no fazem muito. Uma carta simplesmente exibe seu nai pe e seu
valor. Uma cana tem um estado: face para cima ou face para baixo. Do mesmo modo, um baralho no fa z muito no mundo real. Em vez disso, o carteador aque le que embaralha e distribui as
cartas. O bara lho simplesmente contm as cartas de jogo.
No mundo dos computadores, uma cana conter seu naipe, valor e estado. Em um programa
simples, uma cana tambm saber como ser apresentada. Um baral ho criar e conter as cartas.
Finalmente, o caneador saber embaral har as cartas e distribuir uma carta.

NeTA

Posteriormente, voc aprender a importncia de separar a exibio de seu modelo/dados. Entretanto, para nossos objetivos aqui, voc pode misturar os dois.

Exposio do problema
Use as classes de projeto de descrio de carta de pquer para representar as cartas, o mao de
cartas e o caneador. EllIo, voc deve escrever um pequeno mtodo mai n() , que instancie o carteador e seu mao de canas, embaralhe as cartas e, em seguida, imprima o baral ho.
Este laboratrio deixa a voc muita margem de movimento, enquanto projeta suas cartas, o baralho e o carteador. Ao pensar nas classes que voc criar, certi fi que-se de considerar a ocultao
da implementao e a diviso da responsabilidade. Coloque a responsabi lidade apenas onde ela
pertence e, quando voc a colocar, certifique-se de que ela no 'vaze'.

NeTA

Veja java.lang.Math.randomH para a gerao de n meros aleatrios. A fu no


randomO ser til pa ra embaralhar o mao. Voc pOde obter a documentao
completa das APls Java no endereo http ://www.javasoft.com/.
Por exemplo, (i nt) fMath.randomO * 52) fornecer um nmero entre O e 51.

A prxima seo discutir as solues do Laboratrio 3. No prossiga at completar o laboratrio 3!

Solues e discusso
A Listagem 3.3 apresenta uma possivel classe Ca rdo
LISTAGEM 3,3

Card. j ava

public cl ass Card {


private int ranki

Dia 3

LISTAGEM 3.3

Ca rd. java (con t inua o)

private i nt suit;
priva te boolean face_up ;

II constan tes usadas pa ra i nstancia r


II na i pes
publ ic sta tic
publ i c static
publ i c static
public sta ti c
II valores
pu bl ic static
publi c static
publi c static
publi c static
publ ic st atic
publ ic st atic
publ ic stat ic
pub l ic static
pub l ic stat i c
pub l ic static
pub l i c st at i c
publi c stati c
publ ic stati c

final i nt OIAMONOS
final i nt HEART S
fina l i nt SPAOES
fi nal
CLUBS

'o,

fi na l
fi na 1
fi nal
fi nal
fi na1
fina l
fi nal
fina l
fina l
f inal
f inal
f i na1
fi na 1

in t
i nt
in t
i nt
in t

'o,

'THREE
"O
FOUR
FIVE

SI'

4o

3o
6;
5;

2;
3;
4 o

5o

,.

6;
o

SEVEN
i nt EIGHT 8o
i nt NINE 9 ;

,o,

TEN

i nt JACK
i nt QUEEN
KING
i nt ACE

,o,

10 ;
74 o
8 1;
75 ;
65;

II cria uma nova ca rt a - usa apenas as cons tantes para i ni cia l iza r
pu blic Card( i nt suit, int rank ) I
II Em um programa rea l . voc preci sari a fazer a val i dao dos argumentos.
this.suit sui t;
this.rank rank;
}

publi c int getS uit () {


ret urn s uit;
}

publ ic i nt getRank() {
return rank;
}

pub l iC voi d faceUp() {


face_up true;
}

publ i c voi d fa ceOown() I

Enca p sulamento : ho ra de escrever algum cdigo

LISTAGEM 3 .3

59

Ca rd. java (continuao)

pub ll C boolean l sFaceUp() {


return face_up;
}

public String display() {


St ring di spl ay ;
H( ra nk > 10

} I

display Str ing .valueOf( (char) rank } ;


} el se (
di splay String . valueOf( rank );
}

switch ( suit ) (
case OIAMONOS:
return dlsp lay
case HEARTS:
return displ ay
case SPAOES:
retur n display
default:
return display

String.val ueOf( (char) OIAMONOS ) ;

St r ing. val ueOf( (char) HEARTS } ;

St r ing.val ueOf{ (char) SPAOES } ;

Str i ng.va l ueOf( (char) CLUBS };

}
}

A defin io da classe Card comea defini ndo vrias constantes. Essas constantes enumeram os
valores e naipes de carta vli dos.
Voc notar que, uma vez instanciado, no possvel mudar o valor da cm1a. As insI!incias de
Card so imutveis. Tornando a carta imutvel , ningum poder alterar erroneamente o va lor de
uma carta.
Novo

TERMO

Um objelo imlltvel aquele cujo estado no muda, uma vez construido.

A classe Card responsvel por conter seu nai pe, assim corno o valor. A carta tambm sabe
como retornar urna representao de String de si mesma.
A Li stagem 3.4 apresenta uma possvel implementao de Oeck.

LISTAGEM 3.4

Oeck.java

public class Oeck {


private java.util . LinkedList deck :
publiC OeckO {
bulld CardsO;
}

public Card get( int index) {


if( index < deck .size() ) {
return (Card) deck.get( index ) :
}

return null :
}

publ iC void replace( int index. Card card ) {


deck.set( index . card ) ;
}

pub l ic int size() (


return deck.size():
}

public Card removeFromFront() (


if( deck.size() > O ) (
Card card (Card) deck.removeFirst() ;
return card;
}

return null;
}

public void returnToBack( Card card ) {


deck.add( card );
}

private void buildCards() {


deck new java. util.LinkedListO ;
deck.add( new Ca rd( Card .CLUBS . Card .TWO )} :
deck.add( new Card( Card.CLUBS . Card. THREE ) };
deck.add( new Card( Card.CLUBS . Card.FOUR )} ;
deck.add( new Card( Card.CLUBS. Card.F IVE )}:
/1 a definio compl eta foi cortada por brevidade
/1 veja a l istagem compl eta no cdigo -fonte
}
}

Enca p sulamento : ho ra de escrever algum cdigo

61

A classe Deck responsve l por instanciar as cartas e, em seguida, fornecer acesso a elas. A classe Oeck forne ce mlodos para recuperar c rclomar as cartas.
A Li stagem 3.5 apresenta a implementao de Oeal er.
LISTAGEM

3.5

Oea 1er . java

publ i c class Dealer

private Deck deck i


publiC Dea l e r ( Deck d
deck =d i

li

I
public vo i d sh uffle() 1
Il torna o array de cartas aleatrio
int num_ca rds deck.size()i
for( in t i .. O; i < num_c ards; i ++ ) I
int index " (int)( Math.random() * num_cards )i
Card ca rd_i .. ( Card ) deck.get( i ) ;
Card card_ index a ( Card ) deck.get( index )i
deck.rep lace( I. card_index ) i
deck.replace( index , card i )i

I
I
public Card dealCard() I
if( deck.size() > O ) I
return deck. remove FromFront() ;

I
return nu ll;

I
I
A classe Dealer responsvel por embaral har o mao e di stribuir as cartas. Essa imp lementao
de Oeal er honesta. Outra implementao de Deal er poderia dar as cartas a partir do final do baralho!
Todas as trs classes tm uma diviso da responsabilidade clara. A classe Card representa cartas
de pquer, a c lasse Deck contm as cartas e a classe Oea ler distribui as cartas. Todas as trs classes tambm ocultam sua implementao. Nada sugere que a classe Oeck tenha realmente uma
Unked Us t de cartas.

Dia 3

Embora Ca rd possa definir vrias constantes, isso no com promete a integridade de sua implementao, pois a classe Ca rd est livre para usar as constantes como qu iser. Ela tambm est livre para mudar os valores das constantes a qualquer momento.
O mtodo bui l dCards() de Deck destaca uma deficinc ia da ocultao da implementao. Voc
poderia instanciar cartas com nmeros de 2 a 10 em um lao for. Se voc examinar as constantes, ver que 1WOa TEN contam de 2 alO, seq encialmente. Tal lao muito mais simples do que
instanc iar cada carta individualmente.

Entretanto, tal suposio o vincul a aos valores correntes das constantes. Voc no deve penn itir
que seu programa se torne dependente de determinado valor, escond ido na constante. Em vez
disso, voc deve usar a constante cegamente, chamando Cardo TWO , Card. THREE, etc. Voc no
deve faze r quaisquer tipos de suposies sobre o valor. Card poderia redefini r os valores das
constantes a qualquer momento. No caso de bui 1dCards () , fc il cair na tentao de usar os valores das constantes di rctamcnle.
Aqui, o contrato entre Card e o usu rio das constantes de Card so os nomes das constantes e no
seu valor subjacente. O Dia 12, "Padres avanados de projeto", apresentar urna soluo um
pouco mais elegante do que esse uso de constantes.

laboratrio 4: estudo de caso - os pacotes


de primitivas Java (opcional)
o Laboratrio 4 um laboratrio opcional. Embora a concluso do laboratrio

d a voc mais idias sobre a programao orientada a objetos, sua concluso


no necessria para ter xito nos prx imos dias.

Cada linguagem orientada a objetos tem suas prprias regras para detenninar o que e o que no
um objeto. Algumas linguagens orientadas a objetos so mais 'puras' que outras. Uma linguagem puramente orientada a objetos, como a Smallta lk, considera ludo um objeto, at mesmo
operadores e primitivas.
Novo

TERMO

Uma linguagem orientada a objetos pllra suporta a noo de que ludo um objeto.

Em uma linguagem puramente orientada a objelos, tlldo- classes, primitivas, operadores e at


blocos de cdigo - considerado um objeto.
A linguagem Java tem suas prprias regras para determinar o que e o que no um objcto. Na
linguagem Java nem tudo um objeto. Por exemplo, a linguagem Java declara diversos valores
de primiti vas. As primitivas no so consideradas objetos na linguagem Java. Essas pri mitivas
compreendem boolean, cha r, byte, short, i nt, 10ng, float c double.

Enca ps ulamento: hora de escrever algum cdigo

63

Novo TERMO Uma linguagem or ielllada a objelos no considera tudo um objclO.


As primitivas oferecem algumas vantagens em relao os objetos. Para usar uma primitiva, voc
no precisa instanciar uma nova instncia usando new. Como resultado, usar uma primi tiva muito
ma is eficiente do que usar um objeto, pois ela no sofre da sobrecarga associada aos objetos.
Por outro lado, s vezes voc achar o uso de primitivas limitante. Voc no pode tratar pri mitivas como objctos. Isso sign ifi ca que voc no pode us-Ias em lugares que exigem um objelo.
Considere java . uti 1. Vector, da colco de classes genricas. I)ara colocar um valor no vetor,
voc precisa chamar o mtodo add () do vetar:
public boolean add( Object o ) i
Para armazenar um va lor no vetor, o valor deve ser um obj eto. Colocado de maneira simples, se
voc quiser colocar lima pri mitiva em um vetor, estar sem sorte.
Para contornar essas fa lhas, a linguagem Java tem vrios pacotes de primitivas, incluindo Boolean, Characte r, Byte, Ooub l e, Fl oa t, Integer, l ong e Short. Essas classes so chamadas de pacotes, pois elas contm, ou possuem , um valor de pri miti va.
Novo TERMO Um pacole um objeto cujo nico propsito conter outro objcto ou primiti va. Um pacote fornecer qualquer nmero de metodos para obter e manipularo valor possudo.
Vamos considerar a interface pblica de Boolean, que est delineada na Listagem 3.6.
LISTAGEM3.6

java.1ang.Boolean

publ i C final cl ass Boolcan impl ements Se r ial iz able I


publi c Boolean( boolean value ) ;
publ i c Boolean( String s l i
publiC s t atic final Bool ean FAlSE;
public static final Boolean TRU Ei
publi c static final ClASS TYPEi
publiC static boolean getBoolean( St ring name }i
publi c s tati c Boolean valueOf( String s )i
publ iC
public
pub l ic
pub l i c

boolean booleanValue() ;
boolean equals( Object obj li
int hashCode();
Stri ng toSt r i ng( )i

Dia 3

NOTA

Final se ref ere ao conceito de impedir que cla sses descendentes alterem esse
elemento, quando herdadas. A herana ser d iscutida no Dia 4, -Herana: obtendo algo para nadaM.
Impfements est rela cionado constr uo de 'interface' especial da linguagem Java, d iscutida no Apndice B, ' Aesumo d o Java' .

Internamente, o pacote Boo l ean conter uma primitiva booleano Ass im , para passar um valor
boa 1ean para um vetor, voc prec isaria primeiro instanciar um pacote Boo1 ean. possuir a primitiva boo 1ean e passar esse pacote para o vetor.
A interface Boo 1ean introduz outros recursos das linguagens orientadas a objetos: mtodos de classe e va ri veis de classe.
At agora, todos os mtodos e variveis que voc viu eram mtodos de instncia e variveis de instncia. Isto , cada varivel e ca da mtodo est ligado a alguma instncia de
objeto. Para chamar o m todo o u acessar a varivel. voc deve ter uma instncia do objeto.
O fat o de que voc precisa de uma instncia freqentemente lgico. Considere o m
todo booleanvalueO de Boolean. O m todo booleanValueO um mtodo de inst ncia. O
valor que o mtodo retorna depender do est ado interno das instncias de Boo I ean individuais. Uma inst ncia pode possuir o va lor true, out ra pode possuir o valor fal se. O
valor retornado depender do valor que a instncia contm int ernamente.
Agora, considere o mtodo get8001 ean() de Boolean. Esse um mtodo de classe. Se
voc estudar a definio de getBooleanO, notar a palavra-chave static. Na linguagem Java, a palavra-chave statle declara que o m todo ou varivel um mtodo ou
var ivel de classe.
Ao contrrio das variveis e mtodos de instncia, os mtodos e variveis de classe no
esto v inculados a nenhuma instncia. Em vez disso, voc acessa mtodos de classe
atravs da prpria classe. Assim, para cham ar getBoo leanO , voc no precisa de uma
instncia (contudo, voc ainda poderia chamar o mtodo como se ele fo sse um mtodo
de instncia). Em vez disso, voc pode simplesmente chamar Boolean.getBoolean(). A
resposta de getBoolean() no depende do estado de nen huma instncia. Po r isso, ele
pode escapar impun emente, sendo declarado como um mtodo de classe.

Variveis de classe so variveis que pertencem classe e no a uma


instncia especfi ca . As variveis de classe so compartilhadas entre
todas as inst ncias da classe.

Novo TERMO

Mtodos de classe so mtodos que pertencem classe e no a uma


instncia especifica. A operao executada pelo mtodo no dependente do estado de qualquer instncia.

Novo TERMO

As variveis de classe funcionam da mesma maneira. Voc no precisa de uma instncia para acess-Ias. Entretanto, elas tambm t m outro uso. Como a varivel mantida
no nfvel da classe, todas as instncias compartilham a mesma varivel (e, se for pblica,
todos os objetos podero compartilh-Ia). As variveis de classe diminuem os requisit os de memria. Considere publ i e statle final Boolean FAlSE'. Essa uma constante que
possui o valor fa I se. Com o ela esttica, todas as instncias compartilham essa mesma
constante. Cada instncia no precisa de sua prpria cpia. Considere a classe, Counte<!Object, a seguir:

Encapsu lamento : hora de escrever algum cdigo

65

publlC class CountedObject {


private static i nt instances;

,u

Cri a novo CountedObject */


public CountedObj ectO {
i nstances++ :
I
oubl ic s tat ic int oetNumberi ns tancesO I
return instances:
I
oublic static void mainr Strino n aros) I
CountedObiect obi = null:
for{ int i = O: i < 10: i++ I I
obi new CountedObiect():
I
Svstem.ouLorintlnl "Instances created: " +
ob:i .oetNumberInstances II \:
/I note oue isso tambm funcionari
Svstem.ouLorintlnl "Instances created: +
CountedObiect.oetNumberlnstancesO \:
I
I
CountedObject declara uma varivel de classe chamada instances. Ela tambm declara
um mtodo de classe para recuperar o valor, getNumberInstances (). Dentro do constr utor,
o valor incrementado sempre que uma instncia criada. Como todas as instncias
compartilham a varivel, a varivel i nstances atua como u m contador. medida que
cada objeto criado, ela incrementa o contador.

O mtodo ma i n () cria 10 instncias. Voc notar que pOde usar uma instncia para fazer
a chamada de getNumberlnstances{) ou a prpria classe.
Se voc vai ou no declarar um mtodo ou varivel esttica uma deciso de projeto.
Se o mtodo ou varivel for indepen dente do estado de qualquer instncia, provavelmente uma boa idia torn-lo um mtodo ou varivel de classe. Entretanto, voc no
pode declarar variveis e mtodos que so d ependentes da instncia, como estticos,
como o mtodo booleanValueO de Boolean.

Voc pode ter feito algumas observaes a respeito de Boo I ean. Se voc estudar a interface, notar que no h meios de mudar a valor bool ean possudo, uma vez q ue tenha inslanciado a instncia de Boolean! Como voc no pode mudar seu valo r, diz-se que as instncias de Boolean so
imutveis.
Existem ocasies em que usar um objeto imutvel fundamental. Se voc estiver fami liarizado
com linhas de execuo, um objcto imutve l inerentemente seguro quanto a linha de execuo,
pois seu estado nunca pode mudar.

Dia 3

Entretanto, existem ocasies em que os objetos imutveis causam mais danos do que trazem
vantagens. No caso dos pacotes de pri mitivas, a sobrecarga da instanc iao de um pacote para
cada primiti va pode se tornar dispendiosa.

Exposio do problema
Para o Laboratrio 4, voc precisa criar um pacote de primit iva Bool ean mutvel. No mnimo,
esse pacote deve pennitir que voc o btenha e configure o va lor possudo. O pacote tambm
deve fornecer do is construtores: um construtor noargs e um construtor que recebe o va lor inicia l
do pacote.
Sinta-se livre para ad icionar quaisquer outros mtodos que considere conven iente. Entretanto,
no se esquea de seguir as regras do encapsulamento eficaz.
Talvez voc ache interessante examinar a discusso do Apndice B sobre a palavra-chave sta tic. se decidir fornecer todos os mtodos oferecidos pelo pacote de primitivas Bool ean.

ALERTA

A prxima seo discutir as solues do Laboratrio 4. No prossiga at com


pletar o Laboratrio 4!

Solues e discusso
A Li stagem 3.7 apresenta uma possvel soluo para o Laboratrio 4 .
LISTAGEM

3.7

MyBoolean.java

publi c class MyBoo l ean {

II

alguma s cons tantes, por convenincia


publi c static final Class TYPE K Boolean.TYPE;

private boolean va l ue;

II

construtor sem argumento - tem false como padro


publi c MyBooleanO {
val ue fal se ;
}

II

configura o valor in ic ial como value


publi c MyBool ean( boo lean value ) {
t his. val ue vai ue;
}

publ ic boolean booleanVa lueO {

Enca psulamento : ho ra de escrever algum cdigo

LISTAGEM 3 .7

67

MyBoolean.java (continuao)

return value :
}

publiC void setBooleanValue{ boolean va l ue ) I


this . value value:
E

II para getBoolean e valueOf. podemos simplesmente delegar para Boolean


II voc vai aprender mais sobre delegao no Captulo 4
public static boolean getBoolean( St ring name ) I
return Boolean.getBoolean( name );
}

public static MyBoolean valueOf( St ring s ) {


ret urn new MyBoolean( Boolean.ge tBoolean( s ) ) ;
}

II definies de hashCode . equals e toString omit i das por brev i dade


}

MyBoolean mantm a interface pbl ica encontrada em Boolean, com trs excees:

MyBoo1ean adiciona um mutante: pub 1i c voi d setBoo 1eanVa 1ue ( boa 1ean va 1ue ). Esse
mutante permite que voc mude o valor dos pacotes.
MyBool ean redefi ne val ueOf () de modo que retorne uma instnc ia de MyBoolean, em vez
de Boolean.
MyBool ean remove as constantes TRUEe fAlSE. Agora que MyBoolean mutante, esses vaIares no se tornam constantes adequadas, pois seus valores podem ser alterados por qualquer um, a qualquer momento.
A soluo do Laboratrio 4 tambm fornece um vislumbre do Dia 4, "Herana: obtendo algo
para nada". Mtodos como va 1ueOfO demonstram a delegao. A so luo de cd igo-fonte completa do Laboratrio 4 tambm proporciona urn a viso da herana e da sobrecarga, atravs dos
mtodos toString() hashCode() e equals().
I

Perguntas e respostas
P No Laboratrio 3, voc escreveu, "Essa implementao de Deal er honesta. Outra
implementao de Dea1er poderia distribuir as cartas a partir do final do baralho! "
O que voc quer dizer com outra implementao?
R Voc pode dizer que os mtodos shu ffl eC) e dea 1Ca rdO constitucm a intcrface pblica
de Dea ler. A classe Dea 1er apresentada honesta. Ela di stribui as cartas a partir do in cio

Dia 3

do baral ho. Voc poderia escrever outro carteador, chamado OishonestDealer, que tivesse a mesma interface pbl ica. Entretanto, esse carteador poderia distribuir as cartas a
partir do final do baralho.
Voc chama esse carteador de outra implementao, porque ele reimplementa uma interface igual quela encontrada em Oea 1er. Entretanto, essa classe implementa a funciona lidade oculta no mtodo de forma ligeiramente dife rente.

P O encapsulamento pode ser prejudicial?


R Na verdade, o encapsu lamento pode ser prejudicial. Imagine que voc tenha um componente que efetue c lculos matemticos. Suponha que voc prec ise manter determinada
prec iso, quando concluir seu c lculo. Infelizmente, o componente pode encapsu lar
completamente a quantidade de preciso que mantm. Voc poderia acabar com um valor incorrelo, se a implementao usasse uma preciso diferente daquela que precisa.
Voc pode acabar com erros estranhos, se algum alterar o componente.
Ass im, o encapsulamento pode ser prejudicial, se voc prec isar de um controle preciso
sobre as maneiras pelas quais um objeto manipula seus pedidos.
A nica defesa a boa documentao. Voc deve documentar todos OS detalhes e s uposies importantes da im plementao. Uma vez documentados, voc no poder fazer alteraes fa cilmente cm quaisqucr dctalhcs ou suposies documentados. Assim como no
componente matemtico, se voc fizer uma alterao, correr o risco de prejud icar todos
os usurios desse objeto.

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respostas no Apnd ice A, " Respostas".

Teste
I. Examine a c lasse Account do Laboratrio 2. Qual(is) rntodo(s) (so) mutante(s)?
Qual(is) rntodo(s) (so) acessor(es)?

2. Quais so os dois tipos de construtores? A partir das sol ues de laboratrio, encont re
um exemplo de cada ti po de construtor.
3. (Opcional) Boolean, conforme discut"ido no Laboratrio 4, declara trs variveis pblicas. Neste caso, o uso de variveis pbl icas aceitvel. Voc pode explicar por que est
certo usar variveis pbl icas nesse caso?
4. (Opcional) Como voc pode to mar a soluo do Laboratrio 3 ma is e fic iente?

Enca ps ulamento : ho ra de escrever algum cdigo

69

5. Por que voc acha que a soluo do Laboratrio 3 no criou uma classe Card separada
para cada nai pe?
6. No Laboratrio 3, voc explorou a diviso da responsabilidade. Quais vantagens a divi
so da responsabil idade proporciona s classes Ca rd, Deck e Deale r?

Exerccos
I. (Opcional) Pegue o Laboratrio 2 e abstraia Ooub leKey ainda mais. Refaa o projeto de
Doubl eKey de modo que ela possa aceitar qualquer tipo de objeto como chave - no ape
nas urna String.
Para que sua nova classe Ooub 1eKey funcione, voc precisar alterar a definio dos mtodos equal s () e hashCode{). Esses mtodos foram omitidos por brevidade nas solues im
pressas. Entretanto, os mtodos esto disponve is no cdigo fonte completo das solues.
2. (Opcional) No Laboratrio 3, as instncias de Card sabem como se apresentar. Entrctan
to, a classe Oeck no sabe como se apresentar sozinha. Refaa o projeto de Oeck de modo
que as instncias de Oeck saibam como se apresentar.

SEMANA

DIA
Herana: obtendo algo para nada
Nos trs ltimos dias, voc se concentrou em aprender sobre o primeiro pilar da programao
orientada a objelos: encapsulamento. Embora o encapsulamento seja um conceito fundame nta l
na POO, h mais na histria do que apenas suportar TADs e mdulos si mples. Na verdade, a
POO ofereceria muito pouco cm relao ao estilo de programao antigo, se ludo que ela fizesse
fosse oferecer encapsulamento simples. claro que a POO oferece muito mais.
A POO va i alm, adicionando dois outros recursos: herana e polimorfismo. Voc vai passar os
prximos dois dias considerando a herana, o segundo pilar da POO.
Hoje voc vai aprender:

O que herana

Os diferentes tipos de herana

Algumas das arm adi lhas da herana

Dicas para a herana eficaz

Como a herana atende aos objetivos da 00

o que herana?
Ontem, voc viu como o encapsulamento penniteescreverobjetos bem definidos e indepcnden
teso O encapsu lamento permite que um objeto IIse outro obj eto, atravs de mensagens. O liSO
apenas uma das maneiras pelas quais os obj etos podem se relacionar na POO. A POO tambm
fornece uma segunda maneira de relacionamento entre os objetos: herana.

Dia 4

A herana permite que voc baseie a defi nio de uma nova classe em uma classe previamente
ex istente. Quando voc baseia uma classe em outra, a definio da nova classe herda automaticamente todos os atributos, comportamentos e implementaes presentes na classe previamente
existente.
Novo TERMO Herana um mecanismo que penn ite a voc basear uma nova classe na definio
de uma classe previamente existente. Usando herana, sua nova classe herda todos
os atributos e comportamentos presentes na classe previamente existen te. Quando uma classe
herda de outra, todos os mtodos e atributos que aparecem na interface da classe previamente
ex istente apareceri\o automaticamente na interface da nova classe.
Consi dere a classe a segui r:
pub li c class Empl oyee {
private String f1rst_name
private String last_name
priva t e doub le wage
public Employee( String first_name . Stri ng la st_name. double wage ) {
th is .first name f i rst_name
this.las t name last_name
t his.wage wage

I
public double getWage() {
return wage

I
pub lic String getFirstName() I
return fi rst_name

I
publ iC String getLastName() I
return last_name

I
I
Instncias de uma classe como Emp 1oyee podem aparecer em um aplicat ivo de banco de dados
de fo lha de pagamento. Agora, suponha que voc precisasse modelar um func ionrio comissionado. Um funcionrio comiss ionado tem um sa lrio-base, ma is uma pequena comisso
por venda. Alm desse req uisito sim ples, a classe Corrmi ssi onedEmployee exatamente igual
classe Empl oyee. Afinal, um objeto COfllTri ss i onedEmployee um objeto Employee.
Usando-se o encapsulamento di reto, existem duas maneiras de escrever a nova classe COIIIlli ss i onedEmpl oyee. Voc poderia si mplesmente repetir o cdigo encontrado em Emp loyee e ad icionar

Herana: obtendo algo para nada

o cd igo necessrio para controlar comisses e calcular o pagamento. Entretanto, se voc fizer
isso, ter de manter duas bases de cdigo separadas, mas semel hantes. Se voc precisar corrigir
um erro, ter de faz-lo em cada lugar.
Assi m, simplesmente copiar e colar o cd igo no boa uma opo. Voc precisar tentar outra
coisa. Voc poderia ter uma varivel employee dentro da classe Corrrni ss ionedEmpl oyee e delegar todas as mensagens, como getWageO e getfirstNameO, instncia de Employee.
Novo TERMO

Delegaao o processo de um objeto passar uma mensagem p.1ra outro objeto, para

atender algum pedido.

Entretanto, a delegao ainda o obriga a redefinir tooos os mtooos encontrados na interface de


Emp 1oyee para passar tooas as mensagens. Assim, nenhuma dessas duas opes parece satisfatria.
Vamos ver COmO a herana pode corri gir esse problema:
pub li c cla ss CommissionedEmployee extends Employee
private doub le commission;
private int units;

II o custo por unidade


II controle do nmero de unidades vendidas

publiC CommissionedEmployee( String firs t_name. String last_name.


doub le wage. double commission ) (
super( fi rs t_name , last_name , wage ); II chama o construtor original
II para inicializar corretamente
11 0 valor da comisso
this.commission commission ;
}

publ ic double calculatePay() I


return getWage() + ( commission * un i ts ) ;
}

public void addSales( lnt units ) {


thiS.units this.units + units ;
}

public void resetSales() {


units O;
}
}

Aqu i, CommissionedEmp l oyee base ia sua definio na classe Empl oyee j ex istente. Como
Commi ss i onedEmp Ioyee herda de Emp 1oyee. getFi rs tName O, getLas tName O, getWage O.
first_name. l ast_name e wage se tomaro tooos parte de sua defi nio.

Dia 4

Como a interface pblica de Empl oyee se toma parte da interface de Conmi ssionedEmployee, voc
pode enviar para ConmissionedEmpl oyee qualquer mensagem que poderia enviar para Employee.
Considere o mtodo ma inO a seguir, que faz exatamenle isso:
publ i c static yoid ma;n(String [) args ) 1
Commiss1onedEmployee c
new Coomi ss i onedEmp I oyee ("Mr. " Sa1es" 5. 50 . 1. 00) ;
c.addSa l es(5);
System.out.println( KFirst Name: " + c.get FirstNameO ) ;
System.out.println( "last Name : + c.get l astNameO ) ;
System.out.pri ntln( "Base Pay:$ + c. getWageO };
System.out.pri ntln( "Total Pay:$ " + c .calcula t ePayO ) ;
J

A Figura 4. I ilustra o que voc ver aps a execuo desse cd igo.


FIGURA 4 .1

S(l(/a ge/'(/da a punir de


COIIlfIiss ionedflllp I oyee.

Por que herana?


Conforme voc viu no lt im o exemplo, s vezes o relacionamento de liSO do encapsulamento
simples no suficiente. Entretanto, h mais na herana do que si mplesmente herdar urna interface pblica e impl ementao.
Conforme voc ver posteriormente no dia de hoje, a herana permite classe que est herdando
redefi nir qualquer comportamento de que no goste. Tal recurso permite que voc adapte seu
soft ware, quando seus req uisitos mudarem. Se voc precisar faze r uma alterao, bastar escrever uma nova classe, que herde a antiga funcio nalidade. Ento, sobreponha a funcionalidade que
precisa mudar ou adicione a func ional idade que est faltando e pronto. A sobreposio interessante. pois permite mudar a maneira como um objeto funciona sem tocar na defin io origina l da
classe! Voc pode deixar seu cdigo bem testado e validado intacto. A sobreposio funciona
mesmo que voc no tenha o cd igo-fonte original de uma classe.
A herana tem outro uso mui to importante. No Dia I, "Introduo programao orientada a objelos", voc viu como uma classe agrupa objetos relacionados. A herana pemlite que voc agrupe
classes relacionadas. A POO sempre se esfora por produzir software natural. Assi m como no
mundo real, a POO pennite que voc agrupe e classifi que suas classes.

Herana: obtendo algo para nada

"E um" versus "tem um" : aprendendo


quando usar herana
Para apresemar os mecanismos de herana, a primei ra seo abordou o que conhec ido como
herana de implemelltao. Conforme voc viu, a herana de implementao perm ite que suas
classes herdem a implementao de outras classes. Entretanto, somente porque uma classe pode
herdar de Qlura no significa que isso deve ser feito!
Ento, como voc sabe quando deve usar herana? Felizmente, existe uma regra gera l a ser seguida, para evitar uma herana incorreta.
Quando voc est considerando a herana para reut ilizao ou por qualquer outro moti vo, prec isa primeiro perguntar-se se a classe que est herdando do mesmo tipo que a classe que est sendo herdada. O fato de pensar em termos de tipo enquanto se herda freqUentem ente re rerido
como teste ' um ' .
,

Novo

TERMO

E 1111/ descreve o relacionamento em que uma classe considerada do mesmo tipo de


outra.

Para usar ' um ' , voc diz a si mesmo, " um objeto ConmissionedEmployee ' um' Empl oyee".
Essa declarao verdadeira e voc saberia imed iatamente que a herana vlida nessa situao. Agora, pare e considere a interface Ite rator Java :
public interface I terator 1
publ ic boolean hasNext();
pub l ic Object next()j
public void remove()j
J

Digamos que voc qui sesse escrever uma classe que implementasse essa interrace. Se voc lembrar do Dia 2, poder perceber que uma implementao de Queue poderia ser til na const ruo
de sua interrace Iterator. Voc poderia usar toda a implementao de Queue previamente existente, para conter os elementos da interface Ite ra tor. Quando voc precisa verificar hasNext ()
ou remove () , pode simplesmente chamar o mtodo Queue correto e retornar o resultado.
Nesse caso, a herana fornecer um modo rpido de implementar lim a interface Iterator. Entretanto, ames de comear a codificar, no se esquea do teste ' um '.
" Uma interface Itera tor ' uma' Queue". Claramenle essa declarao fa lsa. Esq uea-se de herdar de Queue!

NO TA

Uma Queue pode 'ter uma' interface Iterator que saiba como percorrer os elem entos.

Dia 4

Existi ro muitas situaes onde o teste ' um ' fa lhara, quando voc quiser reuti lizar alguma implememao. Fel izmente, existem outras maneiras de reutil izar implementao. Voc sempre
pode usar composio e delegao (veja o quadro a seguir). O teste 'tem um' salva o dia.
NovO TERMO

Tem U/II descreve o relacionamento em que uma classe contm uma instncia de outra classe.

NovO TERMO

Composi(io significa que urna classe im plementada usando-se variveis intemas


(chamadas de variveis membro), que contm instncias de outras classes.

Composio uma form a de reutiliza o que voc j viu. Se voc no puder herdar,
nada o impede de usa r instncias da outra classe dentro da nova classe. Quando voc
quiser usar os recursos de o utra classe, use simplesmente uma i nstncia dessa classe
como uma de suas partes constituintes. claro que voc sofre as limitaes apresenta
das anteriormente.
Considere novamente o exemplo Queuej lterator. Em vez de herdar de Queue, a interface
Itera tor pode simplesm ente criar uma instncia de Queue e armazen-Ia em uma va rivel de instncia. auando a interface Itera tor precisa recuperar um elemento ou verificar se est vazia, ela pode simplesmente delegar o trabalho para a instncia de Queue,
como demonstrado na Figura 4.2.
FIGURA 4 .2

InstAncia de lteflllQl'

Uma illll!lface Iterator


delegando chamadas de
miooo para Queue.
HasNextU

IsEmptyU

InslAncia
de allelle

Quando usa composio, voc esco lhe cuidadosamente o que vai usar. Atra vs da delegao, voc pode expor alguns ou todos os recursos de seus objetos constituintes. A Figura 4.2 ilustra como a interface I terator direciona o m todo hasNext () para o mtodo
isEmptyO de Queue.

importante indicar que a delegao difere da heran a de duas maneiras importantes:


1.
2.

Com a herana. voc tem apenas uma instncia do objeto. Existe apenas um objet o indivisvel, pois oque herdado se torna uma part e intrinseca da nova classe.
A delegao geralment e fornece ao usurio apenas o que est na interface publ ica. A herana norm al d mais acesso aos detalhes internos da classe herdada. Vamos falar a respei to de t al acesso em d etal hes, no final da lio de hoje.

Herana: obtendo algo para nada

77

Aprendendo a navegar na teia emaranhada


da herana
Os conceitos de ' um ' e composio mudam a natureza da discusso sobre herana da ambiciosa reutil izao da implementao para inter-relacionamentos de classe. Uma cl asse que herda de
outra deve se relacionar com essa classe de alguma maneira, para que os relacionamentos ou hierarquias de herana resultantes faam sent ido.
Uma hierarquia de herana um mapeamento do tipo rvore de relacionamentos
que se ronnam entre classes como resultado da herana. A Figura 4.3 ilustra uma hierarquia real extrada da linguagem Java.

Novo TERMO

FIGURA 4 .3

Fermat

Um exemplo de hierarqllia
de j ovo. text o

tmefemm

MluageF"""' 1

Num"-rf"ormM

Simpleo.tlForrnet

ChoiceForm.1t

Ded.... IForm.t

A herana defin e a nova classe, afilha, em termos de uma classe antiga, a progenitora ou me.

Esse relacionamento filh a-progenitora ou filha-me o relacionamento de herana mais simples. Na verdade, todas as hierarqu ias de herana comeam com uma progenitora e uma fil ha.
Novo

TERMO

Novo TERMO

A classe filha

a classe que est herdando; tambm conhecida como subc lasse.

A classe progenitora ou me a classe da qual a fi lha herda diretamente; ela tambm

conhec ida como superclasse.

A Figura 4.4 ilustra um relacionamento progen itora/filha. NumberFonnat a progenitora das duas
filhas Cho l ceFo nnat e Dec ima lFonna t .

Dia 4

FIGURA 4 .4
Uma progellitor a com

NumlMlrl'ormat

\'{;rias filhas.

ChoiceFonnet

OeclmalFormat

Agora que voc j viu mais algu mas definies, pode refinar a defini o de herana.
Novo TERMO

Herana um mecanismo que pemlite estabelecer relacion amentos ' um ' en tre

classes. Esse relacionamento tambm penn ite que uma subc lasse herde os atributos
e comportamentos de sua superclasse.

NO TA

Quando uma filha herdar de uma progenitora, a filh a obter todos os atributos
e comportamentos que a progenitora possa ter herdado de outra classe.

Confonne voc viu, para que a hierarquia de herana faa sentido, deve ser possivel faze r na filha tudo que possivel fazere m sua progen itora. isso que o teste ' um' rea lmente testa. A uma
mha s6 permit ido aumentar a funciona lidade e adicionar funcionalidades. Uma fi lha nunca
pode remover funcio nalidade.

Se voc verificar que uma filha precisa remover funci onalidade, isso ser uma
indicao de que ela deve aparecer antes da progenitora na hierarquia de herana!

Assim como pais e filh os da vida real, as fi lhas e progen itoras da classe sero semelhantes entre
si. Em vez de compartilhar genes, as classes compartilham in formaes de ti po.

NOTA

Como na vida rea l dos filhos, uma classe pode ter apenas uma progenitora flsica. Tudo depende de como a linguagem im plementa herana.
Algumas l inguagens permitem que uma classe tenha mais de uma progenitora. Isso conhecido como herana mlt ipla.
Algumas linguagens restringem a filha a uma progenitora.
Outras l inguagens, com o Java, permitem apenas um a progen itora por implem entao, m as fornecem um m ecanismo para herdar mltip las interfaces
(m as no a implem entao, apenas as assi naturas de mtodo).

Herana: obtendo algo para nada

Assim como as filhas reais, as classes fil has podem adicionar novos com portamentos e atributos
a si mesmas. Por exemplo, uma fil ha real pode aprender a tocar piano. mesmo que a me nunca
tenha aprendido. Do mesmo modo, uma filha pode redefinir um comportamento herdado. For
exemplo, a me pode ter sido m aluna de matemtica. A filha pode eSlUdar mais e se tornar uma
boa aluna de matemtica. Quando voc quer adicionar novo comportamento em uma classe, pode
fazer isso adicionando um novo mtodo na classe ou redefinindo um comportamento ant igo.

Mecnica da herana
Quando uma classe herda de outra, ela herda im plementao, comportamentos e atributos. Isso
signi fi ca que todos os mtodos e atributos disponveis na interface da progen itora aparecero na
interface da filha. Uma c lasse construda atravs de herana pode ter trs tipos importantes de
mtodos e atributos:

Sobreposto: a nova classe herda o mtodo ou atributo da progenitora, mas fornece uma
nova defini o.

Novo: a nova classe adiciona um mtodo ou atributo completamente novo.

Recursivo: a nova classe simplesmente herda um mtodo ou at ributo da progenitora.

A maioria das linguagens 00 no permite que voc sobreponha um atribu to.


Entretanto, o atributo sobrepost o foi i ncludo aqui para serm os completos.

Primeiro, vamos considerar um exemplo. Em seguida, exploraremos cada tipo de mtodo e atributo.

public class TwoDimcns1onal Po int (


private double x_coord;
private double y_coordi
publiC TwoDimensiona l Po i nt( double x,double y ) (
se tXCoo rdinate( x );
se tYCoordinate( y ) i
}

public double getX Coordi nate() {


retu rn x_coord;
}

public void setXCoordinate ( double x ) {


x coo rd = Xi
}

Dia 4

pub l ic double getYCoordinate() I


relurn y_coord ;
}

public void setYCoo rd ina te( double y ) 1


y_coord y;
}

public String toString() (


return "I am a 2 dimensional poinl.\n " +
~My x coo rdinate is: " + getXCoordinateO + "\ n" +
"My y coo rdinate is: " + getYCoordinateO:
}
}

pub li C cla ss ThreeDimensionalPoint extends TwoDimensionalPoint (


priva te double z_coord :
public ThreeOimensionalPoint( double x. doubl e y. double z ) (
super( x.y) ;
II inicializa os atributos herdados
II chamando o construtor progenitor
setZCoordinate( z ) ;
}

publiC double getZCoord inale() {


return z_coord:
}

public void setZCoordinate( double z ) {


z-coord z'

publiC Stri ng toString() I


return "I am a 3 dimens i onal
"My x coordinate is:
"My Y coordinate is:
"My z coordinate is:

point. \ n" +
.. + gelXCoordinate() + U\n" +
.. + getYCoordinate() + "\n" +
.. + getZCoordinate();

Aqui, voc tem duas classes ponto que representam pontos geomtricos. Voc poderia usar pontos em uma ferram enta de traado de grficos, em um modelador visual ou em um planejador de
vo. Os pontos tm muitos usos prticos.
Aqui, TwoOimens ionalPoint contm coordenadas x e y. A classe define mtodos para obter e
configuraras pontos, assi m como para criar uma representao de String da instnc ia do ponto.

Herana: obtendo algo para nada

ThreeDimensionalPoinl herda de TwoDimensionalPoint. ThreeDimensiona lPoi nl acrescenta a


coordenada z, assim corno um mtodo para recuperar a valor e para con fi gurar o valor. A classe
tambm fornece um mtodo para obter uma representao de String da instncia. Como Thr eeDimensional Poinl herda de TwoDimensiona l Poi nt, ela tambm tem os mtodos contidos dentro
de TwoDimensionalPoint.
Esse exemplo demonstra eada tipo de mtodo.

Mtodos e atributos sobrepostos


A herana perrnite que voc pegue um mtodo ou atributo previamente existente e o rede fina. A
redefinio de um mtodo permite que voc mude o comportamento do objeto para esse mtodo.
Um mtodo ou atributo sobreposto aparecer na progenitora e na filha. Por exemplo, ThreeDimensionalPoint redefine o mtodo toStringO que aparece em TwoDlmenslonalPoint:

II de TwoDimensionalPoint
pub l ic String toString() {
return "I am a 2 dimensional poinl. \n" +
"My x coordinate is: + getxCoordinateO + "\n" +
"My Y coordinate is: + getYCoordinateO:
}

TwoOimens iona I Point define um mtodo toSt r i ng() que identifi ca a instncia como um ponto
bidimensional e impri me suas duas coordenadas.
Th reeOimensionalPoint redefi ne o mtodo toSt ringO para identi fi car a instncia como um
ponto tridimens ional e imprime suas trs coordenadas:

II de ThreeOimensional Point
public String toString() {
return "I am a 3 dimensional
"My x coordinate is:
"My Y coordinate is:
"My z coordinate is:

point.\n" +
" + getXCoordinate() + "\n" +
" + getYCoordinate() + "\n" +
" + getZCoordinate();

Considere o mtodo mainO a seguir:


publ ic s tati c void main( String [] args ) {
TwoDimensionalPoinl two : new TwoDi mensionaIPoint(1.2);
ThreeDimens ionalPo int three = new ThreeO imensionalPo i nt(1.2.3);
Syslem.out. pr int ln (two.toString( :
Syslem.out. pr int ln(three . toStri ng( ;
}

A Figura 4.5 ilustra o que voc ver aps executar o mtodo mai nO.

Dia 4

FIGURA 4 .5

TestaI/do o lIItodo
toString() sobreposto.

Conforme voc pode ver na Figura 4.5, ThreeDimensionalPoint retorna sua representao de
String sobreposta.
Sobrepor um mtodo tambm conhecido como redefinir um mtodo. Redefinindo um mtodo, a filha
fomece sua prpria implementao personalizada do mtodo. Essa nova implementao fomeccr um
comportamento novo para o mtooo. Aqui, ThreeDimensionalPoint redefine o comportamento do
mtooo toStri ngO, para que ele seja correlamente transfonnado em um objeto String.
Novo

TERMO

Sobrepor O processo de uma filh a pegar um mtodo que aparece na progenitora e

reescrevlo para mudar o comportamento do mtodo. A sobreposio de um mto


do tambm conhecida como redefinio de um mtodo.

Ento, como o objelo sabe qual definio deve usar?


A resposta depende do sistema 00 subjacente. A maioria dos sistemas 00 procurar primei ro a
defini o no objeto para o qual passada a mensagem . Se uma defi nio no for encontrada l. o
ambiente em tempo de execuo percorrer a hierarquia, at que uma defi nio seja encontrada.
importante perceber que assim que uma mensagem manipulada e que por isso que a sobreposio fu nciona. A definio da filha ser a prim eira a ser chamada, poi s a primeira encontrada. O mecanismo igual para mtodos e atributos recursivos, que veremos posteriormente.
A Figura 4.6 ilustra a propagao de mtodo entre os objetos ponto para LIma chamada de get XCoordi nate (). Uma chamada de mtodo para getXCoord i na te () percorrer a hierarq ui a at encontrar LIma defi ni o para o mtodo.

FIGURA 4 .6

Pl'op(/ga(10 de
mellsagem emre

(Irl"

d'

-,1

os objeto.f pomo.
D

;/ ~

. . .J;:;

L ___

L I

Herana: obtendo algo para nada

83

Ao considerarmos a sobreposio de um mtodo ou atribulo, importante perceber que nem todos os mtodos e atributos esto disponveis para sua filha sobrepor. A maioria das linguagens
orientadas a objelos tem alguma noo de controle de acesso. As palavras-chave controle de
acesso defi nem exatamente quem pode ver e acessar mtodos e atributos. Genericamente, esses
nveis de acesso caem em trs categorias, conforme discutido brevemente no Dia 2:

Privado: um nvel de acesso que restringe o acesso apenas classe.


Protegido: um nvel de acesso que restringe o acesso classe e s filhas.

Publico: lIm nvel de acesso que permite o acesso a todos e a qualquer um.

Os mtodos e atributos protegidos so aqueles aos quais voc deseja que apenas as subclasses tenham acesso. No deixe tais mtodos pblicos. Apenas aq ueles com amplo conhecimento da
classe devem usar mtodos e atributos protegidos .
Voc deve tornar privados todos os atributos no-constantes e qualquer mtodo destinado unicamente prpria classe. O nvel privado impede que qualquer outro objeto chame o mtodo, exceto quanto ao prprio objeto. No torne protegidos os mtodos privados, apenas para o caso de
alguma subclasse querer acess-los algum dia. Use o nvel protegido apenas para os mtodos
que voc sabe que uma subclasse deseja usar. Caso contrrio, use o nvel privado ou pblico. Tal
prtica rgida significar que talvez voc tenha de voltar ao seu cd igo posteriormente e mudar o
nvel de acesso de um mtodo. Entretanto, isso leva a um proj eto mais conciso do que um que
abra tudo para uma subclasse.

NOTA

Vollar e mudar niveis de acesso pode parecer uma prtica ruim. Entretanto, as
hierarqui as de herana nunca devem acontecer por acidente. Em vez disso, as
hierarquias devem ser desenvolvidas naturalmente, enquanlO voc programa.
No h vergonha em refazer suas hierarquias com o passar do tempo. A POO
real um processo iterativo.
Contudo, lembre-se de que torna r tudo privado uma regra geral . Existem casos em que esse consel ho no fun cionar a seu fav or . Tudo depende do que
voc estiver programando. Por exemplo, se voc vender bibliotecas de classe
genricas sem fornecer o cd igo-fonte, provavelmente dever ter o n vel protegido como padro, para que seus clientes possam usa r herana para estender suas classes.
Na verdade, existem ocasies em que voc d esejar projetar um a subclasse
com a herana em mente. Em tal caso, fa z sentido estabelecer um protocolo de
herana. Um protocolo de herana uma estrutura abstrata, vislvel apenas
atravs dos element os protegidos da classe. A classe progenitora chamar esses mtodos e a classe filha poder sobrepor esses mtodos para aumenlar o
comportamento. Voc vai ver um exemplo assim, amanh.

Usando essas definies e regras, fcil ver que os mtodos e atributos protegidos e publicos
so os mai s importantes para a herana.

Dia 4

Novos mtodos e atributos


Um novo mtodo ou atributo um mtodo ou atributo que aparece na fil ha, mas no aparece na
progen itora. A filha acrescenta o novo mtodo ou atributo em sua interface. Voc viu novos mtodos no exem plo ThreeDimens ional Poi nt . ThreeDimensiona I Poi nt acrescenta os novos mtados getlCoordinate() e setZCoordinateO. Voc pode adicionar nova funcionalidade na
interface de sua fi lha, adicionando novos mtodos e at ributos.

Mtodos e atributos recursivos


Um mtodo ou atri buto recursivo definido na progenitora ou em alguma outra ancestral, mas
no na fi lha. Quando voc acessa o mtodo ou atributo, a mensagem enviada para cima na hierarqu ia, at que uma definio do mtodo seja encontrada. O mecan ismo igual quele apresentado na seo sobre mtodos e atributos sobrepostos.
Voc viu mlodos recursivos no cdigo-fonte de TwoDi mens i ona I Poi nt e ThreeDi mens i ona 1Poi nt. getXCoord1 na te () um exemplo de mtodo recursivo, pois ele definido por TwoDimens ional Point e no por ThreeDimensiona 1 Poi nt.
Os mtodos sobrepostos tambm podem se comportar de forma recursiva. Embora um mtodo
sobreposto aparea na filha, a maioria das linguagens orientadas a objetos fornece um mecanismo que permite a um mtodo sobreposto chamar a verso da progenitora (ou de algum outro ancestral) do mtodo. Essa capacidade permite que voc enfat ize a verso da superclasse, enq uanto
define novo comportamento na subclasse. Na linguagem Java, a palavra-chave super d acesso
implementao de uma progeni tora. Voc ter a chance de usar super nos laboratrios do Dia 5,
" Herana: hora de escrever algum cd igo".

NOTA

Nem todas as tinguagens fornecem a palavra-chave super. Para essas linguagens, voc precisar tomar o cuidado d e inicia lizar corretamente qualquer cdigo herdado.
No referen ciar co rretamente as classes herdadas pode ser uma fonte sutil de
erros.

Tipos de herana
Ao todo, existem trs maneiras principais de usar herana:
I. Para reutilizao de implementao

2. Para diferena
3. Para substituio de tipo

Herana: obtendo algo para nada

Esteja avisado de que alguns tipos de reutilizao so mais desejveis que outros ! Vamos explorar cada uso em detalhes.

Herana para implementao


Voc j viu que a herana possibil ita que lima nova classe reuti lize implementao de outra c lasse. Em vez dc recortar e colar cdigo ou instanciar e usar um componente atravs de composio, a herana torna o cdigo automaticamente disponvel, como parte da nova classe. Como
mgica, sua nova classe nasce com funcionalidade.
A hierarquia Emp 1oyee e a mal gui ada Queue/ Itera tar demonstram a reutil izao de implementao. Nos dois casos, a filha reut ili zou vrios comportamentos encont rados na progen itora.

DI CA

Lembre-se de que, quando programa com herana de implementao, voc


est preso imp lementao que herda. Escolha as classes que herdar com
cuidado. Voc precisar ponderar as vantagens da reutilizao em relao a todos os faiaS negativos de reutilizar algumas implementaes.
Entretanto, uma classe corretamente definida para heran a far bastante uso
de mtodos protegidos refinados. Uma classe que herda pode sobrepo r esses
m todos protegidos para alterar a implementao. A sobreposio pode diminuir o impact o da herana de uma implementao mal feita o u inadequada.

Problemas da herana da implementao


At aqui, a herana de im plementao parece excelente. Cu idado, contudo - o que parece lima
tcnica til na superficie se mostra uma prtica perigosa no uso. Na verdade, a herana de implementao ti fonna mais de fici ente dc herana e nonnalmenle voc deve evit-Ia. A reutilizao
pode ser fcil , mas, conforme voc ver, ela tem um alto preo.
Para entender as fal has, voc precisa cons iderar os tipos. Quando uma classe herda de oulra, e la
assume automaticamente o tipo da classe herdada. A herana de tipo correto sempre deve ter
precedncia, ao se projetar hierarquias de c lasse. Voc ver os motivos posteriormente, por enquanto, assuma isso como verdade.
D uma o lhada no exemp lo Queue / lterator novamente. Quando Iterator herda de Queue,
ela se torna um a Queue . Isso significa que voc pode tratar Iterator com o se fosse do tipo
Queue. Como Iterator tambm uma Queue, ela tem toda a fu ncionalidade que estava presente na Queue. Isso significa que os mtodos como enqueueO e dequeue() tambm fazem
parte da interface pblica de Iterator.
Superficia lmente, isso no parece ser um problema, mas d uma o lhada melhor na definio de
Iterator. Uma interface Iterator simplesmente defi ne dois mtodos, um para recuperar um
elemento e outro para testar se restam quaisquer elementos no I terador. Por defin io, voc no
pode adicionar itens em um Iterador; entretanto, Queue define o mtodo enqueue() justamente

Dia 4

para um caso assim. Em vez disso, voc s pode remover elementos. Voc no pode pegar um
elemento e, ao mesmo tempo, deix-lo dentro da interface I terator. Novamente, Queue define o
mtodo peek () ,j ustamente para esse caso. Esimples ver que usar Queue como uma base herdada
para I terator no uma boa escol ha; isso fornece comportamentos que si mplesmente no pertencem a uma interface Iterator.

NOTA

Algumas linguagens permitem que uma classe simplesmente herde implementao, sem herda r as informaes de tipo. Se sua linguagem permite tal
herana, ento o exemplo Queue/I terator no muito problemtico. Entretanto, a maioria das linguagens no permite a separao de interface e implement ao, durante a herana. Das linguagens que fazem a separao, algumas
fazem isso automaticamente. Outras ainda, como C++, permitem a separa o,
mas exigem que o programador a solicite explicitamente. Tal linguagem exige
que o programador projete e solicite a separao explicitamente, enquanto codifica a classe. Obviamente, pode ser muito fcil igno rar o fato de qu e voc
precisar separa r a implementao e o t ipo, se no tomar cuidado.

Este livro usa uma definio de herana simples. A discusso sobre herana
pressupe que ela inclui implementao e interface, quando uma classe herda
de outra.

Uma herana pobre o monstro de Frankenstein da programao. Quando voc usa herana un icamente para reutil izao de implementao, sem quaisq uer outras consideraes, freqUen temente pode acabar com um monstro construido a partir de partes que no se encaixam.

Herana para diferena


Voc viu a herana para diferena no exemplo de TwoOimens i onal Point e ThreeOimensional Po int. Voc tambm a viu no exemp lo Employee .
A programao peta diferena permi te que voc programe especificando apenas como uma clas-

se filha difere de sua classe progenitora.


Novo

TERMO

Programa(:t;o por diferena significa herdar uma classe e adicionar apenas o cdigo

que tome a nova classe diferente da classe herdada.

No caso de Th reeOimens i ona 1Po int, voc v que ela difere de sua classe progen itora pe lo acrscimo de uma coordenada Z. Para suportar a coordenada Z, ThreeOimens i onal Poi nt adiciona dois
novos mtodos para configurar e recuperar o atributo. Voc tam bm v que ThreeOimens f ona1Point redefine o mtodo toStringO.
A programao por di ferena um conceito poderoso. Ela permite que voc adicione apenas o
cd igo necessrio o suficiente para descrever a diferena entre a classe progenitora c a classe fi lha. Isso permite que voc programe atravs de incrementos.

Herana: obtendo algo para nada

Um cd igo menor e mais fcil de gerenciar toma seus projetos mais simples. E como voc programa menos li nhas de cdigo, teoricamente deve introduzir menos erros. Assi m, quando programa pela diferena, voc escreve cdigo mais correto em um espao de tempo mais curto.
Assi m como a herana de implementao, voc pode fa zer essas al teraes incrementais sem al terar o cdigo existente.
Atravs da herana, ex istem duas maneiras de programar pela diferena: adicionando novos
comportamentos e atributos. e redefini ndo comportamentos c atributos antigos. Cada caso conhecido como especializao. Vamos ver deta lhadamente a especial izao.

Especializao
Especializao O processo de uma classe filha ser projetada em tennos de como ela
diferent e de sua progenitora. Quando tudo estiver dito e feito, a definio de classe
da filha incluir apenas os elementos que a tomam diferente de sua progenitora.

Novo

TERMO

Uma classe fil ha se especializa em relao sua progenitora, adicionando novos atributos e mtodos em sua interface, assim como redefinindo atributos e mtodos previamente existentes. A
adio de novos mtodos ou a redefinio de mtodosj existentes permite que a filha ex presse
comportamentos que so diferentes de sua progenitora.
No se confunda com o tenno especiali zao. A especializao permite apenas que voc adicione ou redefina os comportamentos e atributos que a fil ha herda de sua progeni tora. A especializao, ao contrrio do que o nome possa sugerir, no permite que voc remova da fi lha
comportamentos e atributos herdados. Uma classe no obtm herana se letiva.
O que a especial izao faz rest ri ngir o que pode e o que no pode ser um ponto tridimensional.
Um ThreeOimensiona 1Point sempre pode ser um TwoDimensiona l Point. Entretanto, incorreto
dizer que um TwoDimensi onal Poi nt sem pre pode ser um ThreeDimensional Point.

Em vez di sso, um ThreeD imensiona 1Poi nt uma especializao de um TwoDimensional Poi nt e


um TwoOimens ionalPoint uma genera li zao de um ThreeDimensionalPoint.
A Figura 4.7 ilustra a di ferena entre general izao e especial izao. Quando voc percorre uma
hierarquia para baixo,
voc se especial iza. Quando voc percorre uma hierarquia para cima,
,
voc
generaliza. A medida que voc generaliza, mais classes podem cair sob esse agrupamento.
,
A medida que voc espec iali za, menos classes podem satisfazer todos os critrios para serem
classi ficada s nesse nvel.

Dia 4

FIGURA 4 .7

Quando percorre /filia


hierarquia para cima.
\'oc gellerali: a. Qllalldo

perco,.re lima hierarqllia


para boi.to. !"oc
especia!i:a.

Como voc v. especializao no significa uma restrio de fun ciona lidade, ela significa restrio da categori zao de tipo. A especializao no precisa acabar com ThreeOi mens; ona 1Poi nt.
Na verdade, ela no precisa necessariamente nem mesmo comear com TwoOi mens i ona 1Poi nt. A
herana vai ter a profundidade que voc quiser. Voc pode lIsar herana para formar estruturas
de hierarq uia de classe comp lexas. A noo de hierarquia introd uzida anteriormente leva a mais
dois termos novos: Gnceslral e descendente.

Apenas porque voc pode ter hierarquias complicadas no significa que deve
t-Ias. Voc deve se esforar po r ter hierarquias pouco profundas e no hierarquias demasiadamente profundas. medida que uma hierarquia se aprofun da, ela se torna mais difcil de manter.

NOTA

Novo

TERMO

Dada alguma filh a, uma ances/ral uma classe que aparece na h ierarqu ia de classes
antes da progenitora. Conforme a Figura 4.8 il ustra, Format uma ancestral de Oeci-

mal Format .

Novo TERMO Dada lima classe, toda classe que aparece depois dela na hierarquia de classes uma
descendellle da c lasse dada. Conforme a Figura 4.8 ilustra, Oec imal Format uma

descendente de Fermat.

FIGURA 4 .8

Formal

OecimolFormat
desceI/deli/e de
Formot.
NumberFo rmat

-'ChoiceFormlll

OecimalFormlll

Herana: obtendo algo para nada

89

Digamos que tivssemos a hierarqu ia de herana de classes mostrada na Figura 4.9. Dizemos
que OneDl mensional Point a progenitora de TwoDimensional Point e ancestral de ThreeDimen s i onalPoint e de FourOimensionalPoint. Tambm podemos dizer que TwoDimensionalPoint,
ThreeDi mens i ona 1Poi nt c FourOi mens i ona 1Pai nt so todas descendentes de OneOimens i ona 1Pa int. Todos os descendentes com pan il ham os mtodos e atributos de seus ancestrais.
FIGURA 4 .9

hierarqllia
de pallfo.

II

I "".~~~M I..~___~
1
I.
TwoOI......w .....PoI'"

TII ...Di......1.... IPo!m

1'41

1 F......oimI_.. I~

Podemos fa zer mais algumas declaraes interessantes sobre a hierarq uia de classes. OneDimen sianalPo int a raiz e FaurOi mensionalPaint uma folha.
Novo TERMO A c/euse raiz (tambm referida comum ente como classe base) a classe superior da hierarquia de herana. A Figura 4.9 mostra que OneOimens i ona 1Poi nt uma classe raiz.
NovO TERMO Uma c/(I.u efolha um a classe sem filhas. Na Figura 4.8, Decimal Format uma classe fol ha.
imponantc notar que as descendentes refl etiro as alteraes feitas nas ancestrais. Digamos
que voc encontre um erro em TwoOimens i ona 1Po int. Se voc corrigir TwoOimensional Point, todas as classes de ThreeOimens i ona 1Poi nt at FourOi mens i ona 1Poi nt tiraro provei to da alterao. Assim, se voc corrigi r um erro ou tomar lima implementao mais efi ciente, todas as
classes descendentes da hierarquia tiraro proveito disso.

Herana multipla
Em todos os exemplos voc viu herana simples. Alg umas implementaes de herana
permitem que um objeto herde direta mente de mais de uma classe. Tal implementao
de herana conhecida como herana mltipla. A hera na mltipla um aspecto controverso da POO. Atguns dizem que ela s torna o software mais diflcil de entender, projetar e manter. Outros tm grande confia na nela e dizem que uma linguagem no est
completa sem ela.
De qualquer modo, a herana mltipla pode ser valiosa, se usada cuidadosa e corretamente. Existem vrios problemas introduzidos pela herana mlti pla. Entretanto, uma
discusso completa do que a herana mltipla pode e no pode fazer est fora dos objetivos deste dia.

Dia 4

Herana para substituio de tipo

o tipo fina l de herana a herana para substituio de tipo. A substituio de tipo penni te que
voc descreva re lacionamentos com capacidade de subst ituio. O que um relacionamento
com capacidade de substituio?
Considere a classe li ne:

publi c class l i ne (
private TwoOimens i ona lPoi nt pI :
private TwoOimensionalPoint p2:
publiC Li ne( TwoDimensionalPoi nt pI, TwoDimensionalPoint p2 ) (
thi s.p l pI:
th is.p2 p2:
)

publ ic TwoDimensionalPo in t getEndpo i nt l() {


return pI:
}

publi c TwoDi mensionalPoint getEndpo i nt2() {


return p2:
}

publ ic double getDistanceO I


doub l e x
Math.pow( (p2.ge tXCoordinate( ) pl.getXCoordinate ( , 2 );
doub l e y
Math.pow( (p2.getYCoordinate() - pl . getYCoordinate(, 2 ) ;
doub l e di st ance Math. sqrt( x + y ) ;
return di stance :
}

public TwoDi mensional Po i nt getMidpoint () I


double new_x (p l . ge t XCoordinate() + p2 .getXCoordinate() ) / 2;
double new_y (p l .ge t YCoord in ate() + p2 .getYCoordinate() ) / 2:
ret urn new TwoOimensionalPoi nt ( new_x . new_y ) :
}
}

Li ne recebe dois objetos TwoDimensiona l Poi nt como argumentos e fornece alguns mtodos para
recuperar os valores, um mtodo para calcular a distncia entre os pontos e um mtodo para calcular o ponto mdio.
Um relacionamento com capacidade de substi tuio significa que voc pode passar para o construtor de l ine qualquer objelo que herde de TwoDimensional Point.

Herana: obtendo algo para nada

91

Lembre-se de que, quando uma filha herda de sua progen itora, voc diz que a filha ' uma' progenitora. Assim, como um objclo ThreeO imens iona 1Poi nt ' um ' objeto TwoDimensional Poi nt,
voc pode passar um objeto ThreeDimensiona 1Poi nt para o construtor.
Considere o mtodo mainO a seguir:
publi c s ta tic void main( Str ing [] args } I
ThreeDimensionalPoint pi = new ThreeDimensionalPoint( 12, 12, 2 };
TwoDimensiona l Point p2 z new TwoDimensionalPoint( 16 , 16 );
Line 1

new Line( pi, p2 );

TwoOimens i ona lPoint mi d = 1. ge tM idpoint() ;


System.out.println( "Midpoint: (" +
mid.getXCoordinate() +
" " +

mid.getYCoordinate() +

"l" );
System.out.println(

"Distance:" + l.getOistanceO );

I
Voc notar que o mtodo principal passa um objeto TwoDi mens ional Poi nt e um objeto Th reeDimens iona 1Poi nt para o construtor de Li ne. A Figura 4.1 OiI ustra o que voc ver, se executar o
mtodo mainO .
FIGURA 4 .10

Tes/(mdo re/aciollamelllos
com capacidade de
.mbslillli{i o.

NOTA

Tente imaginar as possibilidades que os relacionament os co m capacidade de


substituio oferecem a voc. No exemplo da linha, eles poderiam possibilitar
uma ma neira rpida de trocar de um modo de visualizao em 3D para um
m odo de visualizao em 20 em u ma GU!.

Capacidade de conexilo um conceito poderoso. Como voc pode enviar a uma filha qualquer
mensagem que pode ser enviada para sua progenitora, passiveI trat-Ia como se ela pudesse ser

Dia 4

substituda pela progenitora. Esse o motivo pelo qual voc no deve remol/er comportamentos
ao criar uma fil ha. Se voc fizer isso, a capacidade de conexo ser invalidada.
Usando a capacidade de conexo, voc pode adicionar novos subtipos em seu programa, a qual
quer momento. Se seu programa fo r feito para usar uma ancestral, ele saber como usar os novos
objetos. O programa no precisar se preocupar com o tipoexato do objeto. Desde que tenha um
relacionamento com capacidade de substituio com o ti po que espera que possa usar.

ALERTA

Novo

TERMO

Saiba que os relacioname ntos com capacidade de substituio s6 podem ir at


um n(vet acima na hierarquia de herana. Se voc programar seu objeto para
aceitar determinado tipo de objeto, no poder passar para ele a progenitora
do objeto esperado. Entretanto, voc pode passar para ele qualquer descendente.
Pegue como exemplo o construtor de Une:
public Line( TwoDimensionalPoint pl,TwoDimensionalPoint p2 )
Voc pode passar para o construtor um objeto TwoDemenslonalPoint ou qualquer
descen dente de TwoDimens i ona 1Po i nt . Entretanto, voc no pode passa r para o
construtor um objeto OneDimensionalPoint, pois essa classe aparece antes de
TwoDimensionalPoint na hierarquia .

Um slIbtipo um tipo que estende outro tipo atravs de herana.

A capacidade de substituio aumenta sua oportunidade de reutil izao. Digamos que voc tenha escrito um pacote para conter objetos TwoDirnens i ona 1Poi nt. Devido a capacidade de conexo, voc tambm pode usar o pacote para qualquer descendente de TwoOirnens ional Poi nt.
A capacidade de subst ituio importante, pois ela pennite que voc escreva cdigo genrico.
Em vez de ter vrias instrues case ou testes if/else para ver que ti po de ponto O programa eSlava usando, voc si mplesmente programa seus objetos para tratar com objetos do tipo TwoOimen
si ona 1Poi nt.

Dicas para a herana eficaz


A herana vem com seu prprio conjunto de problemas de projeto. Embora seja poderosa, na
verdade a herana fornece a corda para voc se enforcar, quando usada incorretamente. As dicas
a seguir o ajudaro a usar a herana eficazmente:
Em geral, use herana para reutilizao de interface e para defin ir relacionamentos de
substituio. Voc tambm pode usar herana para estender uma implementao, mas 50-mente se a classe resultante passar no teste ' um ' .
Em geral, prefira a composio em vez da herana para reut ili zao de implementao
simples. Use herana apenas se voc puder apl icar o teste ' um ' na hierarqu ia resultante.
No use herana para reutilizao de implementao ambiciosa.
Scmpre use a regra ' um '.

Herana: obtendo algo para nada

As hierarquias de herana corretas no acontecem sozinhas. Freqlientemente, voc descobrir


hierarquias medida que prosseguir. Quando isso acontecer, refaa seu cd igo. Em o utras ocasies, voc precisar projetar deliberadamente suas hierarquias. De qualquer modo, existem alguns princpios de projeto a seguir:

Como regra gera l, manten ha suas hierarquias de classe relativamente rasas.

Projete cuidadosamente a hierarq uia de heranas e remova as caractersticas comuns das


classes base abstratas. As classes base abstraIas pennilem que voc defina um mtodo
sem fornecer uma implementao. Como a classe base no especi fica uma implementao, voc no pode instanci-Ia. Entretanto, o mecanismo abstraio obri ga uma classe que
esteja herdando a fornecer uma implementao. As classes abstratas so valiosas para herana planejada. Elas ajudam o desenvolvedor a ver o que elas precisam implementar.

Ne TA

Se sua linguagem no fornece um mecan ism o abstrato. cri e mtodos vazios e


documente o fat o de que subclasses devem implementar completamente esses mtodos.

As classes freqUentemente compartilham cdigo COmum. No h sentido em ter vrias


cpias de cdigo. Voc deve remover o cdigo comum e isol-lo em uma (mica classe
progenitora. Entretanto, no o coloque muito acima . Coloque-o apenas no primeiro nvel
ac ima de onde ele necessrio.

Simplesmente no possvel planejar sempre suas hierarquias com pletamente. As caractersticas com uns no aparecero at que voc escreva o mesmo cdigo algumas vezes.
Quando voc ver caracterst icas com uns, no tenha medo de refazer suas classes. Esse
trabalho freqlentemente referido como refazer.

O encapsulamento to importante entre progenitora e filha quanto entre classes no relacionadas. No relaxe quanto ao encapsulamento, quando voc estiver herdando. A prti ca de usar uma
interface bem definida to vl ida entre progenitora e fi lha quanto entre classes completamente
no relacionadas. Aqui esto algumas dicas que o aj udaro a ev itar a quebra do encapsulamento,
quando voc herdar:

Use interfaces bem defin idas entre a progen itora e a fi lha, exatamente corno as usaria entre classes.

Se voc adicionar mtodos especificamente para uso por subclasses, certifique-se de torn-los protegidos, para que apenas a subclasse possa v-los. Os mtodos protegidos permitem que voc oferea s suas subclasses um pouco mai s de controle, sem abrir esse
controle para toda classe.

Em geral , evite abrir a implementao interna de seu objeto para s ubclasses. Uma subclasse pode se tomar dependente da implementao, se voc fi zer isso. Tal acoplamento
tem todos os problemas delineados no Dia 2.

Aqui esto alguns segredos fi nais para a herana eficaz:

Dia 4

Nunca se esquea de que a substituio o objet ivo nmero um. Mesmo que um objeto
deva ' intuit ivamente' aparecer em uma hierarquia, isso no quer dizer que ele deve aparecer. Apenas porque possvel ou porque sua intuio clama, no sign ifica que voc deve
fa zer isso.

Programe pela di ferena para manter o cdigo fcil de gerenciar.

Sempre prefira a composio herana para reutilizao de implementao. Geralmente


mais fcil alterar as classes envolvidas na com posio.

Resumo
Existem do is tipos de relacionamentos fornecidos pela POO : um relacionamento de /(so entre
objetos e um relacionamento de herana entre classes. Cada relacionamento fornece urna forma
de reutili zao. Entretanto, cada um vem com s uas prprias vantagens e problemas.
A simples instanc iao e uso freqUentemente limitam a nexibilidade de uma classe. Atravs da
reutili zao simples, no h meios de reutil izar ou estender uma classe. Em vez disso, voc fica
com uma instanciao simpl es o u recorte e colagem. A herana supera essas defi cincias, fornecendo um mecan ismo interno para a reutil izao segura e eficiente do cdigo.
A reuti lizao de implementao proporciona a voc um modo rpido e grosseiro de usar cd igo
previamente existente em s uas novas classes. Ao contrrio da operao de recorte e colagem
simples. existe apenas uma cpia do cd igo para manter. Entretanto, simplesmente herdar para
reuti lizar imprevidente e lim ita seus projetos.
A implementao para diferena permite que voc programe suas novas classes em termos de
como el as d ife rem da classe original. Voc s programa os atributos que diferenciam a filha da
progenitora .
Finalmente, a herana para substituio penni te que voc programe genericamente. Com a substituio, voc pode trocar de s ubclasses para a progen itora a qualquer momento, sem dani fica r
seu cdigo. Isso permite que seu programa seja flexve l para futuros requisitos.

Como a herana atende aos objetivos da 00


A herana preenche cada um dos objelivos da POO. Ela ajuda a prod uz ir so ftware que :
i. Natura l

2. Confive l

3. Reutili zvel

4. Manutenve l
5. Extensvel

6. Oportuno

Herana: obtendo algo para nada

Ela atinge esses objetivos, como segue:


o

Natural: a herana permite que voc modele o mundo mais naturalrnente. Atravs da herana, voc pode fonnar hierarquias de relacionamento complexas entre suas classes. Como
seres humanos, nossa tendncia natural querer categorizar e agrupar os objetos que esto
em tomo de ns. A herana pennite que voc traga essas tendncias para a programao.
A herana tambm abrange o desejo do programador de evitar trabalho repetitivo. No
faz sentido fazer trabalho redundante.

Confivel: a herana resulta em cdigo confivel.


A herana si mplifi ca seu cdigo. Quando programa pela diferena, voc adiciona apenas
o cdigo que descreve a diferena entre a progen itora ea filha. Como resultado, cada classe pode ter cdigo menor. Cada classe pode ser altamente especializada no que faz. Menos cdigo significa menos erros.
A herana permite que voc reuti li ze cdigo bem testado e comprovado, como a base de
suas novas classes. A reutilizao de cd igo com provado sempre mais desejvel do que
escrever novo cdigo.
finalmente, o mecanismo de herana em si confivel. O mecani smo incorporado linguagem, de modo que voc no precisa construir seu prprio mecanismo de herana e
cert ifica r-se de que todo mundo segue suas regras.
Entretanto, a herana n1l0 perfeita. Ao usar subclasses, voc deve estar vigi lante com relao introduo de erros sutis destruindo inadvertidamente dependncias no expostas.
Prossiga com cuidado, quando herdar.

Reutilizvel: a herana auxilia a reuti lizao. A prpria natureza da herana permite que
voc use classes antigas na construo de novas classes.
A herana tambm perrn ite que voc reuti lize classes de maneiras nunca imaginadas pela
pessoa que escreveu a classe. Sobrepondo e programando pela diferena, voc pode alterar
o comportamento de classes existentes e us-las de novas maneiras.

Manuten vel: a herana auxil ia a manutenibil idade. A reuti !izao de cd igo testado significa que voc ter menos erros em seu novo cdigo. E quando voc encontrar um erro
em uma classe, todas as subclasses tiraro proveito da correo.
Em vez de se aprofundar no cdigo e adicionar recursos diretamente, a herana permite
que voc pegue cdigo previamente existente e o trate como a base da construo de uma
nova classe. Todos os mtodos, atributos e infornlacs de tipo se tomam parte de sua
nova classe. Ao contrrio do recorte e colagem, ex iste apenas uma cpia do cdigo original para manter. Isso ajuda na manuteno, diminuindo a quantidade de cd igo que voc
precisa manter.
Se voc fosse faze r alteraes diretamente no cdigo existente, poderia danificar a classe
base e afetar partes do sistema que usem essa classe.

196

Dia.

Extensve l: a herana torna a extenso ou especializao de classe possvel. Voc pode


pegar uma classe antiga e adic ionar nova funcionalidade a qualquer momento. A programao pela diferena e a herana para capacidade de conexo estim ulam a extenso de

classes.

Oportuno: a herana o aj uda a escrever cdigo oportuno. Voc j vi u como a reutilizao


simples pode di mi nuir o tempo de desenvolvimento. Programar pela diferena signi fi ca
que existe menos cd igo para escrever; portanto, voc deve terminar mais rapidamente.

Capacidade de substituio sign ifica que voc pode adicionar novos recursos, sem ter de
alterar muito o cd igo j existente.
A herana tambm pode tornar os testes ma is fceis, pois voc s precisa testar a nova

funcionalidade e qua lquer interao com a funci onalidade antiga.

Perguntas e respostas
P Hoje, foram listados trs motivos separados para usar herana. Esses motivos precisam ser mutuamente exclusivos ou posso combin-los? Por exemplo, quando eu
herdo pela diferena, parece que tambm poderia herdar para implementao.
R No, os moti vos por trs da herana no precisam ser mutuamente exclusivos. Voc poderia usar herana e acabar satisfazendo cada um dos mot ivos.
P Herdar para reutilizao de implementao parece ter uma conotao negath'a. A
reutilizao mio um dos principais motivos para se usar programao orientada a
objetos?
R A relllilizao apenas um dos objet ivos da roo. A roo uma estratgia de programao que permite modelar as solues para seus problemas de uma maneira mais natural:
atravs de objetos. Embora a reut ilizao seja importante, voc no deve simplesmente
busc-Ia, ignorando os outros objetivos da 00. Lem bre do exemplo lterator/Queue.
Aque le era um model o natural de uma interface Iterator? claro que no!
Alm disso, a herana para reutilizao de implementao apenas uma maneira de obter a reutiIizao. FreqUentemente, a delegao a melhor maneira de obter reuti lizao de impl ementao simpl es. A herana si mplesmente no a ferram enta correta, se seu objeti vo apenas
reut ili zar uma implementao. A herana a ferramenta correta quando voc quer programar
pela diferena Oll estabelecer capacidade de substit uio de tipo.

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entend imento. Veja as respostas no Apndice A, "Respostas".

97

Herana: obtendo algo para nada

Teste
I. Quais so algumas das limitaes da reutilizao simples?
2. O que herana?
3. Qua is so as trs formas de herana?
4. Por que a herana de implementao perigosa?

5. O que programao pela diferena?


6. Ao herdar uma classe, pode-se ter trs tipos de mtodos e atributos. Quais so esses trs
tipos dc atributos e mtodos?
7. Quai s vantagens a programao pela diferena oferece?

8. Considere a hierarqu ia da Figura 4.11 , extraida da segurana do Java.


FIGURA 4 .11

P mluion

A hierarquia Permi ss i on.

AU~.m;ss;on

B..icP,rm;uion

Un ...,r..edf'"miuion

Stc:urifvl'ermlulon

Se voc voltar sua ateno para a classe Pcnni ss i on, quais classes so suas !ilhas? Quais so descendentes?
Consi dera ndo a hierarquia intci ra, qual classe a classe raiz? Quais classes so classes fol has?
Fina lmente, Permission uma ancestral de SecurityPermission?
9. O que herana para substitui o de tipo?
10. Como a herana pode destruir o encapsulamento? Como voc pode impor o encapsulamento ao usar herana?

Exerccios
I. Dada a defini o da classe a seguir, quais problemas poderiam ocorrer, se ela fosse herdada?
publ lc class Point (
public Point( i nt x, i nt y) I

Dia 4

this . x x:
this.y "' y;

publ1c Po1nt getlocation{) {


return new POint( x, y ):

public void move( int x, i nt y ) {


thi s.x x;
this.y ., y;

public void setlocation( int x, int y ) {


this.x x
thiS.y .. y:

pub l ic void setlocation( Point p ) {


th;s.x = p.x ;
this.y .. p.y :

public ;nt X;
public int y;

2. Como voc evitaria esses problemas?

SEMANA

DIA
Herana: hora de escrever algum
cdigo
A herana uma ferramenta poderosa. Hoje, voc vai explorar o uso dessa nova ferramenta ,
atravs de varios exerccios prticos de laboratrio. No fina l da liOde hoje, voc dever se sentir um pouco mais vo ntade com a teoria apresentada no Dia 4.
Hoje voc aprender:

Corno usar herana enquanto programa

Como as c lasses abstraIas o ajudam a planejar a herana

Sobre a impOrlincia do relacionamento

Como a linguagem Java pode ter violado os relacionamentos ' um' e ' tem um '

'e um' e ;tem um '

laboratrio 1: herana simples


A Li stagem S. l apresenta a classe base MoodyObject personificada.
LISTAGEM 5 .1

MoodyObject.java

public cla ss MoodyObject (

II retorna o humor
protected String getMood() I

Dia5

1 100

LISTAGEM 5 .1

MoodyObject.java (continuao)

return "moody" i
}

II

pergunta ao obje to como ele se sente


public voi d queryHood() I
System.out.prin t ln("I feel " + ge tMood O + " today!")i
}

MoodyObject define um mtodo pblico: queryMood (). queryMood () imprime o humor do objeto
na lin ha de comando. MoodyObject tambm declara um mtodo protegido, getMood (). queryMood ()
usa getMood () internamente para obter o humor que coloca em sua resposta . As subclasses podem si mplesmente sobrepor getMoodO para especializar seu hum or.
Se uma subclasse qui sesse mudar a mensagem escrita na linha de comando, ela precisaria sobrepor queryHood ().

Exposio do problema
Neste labomtrio, voc criar duas subclasses: SadObject e HappyObject. As duas subclasses devem
sobrepor getHood() para fornecerem seu prprio humor especialmente personal izado.
SadObject e HappyObject tambm devem adicionar alguns mtodos prprios. SadObject deve
adicionar um mtodo: pub l i c voi d cry(). Do mesmo modo, HappyObject deve adic ionar um
mtodo: pub 1i c voi d 1augh (). 1augh () deve escrever ' hahaha' na linha de comando. Do mesmo modo, cry() deve escrever ' boa hoo' na linha de comando.
A Listagem 5.2 configura um driver de teste que voc deve com pilar e executar quando tiver
concludo a escri la de HappyObject e SadObj ect.
LISTAGEM 5.2

MoodyO riv er.java

pub li c class MoodyOriver {


public f i nal static void ma in( String [] args ) {
MoodyObject moodyObjec t c new MoodyObject() i
SadObject sadObj ec t new SadObject ();
HappyObje ct happyObjec t " new HappyObject( ) ;
System. out.print ln( -How does the moody objec t feel today?M ) i
moodyObjec t . queryMood()i
Sys t em. out . pr1ntl n( "" l i
Sys t em. out . print ln( "How does the sa d object feel today?M )i
sadObjec t.queryMood( ); Ilnote que a sobrepos i o muda o humor
SadObject.cry() ;
System.ouL prin t ln( ,,- ) ;

Herana: ho ra de escrever algum cdig o

LISTAGEM 5.2

101

MoodyDriver. java (continuao)

System.out.print ln{ NHow does the happy object feel today?" );


happyObjec t . queryMood(); Ilnote que a sobreposi o muda o humo r
happyObject . laugh() ;
Sys tem.out .print l n( l ;
J

ALERTA

A prxima seo discute as solues do Laboratrio 1. No prossiga at concluir o Laboratrio 1.

Solues e discusso
As listagens 5.3 e 5.4 apresentam uma soluo para o laboratrio.
LISTAGEM 5.3

HappyOb j ect.java

publ ic cla ss HappyObject extends MoodyObject (

Ilredefine

o humor da cla sse


protected String getMood() I
return "happy;
J

II

especializao
pu bl ic vo i d la ugh () {
Sys tem. ou t. pri nt 1n(" hehehe ... hahaha . .. HAHAHAHAHAHA! ! ! ! ! ") ;
J

LISTAGEM 5.4

SadObject .java

public class SadObjec t ex tend s MoodyObject {

II

redefine o humor da cl asse


protected String getMood() {
return "sad";

II

especializao
publ ic voi d cryO I

Dia 5

1 102

LI STAGEM

5.4

SadObject.java (continuao)

System.out . println{"'wah' ' boo hoo' 'weep ' 'sob' ' weep'"};
}
}

Quando voc executar o driver de teste, dever ver uma sada semelhante a da Figura 5.1.
5.1
A saida correra de
FIGURA

MoodyDriver,

De interesse a chamada de queryMood(). Quando voc chama queryMood () em SadObject. " I

fee l sad today!" impresso na tela. Do mesmo modo, HappyObject imprime, "1 fccl happy today!"
Tal comportamento pode parecer surpreendente, pois nenhuma classe redefi ne queryMood O.
Voc precisa ver queryMoodO detalhadamente. Internamente, queryMoodO chama getMoodO
para obter o hum or. Como as subclasses redefinem getMoodO, queryMoodO chamar a verso
fi lha de getMood (). Esse comportamento um exemplo do processo ilustmdo na Figura 4.6 do
Dia 4.

laboratrio 2: usando classes abstratas para


herana planejada
Ex isti ro ocasies em que voc desejar desenvolver lima classe especificamente para que outros possam herdar dela. Quando voc desenvolve algumas classes relacionadas, pode encontrar
cdigo que comum a todas as suas classes. A boa prtica diz que, ao ver cdigo comum, voc o
coloca em uma classe base. Quando voc escreve essa classe base, planeja para que outras classes herdem dela.
Entretanto, uma vez que voc tiver term inado de mover o cdigo, poder notar que no faz sentido instanciar a classe base di retamente. Embora a classe base contenha cd igo comum, que

Herana: ho ra de escrever algum cdigo

103

muito valioso para subclasses, ela pode no ter nenhum valor para instanciao e uso direto. Em
vez disso, s fa z sentido usar as subclasses. As subclasses se especializam em relao classe
base e fornecem o que est faltando.
Considere a classe Employee:
publ i c cl ass Employee {
private String first_name ;
private String last_n ame;
private double wage ;
publi c Employee ( String first_name . St ring last name . double wage ) (
this.first_name f i rs t _name :
this.las t _name last_name :
this.wage wage;

I
publ iC doub l e getWage() {
return wage:

I
pub l iC String getFirstName() (
return fir st_name:

I
public String getLastName() (
return l ast_name:

I
publ ic double calc ulatePay() (
II No sei como fazer isso !
return O;

I
publiC Stri ng print Paychec k() {
String full_name " l ast_name + " , " + fi r st_name ;
ret urn ( "Pay : " + full name + " $" + ca l culatePay() );

I
I
Voc pode usar Empl oyee como classe base de Conmi ss i onedEmp loyees, HourlyEmployees e Sal ariedEmp loyees. Cada subclasse sabe como calcular seu pagamento. Entretanto, o algoritmo
usado para ca lcular pagamento vai variar de acordo com o tipo de funcionrio. Quando cri amos essa hierarqu ia, imaginamos que cada subclasse preci saria definir seu prprio mtodo
cal cul atePayO .

Dia 5

H um pequeno problema: Empl oyee no tem nenhuma regra para calcular seu pagamento. No
faz sentido executar calc ulatePayO para um objeto Employee. No ex iste nen hum algoritmo
para calcular o pagamento de um runcionrio genrico.
Uma soluo no definir cal culatePayO na classe base. Entretanto, no defi ni r o mtodo na
classe base seria uma deciso inreliz. Isso no modela um runcionrio muito bem . Cada runcionrio saber calcular seu pagamento. A nica diferena a implementao real do mtodo ca 1culatePayO. Assim, na verdade, mtodo pertence classe basco

Se voc no definir ca 1cul atePayD na cl asse base, no poder tratar os ru ncionrios genericamente. Voc perder a capacidade de conexo de subtipo para o mtodo ca 1cul atePay (). Outra so luo simplesmente codificar um retorno en latado. O mtodo poderia simpl esmente
retornar wage .
Um retorno codificado no uma so luo muito limpa. No h garantias de que outro dcsenvolvcdor v se lembrar de sobrepor o mtodo, ao desenvol ver uma nova subclasse. Alm disso, no raz
nenhum sentido instanciar um objeto Emp loyee. Felizmente, a 1'00 oferece um tipo especial de
classe, desl'inada especificamente herana planejada: a classe abstrata.
Uma classe abstrata mui to parecida com qualquer outra definio de classe. A de fi nio da
classe pode defin ir comportamentos e atributos, exatamente como uma classe normal. Entretanto, voc no pode instanciar diretamente uma classe abstraIa, pois uma classe abstrata pode deixar alguns mtodos indefin idos.
Novo

TERMO

Um mtodo declarado, mas no implemelllado, chamado de melOdo absl NIIQ. Somente classes abstraIas podcm tcr mtodos abstratos.

Em vez di sso, voc pode instanciar apenas as descendentes da classe abstrata que realmente implementam os mtodos abstraIaS.
Vamos ver uma classe Employee abstraIa:
public abstract cl ass Empl oyee (

publiC abstract double calculatePay{) ;


II o re s tante da definio permanece igual

I
A classe abslrata Emp 1oyee de fi ne um mtodo ca1cu 1a tePay () ; entretanto, ela o deixa inde fi nido.
Agora, fica por conta de eada subclasse implementar realmente o mtodo. HourlyEmp l oyee
uma dessas subclasses:
pub lic cla ss Hou r ly Employee extends Emp l oyee {
private i nt hours ;

Ilcontrola o nmero de horas trabalhadas

public HourlyEmpl oyee ( Str i ng f lrst_name, String last_name. double wage ) {


supe r ( flrst _name. l ast_name. wage };

Herana: hora de escrever algum cdigo

105

publiC double calculatePay() I


return getWage{) * hours;
}

publi c void addHours( i nt hours ) I


this . hours thiS.hours + hours;
}

public void resetHours() {


hours O;
}
}

Declarando mtodos abstratos, voc obriga suas subclasses a se especial izarem em relao
classe base, fornecendo uma implementao para os mtodos abstratos. Tornando uma classe
base abstrata e criando mtodos abstratos, voc planeja com antecipao o que a subclasse deve
redefi nir.

Exposio do problema
No Laboratrio 1, voc criou uma classe MoodyObject. Todas as subclasses redefinem getMood (). Para o Laboratrio 2, altere um pouco essa hierarquia. Torne o mtodo gctMood()abstrato.
Voc tambm precisar atualizar a classe MoodyDriver para que ela no tente mais instanciar MoodyObject diretamenle. Voc no ter de fazer quaisquer alteraes em SadObject ou
HappyObject, pois elas j fornecem uma implementao de getMoodO.

A prxima seo discute as solues do Laboratrio 2. No prossiga at concluir o Laboratrio 2.

Solues e discusso
As li stagens 5.5 e 5.6 apresentam as definies de MoodyObj ect e MoodyDri ver reestruturadas.
LI STAGEM

5.5

MoodyObject .java

public cla sse abstrata MoodyObjec t I

II retorna o humor
protected abstract Stri ng getMood();

II pergunta ao objeto como ele se sente


public void queryMood() I

Dia5

1 106

LISTAGEM 5 .5

MoodyObject .java (cont inuao)

System.out.println{"I feel N + getMood{) + N today!N);


}
}

LISTAGEM 5 .6

MoodyDriver . java

public class MoodyOriver (


publi c final stat i c void main{ String [] args ) (
IIMoodyObject mo new MoodyObject{); l lno pode instanciar MoodyObject
SadObject so new SadObject();
HappyObject ho new HappyObject() ;
IISystem.out.println( "How does the moody object feel today?" );
Ilmo.queryMood();
II Sys tem.out.println{ "" );
System. out.println( "How does the sad object fee l today?" };
so.queryMood(); II note que a sobrepos i o muda o humor
so.cryO;
System.out . println( MM );
System.out.print l n{ NHow does the happy obj ect feel today?M );
ho.queryHood(); II note que a sobreposio muda o humor
ho.laughO;
System.out.println( N_ );
}

As al teraes so muito simples. MoodyObject define um mtodo getMood () abstrato e deixa por
conta de suas subclasses fornecer a implementao real. Quando O mtodo queryMood () precisa
recuperar o humor, ele simplesmente faz uma chamada ao mtodo abstrato.
O uso de classes abstratas define o contrato que as subclasses devem atender para utilizar a classe base. Como descnvolvedor, quando voc ver uma classe base abstrata, saber exatamente o
que preci sa especiali7..ar ao herdar. Voc pode especializar os mtodos abstratos. Entretanto,
voc sabe que definindo os mtodos abstratos, sua nova classe se encaixar na hierarquia corretamente.
Quando uma classe base tem muitos mtodos, pode ser confuso descobri r quais deles devem ser
sobrepostos. As classes abstratas fornecem uma dica.

Herana: ho ra de esc rever algum c digo

laboratrio 3: conta em banco


a herana simples

107

praticando

Agora hora de testar seus conheci mentos de herana. Vamos voltar ao Banco 00 e vero que a
herana pode fazer para o sistema de contas do banco.
O Banco 00 oferece aos seus clientes algumas escolhas de contas: uma conta poupana, uma
conta com cheques, uma conta com vencimento programado e uma conta de cheque espec ial.

Uma conta genrica


Cada tipc de conta pcrmitc ao usurio depositar e sacar fundos, assi m como veri ficar o saldo corrente. A conta bsica genrica no permite saque a descoberto.

A conta poupana
A conta poupana especial iza a conta genrica do banco, aplicando juros no saldo, quando instru da a fazer isso. Por exemplo, se um depositante tem um saldo de US$I.OOO e a taxa de juros
de 2%, aps o pagamento dos juros, o saldo ser de USS 1020:

balance

balance + (balance * inte rest_rate)

A conta poupana no pennite saque a descoberto.

Uma conta com vencimento programado


A conta com venc imento programado tambm aplica juros ao saldo. Entretanto, se o titular da
conta fizer qualquer saque do capital investido, antes do prazo de vencimento, banco deduzi r
uma porcentagem do saque. Ass im, por exemplo, se o depositante sacar US$I.OOO antes do prazo de venci mento e houver urna multa de 5% sobre o valor sacado, o saldo da conta diminuir
US$IOOO. Entretanto, o depositante receber apenas US$950. Se a conta estiver no venc imento,
o banco no pena lizar os saques.

balance

balance - withdraw amount

mas

amount_given_to_depositor amount - (amount * penalty_rate)


a conta com vencimento programado no permite saq ue a descoberto.

Conta com cheques


Ao contrrio das contas poupana e com vencimento programado, a conta com cheques no aplicaj uros ao saldo. Em vez disso, a conta com cheques pcnni te que o depositante emi ta cheques e
faa transacs na conta atravs de ATM (caixa elelrnico de auto-atendimento). Entretanto,

Dia 5

banco limita o nmero de transaes mensais a algum nmero fixo. Se o depositante ultrapassar
essa quota mensal , o banco cobrar uma taxa por transao. Assim, por exemplo, se o depositante tiver direito a cinco transaes gratuitas por ms, mas fi zer oito transaes a uma taxa de US$I
por transao, O banco cobrar do deposi tante uma taxa de US$3:
fee (total _t ransac t ions - month l y_quota) * per_transac ti on_fee
A conta com cheq ues no permite saque a descoberto.

Conta com cheque especial


Finalmente, a conta com chcquc especial perm ite ao depositante sacar dinheiro alm do saldo da
conta. Entretanto, nada de graa. Periodicamente, o banco apl icar uma taxa de j uros no caso
de qualquer sa ldo negativo. Assim , por exemplo, se o depositante acumular um saldo negativo
de US$I.OOO a uma taxa de 20%, poder pagar uma taxa de US$200. Depoi s da aplicao da
taxa, seu saldo ser de - US$ 1200:
balance balance + (balance * i nteres t_rate)
Noteque o banco s calculajuros em contas com saldo negativo! Caso contrrio, o banco acabaria di stribuindo dinhei ro. O Banco 00 no est no ramo de distribuio de dinheiro. Nem mesmo para desenvolvedores.
Ao contrario da conta com cheques, a conta com cheque especial no coloca um Iimite no nlllnero de transaes mensais. O banco estimularia os saq ues - eles poderiam cobrar juros!

Exposio do problema
Sua tarcfa formular uma hierarquia de herana e implementar as contas confonne definido anteriormente. Voc deve criar as seguintes classes de conta:
Ban kAccount
Sa vi ng sAccount
TimeMaturityAccount
CheckingAccount
OverdraftAccount

BankAccount a classe base. Ela contm as tarefas comuns a todas as contas. Essa a nica dica
hierrquica que voc ter 1Parte do laboratrio voc experimentar as hierarquias de herana.
Existem v rias si mpl ifi caes que voc pode fazer. Para clcul os de taxas, venc imento programado e juros, supon ha que outra pessoa observar o calendrio. No programe esse tipo de
funcionalidade em suas classes. Em vez disso, fornea um mtodo para outro objelo chamar.
Por exemplo, SaV l ngsAccount deve ler um mtodo addlnterest (). Um objeto externo cha mara o mtodo. quando for hora de calcular osjuros. Do mesmo modo, Checki ngAccoun t deve expor um mtodo access FeesO. Quando chamado, esse mtodo calcular todas as laxas e as
ap licar no saldo.

Herana: hora de escrever algum cdigo

109

No se atrapalhe com detalhes desnecessrios. lembre-se de que voc est


completando este laboratri o para ganhar experi ncia prtica com herana e
no para escrever o sist ema de con ta mais robusto possivel. Assim, no se
preocupe com a validao da entrada (a no ser que queira fazer isso). Voc
pode supor que todos os valores dos argumentos sero sempre vl idos.

NOTA

o Dia 4 abordou brevemente o uso de super. super no um conceito dificiL Considere


a seleo a seguir:
publlc COfTlTlissionedEmployee( String first_name, String last_name,
double wage, double cOfTlTlission ) 1
super(first_name, last_name,wage l; II chama o construtor origi nal

II
this.cOfTlTlission

para inicializar corretamente

cOfTlTlission;

I
Quando voc chama super dentro de um construtor, isso permite que o construto r da
progenitora seja chamado. claro que voc deve fornecer todos os argumentos exig i
dos pelO construtor da progenitora. A maioria das linguagens, Java inclulda, exige
que, se voc chamar super dentro do construtor, ento deve fazer isso antes de tudo.
Na verdade, se voc no chamar super, automaticamente a linguagem Java t entar
chamar superO sozinha.
super permite que voc destaque o cdigo da progenitora, que de outro modo seria
simplesmente sobrescrito. No caso dos constru tores, super permite que a fil ha chame o
construtor de sua progenitora.
Chamar corretamente o construtor da progenitora algo que voc no deve desprezar.
Voc precisa garantir que a classe seja inicializada corretamente.
Voc tambm pode usar super dentro de um mtodo.
Imagine uma classe VeryHappyObject,
publ 1c clas s VeryHappyObject extends HappyObject {

II

redefi ne o humor da cl asse


protected String getMoodO {
String old_mood super.getMood();
return "very" + old_mood;

I
I
VeryHappyObject SObrepe getMood(). Entretanto, super.getMood() permite que VeryHappyObject chame a verso da progenitora de getMood (). VeryHappyObject especializa
o mtodo getMood () de sua progenitora, realizando algum processamento extra no valor retornado por super .getMood ().
Assim, mesmo que uma filha sobreponha o mtodo de sua progenitora, a filha ainda
poder destacar o cdigo existente na progenitora.

Dia 5

Assim como em um construtor, se voc usar super .~todo>() para cha mar um mtodo, ento d eve fornecer t odos os argumentos que o mtodo possa exigir.
Voc achar super til neste laboratrio.

Pare agora e complete o laboratrio, caso se sinta vontade. Se voc precisar de um pouco mais
de ajuda, cOlu inue a ler.

Exposio estendida do problema


Se voc ainda se acha perdido, estas interfaces devem aj ud lo um pouco. Essas interfaces repre
sentam apenas unta maneira de completar o laboratrio.
BankAccount contm os seguintes mtodos:
pub li c void depositfunds( double amoun t )
pub l ic double getBa l ance()
public double withdrawfunds( double amount )
protected void set8a l ance( double newBalance )
Savi ngsAccount deve conter os seguintes mtodos:
public void addlnterest()
public void setlnterestRate( double interestRate )
public double getlnteres tRate()
TimedMaturityAccount contm os seguintes mtodos:
public
public
public
public

boolean isMature()
void mature()
double getfeeRate()
void set feeRate( double rate)

Ti medMatu ri tyAccount precisar redefi nir wi thdrawfunds () para verifi car o venci mento e apli
car todas as taxas necessrias.
Checki ngAccount contm os seguintes mtodos:
pub li c
pub li c
public
public
public
public

void accessfees()
double getFee()
void setfee( double fee )
int getMonth l yQuota{)
void setMonth l yQuota( int quota)
int getTransact ionCount()

Checki ngAccount precisar sobrepor wi thdrawfunds () para controlar o nmero de transacs.

Herana: ho ra de escrever algum cdigo

"1

OverdraftAccount contm os seguintes mtodos:


publl c void chargelnterest()
public double getCreditRate()
publ i c void setC redltRate( doub le rate)
Overd raftAccount pode precisar sobrepor withd rawFunds (), caso 6ankAccount coloque cheq ues
a descoberto no mtodo.
Talvez voc tambm queira iniciar sua hierarquia com a classe Account, que desenvolveu para o
Laboratri o 2 no Dia 3. A (mica mudana que voc dever fazer no mtodo wi thdrawFund s{).
Voc provavelmente deve colocar proteo contra saq ue a descoberto nos mtodos withdrawFunds ().

A prxima seo discute as solues do Laboratrio 3.


cluir o Laboratri o 3.

No prossiga at con-

Solues e discusso
A Figura 5.2 ilustra a hierarquia de herana resultante de conta.

FIGURA 5 .2

Bel'llAccounl

ii hierarquia de conta elll


baIlCO.

S8"; nll'''' """"nl

OvtIrd flAccounl

Ch", kln ll 4 CCOllOl

Ti mflMalll. 11'1 Acooun I

im portante ter essa hierarquia em mente, enquanto voc considera as solues a seguir.
A Listagem 5.6 apresenta uma possivel implementao de 6ankAccount. Essa classe base contro-

la o sa ldo e man ipula depsitos e saq ues.


LISTAGEM

5.7

BankAccount.j ava

publl c cla ss 6ankAccount {

II dados privados
private double ba lance;

1 11 2

Dia5

LISTAGEM 5.7

BankAccount.java (continuao)

II

construtor
public BankAccount( double initoeposit ) {
setBalance( initDeposit ):
}

II

deposita dinheiro na conta


public void depos1tFunds( double amount ) {
II a classe base no ap l ica regras s contas
II no valida a entrada
setBalance( getBalance() + amount ):
}

II

consulta o saldo
public double getBalanceO {
return balance;
}

II

configura O saldo
protected void setBalance( double newBa l ance ) {
balance newBalance:
}

II

saca fundos da conta


pub l ic double withdrawFunds( double amount } {
if( amount >'" balance) {
amount balance:
}

setBalance( getBalance() - amount );


return amount;
}

Savi ngsAccount, na Listagem 5.8, herda diretamente de Ban kAccount. Sav i ngsAccount especializa BankAccount, adicionando mtodos para obter e con figurar a taxa de juros, assim corno um
mtodo para apl ica r juros no saldo da conta.
LISTAGEM 5.8

Savi ngsAccount.java

publiC class SavingsAccount extends BankAccount {

II

dados privados
private double interestRate:

II

Cria novo SavingsAccount


public SavingsAccount(double initBa l ance , doub l e interestRate }I
supere initBalance ) :
setInterestRate(interestRate l:

Herana: hora de esc rever alg um c dig o

LISTAGEM 5 .8

11 3

Savi ngsAccou nt. j ava (continuao )

II

calcula e soma juros na conta


public voi d addInterest() {
double bala nce = getBa l ance( ) ;
double rate
z get InterestRate() ;
doubl e interest ba la nce * rate ;
double new balanc e

balance

i nte rest;

set Bala nce{ new_balance );


}

II

con figura a taxa de juros


pu bli c vo i d set Intere stRate( double i nterestRate ) {
this.interestRate z interestRate ;
}

II

cons ulta a taxa de juros


publ ic doub l e getInterestRate() {
return interestRate;
}
}

Ti meMa t urityAccount, na Listagem 5.9, herda de SavingsAccount, pois juros podem ser aplicados em seu saldo. Entretanto, ela especializa sua progenitora, defin indo mtodos para configurar o nvel de vencimento e taxas. Interessante o fa to de que essa classe redefine o mtodo
wi thd rawFunds (). Atravs de uma chamada a super .wi thdrawFunds () , esse mtodo ai nda usa a
funciona lidade original; ent retanto, ela acrescenta as verificaes necessrias para ver se prec isa
acessar uma taxa para a transao. Se ass im fo r, ela acessa a taxa c retorna o valor do saque, menos a taxa.
LISTAGEM 5 .9

Ti meMaturi tyAccount .java

class Ti medMaturityAcco unt extends SavingsAccount {

II

dados pri vados


private boolean ma ture;
private doub le feeRate;

II

Cria novo TimedMa tu ri tyAccou nt


public TimedMaturityAccount( double i nitBalance.
double interestRate.
double fee Rate ) I
super ( in itBalance . in tere stRate ) ;
set FeeRate ( feeRate );
}

Dia5

1 11 4

LISTAGEM

5.9

TimeMaturityAccount.java (continuao)

II

sobrepe withdrawFunds de BankAccount


public double withdrawFunds( double amou nt ) I
super.withdrawFunds( amount ):
if( !isMature() ) I
double charge ~ amount * getFeeRa t e() :
amount amount - charge :
}

return amount:
}

II

verifica o vencimento
public boo l ean isMature() I
return matu re :
}

II

faz vencimento
publ ic void mature() {
mature true ;
}

II % de

taxa para saque anteC i pado


pub l ic doub l e getFeeRate() {
return feeRate:
}

II

configura % de taxa para saque antecipado


public voi d setFeeRate( doubl e rate) I
feeRate rate:
}
}

Checki ngAccoun t, na Listagem 5. IO, herda diretamente da classe base BankAccount. Essa classe
adiciona os mtodos necessrios para configura r a taxa por transao, configurar a quota mensal,
recon fi gurar a conta da transao e consultar o nmero de transaes corrente. Essa classe tambm sobrepe o mtodo wi thdrawFunds () para controlar o nmero de transaes. Assim corno
TimedMaturityAccount, ChecklngAccount ainda usa a lgica original, chamando super .w ithdrawFundsO.
LISTAGEM

5.10 CheckingAccount.java

publiC cl ass CheckingAccount extends BankAccount I

II

dados privados
private int
monthlyQuota :
private int
transact ionCount:
private double fee :

II

Cria novo CheckingAccount

Herana: ho ra de esc rever alg um cd igo

LISTAGEM 5.10

11 5

Checkl ngAccount . java (continuao)

publiC ChecklngAccount( double initOeposit , int trans, double fee } {


supere in ltOeposit }:
setMonthlyQuota( trans l :
set Fee( fee ):
J

II sobrepe withdrawFunds de BankAccount


public double withdrawFunds( double amount ) {
transactlonCount++ :
return super .withdrawFunds( amount l:
J

II acessa as taxas se ultrapassou o l imite de

tran sa~o

public void accessFees() (


int extra a getTransactionCount() - getMonthlyQuota():
if( extra> O ) {
double total_fee extra * getFee{) j
double balance ge tBalanceO total fee:
setBalance( balance );
J

transactionCount

O:

II al guns mtodos de obten o e con figura o


public double getFee() {
return fee;
J

public void se tFee( double fee ) (


this. fee fee;
J

publi c int getMonthlyQuota() {


return monthlyQuota :
J

public vo id setMonthlyQuota( int quota) {


monthlyQuota a quota:
J

publi C int getTransactionCount() {


return transa ctionCount:
J

Finalmente. Ove rdra ftAceou nt, na Listagem 5.1 I, herda diretamente de BankAceount . Entretanto, ela tambm adiciona mtodos para configurar a taxa de juros de saque a descoberto e para
aplicar quaisquer taxas de juros.

Dia 5

LISTAGEM 5 .11

OverdraftAccount .java

public class Ove rdraftAccount extends BankAccount I

II

dados privados
private double creditRate;

II

Cria novo OverdraftAccount


public OverdraftAccount( double initOeposit. double rate) (
super( 1nitOeposit ) j
setCreditRate( rate ) j

II

cobra j uros sobre qualquer di nh ei ro emprestado


public void chargelnterest() {
double balance a ge tBalance()j
if(balance < O ) I
double charge balance * getCreditRate()j
setBalance( balance + charge )

I
I

II

consulta a taxa de crdito


pub l ic double getCreditRate() (
return creditRate

II

configura a taxa de crdito


public void setCreditRate( doub le rat e) {
creditRate ratei
I

II

saca fundos da conta


public double withdrawFunds( double amount ) (
setBala nce(getBa l ance() - amount )j
return amountj

I
I
Cada uma dessas classes espec ial iza sua progenitora de uma maneira ou de outra. Algumas,
corno SavingsAccount, sim plesmente adicionam novos mtodos. Outras. como Checki ngAccount, Ove rdraftAccount e TimedMaturi tyAccount, sobrepem o comportamento padro
da progenitora, para aumentar a funcionalidade.
Este laboratrio o expe aos mecanismos da herana, assim como herana para reuti lizao de
im plementao e programao pela diferena.

Herana: hora de escrever algum cdigo

117

Embora no seja mostrada aqui, voc tambm pode usar a capacidade de conexo, pois a classe
com um BankAccount se relaciona a todas as contas. Qualquer um que sai ba como atuar na classe
base BankAccount pode sacar, deposi tare emitir um cheque nos fu ndos de qualquer tipo de conta.
Voc vai explorar a capacidade de conexo com detalhes por todo o Dia 6, "Polimorfi smo:
aprendendo a prever o futuro", e Dia 7, "Polimorfismo: hora de escrever algum cdigo".

laboratrio 4: estudo de caso


"tem um" e java.util.Stack

Il um"l

Quando se ini ciante em 00, pode ser tentador ver a li nguagem Java como um exemplo de projeto orientado a objetos perfeito. Voc pode di zer a si mesmo, "se a linguagem Java faz isso,
deve estar correto". I nfel izmente, colocar confiana inquestionvel em qualquer implementao
00 perigoso.
Vamos rever a estrutura de dados de pilha clssica. Voc pode colocar itens em uma pilha, extrair
itens de uma pilha e olhar o primeiro elemento da pilha, sem remov- lo. Talvez voc tambm
quisesse ver se a pi lha est vazia.
A linguagem Java tem uma classe Stack. A Listagem 5.12 ilustra a interface.

LtSTAGEM 5. 12 java.utll.Stack
publ lC class Stack extends {
public boo lean empty() ;
publi c Object peek();
public Object pop ();
public Object push( Obj ect item ) ;
public int search( Object o ) ;
}

Voc notam que a linguagem Java ol im iza um pouco a definio clssica de pi lha. A linguagem
Java acrescenta um mtodo searc h(). O mtodo push () tam bm retorna o item que voc coloca.
Entretanto, h um problema maior. A classe Java Stack tambm herda de Vector. De um ponto
de vista, essa uma deci so inteligente. Herdando de Vector, St ack obtm toda a implementao
contida em Vector. I)ara implementar Stack, tudo de que voc precisa envolver os mtodos de
Stack para chamarem internamente os metodos herdados de Vector corretos.
Infelizmente, a classe Java Stack um exem plo de herana pobre. Stack passa no teste ' um'?
"Um objeto Stack ' um ' Vector"? No- o teste fal ha. Vector tem todos os tipos de mtodos
para colocar elementos em Vecto r e remov-los. Um objeto Stack s permite que voc coloque
elementos no topo da pilha. A classe Vecto r permite que voc insira e remova elementos em
qualquer parte.
Aqui, a herana pennite que voc interaja com a classe Stack de maneiras indefin idas para uma pilha.

Dia 5

Exposio do problema
Stack passa no teste ' tem um'. "Um objeto Stack 'tem um' objeto Vector". Para este laboratrio,
escreva uma nova verso de Stack que empregue o tipo correto de reut ilizao de implementao.

ALE R TA

A prxima seo discute as solues do laboratrio 4. No prossiga at con


cluir o laboratrio 4.

Solues e discusso
A Listagem 5. 13 ilustra uma possivel implementao de Stack

LISTAGEM 5.13 A New Stack Implementation


public cl ass Stack (
private java.u til .Arraylist list :
pub l ic StackO(
list new java.uti l .Arrayl ist() :
}

public boolean emptyO (


return l ist.isEmptyO :
}

publiC Object peek() I


if( !emplyO } I
return li st .get( O };
}

return nu ll :
}

publi C Object popO (


if( !emplyO } I
return list.remove{ O ):
}

return nul l;
}

publiC Object push( Object item ) (


lis t . add( O, item l :
return item:
}

Herana: ho ra de esc rever algum c dig o

11 9

LISTAGEM 5.13 A New Stack Implementation (continuao)


pub l iC int sea rch( Object o ) {
in t index l i st. indexO f ( o ,;
if( index ! - - 1 ) {
return index + 1;
J

return - 1;
J
J

Se este laboratrio nos ensi nar algo, que no devemos depositar toda nossa f em qualquer fo nte de 00. Nada perfe ito.

Resumo
Hoje, voc completou quatro laboratrios. O Laboratrio I permi ti u que voc experi mentasse a
herana simples. Aps concluir o Laboratrio 1, voc deve ter entendido o mecan ismo bsico da
herana. Laboratrio 2 permitiu uma maior explorao da herana, atravs da classe abstrata e
da herana planejada. O Laboratrio 3 deve ter solidifi cado as lies do Dia 4. Os laboratrios I
e 2 permiti ram ver mtodos e atributos redefinidos, novos e recursivos. Voc tambm viu como,
mesmo se sobrepuser um mtodo. ainda pode usar a im plementao da progen itora.

a Laboratrio 4 ilustrou a importncia de considerar os testes ' um ' e 'tem um ', enquanto se
formam hierarquias de herana. s vezes, a melhor ao no herdar. Conforme o Dia 4 enfatiza, a com posio freqUentemente a fomla mais limpa de reutilizao. A herana s fa z sentido
do ponto de vista relacional ou ' um ' . Se dois objetos no esto relacionados pelo tipo, ento
eles no devem herdar. A implementao compart ilhada no motivo s ufi ciente para herdar.
Dentro de um sistema ou aplicati vo, voc sem pre deve planejar a mxima herana possvel.
Entretanto, q uando programa para um apl icativo espec fi co, voc est limitado a esse programa.
Com o passar do tempo, voc trabalhar em muitos programas diferentes. Quando voc comear
a notar que est programando as mesmas coisas repetidamente, as oportunidades para herana
comearo a se apresentar. Voc sempre deve estar atento a essas hi erarqu ias de herana descobertas. Voc deve refaze r seu cdigo, quando descobrir essas novas hi erarquias.

Perguntas e respostas
P No Laboratrio 4, voc mostrou como at a linguagem Java comete erros de 00.
Quando eu examinar as APls Java ou outras fontes de exemplos de 00, como pod erei ter certeza de que o que estou vendo ' boa ' ao?

Dia 5

R dificil dizer o que constitui a ' boa' 00 e a ' m' 00, mesmo aps ter mui ta experincia
em 00. A me lhor coisa que voc pode fazer aplicar o que aprendeu e nunca tomar um
exemplo como garant ido. Encare cada exemplo ponderadamente e, se a lgo no parecer
correto, discuta isso com seus colegas: obtenha uma segunda opinio.

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respostas no Apndice A, 'Respostas".

Teste
I. A partir das so lues de laboratrio, d um exemplo de mtodo redefinido, de mtodo recursivo e de novo mtodo.
2. Por qu voc declararia uma classe como sendo abslrata?
3. No Laboratrio 4, voc explorou os relacionamentos ' um ' e 'tem um'. Antes mesmo de
aprender a respeito de herana, voc viu relacionamentos ' tem um '. Quais os relacionamentos ' tem um" voc viu nos laboratrios do Dia 3?
4. Como esses laboratrios preselVaram o encapsulamento entre a classe base e as subclasses?
5. A partir das solues, encontre um exemplo de es peciali zao.
6. Como as solues do Laboratrio 3 e do Laboratrio 4 adotam lima estralgia diferente
para reutil izao de implementao?

Exerccios
No h exerccios hoje. Faa seus laboratrios!

SEMANA

DIA
Polimorfismo: aprendendo a
prever o futuro
At aqui, voc aprendeu sobre os dois primei ros pilares da programao orientada a objelos: encapsulamento e herana. Como voc sabe, o encapsulamento permi te construir componentes de
soft ware independentes e a herana pennite reutilizar e estender esses componentes. Entretanto,
ainda falta algo. O so ft ware est sempre mudando. Se os usurios exigem nova runcional idade,
erros aparecem ou o software precisa ser integrado em novos ambientes, a nica constante a
mudana. O cic lo de vida do so ft ware no tennina quando voc di stribui um prod uto. Voc precisa de sof1ware que possa se adaptar s necessidades futuras. No seria timo, se voc pudesse

escrever so ftware ' prova do futuro '?


Um software prova do futuro se adapta aos requ isitos futuro s sem alterao. Um software fi
prova do futuro permi te que voc faa alteraes e adicione novos recursos facilmente. Feliz
mente, a POO entende que um software de s ucesso no esttico. Assim , a POO usa o conce ito
de polimorfi smo para perm itir que voc escreva esse soft ware prova do fu turo.
Voc pass<lr os prximos do is dias considerando o polimorfismo, o terceiro e ltimo pilar da
programao orientada a objetos.
Hoje voc aprender:

o que polimorfismo

Quai s so os diferentes tipos de poli morfismo e o que eles o ferecem para seus objetos
Dicas valiosas para o polimorfismo eficaz

122

Dia 6

A respeito de algumas armadil has do polimorfismo

Como o polimorfismo atinge os objetivos da 00

Polimorfismo
Se o encapsulamento e a herana so os socos um e dois da POO, o polimorfismo o soco para
nocaute seguime. Sem os dois primeiros pilares, voc no poderia ler o polimorfi smo, e sem o

polimorfismo, a POO no seria eficaz. O polimorfismo onde o paradigma da programao orientada a objelos rea lmente brilha e seu domnio abso lutamente necessrio para a roo eficaz.
Polimorfismo significa muitas fo rmas. Em termos de programao, o paI imorfi smo penn ite que
um nico nome de classe ou nome de mtodo represente um cdigo diferente, selecionado por
algum mecanismo automti co. Assim, um nome pode assumir muitas formas e como pode representar cd igo difercnte, o mesmo nome pode representar muitos comportamcntos di fe rentes.

Polimorfismo: ter mu itas ronnas . Em tennos de programao, mui tas rorm as significa que um nico nome pode representar um cdigo direrente, selecionado por algum mecanismo automtico. Assi m, o polimorfismo pennite que um unico nome expresse muitos
componamentos direrentes.

Novo

TERMO

De sua prpria maneira, o polimorfismo o di sturbio das multiplas personalidades do mundo do


somvare, pois um nico nome pode expressar muitos comportamentos direrentes.
Toda essa conversa sobre expressar 'm uitos componamentos di rerentes' pode parecer um pouco
abstrata. Pense no termo abrir. Voc pode abrir uma porta, uma caixa, uma janela e uma conta
no banco. A palavra abrir pode ser aplicada a mu itos objetos direrentes no mundo real. Cada ohjeto interpreta 'abrir' de sua prpria maneira. Entretanto, em cada caso, voc pode simplesmente
dizer 'abrir', para descrever a ao.
Nem todas as li nguagens suponam poli morfismo. Uma linguagem que suporta polimorfismo
uma lingl/agem polimrfica. Em contraste, uma lingl/agem monomrfica no suporta polimorfismo e, cm vez disso, restringe tudo a um e apenas um comportamento estti co, pois cada nome
estaticamente vinculado ao seu cd igo.
A herana rornece o aparato necessrio para tornar certos tipos de polimorfi smo poss veis. No

Dia 4, "Herana: obtendo algo para nada", voc viu como a herana perm ite fonnar relacionamentos com capacidade de substituio. A capacidade de conexo extremamente imponante
para o poli morfismo, pois ela pennitc que voc trate um tipo especfico de objeto genericamente.
Considere as classes a segui r:

publl C cla ss Persona l ityObject (


public St r ing speak() {
return - I am an object.";
}
}

Po lim o rfismo: aprendendo a prever o futuro

123

pub1i c c1ass Pessimi sticObject extends Personali t yObject (


public St r ing speak() {
return "The glass i s half empty . ":

I
I
pub1ic class Opt imisticObject extends Personal ityOb ject (
pub1ic String speak() {
re t urn "The gl ass is ha 1f fu ll. ":

I
I
publiC class IntrovertedObject extends PersonalityObj ect (
publlc St ring spea k() {
return "h i ... ";

I
I
publi C cl ass ExtrovertedObject extends PersonalityObject (
public Stri ng speak() {
return "He ll o. blah blah blah. did you know that bl ah blah blah. M:
I

I
Essas classes fo rmam uma hierarquia de herana muito si mples. A classe base, Persona1i tyObject, declara um mtodo: speak(). Cada subclasse redefi ne speak () c retorna sua prpria
mensagem, baseada em sua personalidade. A hierarquia forma relacionamentos com capacidade
de substituio entre os subtipos e seus progenitores.
Considere O mtodo mal n() a segui r:
public static void main(S tring [] args ) (
Persona1 1tyObject personality new PersonalityObject();
Pess1misticObject pessimistic " new Pessimi sticObject() :
OptimisticObject optimis t ic " new OptimisticObject( ):
IntrovertedObject introverted new IntrovertedObject();
ExtrovertedObject extroverted " new Ext rovertedObject():
II a capacidade de substi tuio perm ite fazer o seguinte
Personal ityObject [] personal ities " new Personal ityObject [5] :
personali t ies [O] personal ity:
personalities (1 ] pessimistic;
personalities [2] opt imi st i c:
personalities [3] introve rted:
persona 11 t i es [4] ext roverted;
E

I I o polimorfismo faz com que PersonalityObject parea ter


I I muitos comportamen tos diferentes

Dia 6

II

l embre -se - o polimorf i smo o distrbio das mlti plas


Ilpersonalidades do mundo 00
System.out.prin t ln( "Pe r sonaIHyObject[O] speaks: " +
pe r sona 1 i t ies[O] . speak(;
System.out.prin tl n( "Pe r sona I HyObject[ l] speaks:
+
persona l it i es( l). speak( :
System . out.print ln( "Persona I HyObject [2] s peaks:
+
persona l i ties [2] . speakO) :
System .out . prlntln( "PersonalityObject[3] speaks: " +
persona 1 i t i es [3) . speak O) :
System.out.println( "PersonalityObject[4} s peak s : " +
personalities[4}.s peakO) :
M

Os primeiros dois teros do mtodo mai n{) no aprese ntam nenhuma nov idade. Conforme voc
viu no Dia 4, a capacidade de substituio permite tratar um objeto genericamente. Ent retanto, o
trecho a seguir onde o exemplo se torna interessante :

1/

o po l imorfismo faz com que PersonalityObject parea ter


l/muitos comportame ntos diferentes
II lembre - se - o polimorf i smo o distrb i o da s m l ti plas
Ilpersonalidades do mundo 00
System.out.println( "Pe r sonaI H yObject[O] speaks: " +
pe r sonal i t ies[O] . speak( ;
System.out.print ln( "Pe r sona htyObject[ l] speaks:
+
persona 1H ies[ I] . speakO) :
System.out.print ln( "Per sona lityObject [2] s peaks:
+
persona I i ties (2) . speak() :
System.out.println( "Per sonalHyObjec t (3] speaks: " +
persona 1 i ties (3) . speak O) :
System .out . println( "PersonalityObject(4) s peak s : ~ +
persona l ities(4] . speakO) ;
M

A Figure 6. 1 ilustra a sada.

FIGURA 6 .1

Demolls'raeio do
compor/mllell/O polim/fico.

Po lim o rfismo: aprendendo a prever o futuro

125

Com base na sada, parece que o mtodo speak() de Personal i tyObject tem muitos comportamentos diferentes. Mesmo que PersonalHyObject defina speakO para imprimir " 1 am an object", Pe rsona 1i tyObject est ex ibindo mais de um comportamento. Mesmo que o array
s upostamente contenha instncias de Persona 1i tyObject, cada membro do array se comporta de
forma diferente, quando o mtodo principal chama o mtodo speak (). Esse o dilema do comportamento poli mrfico; Personal 1tyObject, o nome, parece ter muitos comportamentos.
Novo

TERMO

NOTA

persona 1it i es um exem plo de varivel polimrfica. Uma vari(11ef polimrfica


uma varivel que pode conter muitos tipos diferentes.

Em uma linguagem tipa da, as variveis polimrficas esto restritas a conter


va lores especfi cos. Em uma linguagem dinamicamente tipada, uma varivel
polimrfi ca pode conter qualquer valor.

o exemplo anterior explica o mecanismo, mas ele poderia no representar adequadamente o esprito do polimorfismo. Afi nal, voc sabe exatamente o que o array contm.
Em vez disso, imagine que voc tenha um objelo cujo mtodo recebe um objeto Persona1i tyObject como parmetro:
public void makeSpeak( PersonalityObject obj ) I
System.out. prin t ln( obj.speak() );

I
Os relacionamentos com capacidade de subst itu io permitem que voc passe uma instncia do
objeto Personal i tyObject ou qualquer descendente dessa classe para o mtodo makeSpeak (),
como um argumento. Assi m, ao criar descendentes especializados de Persona 1 i tyObject, como
Ext rovertedObject, voc no precisa mudar a lgica do mtodo para que ele use instncias das
novas classes como argumento. Em vez disso, voc pode simplesmente instanciar ExtrovertedObject (ou qualquer descendente) e passar a instncia para o mtodo.
O polimorfis mo entra em ao quando o mtodo makeSpeak() chamado e lhe passado um
obj eto como argumento. O polimorfi smo garante que o mtodo correto seja chamado atravs do
argumento de Persona 1i tyObject, chamando o mtodo do objeto com base no tipo da c lasse real
do argumento, em vez do tipo da classe que o mtodo makeSpeakO pensa que est usando.
Assim, se voc passar um objeto ExtrovertedObject, o polimorfismo garantir que a definio
de speak () de ExtrovertedObject seja chamada e no aquela encontrada na classe base. Como
resultado, makeSpeak() apresentar mensagens diferentes na tela, dependendo do tipo de argumento que for passado.
Voc pode apri morar o polimorfismo para adicionar nova funci onal idade em seu sistema, a
qualquer momento. Voc pode adicionar novas classes, que tenham funcionalidades jamais imag inadas quando O, programa foi escrito pela pri meira vez - tudo isso sem ter de mudar seu cdi go j existente. E para isso que serve o software prova do fu turo.

Dia 6

Este exemplo apenas a ponta do iceberg polimrfi co. Na verdade, o exem plo representa apenas
uma das muitas formas do polimorfis mo. O prprio polimorfi smo correto poli mrfi co!
Infeli zmente, ai nda h pouco consenso na comunidade de 00 quando se trata de polimorfi smo.
Em vez de entrar na controvrsia, este livro apresentar quatro forma s de polimorfismo. O entendimento dessas q uatro fonnas comuns deve dar-lhe a base de que voc precisa para comear a
aplicar o polimorfismo. Hoje voc aprender sobre:
I. Polimorfismo de incluso

2. Po limo rfismo paramtrico


3. Sobrepos io
4 . Sobrecarga

Polimorfismo de incluso
o pol imorfi smo de incluso, s vezes chamado de poli morfismo puro, permite que voc trale obj etos relacionados genericamente. Voc viu o poli morfismo de incluso pela prime ira vez, no
incio do dia.
Considere os mlodos a seguir:

publ 1c v01d makeSpeak( Pess1mist1cObject ob j )


System.out.println( obj.speak() ) ;
}
publ1C v01d makeSpeak( OptimisticObject obj )
System .out . println( obj.speak( ) );

public v01d makeSpeak( Introve rtedObject obj ) (


System.out.println( obj . speak() ):
}

pub l ie void makeSpeak( ExtrovertedObject obj ) (


System.out.println( obj . spe ak() ) :
}

Pess1m1sticObject, OptimisticObjeet . IntrovertedObjec t e Ext rovertedObject esto todos


rel acionados, pois lodos eles so objetos Persona 11 tyObj eet. A capaci dade de substituio e o
polimorfi smo de incluso pennitem que voc escreva um mtodo para manipu lar lodos os tipos
de objctos Persona1 1t yObject:
pu bl 1c void makeSpeak( PersonalityObjec t obj )
System.out.p rin tln( obj.speak() ) ;
}

Po lim o rfismo: aprendendo a prever o futuro

127

A capac idade de substit uio permite que voc passe qualq uer objelo Persona I i tyObject para
o mtodo e o polimorfi smo gara nte que o metodo correto seja chamado na instncia. O polimorfismo chamar o mtodo com base no tipo verdadeiro da instncia (Optimi s t icObjec t.
IntrovertedObject . ExtrovertedObject ou Pess imisticObject) e no cm seu tipo aparente
(Persona 1i tyObject).
O pol imorfis mo de inc luso lltil porque di minui a quantidade de cdigo que precisa ser escrito.
Em vez de ter de escrever um mtodo para cada ti po concreto de Personal i tyObject, voc pode
simplesmente escrever um mtodo que manipule todos os tipos. O polimorfismo de incl uso e a
capacidade de substituio permitem que makeSpeak() funcione cm qualquer objeto que 'sej a
um ' Persona 1ityObj ect.
O po limorfismo de incluso torna mai s fcil adicionar novos subtipos em seu progra ma, pois
voc no precisar adicionar um mtodo especificamente para esse novo tipo. Voc pode simplesmente reut ilizar makeSpeak{).
O polimorfismo de incluso tambm interessante porque faz parecer que as instncias de
Personal i tyObjec t exibem muitos comportamentos diferentes. A mensagem apresentada por
makeSpeak () ser di ferente de acordo com a entrada do mtodo. Atravs do uso cuidadoso do p0li morfismo de incluso, voc pode mudar o comportamento de seu sistema, introduzindo novas
subclasses. A melhor parte que voc pode obter esse novo comportamento sem ler de alterar
nen hum cd igo j existente.

O polimorfismo o mot ivo pelo qual voc no deve associar automaticamente herana com reutili zao de implementao. Em vez disso, voc deve usar herana principal mente para permitir
um comportamento polimrfico atravs de relacionamentos com capacidade de substituio. Se
voc defin ir corretamente os relacionamentos com capacidade de subst ituio, a reutil izao
ser automt ica. O poli morfismo de incluso perm ite que voc reutil ize a classe base, qualquer
descendente, ass im como os mtodos que usam a classe base.

Agora, voc provavelmente j entende o mecani smo, mas por que desejaria usar pol imorfi smo
de incluso?
Considere a hi erarquia a seguir:
publi c abstract class Baselog {

II al gumas constantes te is ; no s. preocupe com a s i ntaxe


private
private
private
private
private

f inal
f ina l
f i nal
f inal
f inal

static
static
stat i c
s tatl c
s t atlc

String
String
St r ing
St r ing
St r ing

DEBUG
INfO
WARNING
ERROR
fATA L

"DEBUG'"

- MIN fO'"

"WARNING" ;
8ERRQR";
8fATAl'"

java.tex t . Da teformat df java .text.Oate Fonmat.getDateTimeInstance( ) ;

Dia 6

public void debug( St ring message ) {


log( message, DEBUG, getDate() );
}
public void info( Stri ng message ) {
log( message , IN FO . getoa teO , ;
}
public voi d warn;ng( St ring message ) (
l og( message , WARNING. getDate() ) ;
}

publ ic void error( String message ) (


log ( message , ERROR , ge tDate() );
}
publi c voi d f atal ( String message ) (
log( message , FATAL, getoateO );
}

II

cr ia uma indicaao de tempo


protected String getDateO {
java.u t il. Date date" new java.util.DateO;
return df.format( date );
}

II

permite que as s ubclasses def i nam como e onde vo gravar o l og


protected abstract vo i d l og( St ring mess age, String leve I . St r i ng t ime ,;

BaseLog um log abstraio que define a interface pblica de um log, assim como alguma implementao. Ba se Log abstraIo porq ue cada desenvol vedor precisa personalizar o modo como o
log gravado. Todo desenvolvedor de Baselog deve definir o mtodo logO.
Tomando a classe abstrata, voc garante que todo desenvolvedor implemente as subclasses corretamente. Tal estratgia permite que voc rellti Iize o projeto do log entre muitos aplicali vos diferentes. Quando um novo aplicativo aparecer, voc poder simpl esmente fornecer a
implementao necessria para esse apli cat ivo. No h necessidade de criar um novo projeto de
logo Em vez disso, voc pode reutilizar o projeto de log delineado em Baselog, fornecendo implementaes personali zadas.
publi c cla ss Filelog extends Baselog {
private ja va .i o.Pri ntWriter pw ;
public Fi l elog ( Stri ng filename )throws java.i o. IOExcepti on {
pw new java.io . PrintWriter( new java.i o. FileWriter( f ilename ) , ;
}
protected void log( St r ing message , String leveI . Stri ng ti me) {
pw . pr in tln( l eve l + "; " + t ime +
+ message );
M;

Po lim o rfismo: aprendendo a prever o futuro

129

pw. flush();
}

public void close() (


pw.c1ose() ;
}

pu bl i c class Screenlog ex tend s Baselog (


protected void log( St ring message , String leve l , String time) (
System. out.println( l eve l + "; " + ti me + ": " + message ) ;
}
}

Fi 1elog e Screenlog herdam de Baselog e implementam o mtodo 1og(). Fi 1elog grava em um


arqu ivo, enquanto Screenlog escreve na tela.
Lembrando do exemplo Emp l oyee do Dia 4, razovel suspe itar que exi sta urna classe que sa iba
corno recuperar objetos Emp10yee a partir de um banco de dados:
pub1ic cla ss Empl oyeeDatabaseAccessor (
private Baselog erro r_log ;
public Empl oyeeDa t abaseAccessor( Basel og l og ) throws InitDBException {
error_log l og;
try (
II a conexo com o banco de dados
I ca t ch( DBExcept ion ex ) I
error_l og. fata l ( "cannot access databa se: " +
ex.ge tMessage() );
throw new Ini tDBException( ex.getMessage() );
}

public Emp10yee ret riev eEmp1oyee( St r ing first name ,String la st name )
throws EmployeeNotFoundException {
try {
II tenta re cuperar o fu ncionrio
return nu11;
} catch ( Emp1oyeeNotFoundExcept ion ex ) {
error_1og.warning ( "cannot loca te employee: " + 1ast_name +
" , " + f irst_name ,;
throw new EmployeeNotFoundException( 1ast_name, first name , ;
}

II etc. , cada mtodo usa error_l og para registrar erros


}

Dia 6

A classe EmployeeDatabaseAccessor recebe um objeto Base l og como argumento em seu constru-

tor. Uma instncia usar esse log para gravar todo e qualquer evento importante. Considere o
mtodo mainO a seguir:
public static void ma i n( Stri ng [] ar gs ) {
Baselog 10g new Screenlog ();
Emp l oyeeDatabaseAccessor eda = new EmployeeOa ta baseAccessor ( 10g ) ;
Employee emp eda. retri eveEmployee ( MEmployee" ,

"Mr .~

Concebivelmente, o mtodo mai n() poderia passar qualquer subclasse de Ba se l 09 para Empl oyeeDatabaseAccessor. Um aplicat ivo poderia fazer o mesmo. EmployeeDatabaseAc cessor
prova de futuro - no que di z respeito ao registro. Talvez no futuro voc precise de um arq uivo
de log que funcione a cada 24 horas ou um que crie um nome de arquivo usando a data. Ta lvez
outro log faa registros em um manipulador de erros, que receba informaes da rede. Quem
pode ter certeza? Entretanto, com O polimorfismo de incluso, voc est pronlo.
Sem pol imorfismo de incluso, voc pred saria de um construtor para cada tipo de log que quisesse fazer o accessor usar. Entretanto, isso no pra a. Voc tambm precisaria trocar cd igo
dentro do accessor. para que ele soubesse qual log deveria usar. Um objeto EmployeeOataba seAccessor que no usasse polimorfi smo, mas quisesse suportar mui tos logs di fe rentes, poderia
ser como segue:
publ i c class Empl oyeeOatabaseAccesso r {
pr ivate Flle log f il e_log;
pr ivate ScreenLog screen_l09;
priva te i nt
log_type ;
/ / a I gumas cons tantes ' tei s'
private f i nal static i nt FILE_LOG "O ;
private final static i nt SCREEN_LOG " 1;
pu bl iC EmployeeData ba seAccessor{ File log 109 ) throws InitDBException {
f ile_l og 109 ;
109_type FI LE_lOG ;
inH();
}

publiC EmployeeDataba seAccesso r( Sc reen Log 10g ) th rows Ini tOBException {


sc reen_l og log ;
l 09_type SCREEN_LOG:
i nH{):
}

publ i C Employee retrieveEmployee ( St r i ng f i r st_name . String la st_name )

Po lim o rfismo: aprendendo a prever o futuro

13 1

throws EmployeeNotFoundExcept ion I


t ry {
II tenta recuperar o funcionr io
return nu11;
) catch( EmployeeNotFoundExcept ion ex ) I
if( 1og_type "" FIlE_lOG ) {
file_1og.warning( cannot locate employee: " +
la st_name + ", " + first_name );
J else if ( log_type ,,~ SCREEN_lOG ) I
screen_1og.warning( "ca nnot locate employee: " +
last_name + ", " + first_name );
}

throw new EmployeeNotFoundException( last name , first name );


}
}

private vold lnlt () throws InitOBException {


try {
II ini cializa a conexo com o banco de dados
) catch( OBException ex ) {
if( log_type Fl LE_lOG ) {
file_log . fatal( "cannot access database :
ex.getMessageO );
) else if ( log_type ... SCREEN_lOG )1
screen_log.fat al( cannot access database:
ex.getMessageO ) ;

throw new In itOBException( ex.getMessage(} );


}

II etc. Cada mtodo usa error_log para registrar erros


}

Voc precisar atual izar Emp 1oyeeDa tabaseAccessor sempre que quiser adicionar suporte a um
novo log. Agora, qual verso voc gostaria de manter?

Polimorfismo paramtrico
o polimorfis mo paramtrico permite que voc crie mtodos e tipos genricos. Assim como o polimorlismode incl uso, os mtodos e tipos genricos pennitem que voc codifique algo uma vez
e faa isso traba lhar com muitos tipos diferentes de argumentos.

Mtodos paramtricos
Embora o polimorfismo de incluso arete o modo como voc v um objeto, o polimorfi smo paramtrico areia os mtodos. O polimorfismo paramtrico penn ite que voc programe mtodos

Dia 6

genricos retirando a referncia de declaraes de tipo de parmetro at o momento da execuo. Considere o mtodo a segui r:
lnt add(lnt a, i nt b)
add() recebe dois intei ros e retoma a soma. Esse mtodo muito explcito; ele recebe dois inteiros como argumentos. Voc no pode passar dois nmeros reais para esse mtodo ou dois objelOS matriz. Se voc tentar, obter um erro em tempo de com pilao.
Se voc quiser somar dois nmeros reais ou duas matrizes, ento deve criar mtodos para cada
ti po:
Matrix add_matrix(matrix a , matrix b)
Rea l addJeal (real a , rea l b)
etc., para cada tipo que voc queira somar.
Seria conveniente se voc pudesse evitar ter de escrever muitos mtodos. Primeiro, ter de escrever muitos mtodos torna scus programas maiores. Voc precisar separar um mtodo para cada
tipo. Segundo, mais cdigo leva a mais erros e a mais manuteno. Voc no quer tornar a manuteno mais difcil do que precisa ser. Terceiro, ter de escrever mtodos separados no modela

add{) naturalmente. E mais natural pensar apenas em tennos de add{) e no de add matrix() e
add_real ().

O polimorfismo de incluso apresenta uma soluo para o problema. Voc poderia declarar um
ti po chamado addab le, que teria um mtodo que soubesse como somar-se a outra instncia de
addable.

O t ipo poderia ser como segue:


publ i c abs tract class Addable (
public Addable add(Addable) ;
J

O novo mtodo seria como segue:


Addable add_addable(Addable a , Addable b)
Retu rn a.add(b)

NOTA

s vezes, o exemplo ant erior referido com o polimorfismo de funAo.

Est tudo bom, tudo bem. Voc s6 precisa escrever um mtodo para somar, entretanto o mtodo
funciona apenas para argumentos de Addabl e. Voc tambm precisa certi fica r-se de que os objetosAddabl e passados para o mtodo sejam do mesmo tipo. Tal requ isito propenso a erros e contrrio ao que a interface implica. De q ualquer modo, voc realmente no resolveu o problcma

Po lim o rfis mo : aprendendo a preve r o futuro

133

original. Voc ai nda precisar escrever mtodos para cada tipo que queira somar, que no seja do
ti po Addabl e. Nem tudo que voc desejar somar ser Addable.

a que o polimorfismo paramtrico entra em ao. O polimorfis mo paramtrico permi te que


voc escreva um e apenas um mtodo para somar todos os tipos. O pol imorfismo paramtrico retarda a declarao dos tipos dos argumentos.
Considere o mtodo reescri to para ti rar proveito do polimorfismo paramtrico:
,dd([T] "

[T] b) , [T]

[T] um argumento exatamente igual a a e b. O argumento [T] espec ifica o tipo de argumento de
a e b. Declarando um mtodo dessa maneira, voc adia a defini o do tipo dos argumentos at o
momento da execuo. Voc tambm notar que a e b devem ter o mesmo [T].

Internamente, o mtodo pode ser como segue:


[T] ,dd([T] "
return a + b j

[T] b)

O polimorfis mo no mgico. Ele ainda espera que o argumento tenha determ inada estrutura.
Neste caso, qualquer argumento que voc passe dever definir + para esse tipo.

NOTA

Determinada estrutura pode ser a presena d e certo mtodo ou operador corretamente definido.

Tipos paramtricos
Levado sua concluso extrema, o poli morfismo paramtrico pode estender seu alcance aos
prprios tipos. Assim como os mtodos podem ter parmetros paramtricos, os ti pos podem ser
eles prprios paramtricos. Consi dere o TA O Queue defin ido no Dia 2:
Queue [T]
void enqueue([T])
[T] deq ueue O
boolean isEmpty()
[T]

,oekO

O Queue um tipo parametrizado. Em vez de escrever uma classe de fil a para cada tipo que gostaria de enfilei rar, voc simplesmente especi fi ca os tipos de elementos que gostaria de enfi leirar,
para conter dinamicamente em tempo de execuo. Originalmente, voc poderia dizer que o objeto Queue era um Queue de Objec t oAgora, oobjeto Queue pode ser um Queue de qua lquer ti po.
Assi m, se voc quisesse annazcnar objctos Empl oyee, fa ria a seguinte declarao:
Queue[Emp l oyeel employee_queue

new Queue [Employee] :

Agora, quando voc usar Queue, s podem usar enqueue() e dequeue () nas inst,'incias de fu ncionrio.

Dia 6

Se tipos paramtricos no forem possveis, voc precisaria escrever uma fil a separada para inteiros, outra para reais e ai nda outra para alien igenas do espao.
Em vez di sso, usando tipos parametrizados, voc pode escrever o tipo uma vez, neste caso uma
fila , e usa- lo para conter todos os tipos possiveis.

NO TA

Polimorfismo paramtrico soa bem no papet, mas h um problema: suporte.


Para aq ueles que esto famitiarizados com Java, os exemplos anteriores podem parecer estranhos. Na verso 1.3, a linguagem Java no tem suporte nativo a tipos parametrizados ou polimorfismo paramtrico em geral. Voc pOde
imitar tipos parametrizados, mas o preo na efi cincia bastante alto. Existem
algumas ext enses Java disponiveis para suporte a polimorfismo paramtrico, entretanto nenhuma de las foi oficialmen te sancionada pe la Su n.
A sintaxe dos exem plos anteriores completamente inven tada. Entre tanto, ela
dem onstra as idias adequadamente.

Sobreposio
A sobreposio um tipo importante de pol imorfismo. Voc viu como cada subclasse de Pe r sonalityObject sobreps o mtodo speakO no incio deste dia. Ent retanto, voc vi u detalhadamente um exemplo ainda mais interessante de sobreposio e polimorfismo no Dia 5.
Especificamente, considere as definics de classe MoodyObject e HappyObject :
publ l c class MoodyObject (

II

retorna o humor
protected Stri ng getMood{) (
return "moody " ;

II

pergunta ao objeto como ele se sent e


public void queryMood() {
System , out.println("I feel " + getMood() + " today! ");

public cl ass HappyObject extends MoodyObject {

II

redef i ne o humor da classe


protected String getMood() {
return "happy";

II

especializao
public voi d laugh() (

Po lim o rfismo: aprendendo a prever o futuro

135

Sys tem. out. pr; nt 1n ("hehehe. .. hahaha... HAHAHAHAHAHA!!!!!");


}

Aqui, voc v que Ha ppyObject sobrepe o mtodo getMood() de MoodyObject. O interessante


que adefi nio de MoodyObject de queryMood( ) faz uma chamada a getMood () internamente.
Voc notar que HappyObjec t no sobrepe o mtodo queryMood(). Em vez disso, HappyObjec t
si mplesmente herda o mtodo como um mtodo recursivo de MoodyObject. Quando voc chama
queryMood() em HappyObject , o poli morfismo da instncia garante a chamada da verso sobrescrita de getMoodO em HappyObject, internamente.
Aqui, o pol imorfismo cuida dos detalhes do mtodo a ser chamado. Isso o libera de ter que redefin ir queryMoodO, para que ele chame a verso correta de getMoodO.
Posteriormente, voc viu como poderia tornar getM oodO abstrato na progenitora:
pub1ic abstract c1ass MoodyObjec t (

II retorna o humor
pro t ected abst ract St r i ng getMood( ) ;

II pergu nta ao obje t o como el e se sente


pub l ic void queryMoodO t
System.out.print1n ( "I fee l " + getMoodO + " t oday!M);
}

Os mtodos abstralos so freq Uentemente referidos como mtodos adiados, poi s voc retarda a
defin io para as classes descendentes. Entretanto, assim como em qua lquer outro mtodo, a
classe que define o mtodo abstraio pode fa zer chamadas ao mtodo. Assim como os mlodos
sobrepostos, o polimorfi smo garantir que a verso correta do mtodo ad iado seja sem pre chamada nas subclasses.

Sobrecarga
A sobrecarga, tambm conhecida como polimorfismo ad-llOc, permite que voc use o mesmo
nome de mtodo para mu itos mtodos diferentes. Cada mtodo difere apenas no nmero e no
tipo de seus parmetros.
Considere os mtodos a segui r, definidos em ja va.1ang.Math:
pub1i c
publ i c
public
pu bl i c

s ta tic
s tat ic
s tati c
s tat ic

int max(i nt a, int b) ;


10n9 max( long a, 10n9 b):
fl oat max(floa t a, float b) :
double max(doubl e a, doub l e b) ;

Dia 6

Os mtodosmax () so todos exemplos de sobrecarga. Voc notar que os mtodosmax( ) di fe rem


apenas no ti po de parmetros.
A sobrecarga lIt il quando um mtodo no defi nido por seus argumentos. Em vez disso, o m

todo um conceito independente de seus argumentos. O mtodo transcende seus parmetros especificas e se aplica a muitos tipos di fe rentes de parmetros. Peguemos o mtodo max (). max()
um conceito genrico que recebe dois parmetros e informa qual ma ior. Essa defini o no
muda se voc comparar intciros, n(mlcros com ponto fl utuante, valores duplos ou a ordem da bi
cada de um bando de pssaros.
A operao + outro exemplo de mtodo sobrecarregado. O conceito + independente de se us

argumentos. Voc pode somar todos os tipos de elementos .

Ne TA

Voc no pode SObrecarrega r ou sobrepor operad ores na linguagem J ava; entretant o, a l inguagem J ava tem alguma sobreca rg a int erna .

Se a sobrecarga no fosse possvel , voc teria que fazer o seguinte:

pub l ic
publ i c
pub1i c
publ i c
publ i c

s ta t i c
s tati c
s ta t i c
s ta tic
stat ic

i nt max_l nt( lnt a. int b } i


10ng max_longe 10ng a. 10ng b ) i
f loat max_fl oa t( fl oa t a, floa t b ) i
doub1e max_doubl e ( double a , doub l e b } i
bi rd max_b i rd ( bi rd a. bi rd b l i

Sem a sobrecarga, voc deve dar a cada mtodo um nome exdusivo. Os mtodos ma x() no
transcenderiam mais seus parmetros. Max deixaria de ser um conceito abstrato. Em vez disso,
voc teria de defi nir o mtodo em tennos de seus argumentos. Ter de cscrever o mtodo ma xO
dessa maneira no um jeito natural de modelar o conceito de max (). Isso tambm fornece ao
programador mais deta lhes para ter em mente.
,

E daro que chamar cada mtodo com um nome diferente no polimrfico. Quando todos os
mtodos comparti lham o mesmo nome, voc obtm comportamento polimrfi co, pois diferen
tes mtodos so chamados internamente, dependendo dos ti pos de parmetros passados. Voc
pode simplesmente chamar max () e passar seus parmetros. O poli morfismo cuidar de chama r a
mtodo correto internamente.
O modo como o polimorfi smo direciona a chamada de mtodo dependc da linguagem. Algumas
linguagens solucionam a chamada de mtodo durante a compilao, enq uanto OUlras vinculam a
chamada de mtodo dinamicamente, em tempo de execuo.

Po lim o rfismo: aprendendo a prever o futuro

137

Converso
Converso e sobrecarga freq entemente andam lado a lado. A converso tambm pode fazer
com que um mtodo parea como se fosse polimrfico. A converso ocorre quando um argumento de um tipo convenido para o tipo esperado, intemamenle.
Considere a definio a seguir:
public f1 0at add( f10at a, f10at b );
add() recebe dois argumentos float e os soma.
O segmento de cdigo a segu ir cria algumas variveis inteiras e chama o mtodo addO:
int iA " 1;
int i B 2:
add(iA,iB);
,

Entretanto, o mtodo add() solic ita dois argumentos float. E a que a converso entra em ao.
Quando voc chama add () com argumentos i nt, os argumentos so convcn idos em valores f10a t pelo compilador. Jsso signi fica que, antes que os argumentos i nt sejam passados para add (),
primeiro eles so convert idos em valores f1 oat. Os programadores Java reconhecero essa converso.
Assi m, a converso faz o mtodo addO parecer polimrfico, pois O mtodo parece funci onar
para valores f 1oa t e int. Conforme voc vi u na ltima seo, tambm seria possivel ter um mtodo add sobrecarregado, da forma:
pub1ic int add(1nt a, 1nt b);
Nesse caso, add (i A, 1B) no resultaria em converso. Em vez disso, o mtodo add () corretamente sobrecarregado seria chamado.

Polimorfismo eficaz
Assim como todos os outros pil ares, o polimorfismo eficaz no aco ntece por acidente. Existem
alguns passos que voc pode executar para garantir um pol im orfi smo eficaz.
O primeiro passo para o polim orfi smo eficaz ter encapsulamento e herana eficientes.
Sem encapsu lamento seu cdigo se torna facil mente dependente da implementao de suas classes. No pcnnita que o encapsu lamento seja destruido. Se o cdigo se tornar dependente de alguns aspectos da implementao de uma classe, voc no poder conectar uma subclasse que
refaa essa implementao. Um bom encapsulamento o primeiro passo para o polimorfi smo.

Dia 6

imponante notar que, nesse con texto, in terface um pouco dife rent e da noo de interfaces Java, embora sejam semelhantes. Aqui, o termo interface
usado para d escrever a lista de mensagens q ue voc pode enviar para um objeto. Todas essas mensagens compreendem a interface pblica de um objeto.
Uma interface Java tambm d efine as mensagens que voc pode enviar para
um o bjeto Java. Quando uma classe Java implementa uma interface, todos os
m todos da int erface se tornam pane da interface pbl ica global da classe.
Enlretanto, a int erface J av a no a nica maneira de definir as mensagens que
voc pode enviar para um objeto. Na linguagem Java, qualquer mtodo pblico d efinido na definio da classe se to rnar pane da interface p blica do objeto. Isso significa que. se uma classe implementar uma interface e definir
mtodos pblicos adicionais. os dois conjuntos d e mtodos se tornar o parte
de sua interface pblica.
Usar interfaces Java ao programar considerada uma boa prtica, pois isso
separa a definio da interface da implementao da classe dessa interface.
Quando voc separa as duas, muitas classes de outro m odo no relacionadas
poderiam implementar a mesma interface. Assim como a herana, os objetos
que compartilham u ma interface comum tambm podem tomar parte em relacio nam entos com capacidade de substituio, mas sem ter de fa zer parte da
mesma hierarquia d e herana .

A herana um fator importante no polimorfi smo de inc luso. Sempre tente estabelecer relacionamentos com capacidade de substituio programando o mais prximo possvel da classe base.
Essa prtica pennitir que mais tipos de objelos participem de seu programa.
Um modo de estimular a capacidade de substituio atravs de hierarquias bem pensadas.
Mova as caractersticas comuns para classes abstraias e programe seus obj etos para lIsar a classe
abstrata e no uma descendente concreta especfi ca. Desse modo, voc poder introduzir qualquer descendente em seu programa.

DICA

Para obter um polim orfis mo eficaz, siga estas dicas:


Siga as dicas d o encapsu lamento e da heran a efi ca zes.
Sempre progra me para a interface e no para a im plementao. Programando para uma interface, voc define especifi camente quais tipos de objetos podem participar de seu progra ma. Ento. o pOlimo rfismo garantir
que esses o bjetos participem corretamente.
Pen se e programe genericamente. Deixe o polimorfi smo se preocupar
com os det alhes especificos. Se voc deixar o pOlim orfi smo faz er seu trabalho. no precisa r escrever muito cdigo. Ele cuidar dos detalhes para
voc!
Defina a base do polimorfismo estabelecendo e usando relacionamentos
com capacidade de substituio. A capacidade de substituio e o polimorfismo garantiro que voc possa adicionar novos subtipos em seu
programa e que o cdigo corret o ser executado, quando esses sUbtipos
fo rem usados.

Polimorfismo: aprendendo a prever o futuro

139

Se sua linguagem fornece uma maneira de separar completam ente a interface e a implementao, favorea esse m ecanismo em detri mento da
herana. Um exemplo d e m ecanism o que permite definir e herdar interface
sem i mplement ao a Java Int erfa ce. Separar os dois permite uma capacidade de substituio mais fl exvel, obtendo-se assim mais oportunidad e
de polimorfismo .
Use classes abstratas para separar a interface da implementao. Todas
as classes no-fo lha devem ser abstratas; programe apenas para essas
classes abstratas.

A discusso anterior focalizou muito as linguagens fortemente tipadas, como Java. Em


uma linguagem fortemente tipada, voc deve deciarar explicitamente o tipo de uma
varivel. Entretanto, algumas linguagens orientadas a objetos, como Sm alltalk. no
tm esse re quisito. Em vez disso, tais linguagens so dinamicamente tipadas. Tipagem
dinm ica significa que voc no precisa indicar explicitamente o tipo de uma varivel,
ao cri-Ia. Em vez di sso, o tipo determi nado dinamicamente, em tempo de execuo.
Assim, basicamente, to da varivel polimrfica .
O polimorfism o um pouco mais simples em linguagens dinamicamente tipadas. As
variveis so automaticamente pol imrficas, pois elas podem conter qualquer valor.
Desd e que o objeto tenha o m todo esperado, ele pode trabalha r de forma pOlimrfica.
E claro que tudo ser destruido, se voc tentar chamar um m todo que no existe !
As l inguagens tipadas so um pouco mais rigorosas. As linguagens di namicamente tipadas permit em que voc trate um objeto de forma polim rfica, desde que ele tenha o
m todo em que voc est interessado. O objeto no precisa pertencer a uma hierarquia de herana especifica. As linguagens fortemente tipadas exigem que o objeto pert ena a uma hierarquia de herana especifica.
Entretanto, os dois casos no so to diferentes assim. O comportamento que real
m ente define um tipo; as linguagens tipadas exigem apenas a presena de todos os
comporta mentos definidos. Assim, os conceit os por trs do polimorfismo em lingua
gens fortemente tipa das e dinmicas so os mesmos. Tudo se re duz a um objeto que
sa be com o executar algum comportamento.
O foco nas linguagen s tipadas d eliberado. Focalizar diretamente a forte tipagem o
obriga a se concentrar no tipo, sem perder os detalhes. Se voc pode entender o polimorfism o em uma linguagem tipada, ento certamente pode entend-lo em uma linguagem no tipada. O inverso parece no ser verdadeiro I
A escolha de foca lizar o tipo tambm pragmtica. A maioria das principais l inguagens orientadas a objetos fortemente tipada.

Armadilhas polimrficas
Ao se usar polimorlismo, ex istem trs annadil has principai s a serem evitadas.

Dia 6

Armadilha 1: mover comportamentos para cima na


hierarquia
Mui to freqUentemente, desenvolvedores inexperientes movero comjX)rtam entos para cima na
hierarquia, para aumentar o pol imorfismo. O entusiasmo em tratar tudo de maneira polimrfica
pode cegar faci lmente um desenvolvedor e resultar em hierarquias mal projetadas.
Se voc mover um comportamento para cima demais em uma hierarquia, nem todos os descendentes podero suportar o comportamento. Lembre-se de que os descendentes nllnca devem retirar funcionalidade de seus ancestrais. No destrua uma boa herana para tornar seus programas
mais pol imrficos.
Se voc tiver vontade de mover comportamentos para c ima na hierarquia, unicamente para melhorar o polimorfismo, pare. Voc est em territrio perigoso.
Se voc encontrar limi taes dema is em sua hierarquia, talvez queira rev-I a. Mova elementos
com uns para classes abstratas; mova fun cional idade por toda parte. Ent retanto, no mova mtodos para cima na hierarq uia, alm do nvel onde eles so necessrios pela primeira vez. Nilo se
habitue a mover comportamentos por capricho, simplesmente para adic ionar suporte polimrfico. Certifiq ue-se de que voc tenha outro moti vo vlido para a mudana. Voc pode ter sorte a lgumas vezes. mas a prtica o pegar posteriormente, e maus hbitos de programao so dificeis
de perder.
Ao desenvolver suas hierarquias, importante considerar a evoluo em potencia l das classes,
com o passar do tempo. Voc pode divid ir a hierarquia em nveis func ionai s. Com o passar do
tempo, voc pode evoluir sua hierarq uia, adicionando novos nveis funciona is, quando eles forem necessrios. Entretanto, voc s deve especular com base nos requi si tos fut uros que conhece. Exi ste um nmero inl1nito de 'e se' indefi nidos. Planeje apenas as eventua lidades que voc
conhece.

Armadilha 2: sobrecarga de desempenho


Tudo tem um preo. O verdadei ro polimorfismo sofrer certa sobrecarga de desempenho. O polimorfismo no pode competir com um mtodo que conhece seus argumentos estaticamente. Em
vez di sso, com o polimorfismo, devem haver verificaes em tempo de execuo. Para o po limorfi smo de incluso, a implementao real do objeto para o qual voc envia mensagens deve
ser determinada em tempo de execuo. Todas essas veri ficaes levam tempo para terminar e
so mais lentas em comparao aos valores que conhecem seus ti pos estaticamente.
As vantagens da manuteno e da nexibilidade do programa devem compensar qualquer perda
de desempenho. Entretanto, se voc estiver escrevendo um aplicativo em que o tempo seja importante, talvez precise tcr cuidado ao usar pol imorfismo. Entretanto, mantenha o desempenho
em perspectiva. C rie uma implementao 00 limpa, trace o perfil da implementao e oti mize
cuidadosamcnte o desempen ho, onde o traado do perfil revela problemas.

Po lim o rfismo: aprende ndo a prever o f utu ro

14 1

Armadilha 3: vendas

o polimorfismo de incl uso tem uma de fi cincia. Embora seja verdade que voc pode passar
uma subclasse para um mtodo que est esperando uma classe base. o mtodo no pode tirar proveito de todos os novos mtodos que a subc lasse possa adicionar em sua interracc. Porcxcmplo,
a classe Fi 1elog ad iciona um mtodo c1oseO em sua interface. O mtodo retrieveEmpl oyeeO
de EmployeeOatabaseAccessor no poder uslo. Um mtodo programado para acei tar a classe
base s saber manipular a interrace da classe base.
A Figura 6.2 mostra como a visual izao de uma instncia relat iva. Optar por ver uma instncia
de Fi 1eLog como se fosse uma instncia de BaseLog corno colocar vendas nos olhos. Voc s
tem acesso aos mtodos declarados em Base Log. claro que, se voc tratar da instncia de Fil e
Log como uma instncia de Fi 1eLog, obter toda a funcionalidade definida ou herdada pela classe
Fi 1eLog, como aconteceria normalmente.
FIGURA 6 .2

Di/erellles l"iscs
do mesmo objero.

Basel og bI '" new FileLogl'file') .

Baselog
debugU
InfoU
wll m ingU
error()
fetaltl

FileLog
loseU

InlJl.lnjll de
Filel og

, "-----'=
,
,,
,,

'--'

BllseLog II '" new FileLogl'fi le'):

Assim, quando voc adicionar novos tipos de fonna polimrfica, seu cdigo antigo no poder
usar nenhum dos mtodos novos. Entretanto, o novo cd igo (ou o cdigo atua lizado) est livre
para usar qualquer coisa na inlerrace pblica.
Novamente, essa armad ilha aponta o moti vo pelo qual um descendente nunca deve remover
componamentos de seu progen itor. Um mtodo que conte com o polimorfismo de incluso s
saber como exercer os mtodos defin idos com o ti po que estiver programado para manipu lar.
Se estiver fa ltando um comportamento, o mtodo no funcionar.
Essa armadil ha tambm mostra que simplesmente trocar para um novo tipo em seu programa j
existente, freqUentemente no to fcil quanto poderia parecer. No exemplo do Fi 1eLog, voc
preci sar encontrar um modo de chamara mtodo cl ose(), quando seu programa tiver termina
do com o log.

Dia 6

Advertncias
Existe uma advenncia imponante a ser lem brada ao se considerar o polimorfismo. Cada linguagem implementa o polimorfismo de uma fonna diferen te. Esta discusso esboou as de fi ni es tericas por trs do poli morfismo.
A maioria, se no todas as linguagens, supona polimorfismo de incl uso em algum grau. Por outro lado, poucas suponam o verdadeiro poli morfismo paramtrico. A linguagem Java cenamente no supona polimorfi smo paramtrico. C++ fi nge implemen t-lo.
A maioria das linguagens tem alguma forma de sobrecarga e converso. Entretanto, a implementao exata va i variar de uma linguagem para outra.
Assim, quando voc comear a programar de fonna poli mrfi ca, lem bre-se da teoria, mas prossiga cuidadosamente. Voc no pode evitar as Iim itaes de sua Iinguagem de im pl ementao.

Como o polimorfismo atende os objetivos


da 00
o polimorfismo atende cada um dosobjetivosda poo. O polimorfismo produz software que:
1. Natural
2. Confive l

3. Reut ilizvel

4. Man utenvel
5. Extensve l
6. Oportuno

O polimorfi smo atende esses objet ivos das seguintes maneiras:

Natural: o po li morfismo permite que voc modele o mundo ma is nattlr'dlmente. Em vez


de programar para casos especiais, o pol im orfis mo permite que voc trabalhe em um nvel mais genrico e conceit uaI.
A sobrecarga e o polimorfismo paramtrico perm item que voc mode le um objeto ou mtodo em nvel conceituai do que esse objetoou mtodo faz e no de quais tipos de parmetros ele poderia processar. O polimorfi smo de incluso permite que voc manipule tipos
de objetos, em vez de implementaes especficas.

Tal programao gencrica c mais natural, pois ela o libera para programar no nvel
concei tuai do problema e no nas im plementaes especficas.
Confivel: o poli morfismo resulta em cd igo confi vel.

Po lim o rfismo: aprendendo a prever o futuro

143

Prime iro, polimorfismo sim pl ifica seu cdigo. Em vez de ter de programar casos especiais de cada tipo de objeto que poderia manipular, voc escreve simplesmente um caso.
Se voc no pudesse programar dessa maneira, teria de atualizar seu cdigo sempre que
adicionasse uma nova subclasse. Ter de atualizar cdigo algo propenso a erros.
Segundo, o polimorfismo pennite que voc escreva menos cdigo. Quanto menos cdigo
voc escreve, menores as chances de introduo de erros.
O polimorfismo tambm pennite que voc isole partes do cdigo das alteraes das subclasses, garantindo que elas tratem apenas com os nveis da hierarquia de herana im portantes para sua funo.
Reutilizvel: o polimorfismo auxilia a reutili zao. Para que um objcto use outro, ele s
precisa conhecer a interface do segundo objeto e no os detalhes da implementao.
Como resultado, a reutilizao pode ocorrer mai s prontamente.
Manutenvel: o po limorfismo auxilia a manutenibilidade. Conforme voc j viu, o polimorfismo resulta em menos cd igo. Assim , h menos para manter. Quando voe precisa
manter cd igo, no obrigado a manter grandes estruturas condiciona is.
Extensve l: o cdigo poli mrfico mais extensvel. O poli morfi smo de incluso perm ite
que voc adicione novos subtipos em seu sistema, sem ter de alterar o sistema para usar o
novo subtipo. A sobrecarga perm ite que voc adicione novos mtodos, sem terde se preocupar com conflitos de atribuio de nomes. Finalmente, o polimorfismo paramtrico
pennite que voc estenda automaticamente suas classes, para suportar novos tipos.
Oportuno: o pol imorfismo oajuda a escrever cdigo oportuno. Se voc pode escrever menos cd igo, ento pode distribui r seu cd igo mais cedo. Como o polimorfismo o estimula
a programar genericamente, voc pode adicionar novos tipos quase que instantaneamente
em seus programas. Como resultado, a manuteno e a extenso de seus programas ocorre em um ritmo muito mais rpido.

Resumo
Polimorfi smo ter muitas formas. O polimorfismo um mecanismo que permi te a um nico
nome representar cdigos diferentes. Como um ni co nome pode representar cdigos diferentes,
esse nome pode expressar muitos comportamentos diferentes. O polimorfismo permite que voc
escreva cdigo humorado: cdigo que exibe diferentes comportamentos.
Para os objetivos deste livro, voc aprendeu a respeito de quatro diferentes tipos de polimorfismo:

Polimorfismo de incluso
Polimorfismo paramtrico

Sobreposio
Sobrecarga

Dia 6

Embora exista certo desacordo em relao ao polimorfismo na comun idade de 00, esses tipos
descrevem algumas das fonnas mais comuns de pol imorfismo. Entender esses tipos proporcionar a voc uma boa base na teoria de polimorfismo.

O pol imorfismo de incluso permi te que um objeto expresse muitos comportamentos diferentes,
em tempo de execuo. Do mesmo modo, o pol imorfi smo paramtrico permite que um objetoou
mtodo opere com vrios tipos de parmetro diferentes.
A sobrepos io permi te que voc sobreponha um mtodo e saiba que o polimorfi smo garantir
que o mtodo correto sempre ser executado.
Fi nalmente, a sobrecarga pennite que voc declare o mesmo mtodo vrias vezes. Cada declarao
difere simplesmente no nmero e no tipo de argumentos. A converso faz um mtodo parecer polimrfico, convertendo argumentos nos tipos de argumentos esperados pelo mtodo.
O polimorfismo permite que voc escreva cdigo mais curto e mais inteligivel, que tambm
mais fle xvel para os requisitos futuros.

Perguntas e respostas
P Existem trs pilares na programao orientada a objctos. Se cu no usar todos os

trs, meu software nllo ser OO?


R No min imo, voc sempre deve usar encapsulamento. Sem encapsulamento, voc real-

mente no ter herana eficaz, polimorfismo ou 00 em geral. Quanto aos outros dois pilares, voc s deve us- los quando fi zer sent ido. No use herana ou polimorfismo
apenas para que voc possa dizer que os uti lizou em seu programa.
A ausncia de herana e polimorfismo no significa que um programa necessariamente
no-OO. Entretanto, voc precisa dar uma boa olhada em seu programa, para ver se est
desperdiando uma oportunidade de lIsar corretamente os outros pilares.
P Por qu e existe tanto desacordo cm relao ao polimorfismo na comunidade de OO?
R H muito desacordo na literatura que ainda precisa ser acertado. Parece que cada autor
tem seu prprio vocabulrio . Grande parte desse desacordo provm do fato de que cada
linguagem im plementa o polim orfismo de sua prpria manei ra. Todas essas diferentes
implementaes tm dividido a comunidade.

O importante que voc entenda os quatro tipos apresentados hoje. Embora eles possam
receber nomes diferentes, esses quatro tipos so bastante reconhecidos.

P A linguagem Java vai suportar polimorfismo paramtrico?


R Somente a Sun pode responder essa pergunta . Entretanto, atualmentc existe um Java
Specificat ion Request (JSR-OOOO 14), que fo i aceito para desenvolvimento. Ele acrescenta tipos genricos na linguagem de programao Java. Assim, a coisa est a caminho!

Po lim o rfismo: aprendendo a prever o futuro

145

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respostas no Apndice A, "Respostas".

Teste
I. Qua is so os quatro tipos de polimorfi smo?

2. O que o poli morfismo de incluso perm ite que voc fa a?


3. Como a sobrecarga e o polimorfi smo paramtrico mode lam mais naturalm ente o mundo
real?
4. Ao programar, por que voc deve programar para uma interface, em vez de para uma implementao?
5. Como o polimorli smo e a sobreposio trabalham j untos?
6. Qual outro nome para sobrecarga?
7. De fi na sobrecarga.
8. Defi na polimorfis mo paramtrico.
9. Quais so as trs armad ilhas associadas ao pol imorfi smo?
10.

Como o encapsulamento e a herana afetam o polimorfismo de incluso?

Exerccios
I. D um exemplo rea l de situao de programao onde voc acha que poderia usar polimorfi smo de incluso. Pode ajudar pensar em algo que voc tenha programado anteriormente, que pudesse ti rar prove ito do pol imorfi smo.
2. D um exem pl o de converso. Explique por que se trata de converso.
3. Exam ine as APl s Java. Encontre um exempl o de sobrecarga e ex pliq ue-o. Em seguida,
encontre uma hierarqu ia de classes que voc poderia destacar para polim orfi smo de inclu so. Identi fiq ue a hierarq uia e expliq ue como voc pode aplicar polimorfismo de inc luso nela.

SEMANA

DIA
Polimorfismo: hora de escrever
algum cdigo
Ontem, voc aprendeu a respeito do polimorfi smo. Voc deve ter um bom entendi mento dos
quatro diferentes tipos de polimorfismo. Hoje, voc ganhar experincia prtica com o polimorfi smo, alravs de vrios exerccios de laboratrio. No final da lio de hoje, voc dever se sentir
vontade com a teoria apresentada no Dia 6, " Polimorfismo: aprendendo a prever o futuro",
Hoje voc aprender:

Como aplicar as diferentes formas de polimorfismo

Como escrever software prova do fu turo

Como o polimorfi smo pode ajud- lo a evitar a troca da lgica

laboratrio 1: aplicando polimorfismo


No Dia 5, o Laboratrio 2 apresentou uma hierarquia de funcionri os. A Listagem 7.1 apresenta
uma classe base E111> loyee ligeiramente alterada.

LISTAGEM 7.1

Empl oyee .j ava

publi C abstracl class Employee {


private String f i rst_name ;
private String las t _name ;

Dia 7

1 148

LISTAGEM 7 .'

Empl oyee. java (continuao)

pri va te doub le wage :


public Empl oyee ( Stri ng first_name. String la st_name . double wage ) I
th is.f irst_name = first name;
th is . las t name z last name;
this.wage wa ge :
}

public double getWage() {


return wage:
}

public String getFirstName() {


return fir st_name;
}

publ iC Str ing getlastName() {


return last_name :
}

publiC abstract double ca lculatePay( ) ;


public vo id printPaycheckO I
String full_oame " l ast_name +
+ first_name ;
System. out. pr i nt l n( "Pay: + full _name + " $" + cal cul atePay() ):
lO,

"

}
}

A nova classe Empl oyee tem agora um mtodo abstrato ca 1cul atePay() . Cada subclasse deve defini r sua prpria imp lementao de ca 1cu 1atePay (). As listagens 7.2 e 7.3 apresentam duas possveis subclasses.
LISTAGEM 7 .2

Corrm i ss ioned Emp loyee.java

publ i c cl ass CommissionedEmployee extends Employee {


priva te double conmi ss i on : II o custo por uni dade
private int
units:
II contro la o nmero de unidades vendidas
publiC CommissionedEmployee ( String first_name . String la st_name .
double wage , double conmission ) {
supe r ( fir st_name . l ast_name. wage ):
II chama o const ruto r origina l para in ic ia lizar corret amente

Polimorfismo: hora de escrever algum cdigo

LI STAGEM

7.2

Colt'lt1i ss ionedEmployee.java (continuao )


th lS.commiss i on

commission ;

public double calculatePay() (


return getWage() + (commission * units );
}

pub11C void addSales( int units ) {


th1s.unlts thiS.units + un1ts;
}

publiC lnt getSales() {


return units;
}

public void resetSales() {


unit s O;
}
}

LISTAGEM

7.3

HourlyEmp l oyee.java

public class HourlyEmployee extends Employee (


pri vate int hours; II controla o nmero de horas trabalhadas
publiC HourlyEmployee ( String first_name. String last name .
double wage ) {
supere first_name . last_name, wage );
II chama o construtor origina l para i nicializar corretamente
}

public double calculatePay () {


return getWage()* hours ;
}

publlc void addHours( int hours ) {


this.hours this.hours + hours;
}

public int getHours() {


re turn hoursj

149

Dia7

1 150

LISTAGEM 7.3

HourlyEmployee.java (continuao )

I
public vo id resetHours() I
hours = O;

I
I
Cada subclasse fornece sua prpria im plementao de cal cul atePay(). HourlyEm ployee simplesmente calcula o pagamento mu ltipl icando as horas lI balhadas pe la taxa horria. Um objeto
Conm; ss; onedEmp 1oyee recebe o sa lrio-base, mais um bnus por cada unidade vendida. Cada
subclasse tam bem ad iciona alguns mtodos prprios. Por exemplo, Hour IyEmp 1oyee tem um mtodo para reconfigurar as horas. Do mesmo modo, Conmiss i onedEmployee tem um mtodo para
adicionar vendas.
Conforme voc aprendeu no Dia 4, " Herana: hora de escrever algum cdigo", Conmi ssionedEmployee e Hourly Employee permitem que as instncias das duas classes compartilhem um
relacionamemo com capacidade de substituio. Voc pode usar uma instncia de Conmi ss ionedEmp loyee ou uma instnc ia de HourlyEmployee, em lugar de Emp l oyee. Entretanto, o que o per
li morfismo permite faze r?
Considere a classe Payroll, apresentada na Listagem 7.4.
LISTAGEM 7.4

Pay r oll. java

public class payroll I


private int
total_hours;
private int
t otal_sales ;
private double total_pay;
public void payEmployees( Employee (] emps ) I
for( int i O; i < emps . length; i ++ ) {
Emp l oyee emp = emps [i];
total_pay +z emp.calculatePay{) ;
emp.printPaycheck();

I
pub li c void recordEmployeeln fo( CommissionedEmployee emp ) (
total_sales += emp.getSales() ;

I
publiC void recordEmployeelnfo( Hourly6mployee emp ) I
total _hours +- emp.getHours();

Polimorfismo: hora de escrever algum cdigo

LISTAGEM

7.4

151

Payroll. java (continuao)

public void pri ntReport() I


System.out.pr int ln( "Payroll Report:"
System.out.println( "Total Hours: " +
System.out.println( "Total Sales: " +
System.out.prin t ln( "Total Paid: $" +

);
total _hours ) ;
total_sales ) ;
tota l_pay );

}
}

ALERTA

Mtodos get e set em demasia indicam um mal projeto 00. Em gera l, voc
quer so licitar os dados de um objeto muito raramente. Em vez disso, voc deve
pedir para que um objeto faa algo com seus dados.
No exemplo de funcionrios, ter ia sido uma 00 melhor se passasse para o ob
jeto Emp 1oyee um objeto Report, onde ele pudesse registrar suas horas. vendas
etc. Embora isso fosse uma 00 melhor, teria se desviado do exemplo.
A 'boa 00' tambm relativa. Se voc estiver escrevendo ob jetos genricos que sero usados em m uitas situaes diferentes, talvez que ira adicion ar m todos get / set. para q ue possa manter a interface da classe fci l de
ger enciar.

Considere o mtodo payEmployees( Employee [] emps ). Os relac ionamentos com capacidade


de substituio permitem que voc passe qualquer subclasse de Emp I oyee para o mtodo. Geralmente, esse mtodo trata objetos HourlyEmpl oyee e CorrmissionedEmployee como simples instncias de Employee.
O polimorfismo o que torna esse exemplo interessante. Quando os mtodos payEmployeesO
dizem
total_pay += emp.calculatePay()
o polimorfismo faz parecer que Employee tenha muitos comportamentos diferentes. Quando
emp.ca I cul atePay() chamado em um objeto que realmente um HourlyEmp loyee, ca I cu l atePayO calcu la o pagamento, multipl icando a taxa horria pelo nmero de horas trabalhadas. Do
mesmo modo, quando a instncia subjacente um objeto Conmiss i onedEmployee . calcu l atepay() retorna o salrio mais todos os bnus de vendas.
payEmployeesO um exemplo de polimorfismo de incll/so. Esse mtodo fu nciona para qualquer funcionrio. O mtodo no precisa de cdigo especial, voc no precisar alual iz-Io cada
vez que ad icionar uma nova subclasse em seu sistema - ele si mplesmente funciona para todos
os objetos Emp I oyee .

Dia 7

Mtodos como
recordEmployeelnfo( CommlsslonedEmpl oyee emp )

e
recordEmployeelnfo( Hour1 yEmployee emp )
demonstram a sobrecarga. A .wbrecarga permite que um mtodo parea ser polimrfico. Por
exemplo, ela permite o segu inte:
Payroll payroll new Payrol1() ;
Commi ssioned Employee empl = new Corrmi ssionedEmployee( "Mr. ". "Sales ".
25000.00 , 1000.00);

Hou r1 yEmp1oyee emp2 new HourlyEmployee( "Mr." , "Minimum Wage" , 6.50 ) ;


payroll.recordEmp loyeelnfo( emp2 ) ;
payroll . recordEmp10yeelnfo( emp l ) j
recordEmp 1oyee I nfo () parece ser pai imrfico. pois pode manipular os dois tipos de funcionrio.
A sobrecarga um pouco mais limitada que o polimorfismo de inc luso. Com o polimorfismo de
incl uso, voc viu que precisava apenas de um mtodo, payEmpl oyees(), para calcular o pagamento de qualquer objeto Emp 1oyee. Independentemente de quantas subclasses de Emp1oyee voc
introduza, o mtodo sempre funcionar . Esse o poder do pol imorfismo de incl uso.
Os mtodos que empregam sobrecarga no so to robustos assim. Pegue como exem plo o mtodo recordEmp loyeelnfo(). Sempre que voc adicionar uma nova subclasse na hierarquia
Empl oyee, ter de adicionar um novo mtodo recordEmp1oyeelnfo() para o novo tipo. Embora
alguns mtodos extras possam ser aceitvei s para uma hierarquia peq uena, talvez voc tenha de
refazer sua hierarquia, para que possa escrever um mtodo recordEmpl oyee lnfo() genrico,
quando o nmero de subc lasses de Employee aumentar.
A Listagem 7.5 fornece um pequeno mtodo principal que executa os mtodos Payroll.
LISTAGEM 7.5

Payro 11 Dri ver . ja va

pub li C cl ass PayrollDri ver (


publi c static vO l d maln( String [J args ) (

II cr ia o sistema de fo lha de pagamento


Payroll payrol1

new Payrol l () ;

II cria e atuallza alguns funcion rios


COIlI1lissionedEmp1oyee emp l - new Corrmi ssionedEmployee( "Mr.", "Sa l es ",
25000.00 , 1000 .00),

CommissionedEmpl oyee emp2 new COIl1lli ssionedEmp1oyee( "Hs." , "Sa les - ,


25000 . 00, 1000.00),

empl . addSales( 7 );
emp2. addSa les( 5 );

Po lim o rfi s mo: hora de escrever algum cdi go

LISTAGEM 7.5

153

Payro110river . java (continuao)

HourlyEmployee
HourlyEmployee
emp3 . addHours(
emp4.addHours(

emp3 .. new Hour l yEmployee( "Hr . " , "Hinimum Wage" , 6.50 ) ;


emp4 .. new Hour l yEmployee( "Hs." , "Hin i mum Wage" , 6.50 );
40 ) ;
46 );

II usa os mtodos sObr eca rregados


pay roll.recordEmployeeI nfo(
payroll.recordEmployeel nfo(
payroll.recordEmployeel nfo(
payroll.recordEmployeel nfo{

II coloca os

emp2
emp l
emp3
emp4

);
);
);
);

fu n cio n ~ ri os

em um array
Empl oyee [] emps new Empl oyee [4];
emps[O] .. emp l; emps [l] " emp2 ; emps [2]

emp3 ; emps[3] .. emp4;

payroll. payEmployees ( emps ) i


payroll.printReport() j

I
I
A Figura 7. 1 mostra a sada do mtodo pri ncipal.
FIGURA 7.1
A Si/ida correia de
Payro 11 Ori ver.

Se voc percorrer o cdigo e calcu lar manual mente o pagamento de cada funci onrio, ver que
payEmp 1oyees () paga o valor correiO. Do mesmo modo, todas as info nnaes de funcionrio so
correlamente gravadas.

Dia 7

Exposio do problema
No D ia 5, voc trabalhou com objetos MoodyObject. A Lis tagem 7.6 aprese nta uma classe
HoodyObject ligeiramente mod ificada.
LISTAGEM

7.6

MoodyObject . java

publiC abstract class MoodyObject (

II

retorna o humor
protected abstract String getMood() ;

II

pergunta ao objeto como ele se sente


publ ic void queryMood() (
System.out.println( " I feel " + getMood() + " today!!") :

I
I
As listagens 7.7 e 7.8 apresentam duas subclasses: HappyObject e SadObject.
LISTAGEM

7.7

HappyObject . java

public class HappyObjec t extends MoodyObject (

Ilredefine

o humor da classe
protected String getMood() I
return "happy;

I
Ilespecializao
public void laugh() {
Sys tem . ou t. pri nt l n (" hehehe. .. hahaha. .. HAHAHAHAHAHA!!!!!") ;

I
I

LISTAGEM

7.8

SadObject.java

publiC c l ass SadObject extends MoodyObject {

II

redefine o humo r da classe


protected Stri ng getMood() {
return "sad":

I
II

especializao

Polimorfismo: hora de escrever algum cdigo

LISTAGEM 7 .8

155

SadObject.java (conti nuao)

publiC vo ld cry{) (
Sys t em.out.println("'wah' ' boo hoo ' 'weep' ' sob ' ' weep'");
J
J

Sua tarefa praticar o pol imorfismo. Escreva uma classe Psychiatri stObject. Psychiat ri s tObj ect deve ter trs mtodos. exami ne () deve pegar qualquer instncia de MoodyObject e
perguntar como ela se sente. Psychi atri stObjec t tambm deve ter um mtodo observe() sobrecarregado. observe{) deve chamar os mtodos cry() ou laughO do objelo. A classe PsychialristObjecl deve tecer um comentrio mdico para cada comportamento.
Certi fi que-se de usar a classe PsychiatristDriver forn ecida, para testar sua soluo!

A prxima seo discutir as solues do Laborat ri o 1. No prossiga at concluir o Laboratrio 1.

Solues e discusso
A Li stagem 7.9 apresenta uma passivei classe PsychiatristObject.
LISTAGEM 7 .9

Psychiatr i stObjec t. java

public cla ss PsychiatristObject {

II usa polimorfismo de incluso para examinar todos os objetos humor


II genericamente
pu bl ic vo i d examine(MoodyObject obj ) {
Sys tem . out . prlnt ln( "Te11 me, object , how do you feel t oday ?" )i
obj . queryMood () ;
System . out.print ln() ;
J

II usa sobrecarga para observar objetos especificamente.


II mas com um mtodo chamado generi camente
pub l ic voi d observe( SadObject obj ) (
obj.cry() j
Sys t em. out.print ln(
"Hnm . .. very . ve ry interest i ng. Some th i ng makes thi s object sad." );
System.out . println()j
J

Dia7

1 156

LISTAGEM 7 .9

Psychi atri stObjec t.j ava (continuao)

publiC void observe{ HappyObject obj ) (


ob j . laugh();
Sys tem.out.println(
MHmm .. very . very i nteresti ng. This object seems ve ry
System.out .print ln() ;

ha ppy.~

);

J
examine como ( MoodyObjec t obj ) trata todos os obj etos MoodyObject genericamente. O objeto
PsychiatristObject pergunta ao objeto MoodyObject como ele se sente e chama seu mtodo
queryMood O. O objeto Psychi atri stObject precisa de um mtodo observe O para cada lipo de
objcto MoodyOb ject que gostaria de observar.
Aps concluir este laboratrio, voc dever comear a se sentir vontade com os mecani smos
bsicos do polimorfi smo.

laboratrio 2: conta de banco


aplicando
polimorfismo em um exemplo conhecido
No Laboratrio 2, voc vai pegar o que aprendeu no Laboratrio 1 e aplicar em um problema li
ge iramente mais compl icado. Este laboratrio focaliza a hierarquia BankAccount, apresentada no
Dia 5. A hierarquia apresentada aqui continua quase igual quela apresentada no Dia 5. A nica
diferena que agora BankAccount uma classe abstrata. Voc no pode mais instanciar um objeto BankAccount diretamente.
Tornar BankAccount abstrata modela mai s precisamente o funcionam ento de con tas bancrias. Quand o voc abre urna conta, abre uma conta de cheque ou urn a co nta de mercado fin anceiro. Voc no abre uma conta de banco genrica. A Li stagem 7.10 li sta a ni ca mudana na
hierarquia.
llSTAGEM 7 .10

BankAccount.java

pub li c abst ract cl ass Ba nkAccount {


II o restante igu al
J

Polimorfismo: hora de escrever algum cdigo

157

Exposio do problema
Neste labormrio, voc precisa escrever uma classe 8ank. A classe Sank tem vrios mtodos.
As instncias de 8ank contm contas. Entretanto, voc precisa de uma maneira de controlar a
quem penencem as contas. addAccount() permite especificar um proprietrio, sem pre q ue voc
adiciona uma nova conta :
publlc YOld addAccount( Str ing name, BankAccount account );
Voc pode usar o nome do propri etrio para acessar a conta correta posteriormente.
totalHol dingsO permite que a classe Bank relate a quantidade total de dinheiro existente no
banco:
pub l ic doub l e totalHoldings() ;
totalHoldingsO deve fazer um lao por todas as contas e totalizar o valor mantido no banco.
total Accounts () permite que voc consu lte a instncia de Bank para ver quantas contas ela poss ui correntemente:
publiC int totalAccounts();
deposi tO permite que voc deposite fundos em uma conta bancria especifica:
public yoid deposite Stri ng name, double amount );
depos i tO um mtodo de convenincia que o li bera de ter de recuperar uma conta especfica,
anlesde poder adicionar rundos ne la. Em vez disso, depos i t () pcnn ite que voc deposite fundos
diretamente atravs do banco.
balanceO permite que voc recupere o saldo de uma conta especifica:
public double balance( Stri ng name )
Assim como depos i t 0 , ba 1ance() um mtodo de conveninc ia.
addAccountO armazena uma conta sob determinado nome. Existem vrias maneiras
de implementar essa fun cionalidade. Entretanto, algumas estratgias so mais fceis
de implementar do que outra s.
Para este laboratrio, voc dever considerar jaya. ut i I . Hashtab I e. Hashtab I e permite
que voc armazene e recupere pares chave/Valor.
Considere esta APl consolidada:
pub1 ic
publ ic
public
publlc

Object get( Object key );


Object put ( Object key, Object ya1ue );
lnt size();
Java . util.Enumeration elementos();

Aqui est um exemplo de Hashtable:

Dia 7

java. ut 11 . Hashtab le tab I e new java. util . Hashtab I e();


table.put( -LANGUAGE-, "JAVA" );
String name table.get( -LAHGUAGE " ) ;
Esse exemplo armazena ovalar JAVA sob a chave LANGUAGE. Para recuperara valor post eri ormente, voc simplesmente chama get() e passa a chave correta .
Estudando a APl, voc notar que os mtodos get () e put () retornam Objecto Assim, se
voc fosse armazenar uma Stri ng, obteria o valor de volta como um Objecto
Na linguagem Java, todos os objetos herdam de Objecto A Hashtable foi escrita
para tratar com Object, de m odo que funcionar para tod os os objet os Java. Entre tanto, e se voc armazenar um objeto CheckingAccount na Hashtable e quiser trat-Ia como um objelo Checki ngAccount, aps recuper -lo? Como voc fari a isso na
linguagem Java?
A linguagem Java fornece um modo de transformar uma referncia de Object de volta
para seu tipo correto. O mecanismo conhecido como converso. A instruo a seguir
invlida na linguagem Java:
CheckingAccount account table.get( "CHECKING ACCOUNT" );
Em vez disso, voc precisa r realizar uma converso, antes de poder armazenar uma
referncia de Object em uma varivel CheckingAccount:
CheckingAccount account " (CheckingAccount) table.get( "CHECKlNG ACCOUNT");
Voc precisa tomar cuidado enquanto converte. A converso pode ser perigosa. Por
exemplo, a converso a seguir invlida:
HappyObject o new HappyObject() ;
lable.put( "HAPPY-, o );
(CheckingAccount) table.gel( "HAPPY - );
Quando voc converte, deve certificar-se de que o Objecl que est convert endo seja realmente do tipo TYPE . Assim, para este laboratrio, quando voc recuperar um objeto
BankAccount da Hashtable, desejar converter para BankAccount. Como exemplo, considere a converslio a seguir:
BankAccount b (BankAccount) table.get( "ACCOUNTl" };
Se voc tentar realizar uma convers o invlida na linguagem Java, ela lana r uma exceo ClassCastE)(ception.

Assim como o Laboratrio I, o Laboratrio 2 fornece um driver para ajud-l o a testar sua soluo. Certifique-se de consultar BankDriver.

A prxima seo discutir as solues do laboratrio 2. No prossiga at concluir o Laboratrio 2.

Polimorfismo: hora de escrever algum cdigo

Solues e discusso
A Li stagem 7. 11 apresenta lima possvel implementao de Bank.
LI STAGEM

7.11 Bank.java

publlc cl ass Bank (


private java.utll .Hashtable accounts

new java.util.Hashtable();

public void addAccount( String name, BankAccount account ) (


accounts .put( name, account ) ;
}

publi C double totaIHoldings() (


double total - 0.0;
java.ut il . Enumeration enum = accounts . elements();
while( enum.hasMoreElements() ) (
BankAccount account ~ (BankAccount) enum.nextElement();
total +- account .getBala nce() ;
}

return to ta 1;
}

public int totalAccounts() (


return accounts.size();
}

publiC voi d deposite Str ing name , double amount l (


BankAccount account - retrieveAccount( name l;
if( account !a null ) {
account.depositFunds( amount l;
}
}

public double balancei String name ) {


BankAccount aCCQunt * retrieveAccount( name );
if( accQunt !- null ) {
return account.getBalance()i
}

return 0.0;
}

private BankAccount retrieveAccount( String name ) {


return (BankAccount) accounts. get{ name l i
}
}

159

Dia 7

Internamente, essa soluo usa java. ut 11 . Hashtab 1e para conter todos os objetos BankAccount.
Em vez de forne<::er seu prprio mean ismo de annazenamento e recuperao, essa implementao tira proveito da reutilizao, utili zando as classes fornecidas pe la linguagem Java.
ba 1ance (), depos i t (), addAccount () e t ota 1Ho 1di ngs (). todos demonstram o pol imorfismo de incl uso. Esses mtodos funcionaro para qualquer subclasse de BankAccount que voc possa criar.
A ps concl uir este laboratrio, voc dever ter uma idia melhor dos mecanismos de pol imorlis-

mo. No Dia 5, os objetos BankAccount mostraram a convenincia da herana. A herana permitiu


que voc cri asse subc lasses rapidamente, programando apenas o que era diferente entre as contas. O polimorfi smo sim plifica ainda mais seu cdigo, fornecend o um mecanismo para programao genrica.

laboratrio 3: conta de banco


usando
polimorfismo para escrever cdigo prova
do futuro
Por toda a discusso sobre pol imorfis mo, voc ouvi u o tenno software prova do futuro. O que
exatamente soft ware prova do futuro? Software prova do futuro simplesmente um software
que se adapta fa ci lmente mudana nos requisitos.
Os requisitos mudam o tempo todo. Quando voc comea a escrever um programa pela pri mei ra
vez, os requisitos podem mudar, enquanto voc aprende mais a respeito do problema que est resolvendo. Uma vez escri to, seus usurios esperaro e exigiro novos recursos de seu software.
Se voc criar so ft ware prova do futuro, no ter de reescrev-lo comp letamente, cada vez que
obt iver um novo requisi to.
Vamos considerar um exemplo de mudana de requisitos. A Listagem 7. 12 apresenta urna nova
classe MoodyObj ect : CarefreeObj ec t.
LISTAGEM

7.12

CarefreeObject.java

pub1ic class CarefreeObject extends MoodyObject {


II redefine o humor da classe
protected Stri ng getMood() {
ret urn "carefree j
M

II especial iz ao
pub1ic void whist le{ ) I
Sys t em . out. print l n{"whi st1e, whist1e, whistle ... );
}

Po limorfismo: hora de escrever algum cdigo


A Li stagem 7. 13 most ra o Psychiatri stOriver atualizado.
LISTAGEM 7.13

PsychiatristDriver.java

public class PsychiatristOriver I


public sta tic void main( Str ing [] args ) I
HappyOb ject happy new HappyObject():
SadObject sad = new SadObjec t( ) ;
Care free Object carefree new CarefreeObject();
PsychlatristObject psychiatrist z new PsychiatristObject();

II usa polimorfi smo de incluso


psychiatrist . examlne( happy ):
psychiatrist.examine( sad ) :
psychiatrist.examine ( carefree ) ;

II usa sobrecarga para que possamos observar os objetos


psychiatrist.observe( happy );
psychiatrist.observe( sad );
}

A Figura 7.2 mostra a saida que voc vera ao executar PsychiatristOriver.


FIGURA 7 .2

A sada correia de
Psychiatri s tOri ver.

161

Dia 7

Aqui , voc v que Psychiatr ;s tObject prova do ful uro. A qualquer momento, voc pode
adi cionar novos objetos MoodyObject, todos com seu prprio comportamento personalizado.
PsychiatrlstObject pode simplesmente usar os novos subti pos.

Voc pode observar que esse exemplo se concentra no mtodo examineO. O


polimorfi smo de incluso possibilita um software realmente prova do futuro.
Entretanto, se Psychi atri s t Object quiser usar observe () em um novo subtipo,
voc precisar atualizar Psychiatri stObj ect tambm.

MoodyObjec t um exemplo simples. Entretanto, tente imaginar corn o voc poderia estender essa
id ia para programas mais complexos!

Exposio do problema
Sua tarefa testemunhar a programao prova do fut uro em primeira mo. No ltimo laboratri o, voc escreveu uma classe Bank. A classe Bank pode trabalhar com qualquer subtipo de
BankAccount. Sua tarefa criar um novo tipo de BankAccount: a Rewa rd sAcount .
Assim como em Savi ngsAccount , a RewardsAccount aplica j uros no saldo. Entretanto, para aumentar
o nmero e o tamanho dos depsitos, o banco gostaria de introduzir um sistema de recompensas.
A RewardsAccount cont rola o nmero de depsitos em relao a certa quantidade de dlares: o
nvel de depsito para recompensa. Por exemplo, digamos que o nvel de depsito para recompensa seja de US$SOO dlares. Sempre que o depositante deposita US$SOO ou mais, ele receber
um poruo de recom pensa.

NeTA

M antenha RewardsAccount simples. Se o nvel de depsito para recompensa for


de US$500 e o depositante depositar US$500, ele receber um ponto de recompen sa. Se o depositante depositar US$3.000, ele ainda dever receber
apenas um ponto de recompensa.

Jun to com os mtodos definidos por BankAccoun t, RewardsAccoun t tambm deve fornecer
um mecanismo para recuperar e recon fi gurar o numero de pontos de recompensa recebidos.
RewardsAccoun t tambm precisa de um modo para configurar e obter o nvel de depsito
para recompensa.
Para este laboratrio, talvez voc queira vol tar ao Dia 5 e reler as descries dc Sav i ngsAccount e
BankAccount . Este laboratrio tambm inclui u
m RewardsAccountor i ver e um BankOri ver atualizados. Certifique- se de us-Ios para testar sua s0luo. Voc tambm desejar ver BankOriver. O BankOri ver demonstra como voc pode adicionar
um novo tipo de objelo em seu programa, sem ter de atualizar qualquer um dos outros objetos.

Polimorfismo: hora de escrever algum cdigo

ALERTA

163

A prxima seo discutir as solues do laboratrio 3. No prossiga at concluir o laboratrio 3.

Solues e discusso
A Li stagem 7. 14 apresenta uma possvel sol uo para RewardsAccount.
LISTAGEM 7.14

Reward sAccount. java

publi c class Rewa rdsAccount extends SavingsAccount {


private double min_reward_balance:
private int quallfying_deposits:
public Reward sAcco unt( double initDeposit. double interest. double min ) {
super( i nitDepos it. interest ) :
min_reward_balance min:

I
publ ic vo i d depositFund s ( doubl e amount ) {
super.deposit Funds( amount ):
if( amount >- min_reward_balance )1
qualifying_deposits++:
}

I
publi c int getRewardsEarnedO I
return qualifying_deposits:

I
publi c voi d resetRewards() {
qual i fyin g_deposi t s O:

I
publ i c doubl e getMi nimumRewardBal ance O {
ret urn min_reward_balance :

I
publi c vo i d setMinimumRewardBalance( doub le min ) {
min reward bal ance : mi n;

I
RewardsAccou nt sobrepe depos i tFunds O. de modo que pode verificar o saldo e os pontos de recompensa. A classe tambm adiciona mtodos para recuperar o saldo das recompensas, recon fi gurar o saldo, assi m como obter e configurar o nvel de depsito para recompensa.

Dia 7

A Listagem 7. 15 apresenta o BankOriver atualizado.


LISTAGEM 7 .15

BankOri ver .java

public class 8ankOriver {


publlc s t atic void main( String [] args ) {
CheckingAccount ca new CheckingAccount( 5000.00 , 5, 2.50 );
OverdraftAccount oa ~ new OverdraftAccount( 10000.00, 0. 18 ):
SavingsAccount
sa new SavingsAccount( 500.00 . 0.02 ):
TimedMaturityAccount tma
new TimedMaturityAccount(
10000 .00, 0.06. 0.05 ):
K

Bank ba nk new Bank( )j


bank.addAccount( "CHECKING", ca ):
bank.addAccount( "OVERORAFT", oa );
bank.addAccount( "SAVINGS" , sa };
bank. addAccount ( "TMA" , tma );
Sys tem.out.println( "Total holdings(shou ld be $25500.0): $" +
bank.totalHoldings() )i
System.out.println( "Total accounts(should be 4): " +
Bank.totalAccountsO ) ;
RewardsAccount ra new RewardsAccount( 5000 . 00 , .05 , 500.00 };
bank.addAccount( "REWAROS", ra };
System.out.print ln( "Tota l holdings(should be $30500 .0): $" +
bank.totalHoldings() ) ;
System .out.println( "Total accounts(shou ld be 5): " +
bank. to ta l Accounts () };
bank.depos1t( "CHECKING", 250 . 00 };
double new_balance bank . balance( "CHECKING " };
Sys t em .out.p r intln( "CHECKING new balance (shou ld be 5250 . 0): $" +
new balance ):

I
I
Para usar a nova classe de conta existem dois passos que voc deve dar.
Para o primeiro passo, voc deve criar seu novo subtipo. Aps criar seu novo subti po, voc precisa aherar seu programa para criar novas instncias do objeto.
No caso de RewardsAccoun t, voc deve atual izar o mtodo mai n () de BankAccount, para criar instnc ias de RewardsAccount. Entretamo, voc no precisa mudar mais nada!

Polimorfismo: hora de escrever algum cdigo

165

Quando voc est iver escrevendo um programa real, percorrer os mesmos passos para introduzir
novos subtipos em seu programa. Primeiro, voc precisar criar o novo subtipo.
Segundo, voc preci sar al terar seu cdigo para que ele possa criar seu novo subtipo. Mas, isso.
Voc no preci sa alterar o restante de seu programa.
Posterionnente, voc ver maneiras de tomar seus programas to flexvei s, que poder nem precisar alterar qualquer cdigo de seu programa para que ele encontre e comece a usar novos subtipos.

laboratrio 4: estudo de caso


estruturas
condicionais Java e polimorfismo
A linguagem Java, assi m como muitas outras, fornece um mecanismo de troca. Considere o mtodo day- of- the- week() a seguir:
public void day_of_the_week(int day ) {
switch ( day ) (
case 1:
System.out.pr in tln ( "Sunday );
break;
case 2:
System.out.prin tln( "Monday ) ;
break;
case 3:
System .out.println ( "Tuesday l;
break;
case 4:
System .out.println( "Wednesday" );
break;
case 5:
System.out.prin tln( "Thursday" );
break;
case 6:
Sys t em.out.println( "Friday" l;
break;
case 7:
System.out.print ln{ "Saturday" )i
break;
default:
System.out.p r i ntln{ day + " is not a valid day. );
break;

I
I

Dia 7

o mtodo recebe um parmetro: um valor inteiro representando o dia da semana. Ento, o mtodo testa todos os dias vlidos da semana. Se o argumento day corresponder a um dos dias, o mtodo imprimir o nome do dia.
Geralmente fa lando, voc usa estnlluras condicionais (case ou i rte1se) para realizar lgica condicionaI. Com a lgica condicional, voc procura certa condio nos dados. Se essa condio for
satisfeita, voc faz algo. Se outra condio for satisfeita, voc faz algo inteiramente diferente. Todos osque tm base procedural devem estar familiarizados com tal estratgia de programao.
Se voc se sente vontade com estruturas condic ionais, hora de desaprender um pouco. A lgica condiciona l geralmente considerada uma m prtica de 00. Na verdade ela to m, que
muitas linguagens 00 no fo rnecem tais estruturas. A lgica cond icional tem uma vantagem;
ela o ajuda a detectar um projeto mal feito!
As estruturas cond icionais so quase sempre ms por natu reza. En tretanto, elas frcqcntemente se insinuam sua frente , pois aparecem em mu itas formas. Considere um mtodo
day_of_the_weekO ligei ramente diferente.
public void day_of_the_week( int day )
iflday"')!

}
}
}
}
}
}
}

System.out.println( "Sunday" );
el se ir ( day == 2 ) I
System.out.println{ "Monday" };
else if ( day 3 ) {
Sys tem.out.print ln( "Tuesday };
else if ( day 4 ) I
System.out.println{ "Wednesday" );
else ir ( day 5 ) I
System.out.print ln( "Thursday );
else if ( day 6 ) I
System.out. println( "Fri day" };
else ir ( day =- 7 ) I
System . out.print ln ( "Saturday" ) ;
else {
System.out.printl n( day + " is not a valid day." };

I
I
Ento, o que h de errado com as estruturas condicionais?
As estrulUras condicionais so contrrias aos concei tos de 00. Na 00, voc no solicita os dados de um objeto e depois faz algo com esses dados. Em vez disso, voc sol icita para que um objeto faa algo com seus dados. No caso do metodo day_of_the_weekO, voc provavelmente
obtem day de algum objeto. Voc no deve estar processando dados brutos. Em vez disso, voc
deve solicitar ao objeto uma representao de string. As estruturas condicionais o obrigam a misturar responsabilidades. Cada lugar que usa os dados ter de aplicar a mesma lgica cond icional.

Po lim o rfi sm o: hora de escrever algum cdi go

167

Existem ocasies em que as cond icionais so absolutamente necessrias. Ento, como voc detecla ' ms ' estruturas condicionais?
Existem meios de saber quando uma estrutura condicional 'boa ' fi ca 'ruim'. Se voc se encontrar atual izando uma estrutura case ou blocos 1fi el se, sempre que ad icionar um novo subtipo,
as chances so de que a estrutura condicional ' ruim'. No apenas isso uma m prtica de 00,
como tambm um pesadelo de manuteno. Voc ter que certificar-se deatua lizar cada condi cionai que teste os dados. Exigir mui to tempo para garantir que voc no se esqueceu de atualizar algo!

Corrigindo uma estrutura condicional


Considere O mtodo a seguir:
pub li c i nt ca l cul ate( Stri ng operao . int operand l. int operand2 ) {
if ( operation.equals( "+" ) ) (
return operandl + opera nd 2;
) el se if ( operat1on. eq uals ( "*" ) ) {
return operandl *operand2;
} el se i f ( operat i on.equals( ~/M ) ) {
return operandl loperand2;
J el se if ( operatlon. equals( "." ) ) I
return ope rand l - ope rand2;
) else (
Sys t em.out.print ln( "invalid oper at ion: + opera t ion ) ;
return O;
J
J

Tal mtodo poderia aparecer em um problema de calculadora. O mtodo calcul ateO recebe a
operao, assim como os dois operandos, como argumentos. Ento, ele efetua o clcul o sol icitado.
Sendo assim, como voc poderia corrigir o problema? Voc pode corrigi-lo com objetos, claro!
Quando voc comear a eliminar lgica condicional , comece com os dados que est testando.
Transforme os dados em um objeto.
Neste caso, voc deve criar objetos ad io, subtrao, mult'i plicao e divi so. Todos esses objetos so operaes. Assim , todos eles devem herdar de uma classe base comum. Con forme voc
j viu por todo este dia, a capacidade de substituio e o pol imorfi smo permitiro que voc faa
algumas coisas inteligentes com esses objetos.
Todos os objetos que voc deve criar so operaes; portanto, voc sabe que precisa de uma classe
base Operati on. Mas o que uma classe Operation faz? Uma classe Ope rat ion calcula algum valor,
dados dois operandos. A Listagem 7. 16 apresenta uma classe Operation.

Dia7

1 168

LISTAGEM 7 .16

Operation.java

publ i c abstract class Operation (


pllblic abstract int cal clll ate ( int operand l. i nt operand2 ):

As listagens 7.17, 7. 18, 7.19 e 7.20 apresentam os vrios objetos operao.


LISTAGEM 7 .17

Add.java

plIbl i c class Add extend s Operati on {


publi c int ca l clllat e( int operandl . int operand2 ) I
retllrn operandl + operand2 :

LISTAGEM 7 .18

Subt ract.java

publi C cl ass SlIbtrac t extends Operation I


pub l ic i nt calcul ate ( int operand I. i nt operand2 ) I
return operandl - operand2 :

,
,

LISTAGEM 7 .19

Mult i ply. j ava

public class Mu l t lply extends Operati on (


public int calc ulat e( int operandl. int operand2 ) {
return operandl * operand2;

LISTAGEM 7 .20

Oivide . ja va

pub l ic cl ass Divide extends Operation (


pub l ic int calcu l ate ( i nt ope rand I. int operand2 ) {
return operandl I ope r and2;

,
,

Cada operao implementa o mtodo ca 1cul ateO de sua prpria maneira. Agora que voc tem
um objelo para cada operao, pode reescrever o mtodo cal cu late() original.

Polimorfismo: hora de escrever algum cdigo

169

public int ca l cu late( Operation operation, int ope randI, int operand2 ) (
return operat i on.ca l culate( operandl , operand2 );

I
Transfonnando a operao em um objeto. voc ganhou muita flexi bilidade. No passado, voc
leria de atualizaro mtodo sempre que quisesse adic ionar uma nova operao. Agora, voc pode
simplesmente criar a nova operao e pass- Ia para o mtodo. Voc no precisa alterar o mtodo
de maneira alguma, para que ele funcione com a nova operao-e le simplesmente func iona.

Exposio do problema
A linguagem Java fornece um operador chamado instanceof. O operador instanceof permite
que voc verifique o tipo subjacente de lima referncia.
String s "somestring"
Object obj = S;
System.out.println( (obj ins tanceof String) ),
Esse segmento de cd igo imprime true. obj contem uma instncia de String. A maioria das linguagens de roo fornece um mecanismo semelhante.
Agora, considere a nova classe Payro 11, na Listagem 7.21.
LISTAGEM

7.21

Payroll.java

public class Payrol1 (


pr; vate i nt
total _hours,
pri vate ; nt
total_sales;
private double total_pay;
public void payEmployees( Employee [J emps ) (
for ( int i - O, i < emps.length; ; ++ ) (
Emp l oyee emp z emps[i];
total_pay +- emp.calculatePay();
emp.printPaycheck();

I
publiC void calculate80nu s( Employee [] emps I I
for( int i .. O; i < emps.length, i++ ) I
Employee emp emps[i] ;
if( emp instanceof HourlyEmp l oyee ) (
System.out. prin t ln(" Pay bonus to .. + emp. getlastNameO +
", " + emp.getFirstNameO + " SIOO.OO." );
I else if ( emp in stanceo f CommissionedEmpl oyee ) {
i nt bonus - ( (Commi ssionedEmployee) emp ).getSales() 100;

Dia7

1 170

Payroll.java (continuao)

LISTAGEM 7 .21

bonus to + emp. getLastName() + ~ " +


emp.get FirstNameO + $" + bonus ):

Sys tem.out. pr in tln(~Pay

I else (
System,ouLprin tln( "unknown employee type

M
):

}
}
}

public vo1d recordEmployeelnfo( CommissionedEmp l oyee emp ) (


total _s ales +- emp.getSales() :
}

publi C vo 1d recordEmployeelnfo( HourlyEmp loyee emp ) (


total_hours +- emp.getHou r s() :
}

publ ic void pr1ntReport() (


System.out.println( "Payroll Report:"
System.out.pri ntln( -Total Hours: " +
System . out.println( MTotal Sa les: " +
System.out.print ln( MTotal Paid: $" +

):
tota l_hours ):
total _sales );
total_pay ):

}
}

Essa classe Payroll tem um mtodo ca l cul ateBonus (). Esse mtodo recebe um array de objetos
Empl oyee, descobre qua l o tipo de cada um e calcula um bnus. Os objetos HourlyEmp loyee recebem um bnus fixo de US$ IOO, enquanto os objetos COIl'Illi ss i oned Empl oyee recebem USS IOO
por cada venda.
Sua tarefa eliminar a lgica cond icional encontrada em ca l culateBonus(). Comece atacando
os dados que o mtodo est testando. Neste caso, ele est testando em um objeto. Ento, o que
est errado?
Em vez de solicitar o bnus ao objeto, o mtodo solicita a ele alguns dados e, em seguida, calcu la
um bnus, usando esses dados. Em vez disso, o mtodo deve so licitar os dados ao objeto.
Voc pode fazer download do cdigo-fonte das classes Payroll, Empl oyee, HourlyEmployee e
Commiss i onedEmp l oyee. Tambm existe um Payroll Dri ver fomecido, para que voc possa testar
fac ilmente sua soluo.

A prxima seo discutir as solues do Laboratrio 4. No prossiga at concluir o Laborat ri o 4.

Polimorfismo: hora de escrever algum cdigo

171

Solues e discusso
Para resolver esse problema, voc deve adicionar um mtodo cal culateBonus () diretamente em
cada objeto Employee. Isso poderia parecer como se voc estivesse cai ndo na armadilha I do Dia
6. Entretanto, est correto mover o mtodo para a classe base, pois todas as subclasses sabem
como calcular seu bnus. Na verdade, isso j deveria estar na classe h muito tem po.
As listagens 7.22, 7.23 e 7.24 apresentam as alteraes exigidas.
L ISTAGEM

7.22

Employee.java

publiC abs tract class Employee (


publi c abstract double calc ulateBonus() ;
II reduz ido por brevi dade. o res tante diz o mesmo
J

LISTAGEM

7.23

Hour l yEmployee .java

publi c cla ss HourlyEmployee extends Employee {


pub l ic double calcul ateBonus() {
return 100 .00 ;

II reduzido po r brevidade. o re stante diz o mesmo


J

LISTAGEM

7.24

CornnissionedEmployee.java

public class Commissioned Employee extends Employee {


publi c double calculateBonus() {
return 100.00 * getSales() ;
J

II r ed uzido por brevidade . o res tante diz o mesmo


J

Com essas alteraes, voc pode atualizar a classe Payroll, como a Listagem 7.25 demonstra.
LISTAGEM

7.25

Payroll.java

publi c cla ss Pay roll {


public void calcula t eBonus( Empl oyee [) emps ) {
for( in t i z O; i < emps.length; i ++ ) (
Employee emp emps [i] ;
System.out.prin tln("Pay bonus to " + emp.getlastName() + M, " +
emp.getFirstName() + " S" + emp.ca l culat eBonus()

Dia7

1 172

7.25

LISTAGEM

Payroll.java (cont inuao)

);
)
)

II reduzido por brevi dade . o rest ante diz o mesmo


)

Vamos! Acabou-se a lgica condicional irritante!

DICA

Dicas sobre estruturas condicionais:


Evite o use de estrutura s condicionais case ou j f/else.
- Considere os blocos if/else grandes com celicismo.
- Cuidado com alteraes em cascata. Se uma altera o exige muitas mudanas condicionais, talvez voc tenha um pro blema.
lnstanceof um si nal de perigo muito grande.
H /ehe, case e ins tanceof so Nculpados at prova em contrrio

DICA

Dicas para a eliminao de estruturas condicionais:


Transforme os dados em objetos.
Se os dados j so um objeto, adicione um m todo no objeto.
Evite verificaes de instanceof; use pOlim orfismo em vez disso.

Resumo
Hoje, voc com pletou quatro laboratrios. O Laboratri o I lhe deu a chance de experimentar alguns dos mecanismos bsicos do poli morfismo. O Laboratrio 2 permi ti u aplicar o que voc
aprendeu no Laboratrio I, em um exemplo mais complicado. O Laboratrio 3 deve ter finalmente respondido a pergunta, ;'0 que exatamente software prova do fu turo?". O Laboratrio 3 resume o motivo pelo qual voc desejaria usar polimorfismo. Finalmente, o Laboratrio 4 fo rneceu
algo para tomar cuidado enquanto estiver programando. El e tambm mostrou como o polimorfismo pode ser til, quando utilizado corretamente.
Juntos, todos esses laboratrios reforam as lies sobre polimorfismo. Eles fornecem o que voc
precisa saber para tirar vantagem do conceito corretamente. Esperamos que, aps concluir esses
laboratrios, voc veja seus programas do ponto de vista do polimorfismo. A verdadeira programao 00 exige uma maneira diferente de pensar a respeito do software. As vantagens da 00 surgem realmente, quando voc pode pensar de forma polimrfica.

Po limorfismo: hora de escrever algum cdigo

173

Perguntas e respostas
P. Pa rece qu e o polimorfismo de inclu so mais conveniente do qu e a sob reca rga, pois
cu s preciso escr ever um mtodo e fa zer com que ele funcione com muitos tipos diferentes. I'or qu e e u usa ria sobrecarga em vez disso?
R. Ex istem ocasies em que a sobrecarga uma escolha mel hor. Um mtodo que usa incl uso s funciona se estiver processando objetos relacionados. A sobrecarga perm ite que
voc reut ilize um nome de mtodo dentre um grupo de mtodos, cujos argumentos podem no estar re lacionados. Voc no pode fazer isso com a incl uso(embora possa usar
uma combinao de incl uso e sobrecarga).

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entend imento. Veja as respostas no Apndice A, " Respostas" .

Teste
I. A part ir das solues de laboratrio, d um exemplo de mtodo sobrecarregado.
2. Qual problema a sobreposio apresenta?
3. Qua is passos voc preci sa dar para alterar o comportamento em uma hierarq uia polimrfica?
4 . A partir dos laboratrios, encontre um exemplo de polimorfismo de incluso.
5. Como voc elimina lg ica condi cional?
6. Qua l a vantagem do polimorfi smo de incluso em relao sobrecarga?
7. Na 00, qual o relacionamento entre objetos e dados?
8.

que h de errado com as estruturas condici onai s?

9. Qua l uma boa indicao de que uma estrutura condic ional ' ruim '?

10.

Ex plique o polimorfismo com suas prprias palavras.

Exerccios
No h exerccios hoje. Faa seus laboratrios!

SEMANA

Em reviso
Na semana um voc no apenas aprendeu os fu ndamentos da programao orientada a objetos,
mas tambm corno e quando deve aplic-los.
Voc aprendeu que os trs pilares da programao orientada a objetos so o ellcap~' lIfalll elllo, a
herana e o polimorfismo. O encapsulamento perm ite que voc construa software independente. O encapsulamento conseguido atravs de abstrao, ocultao da implementao e diviso
da responsabi lidade. A herana perm ite que voc reutilize c estenda cdigo j existente. Voc
aprendeu que existem trs tipos de herana: para reuti lizao de implementao, para diferena
e para substituio de ti po. O polimorfismo pennite que um un ico nome represente cdigo dife-

rente. Os quatro tipos diferentes de polimorfismo so: pol imorfismo de incluso, poli morfismo
paramtrico. sobrecarga e sobreposio.
O uso dos trs pilares da programao orientada a objetos penni te que voc crie cd igo que :

Natural
Confivel
Reutil izvel
Manutenrvel
Extcnsivcl
Oportuno
Embora essas inrormaes tenham sido apresentadas nos dias 2, 4 e 6, os laboratrios dos dias 3,
Se 7 so o que rea lmente rene tudo. A experincia prtica nesses laboratrios aumentou o seu entend imento de como escrever cdigo orientado a objetos que atinge os objetivos mencionados.

SEMANA

Aprendendo a aplicar 00
8

Introd uo fi UML

Introduo AOO (Anlise Orientada a Objetos)

roo (Projeto Orientado a Objetos)

10

Introduo ao

11

Reutilizando projetas atravs de padres de projeto

12

Padres avanados de projeto

13

00 e programao de interface com o usurio

14

Constru indo softwa re confi vel atravs de testes

Panorama
Na primeira semana, voc aprendeu os fundamentos da escrita de cd igo orientado a objelos.
Embora esse seja um primeiro passo na criao de um programa orientado a objelos, ainda h
muito mais para aprender, antes que voc possa comear a codi fi car.
Nesta semana, voc ultrapassar a si mples codi fi cao e abordar o inteiro processo de desenvolvimento de software. Os passos do processo de desenvolvimento de software que voc abordar so: an lise, projeto, implementao e teste.

A anlise orientada a obj etos (ADO) o primeiro passo no processo de desenvolvimento. A


ADO permite que voc entenda o problema que est tentando resolver. Aps concluir a ADO,
voc deve conhecer os requisitos de seu programa, assim corno toda a terminolog ia espec fica do
dom nio.

Aps ter analisado o problema, voc poder comear a projetar sua so lui'lo. O Dia 10 descrever
o projeto orientado a objetos, o processo de pegar o modelo de domnio e criar o mode lo de objetos
que voc usar durante a implementao. Os dias II e 12 apresentamo alguns atalhos de projeto.
O prximo passo a implementao; escrever o cdigo. a que voc utiliza as infonnaes
apresentadas na primeira semana.
O teste o estgio fi nal do processo de desenvolvimento. importantc tcstar durante todo o est
gio de implementao, assim como no final , para poder garantir um sistema livrede defeitos.
Esses assuntos complementaro o conheci mento que voc adquiriu na primeira semana e pennitimo que voc tenha uma idia e acompanhe o processo de desenvolvi mento at ter um programa
orientado a objetos totalmente desenvolvido.

SEMANA

DIA
Introduo UML
Na semana anterior, voc aprendeu as teorias bsicas da programao orientada a objelos. Entre

tanto, si mplesmente conhecer algumas tcnicas e defin ies no o preparar adequadamente


para aplic- Ias. Voc simplesmente mostra ferramentas a algum, explica seu uso e propsi to e
depois manda essa pessoa construir uma casa? claro que no! A programao no diferente.
A programao de sucesso s surge com experincia e boa metodologia. Nesta semana, voc vai
aprender a aplicar corretamente as ferramentas de 00 que viu na semana anterior.
Hoje, voc va i explorar a UML (Unified Modeling Langllage), assim como a lguns dos aspectos
mais elega ntes do relacionamento entre objetos. As lies de hoje fornecen10 a linguagem comum que voc usara enquanto aprende a analisar seus problemas e a projetar so lues 00.
Hoje voc aprender:

Por que deve se preocupar com a Unified Modeling Language

Como modelar suas classes usando UML

Como modelar os vrios re lacionamentos entre classes

Como reunir tudo

Introduo Unified Modeling Language


Quando um construtor constr i uma casa. ele no faz isso aleatoriamente. Em vez disso, o constnllor constri a casa de acordo com um conj unto de cpias hel iogrficas detalhadas. Essas
cpias he liogrficas dispem o projeto da casa explicitamente. Nada deixado ao acaso .

Dia 8

Agora, quantas vezes voc ou algum que voc conhea construiu um programa aleatoriamente?
Quantas vezes essa prtica trouxe problemas para voc?
A UML (Unified Modelillg Langllage) tenta trazer as cpias heliogr licas para o mundo do soft
ware. A UML uma linguagem de modelagem padro. A linguagem consiste em vrias notacs grlicas que voc pode usar para descrever a arq uitetura inteira de seu software. Os
programadores, arqu itetos e anali stas de software usam lingl/agem de modelagem para descrever grafi camentc o projeto do software.
Novo TERMO Uma lillguagem de modelagem uma notao grfica para descrever projeto de so ftware. A I inguagem tambm inclui vrias regras para distinguir entre desenhos corretos e incorretos. So essas regras que tomam a UML uma linguagem de modelagem e no apenas
um pun hado de smbolos para desenho.
Uma linguagem de modelagem no igual a Ll m processo aLi metodologia. Uma melod% giadiz
a voc como projctar o software. Em vez disso, Lima linguagem de modelagem ilustra o projeto
que voc criar enquanto segue uma metodologia.
NovO TERMO Uma metodologia define um procedimento para projetar software. As linguagens de
modelagem capturam esse projeto graficamente.
A UML no a imica linguagem de modelagem. Entretanto, ela um padrJoamplamente aceito.
Ao mode lar software, importante fazer isso em uma linguagem comum. Desse modo, outros
desenvolvedores podem rpida e faci lmente entender seus diagramas de projeto. Na verdade, os
criadores da UML reuniram suas trs linguagens de modelagem concorrentes - por isso, o
U(nified - unificada) em UML. A UM L fornece um vocabulrio comum que os desenvolvedores podem usar para transmitir seus projetos.
Novo TERMO A VAn uma linguagem de modelagem padro. A UML consiste na notao para
descrever cada aspecto de um projeto de software.

NeTA

No o objetivo deste livro apresentar uma introduo exaustiva da UMl. Em


vez disso, este livro apresentar as partes prticas que voc pode usar imediatamente para descrever seu software.

importante notar que uma linguagem de modelagem no diz nada a respeito de como chegar a
seu projeto. Metodologias ou processos que mostram as diretrizes de como analisare projetar
software.
Novo TERMO Uma melodologia ou processo descreve como projetar software. Uma metodologia
freqUentemente contm uma linguagem de modelagem.

Introduo UML

ALERTA

179

A UMl apresenta um rico conjunto de ferram entas de modelagem. Como resultado, existem muitas informaes que voc pode colocar em seus modelos.
Cuidado para no tentar usar toda notao existente ao modelar. Use apenas
notao suficiente para transmitir seu projeto.
l embre-se sempre de que o objelivo de seu modelo transmilir seu projeto.
Faa o que precisar para transmitilo e fique com isso.

Modelando suas classes


Na semana anterior. voc viu mui to cdigo. Quando voc se aprofunda nele, o cdigo est no nvel mais baixo da documentao de seu software. Se seu cdigo funciona, voc tem certeza de
ter seu projeto documentado.
Embora o cdigo seja a documentao mais completa de seu projeto, pode ser extremamente difici l para outros mexerem nele - especialmente se no estiverem familiarizados com o cdigo.
A 'documentao' tambm ti l para algum que no conhea a linguagem de implcmcntao.
Em vez di sso, voc precisa de uma notao que lhe permita documentar seu projeto, para que
outros possam entend-lo imediatamente. Desse modo, outros podero ver a estrutura de classes
de alto nvel e apenas se aprofundar nos detalhes, quando isso for necessrio. De certa forma,
uma notao grfica o isola dos detalhes, para que voc possa exim ir-se de entender a estrutura
de alto nvel de um programa.
Cri ar documentao separada do cdigo exige o comprometimen to de mano
t -Ia em sincronism o com o cdigo.

Uma maneira pela qual a UML o ajuda a transmitir seu projeto fornecendo um ri co conjunto de
notao para descrever suas classes. Usando essa notao, outros podem ver facilmente as principais classes que compem o projeto de seu programa. Conforme voc ver, a UML penn ite defini r as classes, assim como descrever os relacionamentos de alto nvel entre as classes.

Notao bsica de classe


A UML fornece um rico conjunto de notao para modelar classes. Na UM L, uma caixa representa a classe. A caixa superior sempre contm o nome da classe. A ca ixa do centro contm todos os atributos c a inferior contm as operaes. Notas sobre seu modelo aparecem em caixas
com cantos dobrados. A Figura 8.1 resume a estrutura bsica de classes.
NOTA

A UMl faz diferena entre operao e m todos. Na UMl. uma operao um


servio que voc pode solicitar de qualquer objeto de uma classe, enquanto
um mtodo uma implementao especfica da operao. As lies de hoje
acompanharo a utilizao da UMl.

Dia 8

FIGURA 8 .1

A IIOttl(;O de classe
da U/oilL.

-----

._dodoorr,.>

--------

..... ltu' M

,,
,,

Dentro do modelo, voc pode usar os caracteres , # e +, Esses caracteres transmitem a visibilida
de de um atributo ou dc uma operao. O hfe n (-) significa privado, o jogo da ve lha (#) significa
protegido e o sinal de adio (+) significa pblico (veja a Figura 8.2).

8.2
A IIOtatiOda UML

VIsibilidade

FIGURA

.. public...n.
, pMteel/rd.". n.
, priY' __.".1tr

paro especificar

\'isibilidade,

public..opr{ ,
pMtectocLopr( I
, prMte. GP<l )

A Figura 8.3 ilustra a compl eta classe BankAccount dos dias 5 e 7,

BankAccount

FIGURA 8 .3

Uma classe
lotalmellle descrita,

, baI ..... : doubPI

dlpositFur.do l. mounr : doub ll ) : vo!d


g.,elto""" (): doubPI
M5e.5. """ ( I : void
wirhdrowF uod. (omoun5 : doub .. ): doubPI

s vezes, uma nota ajudar a transmitir um significado q ue, de outro modo, fi caria perdido ou
seria ignorado, como a nota da Figura 8.4,
FIGURA 8 ,4

8ank

Um exemplo
delOlflado de lIora.

+ .ddAccounl ( I
+ 100.IHoldings t I
.. 100.IAceounls ( )

.. deposit ( I
.. balance I)

------ -

o blnco cont6m ,,6.1., COnlal


e fornece operaOes porl
m. nipu lar ln'" cont."

Introduo UM L

18 1

Essas notas so a modelagem an loga anotao adesiva do mundo real.

Notao avanada de classe


A UM L tambm de li ne algumas outras notaes, mais avanadas. O uso correIO dessa notao o
ajuda a criar modelos mais descrit ivos.
A UM L o aj uda a ser mais descritivo, permitindo que voc am plie o vocabulrio da prpria linguagem, atravs do uso de esteretipos.
Um eSlere61ipo um elemento da UML qu e permite que voc amplie o vocabulrio da prpria li nguagem UM L. Um esteretipo consiste cm uma pa lavra ou frase
incl uda entre sinais de menor e maior duplos < ). Voc coloca um esteretipo acima ou ao
lado de um elemento ex istente.

Novo

TERMO

Por exemplo, a Figura 8. 1 mostra o esteret ipo Atributo . Esse estereti po ilustra onde
acrescentar atributos em um retngulo de cl asse. A Figura 8.5 ilustra outro esteretipo que informa lIm pouco sobre a operao.
FIGURA 8 .5

Um eS/e/"elipo qlle
qualifica a
OperOf(io.

BankAccount
<<accessor. + gelBalunceU
+ depositfundsU
+ wilhdruwfundsO

Final mente, voc pode se lembrar que a classe BankAccount foi originalmente defi nida como
lima classe concreta. Ent retanto, o Dia 7 redefi ni u a classe BankAccount como uma classe abstrata. A UML fornece uma notao para transmitir que uma classe abstrata: o nome da classe abstrata escrito em itl ico. No caso de BankAccount, o nome deve ser escri to em it lico, conforme
ilustrado na Figura 8.6.
FIGURA 8 .6

O objelo

BankAccount
abSlrato.

BankAccount
b,lance' doubl.
+ deposilFund. lamounl' doubl, ), vOH:!
+ IISIS.lance () : doubl,
' "'t8alance (I' void
+ withdrawfund~ lamaunl: doublel' double

Modelando suas classes de acordo com seus objetivos


As duas sees anteriores apresentaram muitas escolhas diferentes de notao. Dadas todas essas opes, como voc sabe quais notaes deve usar?

Dia 8

Voc sempre precisa voltar s perguntas, "o que eu estou tentando transmitir?" e "para quem eu
estou telllando transmitir isso?" O objetivo de um modelo lransm iti r seu projeto o mais eficientemente (e simplesmente) possivel.
Talvez seu objetivo seja transmitir a interface pblica de uma classe. A Figura 8.7 poderia bastar. Ela transmite adequadamente a interface pblica de Bank, scm sobrecarreg-lo com os detalhes de argumentos de mtodo ou atri butos ocultos. Tal notao bastar, se voc quiser
simplesmente transmi ti r o que outros objetos poderiam fazer com instncias de Bank.

Bank

FIGURA 8 .7

Uma lIo111(io s imples


addAccount ()
tOlolH oldings ( )
1010lAccounlS ( )
dapos it ( )
bol8nce ( )

/um/ Bank.

Entretanto, tome a Figura 8.3 como outro exemplo. Essa figura documenta completamente todos
os atributos e operaes (pblico, protegido e privado) da classe BankAccount. Voc poderia modelar uma classe com esse deta lhe, se quisesse transmitir a defi nio inteira da classe para outro
desenvolvedor. Ou talvez., quando voc progredi r em sua carreira 00, possa se tomar um arquiteto. Voc poderia dar tal modelo para um desenvolvedor, para que ele pudesse criar a c lasse.
Ento, a resposta da pergunla "como eu se i qua is notaes devo usar?" que isso depende.
Qua ndo uma pessoa no-tcnica perg unta a voc o que faz, voc responde de lima mane ira
q ue essa pessoa en tenda. Quando um colega pergunla o que voc faz, voc geral mente d
uma resposta tcnica. Mode lar seu projeto no diferente . Use o vocabulrio que fo r apropriado pa ra o q ue voc esti ver tentando fazer.

DICA

Dicas para a modelagem eficiente:


Sem pre faa a voc mesmo a pergu nta ~o q ue eu estou tentando transmi
tir7~ A resposta o ajudar a decidir exatamente o q ue voc precisa modelar.
Sempre faa a voc m esmo a pergu nta " para quem eu estou tent ando
t ransmitir a informao?" A resposta ditar o modo como voc vai modelar.
Sempre tent e produzir o modelo m ais simples que ainda tenha xito em
t ransmitir seu projet o.
No fique p reso linguagem d e modelagem . Embora voc no deva se r
vago demais na semntica, no deve deixar que o fato de seguir a not ao
perfeit amente o im pea de concluir seus diagramas. Os perigos de paralisia ao modelar so reais - especiatmente quando voc est comeando.
No se preocupe se seu m odelo no estiver 100% perfeit o. Preocupese
somente se seu modelo no transmite corretamente o projeto.
Finalment e, lembrese de q ue a UM L (ou q ualquer l inguagem de modela
gem) simplesmente uma fe rramenta para ajudlo a transmitir o projeto.
Ela no um instrumento em si mesma. No final do dia, voc ainda preci
sar prod uzir cdigo.

Introduo UML

Modelando um relacionamento de classe


As classes no existem no vcuo. Em vez disso, elas tm relacionamentos com plexos entre si.
Esses relacionamentos descrevem como as classes interagem umas com as outras.
NovO TERMO

Um re/aciollllmelllo descreve como as classes interagem entre si. Na UML, UIl1 re lacionamento uma conexo entre dois ou mais elementos da notao.

A UML reconhece trs tipos de al to nvel de relacionamentos de objeto:


Dependncia
Associao
Generali zao
Embora a UML possa fornecer notao para cada um desses relacionamentos, os relacionamentos no so especificos da UML. Em vez disso, a UML simplesmente fornece um mecanismo e
vocabulrio comum para descrever os relacionamentos. Entender os relacionamentos, independentemente da UML, importante em seu estudo de 00. Na verdade, se voc si mplesmente ignorar a notao e entender os relacionamentos, estar bem adiantado nos estudos.

Dependncia
Dependncia o relacionamento mais simples entre objetos. A dependncia indica que um objcto depende da especificao de outro objeto.
NeTA

Novo TERMO

Especifica~o

uma maneira diferemede dizer interface ou comportamen to.

Em um re!acionamel1lo de dependncia, um objeto dependente da especificao de


outro objeto. Se a especifi cao mudar, voc prec isar atual izar o objelo dependente.

Lembre-se dos laboratri os do Dia 7. Voc pode dizer que Psychiatri stOb ject depende de
MoodyObj ect, por dois moti vos. Pri mel ro, o mtodo exami ne () de Psyc hi a t ri s tObj ec t recebe um MoodyOb jec t corno argumento. Segundo, o mtodo examineO chama o mtodo queryMood () de MoodyObject. Se o nome ou lista de argumentos do mtodo queryMood () mudar, voc
precisar atualizar o modo como Psychi atri stObject chama o mtodo. Do mesmo modo, se o
nome da classe MoodyObject mudar, voc ter de atualizar a lista de argumentos do mtodo
examineO.
A Figura 8.8 ilustra a notao UML do relacionamento de dependncia ent re Psychiat r istObject e HoodyObjec t .

Dia 8
8.8
Um relaciol/amelllO de
dependllcia simples.
FIGURA

+ q .... 'VMoodU : String

+e..mineO

To me not a do que a Figura 8.8 no diz. O elemento Psychiat r istObject no


conlm cada m todo encont rado em Psych1atristObject. O mesm o vale para
MoodyObj ect. Em v ez d isso, esse modelo de d ependncia contm apenas os recu rsos necess rios para descrever o rela ci onamento de dependncia.

NOTA

Lembrese d e que a notao UML serve para t ransmi tir info rm aes. Ela no
est l para que voc tente usa r cada truque de modelagem do livro de UML !

Atravs da POO, voc sempre tenta minimizar o mximo possvel as dependncias. Ent retanto,
imposs vel remover todas as dependncias entre se us objetos. Nem todas as dependncias so
criadas de modo igual. As dependncias de interface geralm ente esto corretas, enquanto as dependncias de implementao quase nunca so aceitveis.
Quando voc deve modelar dependncias?

DIC A

Nor malment e, voc m odela dependncias quando quer m ostrar que u m ob jel o usa outro. Um lugar comum onde um ob jeto usa oul ro atravs de um argumento de mt od o. Por exemp lo, o mtod o exami neO de Psych1at r 1st Object
rece be u m HoodyObject com o argumento. Voc pode dizer que Psych iatri stObject usa HoodyObj ect.

Associao
Os relacionamentos de associao vo um pouco mais fu ndo do que os relacionamentos de dependncia. As associaes so rel acionamentos estrut urais. Uma associao indica que um objeto contm - ou que est conectado a - outro objeto.
Novo

TERMO

Uma associado indica que um objelO contm outro objeto. Nos tennos da UM L,
quando se est em um relac ionamento de assoc iao, um objclO est conectado a outro.

Como os objetos esto conectados, voc pode passar de um obj eto para outro. Considere a associao entre uma pessoa e um banco, como il ustrado na Figura 8.9.
FtGURA 8.9
Vma (lssociarfio
/JCSS()(l

e 1/1/1

emre //fila

Pessoa

I Empreste de 1>1

Banto

bW1CO.

A Figura 8.9 mostra que urna pessoa empresta de um banco. Na notao UML, toda assoc iao
tem um nome. Neste caso, a associao chamada de empresta de. A seta indica a di reo da associao.

Introduo UML
Novo

TERMO

185

o nome da associai'lo um nome que descreve o relacionamento.

Cada objeto em uma associao tambm tem um papel, confonne indicado na Figura 8.10.
FIGURA 8 .10
Os pllpis IIl1l1SSOCilllio.

Novo

TERMO

Na associao, o papel de Pessoa devedor e o papel de Banco credor.

Novo

TERMO

o papel da assoc iao a parte que um objeto desempenha em um relac ionamento.

Finalmente, a multip li cidade indica quantos objelos podem toma r parte em uma associao.
Novo

TERMO

A l11uIIIJ)/icidllde ind ica quantos objetos podem tomar parte na instncia de uma associao.

A Figura 8.11 ilustra a multiplicidade da associao entre Pessoa e Banco.


FIGURA 8 .11
Mulriplicidade.

Pessoa

11...

.1

Ba nco

Essa notao nos informa que um banco pode ter um ou mais devedores e que lima pessoa pode
utilizar O ou mais bancos.

NOTA

DICA

Voc especifica suas multiplicidades atra vs de um nico numero, uma l ista


ou com um asterisco (*).
Um nico nmero significa que determinado nmero de objel os - no mais e
no menos - podem participar da associao. Assim, por exemplo, um 6 sig nifi ca que seis objetos e somente seis objetos podem participar da associao.
* sign ifica que qua lquer nmero de objetos pode participar da associao.
Uma lista define um intervalo de objetos que podem participar da associao.
Po r exemplo, 1..4 indica que de 1 a 4 obletos podem participa r da associao.
3 .. * indica que trs ou mais obletos podem participar.

Quando voc deve modelar associaes?


Voc deve m odelar associaes quando um o blet o con ti ver outro objeto - o
relacionamen to rem um. Voc tambem pode modelar um a associao quando
um objeto usa outro. Uma associao permit e que voc modele quem faz o
que em um relaci onamento.

186

Dia 8

A UML tambm defi ne dois tipos de associao: agregao e composio. Esses dois subtipos
de associao o ajudam a refi nar mais seus modelos.

Agregao
Uma agregao um tipo es pecial de associao. Uma agregao modela um relacionamento

tem 1//1/ (oupa,,'ede, no jargo da UML) cnlre pares. Esse relacionamento signi fi ca que um ohjcto contm outro. Pares significa que um objeto no mais importante do que o outro.
Novo TERMO

Novo TERMO

Um re/acioIlOmIIIO IOdo/parte descreve o relacionamento entre objclos onde um

ohjclo contm outro.

Uma agrega(io um tipo especial de associao que modela o relacionamento 'tem


um ' de relacionamentos todo/parte entre pares.

Importncia. no contexto de uma agregao, significa que os objclos podem existir independen-

temente uns dos outros. Nenh um objeto mais importante do que o outro no relacionamento.
Considere a agregao ilustrada pela Figura 8. 12.
FIGURA 8 .12
Agregllli o eml'e 1/111

banco e seus cliellles.

Banco

1..0

Cliente

Aqui, voc v que um Banco pode conter qualquer nmero de obj etos Cl iente. O losango aberto
ajuda seu modelo a indicar qual objeto o todo e qual a parte. Aqui, o losango diz que Ba nco o
todo. Banco o objelo que ' tem um ' no re lacionamento. Banco contm objetos Cl i ente. Em termos de programao, isso poderia significar que Banco contm um array de objetos Cl i ente.

NOTA

Um losango aberto simboliza agregao. O losango toca o objeto que considerado o todo do relacionamento: a classe que se refere outra classe. O todo
constitudo de partes. No exemplo anterior, BanCO o todo e os objetos CI i ente so as partes.
Outro exemplo de agregao um carro e seu motor. Um carro 'tem um' motor. Nessa agregao, o carro o todo e a parte o motor.

Como Banco e Cl iente so independentes, eles so pares. Voc pode dizer que o objeto Banco e
o objeto Cl ien te so pares, porque os objelos Cl i ente podem ex istir independentemente do objeto Banco. Isso sign ifica que, se o banco encerrar suas operaes, os cI ientes no desaparecero

Introduo UM L

187

com o banco. Em vez disso, os clientes podem se tornar clientes de outro banco. Do mesmo
modo, um cliente pode sacar seus fundos e o banco conti nuar.
A agregao entre objetos funci ona como esses exemplos reais. Um objeto pode conter outro olr
jeto independente. Queue ou Vector um exemplo de objeto que pode conter outros objetos, atravs da agregao.

D ICA

Quando voc deve m odelar a agregao?


Voc deve modelar uma agregao quando o objetivo de seu modelo for descrever a estrutura de um relacionament o de pares. Uma agregao mostra explici tamente o relacionamento estrutural todo/parte.
Entret ant o, se voc estiver mais interessado em modelar quem faz o que em
um relacionam ento, melhor usa r uma associao si mples: sem o losango.

Composio
A composio um pouco mais rigorosa do que a agregao. A composio no um relacionamento entre pares. Os objetos no so independentes uns dos outros.
A Figura 8. 13 ilustra um relacionamento de composio.
FIGURA 8 .13
COlllposi(10 elllre
.nta.f filiai.f .

1/1/1 b (/IICQ

Banco

-----.{I-_-_-_~F~;'_;:_'~_-_ll

1...-,

Aqui, voc v que Banco pode conter muitos objetos fi 1ia l . O losango fechado diz que esse
um relacionamento de composio. O losango tambm diz quem ' tem um ' . Neste caso, Banco
' tem um ', Otl contm , objetos filial.

Ne TA

Um losango fechado sim boliza a composio. O losango toca o objeto que


considerado o todo do relacionament o. O todo cons titudo de partes. No
exemplo anteri or, Banco o todo e os objetos Filial so as part es.

Como esse um relacionamento de composio, os objetos Fil ; a1 no podem ex istir independentemente do objeto Banco. A composio diz que, se o banco encerrar suas atividades, as fil iais
tambm fecharo. Entretanto, o inverso no necessariamente verdade. Se uma filia l fec har, o
banco poder permanecer funcionando.
Um objeto pode part icipar de uma agregao e de um relacionamento de composio ao mesmo
tempo. A Figura 8.14 modela tal relacionamento.

188

FIGURA

Dia 8

8 .14

,.~

Banco em 1/111 relacioname"to

de agregatia e de

compositio.
silllulwneamellle.

~,

.1

Filiei

1..

Clie nte

D ICA

Quando voc deve modelar uma composio?


Assim com o a agregao, voc deve modelar uma composio quando o objet ivo de seu modelo fo r descrever a estrutura de um relacionamento . Uma composio mostra explicitamente o relacionamento estrut ural todo/parte.

Ao contrrio da agrega o, a composio no modela rela cionamentos

todo/parte de pares. Em vez disso, a parte dependente do todo. Voltando ao


exemplo Banco, isso significa que quando o banco encerrar suas atividades, as
fili ais t ambm fecharo.
Em l erm os de programao, isso significa que quando o o bjeto Banco fo r destruido, os o bjetos F1l1al tambm sero destrudos.
Novamen te, se o o bjetivo de seu modelo f or capturar os papis dos objetos na
associao, voc deve usar uma associao simples.

NOTA

l embre-se d e que agregao e com posio so simplesmente refinamentos


o u subtipos da associao. Isso significa que voc pode modelar agregao e
composio como uma associao simples. Tudo depende do que voc est iver
t entando modelar em seu diagrama.

Generalizao
Um relacionamento de genera lizao um relacionamento entre o gera l e o espec fi co. a herana.

Novo TERMO Um re/acionamenfO de generalizao indica um re lacionamento entre geral c especifico. Se voc tem um relacionamento de generalizao, ento sabe que pode
substit uir uma classe filha pela classe progenitora.
A generali zao incorpora o relacionamento ' um ' sobre o qual voc aprendeu no Dia 4. Confonne foi aprendido no Dia 4, os relacionamentos ' um ' pennitem que voc defi na rel acionamentos com capaci dade de substituio.
Atravs de relacionamentos com capacidade de substituio, voc pode usar descendentes em
vez de seus ancestrais, ou fi lhos em vez de seus progenitores.
A UML fornece uma notao para modelar generalizao. A Figura 8.15 ilustra como voc mo-delaria a hierarquia de herana BankAccount.

Introduo UML

189

FIGURA 8 .15

BIonkAccount

A hierarquia de herana
BankAccount.

"fi
SavingsAccoun1

OYerd,aftAccoun1

Ch~kingAccoun1

1\
TimaMa1uri1yAccoun1

Rewa,dsAccoun1

Uma linha chcia com um a seta fechada e vazada indica um relac ionamento de ge nera lizao.

Reunindo tudo
Agora que voc j viu a modelagem bsica de classe eos relacionamentos, pode comear a monlar modelos bastante expressivos. A Figura 8.8 apresentou um exem plo de dependncia simpl es.
Usando o que aprendeu durante lodoo dia, voc pode tomar esse mode lo um pouco mais expressivo. A Figura 8. 16 expande o relacionamento modelado na Figura 8.8.
Figura pgina 198 em ba ixo
FIGURA 8 .16

Psychia1ris1Object

Vm modelo de dependncia
mais e.'(pressivo.

+ examine ( I

---------

SadObject
+ queryMood

HappyOblect
~

+ queryMood ( )

A Figura 8. J 6 acrescenta uma generalizao para que voc possa ver quai s objetos pode substi
tuir por MoodyObject nesse relacionamenlo.
Do mesmo modo, a Figura 8. 17 expande a hierarquia de herana apresentada na Figura 8. 15.

Dia 8

' M \'

FIGURA 8 .17

,...,

V II/a hierarquia
de herana

BankAccount

mais dela/hada.

O...../L"

..

;$.. . .

Row .. _

", ,,,"

Examinando esse modelo, voc pode ver exatamente o que cada classe acrescenta na hierarquia.
Tal modelo poderia ajudar outros desenvolvedores a ver o que cada classe o ferece, aci ma e alm
de suas descendentes.
Todos esses modelos tm um elemento comum . Cada modelo contm apenas infonnaes sufi cientes, apenas notao suficiente, para transmitir a idia. O objeti vo desses modelos no usar
cada notao d isponvel.
Todos esses modelos tambm com binam diferentes elementos da UML. Como uma linguagem
de programao, a UML pcnnite que voc combine suas vrias pan es de mane iras excl usi vas.
Atravs da combinao de vrios elementos, voc pode cria r modelos muito expressivos.

Resumo
Hoje, voc aprendeu os fundament os da modelagem de classe e relacionamentos. Aps prat icar
os exerccios de hoje, voc dever consegui r comear a desenhar model os de classe simples,
usando a UML.
A UML fornece notaes para modelar classes, assim como os relacionamentos entre objetos, A
UML fornece notaes para descrever trs tipos de re lacionamentos:

Dcpendncia

Associao

Genera lizao

Introduo UM L

A UML tambm reconhece dois subtipos de associao: agregao e composio. Combinando


todos esses elemeruos, voc pode gerar diagramas de classe expressivos. Seu domnio da UML
importante para documentar e transmitir seus projetos para outros.

Perguntas e respostas
P. Voc I)ode misturar os trs lipos de relacionamenlOS dentro do mesmo modelo?
R. Sim. Seu modelo pode ilustrar qualquer combinao dos relacionamentos delineados
neste dia. O modelo ex iste para descrever os re lacionamentos entre suas classes. Voc
deve modelar os relac ionamentos entre suas classes.
P. Como voc

" S:I

a UML? Existem ferramentas especficas?

R. Voc pode usar a UML como quiser. Voc pode dese nhar seus diagramas em uma ferramenta de mode lagem, em um quadro negro ou em um guardanapo de papel. Depende da
si tuao. Se voc estiver em uma discusso interativa sobre o projeto, provavelmente desejar usar um quadro negro, pois atualizar um computador pode ser complicado.
As ferrame ntas de model agem por computador so melhor lIsadas quando voc quer documentar forma lmente um projeto.

Workshop
As perguntas e respostas do leste so forneci das para seu melhor entendi mento. Veja as respostas no Apndice A, "Respostas".

Teste
I. o que UML?
2. Qua l a diferena entre uma metodolog ia e uma linguagem de modelagem?
3. Que tipo de relacionamento ex iste entre Employee e Payroll , no Laboratrio I do Dia 7?
4. Examine cuidadosam ente o modelo da Figura 8.15. Usando apenas o modelo, o que voc
pode dizer a respeito de MoodyObject?
5. Exam ine os laboratrios do Dia 7. Encontre um exemplo de dependncia.
6. Na UML, o que os sinai s a seguir sim bolizam: +, #, -?
7. O Dia 2 apresentou a segui nte interface:
publ ic interface Queue (
publ i c void enqueue( Object obj );
publlC Object dequeue() ;

Dia 8

pub l i C boo1ean lSEmpty();


pu b1 i c Object peek() ;
}

Q ue tipo de relacionamento Queue tem com os elementos que contm?


8. No Dia 3, Laboratrio 3, a classe Deck criava vrias cartas. Que tipo de relacionamento
' tem um ' isso representa?
9. Como voc ilustra que uma classe

OLl

mtodo abstraio?

lO. Qual o objeti vo fi nal da modelagem? Qua is conseqUncias esse obj etivo tem?
I I. Explique associao, agregao e composio.
12. Expl ique quando voc deve usar associao, agregao e composio.

Exerccios
I. Modele a classe Queue defin ida na questo 7.

2. Modele um relacionamento de com posio abelhalcolmia.


3. Mode le o relac ionamento entre Bank e BankAccount do Laboratrio 2, Dia 7.
4. Modele a associao entre um com prador e um comerci ante. Especifique os papi s, a
mu ltiplicidade e o nome da dependncia.
5. Modele a hierarquia de funcionri os do Laboratrio 2 do Dia 5. Atravs de seu mode lo,
transmita o que cada classe adiciona acima e a lm de suas descendentes.
6. Veja o Dia 6. Modele a hierarquia de herana Persona 11tyObject.

SEMANA

DIA
Introduo AOO (Anlise
Orientada a Objetos)
Ontem, voc aprendeu ti vis ualizar seus projetas de classe atraves de modelos de classe. Voc
viu como os modelos de classe podem aj udaroulros desenvo lvedores a entender melhor seu projeto, destacando os diferentes tipos de objetos e relacionamentos que eles encontraro em seu
software. As linguagens de modelagem, como a UM L, fomecem a voc e ti seus colegas desenvo lvedores lima linguagem comum para falar a respeito de projeto.
Entretanto, a questo ainda permanece; como voc projeta software orientado a objetos? Os modelos simplesmente captu ram um instantneo de seu projeto. Eles no o ajudam a entender seus
problemas ou a fo rmu lar lima sol uo. Em vez disso, os modelos so simplesmente o resultado

final do projeto de software. Como voc chega l?


Nos prximos dois dias, voc vai aprender a respeito da AOO (An li se Orientada a Objelos) e
POO (Projeto Orientado a Objetos). AOO uma estratgia orientada a objelos para entender
um problema. Voc usa AOO para ajudar a entender o nllcleo do problema
que deseja resolver.
,
Aps entender seu problema, voc pode comear a projetar uma soluo. E a que o Projeto Orientado a Objetos (POO) entra em ao. No restante da lio de hoje, voc vai aprender a respeito
de AOO.
Hoje voc aprender:

Sobre o processo de desenvolv imento de software


Como a AOO o aj uda a entender seus problemas de software

Dia9

1 194

Como chegar a um entendimento de seu problema usando casos de uso


Como usar a UML para visualizar sua anl ise
Como construir seu modelo de domnio
O quc fazer com lUdo que voc cria durante a AOO

o processo de desenvolvimento de software


Existem tantas maneiras de desenvolver software quanto existem desenvolvedores. Entretanto,
uma equipe de desenvolvimento de software precisa de uma estratgia uni ficada para desenvolver software. Nada ser feito, se cada desenvolvedor fizer sua prpria atividade. As metodolog ias
de software definem uma maneira comum de encarar desenvolvimento de software. Uma metodologia rreqUentemente conter um a linguagem de modelagem (como a UML) e um processo.
Novo

TERMO

Um processo de software mostra os vrios estgios do desenvolvimento de software.

Um exemplo familiar de processo de software o processo de cascata.


FIGURA 9 .1
O proce.fSo de

casemo.

Anlise de
requisitos

"
Projeto

L
Irnplementaio

"
Teste

Conforme a Figura 9. 1 ilustra, o processo de cascata seqUencial e un idireciona l. O processo


const itudo de quatro estgios di st intos:
I. Anli se de requi sitos

2. Projeto
3. Implementao
4. Teste

Quando segue o processo de cascata, voc vai de um estgio para prximo. Entretanto, uma
vez que voc complete um estgio, no h volta - exatamente como descer uma cascata ou um
penhasco escarp."ldo! O processo de cascata tenta evitar alterao, proibi ndo mudar quando um
estgio est concludo. Tal estratgia protege os desenvolvedores de requisitos que mudam

Introd uo AOO (Anlise Orientada a Objetosl

195

constantemente. Entretanto, ta l processo rigido freqentement e resulta em software que no o


que voc ou seu cl iente quer.
Quando voc analisa um problema, projeta uma soluo e comea a implementar, seu entendi
menta do problema continuamente aprofundado. O mel hor entendimento de seu problema
pode muito bem invalidar uma anlise ou projeto anterior. Os requi sitos podem at mudar enquanto voc desenvolve (ta lvez um concorrente tenha acrescentado um novo recurso em seu
produto). Infelizmente. o processo de cascata no pode enfrentar a realidadc do moderno desenvolvim ento de softwa re - requisitos que mudam constantemente.
Embora este li vro ni'lo tente impor nenhuma metodologia especfi ca, h um processo que tem se
mostrado muito efi ciente para desenvolvimento orientado a objetos: o processo iterativo. Este li
vro impe esse processo!

o processo iterativo
O processo iterati vo o oposto do processo de cascata. O processo iterativo permite alteraes
em qualquer ponto do processo de desenvolvimento. O processo iterativo permite al terao ada.
tando uma estratgia iterativa e incremental para o desenvolvimento de software.
Um processo ileralivo uma estratgia iterativa e incrememal para desenvolvimen
to de softw are. Outro modo de pensar a respeito do processo como uma estratgia
'evolut iva'. Cada ilerai'l o aperfeioa e elabora gradualmente um produto bsico em um produto
amadurecido.

Novo TERMO

Uma estratgia iterativa


Ao contrrio do processo de cascata, o processo iterativo pennite que voc continuamente volte
e refine cada estgio do desenvolvimento. Por exemplo, se voc descobrir que o projeto simplesmente ni'lo funciona ao executar a implementao, pode voltar e faze r um projeto adici onal e
uma nova an lisc o esse refin amento contnuo que torna o processo iterati voo A Figura 9.2 ilustra a estratgia.

Uma estratgia incremental


Ao segui r um processo iterativo, voc no conclui sim plesmente lim a iterao grande que constri o programa inteiro. Em vez disso, o processo iterativo divide o traba lho de desenvolvi mento
em vri as iteraes pequenas. A Figura 9.3 ilustra essa estratgia incremental.

Dia 9

FIGURA 9 .2
UII/a ilera(10.

Implementao

Anlise

Projeto

Implementa60

Teste

Fim da Itera60

FIGURA 9 .3

Iterlllo 1

O processo iterO/ho.

Itera!o 2

Itera60 N

Ent rega

Cada iterao do processo inl roduz uma pequena melhoria incremental no programa. Essa melhoria pode ser um novo reurso ou um refinamento de um recurso j existente.

Introd uo AOO (Anlise Orientada a Objetos)

197

De qualquer modo, a iterao tem um objetivo especfico e, no fina l da iterao, voc tem uma
melhoria notvel na funcionalidade .
Imagine que voc esteja criando um MP3 player. Durante uma iterao do projeto, voc pode
terminar o componente que reproduz um arquivo MP3. Para determi nar se o componente funciona, voc pode codific-lo de modo que abra e reproduza um arquivo de msica especfi co. Na
prx ima iterao, voc pode adicionar a capacidade de escolher qual arquivo vai ser reproduzido. Em cada iterao, voc tem um progresso mensurvel. No final da pri meira iterao, voc
pode ouvir o componente reproduzir uma msica. No fina l da iterao seguinte, voc tem um
mecanismo que perm ite escol her dinamicamente uma msica para tocar.
Seguindo uma estratgia iterativa, voc v o progresso constantemente. Por outro lado, se voc
tentar faze r tudo sim ultaneamente, poder ser dificil ver qualquer forma mens unvel de progresso. Em vez disso, o projeto parecer constantemente atolado em um n ico lugar - nunca h
qualquer resultado. Se um projeto nunca for adiante, o mora l vai ba ixar e se tornar diflcil determinar o que precisa ser fe ito em seguida. Moral baixa e confuso sobre o que fazer em seguida
fragme ntar e matar um projeto.

A LER T A

Os processos iterativos precisam ser cuidadosament e m onitorados para se garantir que eles no sejam simplesment e reduzidos a 'cavar' uma soluo. A
AOO e o POO fornecem ta l verificao de sanidade.

o progresso constante fornece a voc relorno constante. Voc pode usar esse retorno como um
modo de garant ir se est no caminho certo. Se voc tentar completar o proj eto inteiro de uma
vez, no saber se criou a soluo correta at tenninar. Voltar e corrig ir algo que niio foi fei to
corretamente ser muito mai s dispendioso se voc precisar voltar e reescrever o programa inteiro! A iterao, por outro lado, torna muito mais barato vo ltar e corrigi r algo. Como voc recebe
retomo constante, mais provve l que ident ifique um problema mais cedo. Se voc identificar
seus problemas mais cedo, ser mais fc il refazer uma iteraiio ou duas para corrigi-lo. sempre
mais desejvel reescrever urna iterao do que reescrever um programa inteiro! Se voc mantiver
s uas iteraes peq uenas, no perder muito tempo, caso tenha de se des faze r de alguma delas.
Se um problema chegar base da iterao original, uma estratgia iterativa
no poder salv-lo. Tal problema fundamental pode ser dispendioso demais
para corrigir e pode danificar a qualidade do produto.

Uma metodologia de alto nvel


Este livro apresenta uma metodologia de desenvolvimento orientada a objelos infonnal. A metodologia sclcciona e escol he as tcn icas que se mostraram eficazes a partir de outras metodolog ias. A metodologia consiste em um processo iterativo, no q ual uma iterao tem quatro
estgios:

Dia9

1 198

Anl ise
Projeto
Im plementailo
Teste

NOTA

Aps o estgio de teste. voc tambm pode ter estgios de la namento e manuteno. Esses so estgios importantes no ciclo de vida de um projeto de
sohware. Entretanto, para os propsitos da tio de hoje, esses estgios sero
omitidos. HOje, voc vai fo cal izar anlise, projeto. implementao e teste.

As metodolog ias ' reais' freqUentemente enumeram estgios ad icionais. Entretanto, quando
voc est aprendendo pela pri mei ra vez, esses quatro estgios silo aqueles que mais im portam .
Por isso, este li vro se concentra nesses quatro estgios. O restante deste dia abordar a anlise
orientada a objetos.

AOO (Anlise Orientada a Objetosl


AOO (Anlise Orientada a Objetos) o processo usado para entender o problema que voc est
tentando resolver. Aps completar a anlise, voc dever entender os requisitos do problema, assim como o vocabulrio do domn io do problema.
Novo

TERMO

Analise orientada a ohje/os um processo que usa uma estratgia orientada a objetos

para ajud- lo a enlender o problema que est tentando resolver. No final da anlise,
voc dever entender o domnio do problema e seus requisitos em tennos de classes e interaes
de objetos.

Para projetar uma soluo para um problema, voc precisa entender como os usurios uti lizari'io
o sistema . A resposta dessa pergunta so os requisitos do sistema. Os requ isitos in formam a voc
o que os usurios querem faze r com o sistema e quais tipos de respostas eles esperam receber.
Novo

TERMO

Sislema o termo da AOO para um conjunto de objetos que interagem. Voc pode

dizer que esses objetos constituem um sistema ou modelo do probl ema.

Esses objetos so instncias de classes derivadas de objetos concretos ou abstratos no domn io


do problema que est sob est udo.
A anlise tambm o ajuda a se familia rizar com o domnio do problema. Estudando o domnio,
voc comea a identificar os objetos de que precisa para modelar corretamente o sistema.
A AOO, confonne o nOme sugere, uma estratgia orientada a objetos para anl ise de requisitos. A AOO util iza uma estratgia baseada em 00, modelando o problema atravs de objctos e
suas interacs. Existem dois modelos principais. O modelo de caso de uso descreve como um
usurio interage com o sistema . O modelo de domnio captura o vocabu lrio princi pa l do siste-

Intro duo AOO (An lise Orientada a Objet os )

199

ma. Usando o modelo de domn io, voc comea a identi fi car os objetos que pertencem ao seu
sistema. Um modelo de domnio corrctamente construdo pode resolver muitos problemas no
mesmo domnio.

Usando casos de estudo para descobrir o uso do sistema


Ao comear a analisar um problema, voc primei ro precisa entender como seus usurios utilizaro ou interagiro com o sistema. Esses usos com preendem os requisitos do sistema e prescrevem o sistema que voc cria. Atendendo os req ui sitos de seus usurios, voc produz um sistema
til.
Novo

TERMO

Os requisitos so os recursos ou caractedsticas que o sistema deve ter para resolver


determinado problema.

Um modo de descobrir esses usos atravs de anlise de casos de uso. Atravs da


anli se voc definir vrios casos de uso. Um caso de uso descreve como um usurio
vai interagir com o sistema.

Novo

TERMO

Novo

TERMO

Novo

TERMO

Amlise de ClI:,-oS de /(so o processo de descobena de casos de liSO atravs da criao

de cenrios e histrias com usurios cm potencial ou ex istentes de um sistema.


Um caso de liSO descreve a intcrao entre o usurio do sistema e o sistema - como
O usurio ut ilizar o sistema do seu prprio ponto de vista.

A criao de casos de uso um processo iterativo. Existem vrios passos que voc deve dar durante cada iterao, para fonnalizar seus casos de uso. Para defin ir seus casos de uso, voc deve:
i. identificar os atares.
2. Criar uma lista preliminar de casos de uso.
3. Refi nar e nomear os casos de uso.
4. Definir a seqilncii\ de eventos de cada caso de uso.

5. Modelar seus casos de uso.

NO TA

Voc no cri a casos de uso no vcuo ! Enquanto deriva seus casos de uso, voc
deve consultar aqueles que utilizaro o sistema - seus clientes. A participao do client e absolutamente fundam ental para se descobrir os casos de uso
(a no ser que voc esteja escrevendo o software para si m esm o).
Seus clien t es so os especialistas do dom nio. Eles conhecem bem seu espao
de atuao e sabem do que precisam em seu software. Sempre se certi fique
de contar com o conhecimento deles e us-lo para ori entar os requisitos de seu
software.
Fazer os usurios comporem hist ria s sobre seu d ia ideal de intera o com o
sistema pode ser uma boa maneira de quebrar o gelo nessa atividade.

Dia 9

Antes de co ntinuar com o dia, importa nte dizer que os exemplos no ten tam
real izar u ma anlise completa de um sit e da Web on-line. Em vez disso, o s
exemplos ensinam os passos que voc dar enquanto realizar uma anlise
real. Assi m, muitos casos de uso sero omitidos.
Na prxima semana, voc trabalhar com uma anlise ori entada a objetos
completa.

Identifique os atores
O primeiro passo na definio de seus casos de uso definir os atores que usaro o sistema.

Novo

TERMO

Um (1/01' tudo que interage com o sistema. Pode ser um usurio humano, outro sistema de com putador ou um chimpanz.

Voc preci sa pedir aos seus clientes para que descrevam os usurios do sistema. As perguntas
podem incluir as seguintes:
Quem principalmente usar o sistema?
Existem outros sistemas que usaro o sistema? Por exemplo, ex istem quaisquer usurios
que no so seres humanos?
O sistema se comun icar com qualquer outro sistema? Por exemplo, h um banco de dados j existente que voc precise integrar?
O sistema responde ao estimulo gerado por algum que no seja usurio? Por exemplo, o
sistema precisa fazer algo em certo dia de cada ms? Um estimu lo pode ser proveniente de
fontes nonnal mente no consideradas ao se pensar do ponto de vista puramente do usurio.
Considere uma loja da \Veb on-line. Uma loja on-line pennite que usurios convidados naveguem pelo catlogo de produtos, verifique o preo dos itens e solicite mais infonnaes. A loja
tambm permite que usurios registrados com prem itens, assi m como cont rola seus pedidos e
mantm informaes dos usurios.
A partir dessa breve descrio, voc pode idenli ficar dois ata res: usurios convidados e usuri os
registrados. Cada um desses doi s atares interage com o sistema.
A Figura 9.4 ilustra a notao UML para um ata r: um desenho de pessoa com um nome. Voc
deve dar a cada um de se us atares um nome no ambguo.
FIGURA 9. 4
Q. al ores lia UML.

Usutirio Regist rado

Introd uo AOO (Anlise Orientada a Objetosl

201

importante evitar confu so

ao nomear seus atores. D a cada ator um nome


que identifique exclusivamente o ator.
Uma boa atribuio de nomes fundamental. Os nomes devem ser simples e
fceis de lembrar.

E importante notar que detemlinado usurio do sistema pode assumir o papel de muitos alares
di ferentes. Um ator um papel. Por exemplo, um usurio poderia entrar no site como convidado,
mas posteriormente se conectar como registrado para poder fazer uma compra.

N O TA

AL ERTA

Um usurio pode assumir muitos papisdiferentes enquanto interage com um


sistema. Um ato r descreve o pape/que o usurio pode assumi r enquanto interage com o sistema.

Quando voc comear a definir seus casos de uso, crie uma lista preliminar de
atares. No se atrapalhe ao identificar os atares. Ser diflcil descobrir todos os
atares na primei ra vez.
Em vez disso, encontre atares suficientes para comear e adicione os outros
medida que os descobrir.

Os atares so os instigadores de casos de uso. Agora que voc j identificou alguns atorcs, pode
comear a definir os casos de uso que eles executam.

Crie uma lista preliminar de casos de uso


Para defin ir seus casos de uso, voc precisa fazer algumas perguntas. Comece com sua lista de
atores conhecidos. Voc precisa perguntar o que cada ator faz com o sistcma.
No caso da loja da Wcb on- line, voc tem usurios regi strados c usurios convidados. O que
cada um desses atares faz?
Os usurios conv idados podem fazer o seguinte:
I. Navegar pelo cat logo de produtos.
2. Pesqu isar o catlogo de produtos.
3. Procurar um item especfico.
4. Pesqui sar o site.
5. Adicionar itens em um carri nho de compras e especificar a quantidade.
6. Ver o preo dos itens selecionados.
7. Mudar a quantidade de itens em seu carrinho.
8. Ver a lista de produtos popular e nova.
9. Navegar pela lista de itens desejados de outros usurios.
10. Solicitar mais inrormaes sobre produto.

Dia 9

Os usurios regi strados podem fazer o seguinte:


1. Tudo que o usurio convidado pode fazer.
2. Fazer uma compra.
3. Adicionar itens em sua lista de itens desejados.
4. Ver uma lista personalizada recomendada.
5. Manter sua conta.
6. Assinar notificaes.
7. Tirar proveito de ofertas especiais personalizadas.
8. Contro lar seus pedidos .
9. Ass inar vrias li stas de di stribu io.
10. Cance lar um pedido.

NOTA

Provavelmente existem muit o mais casos de uso. Entretanto, para nossos propsitos aqui e por brevidade, isso suficiente para comear.

Quando tentar identi fi car casos de uso, voc tambm dever fazer a pergunta, "como um atar
muda seu papel?"
No caso da loja on-l ine, um usurio convidado pode se tomar um usurio registrado, das seguintes maneiras:

O usurio convidado pode se conectar com o site.

O usurio convidado pode se registrar no si te.

Um usurio registrado se torna um us uri o convidado, como segue:

Um usuri o regi strado pode se desconectar do site.

At aqu i, essas perguntas so orientadas pela interao. Voc tamb m pode adotar uma estratgia orientada por resultados para a descobelta. Por exemplo, voc pode d izer que um usurio registrado recebe uma notificao. Um segundo ponto de vista pode ajud-l o a descobrir casos de
uso que voc poderia ter ignorado, se si mplesmente fica sse com o primeiro ponto de vista.
Finalmente, considere as vrias entidades que os usurios manipulam . Aqui, voc v produtos,
informaes sobre a conta e vrias listas de produto e descontos. Como todas essas entidades entram no sistema? Quem adiciona novos produtos e edita ou excl ui produtos antigos?
Esse sistema precisar de um terceiro atar, o administrador. Passando pelo processo anteriormente del ineado, voc pode verificar que os administradores podem fazer o seguinte :

Introd uo AOO (An lise Orientada a Objetosl

203

I. Ad icionar, edi tar e exclu ir produtos.


2. Ad icionar, edi tar c excl ui r incentivos.

3. Atualizar infonnacs de conta.

As perguntas podem levar a outras perguntas. Por exemplo, quem atua\iza a lista de produtos p0pu lares? Quem envia noti fi caes e correspondncias para as listas de dist ribuio? Um quarto
ator, o prprio sistema, executa todas essas aes.

Refine e nomeie os casos de uso


Agora que voc tem uma lista pre liminar de casos de uso, precisa refinar a lista. Em particular,
voc desejar procurar oport unidades de dividir ou combinar os casos de uso.
Dividindo casos de uso
Cada caso de uso deve executar um objetivo principal. Quando voc encontrar um caso de uso
que estiver fa zendo muita coisa, desejar dividi\o em dois ou mai s casos de uso. Considere o
caso de uso a seguir:
Os usurios convidados podem adicionar itens em um carrinho de compras e especi ficar a quan
tidade.
Voc deve dividir esse caso de uso em dois:
Os usurios convidados podem adic ionar itens em um carrinho de compras.
Os usurios convidados podem especificar a quantidade de um item.
Voc pode fazer a div iso de casos de uso, dev ido maneira como eles se relacionam entre si. Os
casos de uso so muito parecidos com as classes. Um caso de uso pode conter outro. Assim, se
uma instncia de caso de uso exige que outra faa seu trabalho, ela pode us-Ia.
Um caso de uso tambm pode estender o com portamento de outro caso de uso. Como resultado,
voc pode colocar comportamento comum em um caso de uso e, ento, desenvolver outros casos
de li SO que sejam especia li zaes do original. Pegue o exemplo "os usurios registrados podem
faze r uma compra". Um caso de uso pode espec ializar o ped ido, criando um caso de uso pedido
para presente. Um pedido para presente poderia ser entregue sem recibo.
Combinando casos de uso
Voc noquercasos de uso redundantes. Um modo de evitar a redundncia ficar atento s vari
antes do caso de uso. Quando voc as encontrar, dever combinar as variantes em um (mico caso
de uso.
Novo TERMO Uma varianle de caso de uso uma verso especializada de outro caso de uso mais
geral.

Dia 9

Considere os dois casos de uso a seguir:

Os usurios convidados podem pesqu isar o cat logo de produtos .

Os usurios convidados podem procurar um item especfico .

Aqui , o segundo si mplesmente uma variante do primeiro caso de uso mais geral.
Neste caso, o caso de uso difere apenas nos parmetros de pesquisa. melhor ter si mplesmente um caso de uso e documentar a variante nos modelos de caso de uso que voc construir posteriormente.
Uma variante muito parecida com uma instncia de uma classe. Lembre do exemplo
BankAccount. Um objcto BankAccount com um saldo de US$ l 0.000 pode ter mais dinheiro que
um BankAccount com US$ l 00. Entretanto, ambos ainda so objetos BankAccount. Tudo que d iferencia um objeto BankAccount de outro Ova lor de seus atributos. Os casos de uso funcionam da
mesma maneira.

Os casos de uso resultantes


Aps concluir o refinamento de seus casos de uso, voc deve nomear cada caso de uso. Assim
como na atribuio de nomes de atores, voc deve se esforar por nomear seus casos de uso de
maneira que evite confuso.
Aqui esto os casos de uso resultantes para us urios convidados e usurios registrados, aps a diviso e a combinao:
I. Navegar pe lo catlogo de produtos.

2. Pesquisar o cat logo de produtos.


3. Pesquisar o site.
4. Adicionar item no carri nho de compras.

5. Ver o preo dos itens.


6. Mudar a quantidade de item.
7. Ver a lista de produtos destacada.

8. Navegar em uma lista de itens desejados.


9. Solicitar informaes sobre produto.
10. Pedir.
I I. Manter o pedido.

12. Ad icionar itens na li sta de itens desejados.

13. Atualizar a conta.


14. Assinar a correspondncia.
15. Aplicar incent ivos.

Introduo AOO (Anlise Orientada a Objetos l

205

16. Conectar.
I 7. Desconectar.
18. Registrar.
Neste ponto, voc tem uma lista de casos de uso bem desenvolvida. Agora, basta especi fi car totalmente cada caso de uso.

Defina a seqncia de eventos de cada caso de uso


A breve lista de casos de uso s6 infonna parte da histria. Internamente, muito mai s poderia estar
ocorrendo dentro de um caso de uso. Pegue um pedido como exemplo. Um usurio no pode fa
zer um pedido em um passo. Em vez disso, ele deve usar uma seqncia de passos para conclu ir
um ped ido com xito (como fornecer um mtodo de pagamento).
A seqncia de passos que um usurio usa para completar um caso de uso conhecida como cenrio. Um caso de uso const itudo de vrios cenrios.
Novo

TERMO

Um cenrio uma seqUncia ou fluxo de eventos entre o usurio e o sistema.

Como parte de sua anlise de casos de uso, voc deve especificar os cenrios de cada caso de uso.
Vamos desenvolver o caso de uso Pedido. Primeiro, comece descrevendo o caso de uso em um
pargrafo:
O usurio registrado prossegue com a totalizao e pagamento, para adquirir os itens de seu
carrinho de compras. Uma vez na pgina de totalizao e pagamento, o usurio fornece informaes de entrega. Uma vez fornecidas, o sistema totaliza e apresenta o ped ido. Se tudo estiver correto, o cliente poder optar por cont inuar com o pedido. Quando o usurio continua
com o pedido, o sistema consulta suas informaes de pagamento. Uma vez fornec idas, o sistema autoriza o p<lgamento. Ento, ele exibe uma pgina de conformao de pedido fina l,
para os regist ros do usurio, e envia um e-mail de confinnao.
Existem alguns aspectos interessantes nesse caso de uso. Primeiro, ele no diz nada sobre a implementao subjacente. Segundo, voc pode us lo para identificar as condies prvias e pos
teriores do caso de uso.
Novo

TERMO

NOTA

Condies previas so aquelas condies que devem ser satisfeitas para que um caso
de uso comece. Condies posteriores so os resultados de um caso de uso.
Um dos problemas desse tipo de sistema que voc provavelmente no est
reun indo casos de uso dos usurios do sistema, mas das pessoas que querem
que voc os escreva. Lembre-se de que os modernos aplicativos da Web e outros aplicativos que se d eparam com o cliente, como quiosques, podem exigir
que voc trabalhe com grupos convergentes.

Dia 9

Aqui, a condio prvia que o usurio j colocou itens no carrinho. O caso de uso Ped ido pede
os itens do carrinho. A condio posterior um pedido. Aps completar a caso de uso, o sistema
conter um ped ido para o usurio.
Nesse ponto, ajuda considerar todos os caminhos alternativos no caso de uso de ped ido. Talvez a
autorizao de pagamento fa lhe ou o usurio decida cancelar o pedido, antes do trmino. Voc
precisa capturar esses cami nhos alternativos.
Aps se sentir vontade com o caso de uso, voc deve escrev-lo formalmente. Um modo de escrever o caso de uso listar os passos seqencialmente. Aps os passos, voc deve listar as condies prvias, as condi es posteriores e os camin hos alternat ivos. Considere novamente o
caso de uso Pedido:
o

Pedido
I. O usurio registrado passa para a totalizao e pagamento.
2. O usurio registrado fornece infonnaes de entrega.
3. O sistema ex ibe o total do pedido.
4. O usurio registrado fornece informaes de pagamento .
5. O sistema autoriza o pagamento.
6. O sistema conli rma o pedido.
7. O sistema envia um e-mail de continnao.

Condies prvias
o

Condies posteriores
o

Um carrinho de compras no vazio .


Um pedido no sistema.

Alternat iva: cance la ped ido


Durante os passos I a 4, o usurio opta por cancelar o pedido. O us urio volta para a homc
page.

Alternativa: a autorizao falhou


No passo 5, o sistema fa lha em autorizar as info rmaes de paga mento. O usurio pode
reintrod uzir as infonnaes ou cancelar o pedi do.

Voc precisar completar o mesmo processo para cada caso de uso. Defi nir formalmente os cenri os o ajuda a ver o fluxo de eventos no sistema, assim como a solidificar seu entendi mento do
sistema.

Introduo AOO (Anlise Orientada a Objet osl

207

Ao escrever seus casos de uso, inclua apenas as informa es que fizerem sentido. A ssim com o na m odelagem de classe, seu objeti vo transmitir algum
tipo de informa o. Inclua apenas as informaes para transmitir o que voc
est tentando fazer.

DICA

Inclua apenas as condies prvias necessrias para Que o caso de uso comece. Nilo inclua informaes extras e desnecessrias.
Certifique-se de consultar outros textos sobre casos de uso. Existem muitas
maneiras de escrever um caso de uso (no h um padro).
Ao escrever seus casos de uso pela primeira vez, considere o uso de uma ficha de
arquivo com um lpis. Desse modo, voc no ter de estar diante de um computador, enquanto gera seus casos de uso iniciais. Dependendo de quem forem
seus clientes, pode ser dificil trabalhar com eles diante de um computador.

Diagramas de caso de uso


Assim como a UML fo rnece uma maneira de documentar e transmiti r projeto de classe, tambm
existem maneiras formais de capturar seus casos de uso. De especial interesse so os diagramas
de caso de uso, diagramas de interao e diagramas de atividade. Cada um ajuda a visual izar os
vrios casos de uso.
Os diagramas de caso de uso modelam os relacionamentos entre casos de uso e os re lacionamentos entre casos de usoe atares. Embora a descrio textual de um caso de uso possa aj ud-lo a entender um caso de uso isolado, um diagrama o ajuda a ver como os casos de uso se relacionam
uns com os outros.
A Figura 9.4 mostra como modelar atares. A Figura 9.5 ilustra a notao UML para um caso de
uso: uma elipse rOlUlada.
FIGURA 9 .5

O caso dI!

liSO

lia UMC

pedido)

Coloque um atar e um caso de LISO juntos no mesmo diagrama e voc ter um diagrama de caso
de uso. A Figura 9.6 o diagrama de caso de uso Pedido.

FIGURA 9 .6

O caso de

I/S0

Pedido.

---,,>.. (

pedidO )

Usu ri o Registrado

Esse diagrama mu ito simples; entretanto, examinando-o, voc pode ver que o usurio registrado executa o caso de uso Pedido.

Dia 9
Os diagramas podem ser um pouco mais complicados. O diagrama tambm pode mostrar os relacionamentos existentes entre os prprios casos de uso. Conforme voc j leu, um caso de uso
pode conter e usar outro. A Figura 9.7 ilustra lal relacionamento.
FIGURA 9 .7

Um relaciOllamento lisa.

Pedido

uA

AssInatura da corrupond6ncl l

Aqui , voc v que o caso de uso Registro usa o caso de uso Assinatura da correspondncia.
Como parte do processo de regi stro, o usurio pode optar por receber e-mail s e notificaes.
A Figura 9.8 ilust ra o segundo tipo de relacionamento, o relacionamento estende.
FIGURA 9 .8

Um relaciollamelllO eSfellde.
U."'rio Registr.OO

Consult 1"" de prod uto. dsstacad.

V recomendaes de produto estende a genrica Consulta a /is/a de produ/os destacada, apre-

sentando ao usurio registrado uma li sta de produtos personalizados para suas preferncias de
compras. A normal V recomel1daes de produto, confonne vista por um usuri o convidado,
pode sim plesmente mostrar os itens mais vendidos ou mais solicitados. Essa extenso apresenta
ao usurio produtos nos qua is seu perfil sugere que ele poderi a estar interessado.
Assim como nas classes, possivel ter um caso de uso abstraio. Um caso de uso abSlrato um
caso de uso que outros casos de uso utilizam ou estendem, mas que nunca usado diretamente
por um atar em si. As abstraes nonnal mente so descobertas aps voc ter fe ito sua anlise de
caso de uso inicial. Enquanto voc estuda seus casos de uso, pode encontrar meios de extrair caractersticas comuns e coloc- Ias em casos de uso abstratos.

Introd uo AOO (An lise Orientada a Objetosl

209

Diagramas de interao
Os diagramas de caso de uso aj udam a modelar os relacionamentos entre casos de uso. Os diagra
mas de interao aj udam a capturar as interaes entre os vrios atares paT1icipantes do sistema.
Vamos expandiras casos de uso que vi mos anterionnente. Vamos adicionar um novo ata r, o representante de serv io ao cliente. Freqentemente, um usurio registrado pode se esquecer de
s ua sen ha. O representante de serv io ao cliente est l para ajudar o usurio a reaver o acesso
sua conta. Vamos criar um novo caso de uso, Senha Esquecida:
Um usurio registrado liga para o representante de servio ao cliente e informa ao represen
lante que perdeu sua senha. O representante de serv io ao c li ente pega o nome completo do
usurio e extrai as informaes de conta do usurio. O representante de servio ao cliente fa z
ento vrias perguntas ao us urio registrado, para estabelecer sua ident idade. Aps passar
por vrias interpelaes, o representante de servio ao cliente exc lui a senha antiga c cria uma
nova. Ento, o us urio recebe a nova senlla por email.
Esse caso de uso tambm pode ser descrito como segue:
o

Senha Esquecida
I. O usurio registrado liga para o representante de servio ao cliente.
2. O usurio regi strado fornece o nome completo.
3. O representante de servio ao cliente recupera as infonnaes do cliente.
4. O usurio registrado responde a vrias perguntas de idemificao.
5. O representante de servio ao cliente cria uma nova senha.
6. O usurio recebe a nova senha por ema il.

Condies prvias

Condies posteriores
o

O us uri o esqueceu s ua senha.


Uma nova senha enviada por email ao usurio.

Alternativa: a identificao falhou


O usurio pode fa lhar cm responder corretamente as perguntas de identificao no passo
4. Se ass im for, a chamada term inar.

Alternati va: usurio no encontrado


No passo 2, o nome fornec ido pode no ser o de um usurio conhecido. Se assim for, o re
presentante de servio ao cliente se oferecer para registrar o usurio chamador.

Existem dois tipos de diagramas de interao: diagramas de seqUncia e diagramas de colabora


o. Vamos explorar cada um deles.

Dia 9

Diag ram as de seqncia

Um diagrama de seqncia modela as interaes entre o usurio registrado, o representante de servio ao cliente e o site Web, com o passar do tempo. Voc deve usar diagramas de seqUncia quando quiser chamar a ateno para a seqUncia de eventos de um caso de uso, com o passar do tempo.
A Figura 9.9 apresenta um diagrama de seqUncia para o caso de uso Senha Esquecida.
Conforme voe pode ver na ilustrao, um diagrama de seqUnci a representa os eventos entre
cada atare o sistema (o site Web). Cada part icipante do caso de LI SO representado no incio
do diagrama como uma caixa ou como um desenho de pessoa (mas voc pode chamar ambos
de caixa).
Uma li nha tracejada, conhecida como linha da vida, sai de cada caixa. A linha da vida representa
o tempo de vida da ca ixa durante o caso de uso. Assim, se um dos atares fosse embora durante o
caso de uso, a li nha termi nari a na l tim a seta que termi na ou se origina no atar. Quando um atar
deixa um caso de uso, voc pode dizer que seu tempo de vida terminou.
FIGURA 9 .9

A diagrama de

seqiilla Se"ha
Esquecida.

SileWeb
Registrado

Representante de ServIo ao Cliente

1: Relata senha esquecida


2: SoIic:lte nome completo

3: Fornece nOrntl oompleto

.: Recupera inlorma6es do u.....io


5: Devolve .egi"ro
6: Fel pargunln de Identificao

7: Responde as perguntas

8: Gera nova IIn ll.


9: Envia senlla por email

Novo

TERMO

Uma linha da vida uma linha tracejada que sai de uma caixa em um diagrama de seqUncia. A linha da vida representa o tempo de vida do objelo representado pela caixa.

As selas se originam na linha da vida para indicar que o ata r enviou uma mensagem para outro
atar ou para o sistema. Quando voc desce na linha da vida, pode ver as mensagens conforme

Introd uo AOO (An lise Orientada a Objetos)

2 11

elas se originam seqencialmente, com o passar do tempo. O tempo corre de cima para baixo em
um diagrama de seqUnc ia . Assim , subi ndo na linha da vida, voc pode reprod uzi r a seqncia
de eventos de trs para frente.

Diagramas de colaborao
Voc deve usar diagramas de seqncia se tiver a inteno de chamar a ateno para a seqnc ia
de eventos com o passar do tcmpo. Se voc quiser modelar os relacionamentos entrc os atares e o
sistema, ento deve criar um diagrama de colaborao.
A Figura 9. 10 modela o caso de uso Senha

E.~qllecida

como um d iagrama de colaborao.

Em um diagrama de colaborao, voc modela uma interao conectando os part ici pantes com
uma lin ha. Ac ima da linha, voc rotula cada evento que as entidades geram , junto com a direo
do evento (para quem e le dirigido). Ele tambm aj uda a numerar os eventos, para que voc saiba em qual ordem eles aparecem.

FIGURA 9 .10

O diag/'ama de

colaborartio
Se"ha & q/lecidll.

Sil. W.b

Use diagramas de seqncia para modelar a seqncia de event os em um cenrio, com o passar do tempo.
Use diagramas de col abora o para m odelar os relacionamentos entre os atares em um cenrio.

Dia 9

Diagramas de atividade
Os diagramas de interao modelam bem as aes seqenc iais. Entretanto, eles no podem modelar processos que podem ser executados em paralelo. Os diagramas de ativ idade o aj udam a
modelar processos que podem ser executados em paralelo.
Considere outro caso de uso Pesquisa. Esse caso de uso pesqui sa o site Web c o catlogo de produtos simultaneamente, usando o caso de uso Pesquisa o catlogo de produtos e o caso de uso
Pesq/lisaosite. No h motivo pelo qual essas duas pesquisas no possam ser executadas simultaneamente. O usurio ficari a impaciente se tivesse de esperar que todas as pesqui sas termi nassem seqUencialmente.
A Figura 9. 1 I modela esses processos atravs de um diagrama de ativi dade.
Uma elipse representa cada estado do processo. A barra preta grossa representa um ponto onde
os processos devem ser sincronizados - ou reunidos-, antes que o fluxo de execuo possa ser
retomado. Aqui , voc v que as duas pesquisas so executadas em paralelo e depois reunidas,
antes que o site possa ex ibir os resultados.

FIGURA 9.11

O diagrama de

alil'idade
Pesquisa.

Vamos ver de perto os diagramas de interao e os diagramas de atividade nos prx imos dias.
Entretanto, ambos se mostram teis ao se analisar um sistema.

Introd uo AOO (An lise Orientada a Objetos)

213

Construindo o modelo de domnio


Atravs da anlise de caso de uso, voc captura as interaes do sistema. Entretanto, os casos de
uso tambm o aj udam a capturar o vocabulrio do sistema. Esse vocabulrio constitui o domnio
do problema. O vocabulrio do domnio identi fi ca os pri ncipa is obj etos do sistema,
O modelo de domnio lista os objetos que voc precisa para modelarcorretamente o sistema. Pe
gue a loja onl inc. Atravs dos casos de uso, voc pode identificar muitos objctos. A Figura 9. 12
visua liza alguns desses objelos.
Neste ponto, voc pode mode lar os relacionamentos entre os objetos do domnio. A Figura 9 .1 3
resume alguns desses relacionamentos.
FIGURA 9 .12

Os objelos do

*'

ReprfteII""'" do s .....

00 CIiont.

domnio.
lhW<Io lleglslr_

u...-",>'t '

FIGURA 9 .13

Sil.. d. W.b

CII"ogO

0,

relaciOl/alllelltos

dos objetos do
domnio.

Usu6tiO

Item

7*
lIepreHm.nl. de 50rvio ao Client..

Usujtio Comridado

UI",",- II-;irltado l ~

..

In'orma~ I I

<N Comi

Pedido

'

Dia 9

o modelo de domnio importante por vrios motivos. Primeiro, o modelo de domnio modela
seu problema independentemente de quaisquer preocupaes com implementao. Em vez disso, ele modela o sistema em um nvel conceituaI. Essa independncia proporciona a flexibilidade para usar o modelo de domnio que voc const ri para resolver muitos problemas diferentes
dentro do domn io.
Segundo, o modelo de domnio constri a base do mode lo de objeto que, fina lmente, se tornar
seu sistema. A implementao final pode adicionar novas classes e remover outras. Entretanto, o
domni o forneee algo para que voc comece e construa seu projeto - um esqueleto.
Finalm ente, um mode lo de domnio bem definido estabelece claramente um vocabu lriocOlllum
para seu problema. Encontrando-se um vocabu lrio comum, todos os envolvidos no projeto podero encar-lo a parti r de uma posio e um entendimento iguai s.

E agora?
Voc reuniu casos de uso. Voc criou diagramas de interao. Voc at iniciou um modelo de
domnio. O que fazer em seguida?
Os casos de uso tm trs uti lizaes pri ncipais. O primeiro uso trata da func ional idade. Os casos
de uso infonnam a voc como o sistema funcionar. Os casos de uso informam quem usar o sistema. o que esses usurios faro com ele e o que esperam receber do sistema. A anlise de caso
de uso o aj uda a aprender a respei to do sistema que voc pretende construir.
Segundo, os casos de uso fornecem uma lista de tarefas 'a faze r', medida que voc desenvolve
o sistema . Voc pode comear priorizando cada caso de uso e fornecendo uma estimativa do
tempo que cada um demorar para tenninar. Em seguida, voc pode ptanejar o tempo de seu desenvolvimento em torno dos casos de uso. A concluso de um caso de uso pode se tornar um
marco. Os casos de uso tambm se tomam itens de barganha. Freqentemente, as restries de
tempo o obrigaro a sacrificar um caso de uso por outro.
Finalmente, os casos de uso o ajudam a construi r seu mode lo de domni o. O modelo de domnio
servir como o esqueleto de seu novo sistema. (E se voc o tiver fe ito corretamente, poder reut ilizar esse mode lo em qualquer lugar!)
Quando voc perceber que o model o de domn io e a anlise de caso de liSO estilo quase terminados, pode comear a fazer o prottipo das diferentes partes do sistema. Entretanto, no faa o
prottipo de tudo. Voc s deve fazer o prottipo dos aspectos do sistema que parecem confusos
ou arriscados. Fazer o prottipo pode aprofundar o conhecimento, assim como descobri r se uma
idia possvel, identi fi cando e reduzindo os riscos.

Intro duo AOO (Anlise Orientada a Objet os )

215

Dicas para a AOO eficaz


Evite a paralisia da anlise. A paralisia da anlise ocorre quando voc tenta realizar a anlise perfeita. Voc n~nca vai ad iant e, pois fica tentando entender perfeitamente o p roblema. As vezes, o ent endimento total no
possivel sem algum projet o e implementao.
Faa iterao. Faa iterao de tudo. Quando voc com ear a anlise, gere
uma lista preliminar de casos de uso. Priorize os casos de uso e, em seguida, apresente-os atravs de iteraes. Cada iterao deve abranger certa
q uantidade de anlise, projeto e implement ao. A q uantidade de implementao aumentar m edida que o projeto prossegui r: muito pouco no
inicio, muito mais durante os estgios posteriores.
Incl ua os especialist as no dom inio em sua anlise - mesmo q ue o especialista seja um cliente. A no ser que voc seja especia lista no d omi nio,
precisa r da entra da para modelar o sistem a corretamente.
No introduza impl em entao em sua anlise. No deixe a impl ementao ent ra r furt ivamente em sua anlise.

Resumo
A anlise orientada a objetos apl ica objetos ao processo de anlise do problema. A AOO o ajuda
a descobrir os requisitos do sistema que voc pretende construir.
Os casos de uso o ajudam a identi fi car como os us urios vo interagi r com o sistema. Os casos de
uso descrevem a interao, assim como o que os usurios es peram receber do sistema.
Modelos como os d iagramas de interao e os diagramas de atividade ajudam a visualizar essas
interacs. Cada tipo de modelo v o sistema de um ponto de vista ligeiramente diferente.
Assi m, voc precisar lembrar das di ferenas e usar cada tipo quando for apropriado.
Os casos de uso oajudam a definir seu modelo de domnio. O modelo de domnio serve como es
queleto do sistema que voc fina lmente construir. O modelo de domnio tem a vantagem dc ser
livre de qua lquer imp lementao ou uso especfico. Como resultado, voc pode aplicar seu mode lo de domnio em mui tos problemas d iferentes.

im portante perceber q ue a AOO real mente um modo orientado a objetos de ver um proble
ma. Os casos de uso nada mais so do que obj etos. Um caso de uso pode se relacionar com o utros
casos de uso, atravs do uso ou da ge nerali zao. As vari antes dos casos de uso no so diferen
tes da di ferena entre instncias de classe. Os atares so objetos tambm.
A AOO decompe um problema em vrios casos de uso e objetos de domnio. Uma vez divi di
do, voc pode fazer iteraes at obter a soluo fina l.

Dia 9

Perguntas e respostas
P

o q ue acontece se voc esquece um caso de uso?

R Se voc verificar que se esq ueceu de um caso de uso, volte e acrescente-o. Se voc precisar do caso de uso imed iatamente, ento deve acrescent- lo imediatamente. Se ele puder
esperar, tome nota c explore-o durante a prxima iterao.
P Ao elaborar um caso de uso, voc sempre precisa fazer diagramas de seq ncia, colaborao e a tividade?

R No. Nem sempre voc precisa faze r todos os trs. Faa o que fo r necessrio pa ra ajudar
seu entend imento do caso de uso.
Entretanto, voc provavelmente deve pelo menos esboar um dos diagramas. Voc nunca sabe quais problemas ou incgn itas poderia descobrir.
Normalmente, sempre fazemos pelo menos o diagrama de seqncia, a no ser que faa
mais sentido comear com um dos outros.
P Como voc sabe quando tcm casos de uso sufic ientes ?

R Na verdade, voc nunca sabe se encontrou todos os casos de uso. Saber quando parar
vem atravs da experincia. Entretanto, voc provavelmente tem casos de uso suficientes
quando percebe que possui um entend imento adeq uado do problema eque se sente confiante de que pode prosseguir.
Se voc omiti r um caso de uso, sempre pode voltar e acrescent-lo em sua anlise. Entretanto, voc deve tomar cuidado com a anlise em demasia de um problema. No sucumba paral isia da anlise.

Workshop
As perguntas e respostas do teste so fornecid as para seu mel hor entendimento. Veja as respostas no Apnd ice A, "Respostas".

Teste
I. o que um processo de software?
2. O que um processo iterativo?
3. No fi na l da AOO, o que voc deve ter fe ito?
4. O que os requisitos do sistema informam a voc?
5. O que caso de liSO?
6. Qua is passos voc deve dar para defin ir seus casos de LISO?

Intro duo AOO (Anlise Orientada a Obje tos )

217

7. O que um atar?
8. Quais so algumas perguntas que voc pode fazer para descobri r os atares?
9. COnl O os casos de uso podem se relacionar entre si?
10. O que uma variante de caso de uso?
I I.

O que um cenrio?

12.

Quai s so algumas mane iras pelas quais voc pode mode lar seus casos de uso?

13.

Descreva as diferenas entre os vrios modelos usados para visua lizar casos de uso.

14.

Para que serve um mode lo de domnio?

15.

I)ara que servem os casos de uso?

Exerccios
I. Quais outros casos de uso voc poderia acrescentar na lista de casos de uso da loja on-li ne?
2. Pegue um dos casos de uso da questo I e desenvolva-o.
3. Uma variante de caso de uso um caso especfico de um caso de uso mais geral. Quais
variames voc consegue identificar nos casos de uso de usurio convidado e de usurio
registrado?
4. Qua is outros objetos de dom inio voc consegue encontrar?

SEMANA

DIA
Introduo ao POO (Projeto
Orientado a Objetos)
Ontem, voc viu como a AOO (Anli se Orientada a O bjetos) o ajuda a entender um problema c
seus requisitos. Atravs da anli se de casos de uso e da construo de um modelo de domn io,
voc pode capturar o ' mundo real ' ou detalhes em nvel de domn io deseu problema. Entretanto,
a ADO apenas parte da histria geral do desenvolvim ento.
O roo (Projeto Orientado a Objetos) o ajuda a pegar a domnio que voc encontrou na AOO e a
projetar urna so luo. Enquanto o processo da AOO o aj udou a descobri r muitos dos objelos de
domn io do problema, o
o ajuda a descobrire projetar as objetos que aparecero na soluo
especfi ca do probl ema.

roo

Hoje voc aprender:

Como transformar sua an lise cm uma soluo

Como identi fi car e projetar os objelos que aparecero em sua soluo

Como os cartes CRC (Classe Responsabilidade Co laborao) podem aj ud-lo a descobrir responsabilidades e relacionamentos de objetos
Como voc pode usar a UML para capturar seu projeto

Dia 10

POO (Projeto Orientado a Objetosl


Novo

TERMO

Novo

TERMO

POO o processo de construir o modelo de objeto de uma soluo. DilO de outra ma


neira, roo o processo de dividir uma soluo em vrios objetos const itu intes.

o modelo de objeto o projeto dos objetos que aparecem na sol uo de um proble

ma. O modelo final de objeto pode conter muitos objetos no encontrados no dom
nio. O modelo de objeto descrever as vrias responsabi lidades, relacionamentos e estrutu ra do
objeto.

o processo de POO o ajuda a descobrir corno voc vai implementar a anlise que com pl etou du
rante a AOO. Principalmente, o modelo de objeto que conter as classes pri ncipais do projeto,
suas responsabil idades e urna definio de como elas vo interagir e obter suas informaes.
Pense no roo em termos da construo de uma casa para uma famlia. Antes de construi r a casa
de seus sonhos, voc decide quai s tipos de ambientes deseja em sua casa. Atravs de sua anlise,
voc pode achar que deseja uma casa que tenha uma cozinha, dois quartos, doi s banheiros e um
lavabo, uma sala de estare uma sala de jantar. Voc tambm pode precisar de um gabinete de lei
tura, uma garagem para dois carros e urna piscina. Todos os ambientes e a piscina compreendem
a idia e o projeto de sua casa.
O que voc faz em seguida? Um construtor simplesmente comea a construir? No. Primeiro,
um arqui teto descobre como os ambientes mel hor se encaixam, comoa fiao deve ser passada e
qua is vigas so necessrias para manter a casa de p. Ento, o arquiteto prepara um conjunto de
cpias heliogrficas detalhadas, que capturam o projeto. O construtor usa essas cpias hei iogr
ficas como guia, enq uanto constri a casa.
Usando os termos do mundo da construo, voc usa o roo para criar as cpias heliogrficas de
seu programa.
Um processo de projeto formal o ajuda a determinar quais objetos aparecero em seu programa e
como eles vo interagir ou se encaixar. O projeto indicar a estrutura de se us objetos e um pro
cesso de projeto o ajudar a descobrir muitos dos prob lemas de projeto que voc encontrar ao
cod ificar.
Ao se trabalhar como parte de uma equipe, importante identificar e resolver o mximo de pro
blemas de projeto possvel, antes de iniciar a construo. Resolvendo-se os problemas antecipadamente, todo mundo trabalhar sob o mesmo conjunto de suposies. Uma estratgia
consistente para o projeto tornar mais fcil reunir todos os componentes posteriormente. Sem
um projeto claro, cada desenvolvedor far seu prprio conjunto de suposies, freq Uentemente
incompativel com outros conjuntos de suposies. O trabalho ser duplicado e a diviso de res
ponsabilidades entre os objetos ser desfei ta. De modo geral, o projeto que emerge poderia se
tornar fac ilmente uma confuso, se no estiver todo mundo na mesma pgi na.

Introduo ao POO (Projeto Orientado a Objetos)

Alm disso, erros so exponencia lmente mais dispendiosos para corrigir, quanto mais tarde na
seqncia de desenvolvi mento eles forem descobertos. Os erros no projeto tm um custo muito
baixo para corrigir.
Enquanto projetar sua soluo, voc ver que freqi.ienlemen le ex iste mais de uma soluo para o
problema. O POO pennite que voc explore cada sol uo interessante e decida antecipadamente
qua l caminho deve seguir. Atravs do projeto, voc pode tomardeci5es acertadas, e atravs da
documentao, voc pode documentar o motivo pelo qual optou pelas escolhas que fez.
O modelo de objeto identifica os objetos significativos que aparecem na soluo; entretalllo, o
modelo de objeto um superconjunto do domnio. Embora mu itos dos objetos que apa recem no
modelo de domnio encontrem seu lugar no projeto, muitos objetos no encontrados no modelo
de domnio tambm aparecero. Do mesmo modo, objetos no encontrados na anli se podem
achar seu lugar no projeto, cxatamente como a fiao no aparece na anlise inicia l de uma nova
casa. Uma vez tendo seu projeto, voc pode comear a codi fic ar.
Dito isso, no leve o projeto ao extremo. Exatamente como a AOO pode sofrer de paralisia da
anlise, o POO pode so frer de paralisia do projeto.
Voc deve evitar o projeto demasiado de sua soluo. Simplesmente no possvel prever cada
deciso de projeto que voc precisar tomar, antes de tom-la, e alguma parte do projeto pode ser
deixada para o momento da construo. Voc no quer ser pego tentando criar o projeto perfe ito;
voc precisa comear a cod ificar em algum momento. O que voc precisa fazer projetar os aspectos arq uitetonicamente significativos do sistema.
Como voc sabe quais aspectos de seu sistema so arqllitetonicGmente significativos? As partes
significativas so os aspectos do sistema onde uma deciso diferente alteraria completamente a
estrutura ou o comportamento do sistema.
Lembre da loja on- line e do carrinho de compras discutidos ontem. Sabendo que tem um objeto
carrinho de compras em sua anlise, voc precisa projetar quais abstraes especificas sero usadas para representar o carrinho de compras - como um mostrador de preo, uma loja persistente
e um monitor de expirao. Mas voc no precisa projetar uma tabela hashing ou vetor que ser
usado para representar o contedo do carrinho - esse um assunto apropriado para lima fase de
projeto detalhado (implementao), mas detalhado demais para esta fase.

Como voc aplica POO (Projeto Orientado a


Objetol?
o poo um processo iterativo que identifica os objetos e suas responsabilidades em seu sistema, e como esses objetos se relacionam . Voc refina continuamente o modelo de objetos, quando faz a iterao pe lo processo de projeto. Cada iterao deve dar uma idia mais aprofundada
do projeto e ta lvez at do prprio dominio.

Dia 10

NO TA

Quando voc aprender mais sobre o problema que est tentando resolver durante o projeto, tal vez precise aplicar m ais anlise. l embre-se de que no h
vergonha em volta r e refinar sua anlise ! A nica vergonha est em cri ar soft ware intil.

Existem vrios passos pouco defin idos que voc pode seguir para construi r seu modelo de objeIas. Nonnal mente, voc:
I. Gerar uma lista inicial de objetos.
2. Refi nar as responsabi lidades de seus objetos.
3. Desenvo lver os pontos de interao.
4. Detalhar os relacionamentos entre objetos.
5. Construi r seu mode lo.
Seu entendimento do projeto aumentar quando voc completar esses passos e repetir o processo.

NO TA

Existem muitas maneiras de completar o poa. Os passos delineados anteriorm ente constituem um processo informal que combina aspectos de muitas m etodologias diferentes.
A metodologia que voc vai seguir depender da exper incia, do dominio, da
postura da empresa e do bom gosto. No final do paa, voc deve ter decom posto a soluo em v rios objetos. Como voc chega a esses objetos fi ca por
sua conta e da sua equipe de projeto.

Passo 1: gere uma lista inicial de objetos


Quando comea a projetar seu sistema, voc precisa comear com o domnio que de fi ni u durante
a anlise. Cada objeto do domn io e cada ator deve se tomar uma classc cm seu novo mode lo de
objetos. Voc ver que alguns dos objetos de domnio no tero lugar em seu modelo de objetos
final ; entretanto, neste ponto, voc no pode ter certeza de qual ter; portanto, voc precisa incl uir todos eles.
Lembre da loja on-line do Dia 9, "Introd uo AOO (An li se Orientada a Objelos) ". A Figura
10.1 iluslra as classes bsicas que aparecero em seu mode lo de objetos ini cial.
Ao procurar a lista de classes inici al, voc tambm desejar considerar todos os eventos q ue possam afelar seu sistema. Cada um desses eventos deve aparecer inicialmente como uma classe. O
mesmo pode ser dito para todos os relatrios, leias e disposit ivos. Todos esses elementos devem
ser transformados em uma classe.

223

Introduo ao POO (Projeto Orientado a Objetos)

FIGURA

10.1

As classes ba.icas da

''''"

"'"''

l oja oll lille.

' ,m

CII!JIomerServiceAep
ShopplngClrt

Aecollml nlo,m.tion

Glle.tUM'

Aqui esto algumas dicas para animar essa lista de classes inicial:
Transforme cada ator em uma classe.
Transfo rme cada objeto de dom nio em uma classe.
Transforme cada evento em uma classe.
Considere como o sistema apresentar informaes e transform e cada
tela em um objeto.
Represen te todos os outros sistemas ou di spositivos com os quais o sistema interage com o classes.

Neste ponto, voc no pode di zer muito a respeito das c lasses que listou. Voc pode ter uma
idia geral das responsabilidades e relacionamentos dos objetos; entretanto, voc precisa se
aprofundar um pouco mai s, antes de poder finalizar seu entendimen to das novas classes.

Passo 2: refine as responsabilidades de seus objetos


Uma li sta de objetos um bom ponto de partida, mas apenas uma pequena parte de se u projeto g lobal. Um proj eto com pleto capturar as responsabilidades de cad a obj eto, assim como a
estrut ura e os re lac iona men tos do objeto. Um proj eto mostrar como ludo se encaixa.
Para ter esse entendimento, voc precisa identificar o que cada objeto faz. Existem dois aspectos
q ue voc precisa explorar para que possa responder pergunta, '0 que o objeto faz?"
Primei ro, voc precisa explorar a responsabi lidade. Atravs do encaps ulamento, voc sabe
q ue cada objeto deve ter um nmero peq ueno de responsabilidades. Dura nte o projeto, voc
prec isa identi ficar as responsabilidades de cada objeto e d ividira objelo. quando e le comear a

Dia 10

fazer coisas demais. Voc tambm precisa ce rtificar~se de que cada responsabil idade aparea
apenas uma vez e esse conhecimento espalhado igualmente entre todos os objetos.
Em seguida, voc precisa explorar o modo como cada objeto faz seu trabalho. Os objctos fre~
qentemente delegaro traba lho para outros objelos. Atravs de seu projeto, voc precisa ident i~
fi car essas colaboraes.
Novo

TERMO

Um objero delega trabalho para colaboradores.

Novo

TERMO

Colaboracio o relacionamento onde os objetos interagem para realizar o mesmo


propsito.

Um entendimento pro fun do dos relacionamentos e responsabili dades de um objeto im portante.


Em um nvel prtico, as responsabilidades sero transform adas em mtodos. Os relacionamentos sero transformados em estruturas; entretanto, um entendimento global da responsabilidade
o ajudar a dividir a responsabilidade eficientemente entre os objetos. Voc prec isa evitar ter
um pequeno conjunto de objetos grandes. Atravs do projeto, voc ter a certeza de dividir as
responsabi lidades.

o que so cartes CRC?


Uma maneira dc distribuir responsabilidades e colaboraes atravs cio lISO de cartes CRC (Classe
Responsabilidade Colaborao). Confonne o nome sugere, um carto CRC nada mais do que uma
ficha de arquivo 4x6 com linhas.
Quando voc comea a projetar pela primeira vez, di ficil simplesmente comear a listar mtodos e atributos. Em vez disso, voc precisa comear a identifi car o propsito de cada objeto.
Os cartes CRC ajudam a defin ir o propsi to de um objeto, chamando a ateno para as responsabilidades do objeto. Quando usa cartes CRC, voc simplesmente cria um carto para cada
classe. Voc esc reve o nome da classe no incio do carto e, em seguida, divide o carto em duas
sees. Li ste as responsabilidades no lado esquerdo e, no lado direito, liste todos os outros objetos que o carto precisa para executar suas responsabilidades.
A Figura 10.2 ilustra um modelo de carto CRC.
Os cartes CRC so intencionalmente de baixa tecnologia. Voc intencionalmente limitado
pelo tamanho do carto. Se voc achar que o carto no grande o su fi ciente, silo boas as chances de que preciso dividir a classe. Uma grande vantagem dos cartes e RC que voc no fi ca
preso a um computador. Acredite se qui ser, ter de projetar diante de um computador nem sem pre
desejvel. O projeto no um exerccio solitrio e pode exigir conversas e di scusses ent re os
projet istas. Os cartes CRC liberam voc e seus colegas projet istas para projetar quando e onde
quiserem. Projete no almoo; v at uma sala de confer ncia ou para um banco de parque. Desde
que possa usar seus cartes, voc pode projetar.

Introduo ao POO (Pro je to Orientado a Objetos)

FIGURA 10.2

Nome da dasse

Um modelo tle
caruio CRC.

"'I'i:

-<I"-

CoI.bor.oos

--

Responsabilidade

Os cartes CRC tambm o liberam de ter de manter um modelo eJelrnica atualizado. Em breve
seu modelo mudar freqUenteme nte e ter de manter o modelo atualizado pode ser uma grande inconvenincia. Em vez disso, voc simplesmente pega seus cartes e apaga, rabisca, dobra, escreve e os rasga, quando necessrio. O custo de mudar um carto muito mais barato (e mais
imediato) do que ter de atua lizar algo em seu computador. Ter de parar a sesso de CRC e atualizar um computador pode interromper o fluxo da sesso.
Finalmente, os cartcs C RC tm apelo em nossos instintos mais primiti vos. Eles apenas aj udam
a ler algo concreto que voc possa pegar. Em vez de ter de modelar vrios projetas alternativos,
voc pode apenas movimentar seus cartes. Para modelar interaes, voc pode sentar-se com
outros prajetistas, dividir os cartes e percorrer as interaes. Tal processo interat ivo est imula a
d iscusso.

Como voc aplica cartes CRC?


A criao de cartes CRC no um exercicio solitrio. Em vez disso, voc deve manter sesses
CRC com outros projetistasldesenvolvedores, para que o processo de projeto seja o mai s interativo possvel.
Voc in icia uma sesso escolhendo vrios casos de uso. A quantidade que voc escol he depende
do tempo de que dispe e da dificuldade dos casos de uso. Se voc tiver alguns casos de uso muito grandes, pode fazer sentido ter uma sesso por caso de uso. Se voc tiver muitos casos pequenos, vai querer atacar vrios casos de uso durante a sesso. O importante que voc manipu le
casos de uso relacionados e que torne notvel o progresso em seu projeto. No pernlilaqueo processo sofra empecil hos.
Quando voc escolher os casos de uso, identifique as classes principais e crie um carto para
cada uma. Quando voc tiver os cartes, divida-os entre os projetistas e, em seguida, inicie a ses-

Dia 10

so. Durante a sesso, voc investigar o cenrio de cada caso de uso. medida que voc percorrer o cenrio, cada projetista dever se concentrar nas responsabilidades e colaboraes de sua
classe. Quando sua classe for necessria no cenrio, notar seu liSO e di r a todos os outros projetistas se preci sa delegar para outro objeto.
A estratg ia que voc adota para a sesso de projeto questo de preferncia pessoal. Algumas
metodologias ex igem o desempenho do papel, onde cada projetista recebe um carto e representa o papel da classe. Out ras metodologias so um pouco mais formais. A estratgia escolh ida fi ca
por sua conta e de s ua equipe de projeto. O importante que todos fiquem engajados no processo
e que ningum fique excl uido. Edurante essas sesses que voc di scut ir a lternati vas de projeto,
descobrir novos objetos e constru ir a camaradagem na equipe.

Um exemplo de carto CRC


Vamos considerara caso de uso Pedido do Dia 9 e ver como voc poderia usarcartcs CRC para
atribuir responsabilidades para ele.

Pedido

O usurio registrado passa para a totalizao e pagamento.


O usurio reg istrado fornece informaes de ent rega.

O sistema mostra o total do pedido.

O us urio registrado fornece infonnaes de pagamento.

O sistema autoriza o pagamento.

O sistema confirma o pedido.

O sistema envia um e-mail de confinnao.

Condies prvias

Condies posteriores

Um pedido no sistema.

Alternativa: cancelar pedido

Um carrinho de compras no vazio.

Durante os passos I a 4, o usurio opta por cancelar o ped ido. O us urio volta para
home page.

fi

Alternativa: a autorizao fal hou

No passo 5, o sistema falha em autorizar as informaes de pagamento. O usurio


pode introd uzir novamente as infonnaes ou cancelar o pedido.

Comece ident ificando as classes. Imed iatamente, voc ver: Usur i o Reg i s trado, Ped i do, Pagamento, Confi nnao de Pedido, Carri nho de Comp ras, Infonnaes de Entrega . Talvez voc
tambm q ueira incluir Si s tema ; entretanto, h um problema . Nos casos de uso, tudo que no fo i
feito por um ator foi feito pelo sistema ' tudo includo'. O objetivo da anlise era entender o problema. Ento, em vez de tentar dividir o sistema em suas partes, a anli se tratou como uma
grande caixa preta. Atravs do projeto, voc vai decompor o sistema em suas panes.

Intro duo ao POO (Projeto Orientado a Objetos)

227

Se um carto de sistema vai ser incluido ou no vai depender da complexidade do sistema. l)ode
ajudar listar todas as responsabilidades do sistema em um cano e, em seguida, dividir esse carto em vrias classes, posteriormente. Neste caso, entretanto, voc pode tentar decom por o sistema, antes de comear. Sc voc se esquecer de algo, sem pre pode acrescentar posteriormente.
Comece lendo os passos do cenrio. Aqui , o sistema autoriza o pagamento, ex ibe e con fi rma o
ped ido. O sistema tambm cria e introduz o pedido. Voc pode comear divid indo o sistema em
Funcionrio, Mostra Pedido e Terminal de Pagamento.
Quando voc se sentir confortvel com s ua lista de classes, pode criar os cartes C RC, como
ilustrado na Figura 10.3.

FIGURA 10.3
Algl/l/:" dos cOr/ue:.' CRC

.,w,., ... c

'

...

u_ ......,_

=l

para Pedido.

o prximo passo percorrer cada passo do cenrio e identi fi car responsabilidades. O passo I, "o
usurio regist rado passa para a totalizao e pagamento", simplesmente um cl ique em um link
na interface. Por simplic idade, vamos ignorar a interface. O passo 2, "o usurio registrado fornece informaes de entrega", um pouco mais interessante. Aqu i, voc v que o Usu!rio Reg l st rado responsvel por fornecer suas informaes de entrega para o Funcion!rio.
A Figura 10.4 il ustra o carto resultante.

FIGURA 10.4

O carl(io e RC de
Usu6rio Regi s trado.

Usu6rio Registredo
fomoce informaOes de

enlreg~

In lorma6e. de Entrega

Dia 10

NO TA

Quando voc ver que um objeto 'providencie' ou 'fornea' algo, precisar certifica r-se de que o objeto no esteja atuando como uma simples estrutura de dados.
Se o objeto no fizer nada alm de forn ecer acesso s informaes, voc desejar combinar esse objeto com o q ue manipula os dados.

o passo 3. "o sistema exibe o total do ped ido''. um pouco mais complicado. Antes que o sistema possa exibi r algo, o Funci onri o deve introduzir o pedido, ver o preo dele e totalizar o pedido.
O Funcionrio usar o Carri nho de Compras para recuperar os itens e o Mos tra Pedido para exi~
bir o pedido resu ltante; entretanto, o Fune i onri o provavelmente no deve ser responsvel tam~
bm por ver o preo ou por totalizar o pedido. Essas tarefas so melhores delegadas para outro
objeto. Lembre~ se de que um objeto s deve ler um peque no nm ero de responsabilidades.
O objeto Ped i do deve cuidar de ver o preo e talaiizar o pedido. A Figura 10.5 resume as respo n~
sabilidades do Funcionlirio at aqu i.
O objeto Pedido tambm deve conter as itens que esto sendo adquiridos. O objeto Item fo i ig~
norado durante a criao da lista de classes; portamo, voc deve adicion- lo agora. O objelo I tem
contm informaes de preo e produto, assi m como uma quant idade. O objeto Item tambm
conter todos os incentivos que o usurio possa ter apl icado. I ncent i vo outra classe que voc
deve adicionar na lista.
Os passos restantes so muito parecidos com os outros. O Usurio Registrado fornece infonnaes de Pagamento, o Funcionlirio autoriza o pagamento e fina liza o pedido.
As fi guras 10.6e 10.7 resumem as responsabi lidades do Funcionrio edo Usurio Registrado.
FIGURA 10.5
O carl{io CRC

recuperllnforma6es de In'rllla. pallamento

Inlo.m~.

pafO Functom1 r io.

Introdu! o pedido

C'fflnho d. Comp,"
Pedido

uibe o pedido

Mo",. Ptilldo

funeion rio
d. Entr80'

229

Introduo ao POO (Pro jeto Orientado a Objetos)

FIGURA 10.6

Fu nclon6 rlo

O Cl/rlaO CRC para

llK:upera informaes de entrega e pag,mento

InfOfma6e* d. Enu~.

Funcionl'irio cOlI/plelo.

introduz o pedido

ea" inho de Compras


~;do

exibe O pedido

Mostre Pedido

autori .. o pedido
confirma o pedido

Terminal de P'g.mento
~ido

Quantas responsabilidades por classe?


Ao desenvolver seus cartes CRe, voc precisa garantir que cada classe tenha apenas duas ou
trs responsabilidades principais. Se voc tiver mais responsabil idades, dever dividi r a classe
em duas ou mais classes separadas.
AL.ERTA

Voc deve considerar a d iviso da classe, mas em sistemas reais, isso no


necessariamente realista.

FIGURA 10 .7

Usu6rio Registrado

O C(lrf(io CRC IXlra

101'11_ inlormll6l1 de emr"'ll'

InformJ~" cIt

Usul'irlo Registrado.

fome inlormll6.s da PIIIamenlO

Pag.mento

Entteg.

--I

Pegue a classe Funcionrio, por exemplo. O Func ionrio responsvel por:

Recuperar infonnaes de pagamento e entrega .


Introduzir o pedido.

I 230

Dia 10

Exibir o pedido.

A utorizar o pagamento.

Confi rmar o pedido.

Confonne a Figura 10.8 ilustra, e ntretanto, todas essas responsabilidades caem sob a responsa bi lidade de ' Processa Ped ido'.

FIGURA 10.8
Processa Pedido.

Funcio nrio
r.,;upe .. informa6e. de en!<eGl e

~.menta

Uw'rio Roogimado

introdu. a pedido

C.urinha d, Compr
Padldo

exibe a pedido

Moerr. Pedido
Terminal de P.Ol me nta

autoriza o pedido
conllrma a pedido

Proce_ Pedido

Pedido

importante li sta r subtarefas; entretanto, voc no quer fazer isso em demas ia. O importa nte
que todas as sub-responsabil idades trabal hem para um objeti vo com um. Aqu i, todas as tarefas
trabalham para o processamento de um pedido.
Ao trabalhar com cartes C RC. voc tambm precisa lembrar que eles ate ndem um props itoespecfico: defi ni r responsabi lidades e relac ionamelllos de colaborao simples. No use cartes
C RC para desc rever relacioname ntos complexos.
Voc tambm deve manter os cartes CRC com baixa tecno log ia cesso de carto C RC.

no tente automati zar o pro-

Limitaes do carto CRC


Assim como toda boa fe rramenta, os cartes C RC tm seus usos, bem como suas lim itaes.
Os cartes C RC foram dese nvolvi dos originalmente como uma ferramen ta de e nsino. Como res ultado, eles so uma manei ra excelente de encarar o projeto inicial de um siste ma - especia lmente se voc for in icia nte e m 00.
Entreta nto, os cartes CRC so di ficcis de usar quando o projeto se toma mais complicado. Pode
se r di ficil controla r inte raes complexas entre os objetos, si mplesme nte atravs do uso de cartes C RC. Um grande nmero de classes tambm toma o uso de cartes desajei tado. Tambm

Introduo ao POO (Projeto Orientado a Objetos)

pode se tornar dificil continuar a usar cartes CRC, quando voc comear a modelar. Manter os
dois em sincronismo pode ser um desafio.
O melhor conselho usar o que runciona. Use cartes CRC at que eles no mais auxiliem o processo de projeto. Nesse momento, simplesmente pare de us- los.

DICA

auando voc deve usar cartes CRC?


Durante os est gios iniciais do projeto.
auando voc ainda inicia nte em 00.
Para descobrir responsabilid ades e colaboraes.
Para percorrer um cen rio. No apenas os cartes encontraro responsa bilidades e colaboraes, como pOdem ajud-lo a ent ender melhor o cenrio.
Em projetas menores ou para se concentrar em uma seo menor de um
projeto grande. No tente atacar um projeto inteiro com cart es CRC.

Passo 3: desenvolva os pontos de interao


Quando tiver completado seus cartes CRC para um conjunto de casos de uso, voc preci sar
desenvolver os pontos de interao. Um ponto de interao qualquer lugar onde um objeto use
Outro.
Novo

TERMO

Um pomo de imera(;o qualquer lugar onde um objeto use outro.

Existem vrios problemas a considerar sobre o ponto de interao.

Interfaces
Voc precisa de uma interrace bem definida, onde um objeto usa Outro. Voc qucr ter certeza de
que uma alterao em uma implementao no v danificar o outro objeto.

Agentes
Voc tambm precisa ver as interaes de forma crt ica. Pegue uma biblioteca, por exemplo.
Uma bibli oteca tem prateleiras e livros. Quando hora de tirar um livro da prateleira, o livro chama um mtodo removeBook() na prateleira ou a prateleira que chama um mtodo removeBook ()
no livro? Na verdade, a responsabi lidade no pertence ao livro ali prateleira. Nenhuma das escolhas modela adequadamente o mundo real. No mundo real, uma bi bliotecria ou um cliente retirar o li vro. As bibliotecrias e os clientes tambm podem aparecer no mundo 00; entretanto,
o mundo 00 chama esses atares de agentes ou intermedirios.
Novo

TERMO

Um agellle faz a mediao elllre dois ou mais objelos para atingir algum objetivo.

Ao desenvolver pontos de interao, voc desejar prestar ateno em lugares para usar agentes.

Dia 10

Consideraes futuras
Ao considerar as interacs, voc desejar procurar lugares onde o objcto que est sendo usado
possa mudar. Se voc puder local izar tais lugares com preciso, desejar projetar a interao de
ta l maneira, que ela no ser desfeita caso novos objetos sejam introduzidos. para planejamento de mudana que serve sofiware prova do futu ro. Em tais lugares, voc desejar estabelecer
relacionamentos com capacidade de conexo e usar polimorfismo, para que possa introduzir novos objetos a qualquer momento.
Assim como em tudo, entretanto, no faa isso em demasia. Planeje a alterao apenas em lugares onde voc saiba com certeza absoluta que ocorrer uma mudana. Existem duas maneiras gerais de prever o futuro:

A alterao um requisito. Se os requisitos solicitarem alteraes futura s, projete a alterao.


Se voc est iver usando uma biblioteca de terceiros e quiser migrar para uma nova verso
de forma transparente no futuro, planeje a alterao.

O primeiro caso melhor resolvido pelo estabe lec imento de algum tipo de relacionamento com
capacidade de substituio, atravs de herana. O segundo req uer um pouco mais de trabalho.
Voc desejar em pacotar a biblioteca em classes que criou. Voc deve tomar o cuidado de projetar esses em pacotamentos para tirar proveito da capacidade de conexo e do pol imorfismo.

Tra nsformao de dados


Durante o projeto, voc pode encontrar lugares onde precisa transformar dados, antes de pass-los para outro objeto. Normalmente, voc delegaria tal transformao de dados para outro objeto; se precisar alterar a transformao, voc s precisar atualizar a classe de transformao.
Essa prtica tambm ajuda a divid ir responsabi lidades.
Ao considerar esses pontos de interao e adicionar novas classes, talvez voc precise rever e
atualizarseus cartes CRC ou modelo de obj etos (se voc tiver iniciado a modelagem formal).

Passo 4: detalhe os relacionamentos entre os objetos


Quando voc tiver estabe leci do os relacionamentos de responsabilidade e colaborao bsicos,
precisar detalhar os relacionamentos complexos entre as classes. Ea que voc define as dependncias, associaes e generalizaes. Detalhar esses relacionamentos Ulll passo importante,
pois isso define como os objetos se encaixam. Isso tambm define a estrutura interna dos vrios
objetos.
Comece com os cartcs CRC. Embora eles no capturem cada relacionamento, eles capturam a
colaborao. Eles tambm vo sugerir alguns outros relacionamcntos.
Procure classes que com partilhem responsabilidades semelhantes. Se duas ou mais classes compartilham o mesmo conjunto de responsabilidades, so boas as chances de que voc possa contar

Intro duo ao POO (Projeto Orientado a Objetos)

com as caractersti cas comuns em uma classe base. Voc tambm desejar rever o passo 3 e considerar todos os relacionamentos com capacidade de substituio que poderia preci sar.

Passo 5: construa seu modelo


Q uando chegar ao passo 5, voc j ter modelado o sistema fonnal mente. Um mode lo completo
consistir em diagramas de classe e diagramas de interao. Esses diagramas descrevero a estrutura e o relacionamento das vrasclasses do sistema. A UML tambm define modelos para mooelar interaes, transio de estado e atividades. Para os propsitos deste livro, entretanto, voc vai
se concentrar nos d iagramas de classe e interao. Voc viu os dois ti pos em dias anteri ores.
A Figura 10.9 modela a estrutura Pedido.
O modelo Pedido ilustra todos os relacionamentos importantes entre Pr:dido e as classes que ex ibem o pedido. Concebivelmente, voc tambm ter modelos que ilustram os relacionamentos
entre Func ion.! r io, Pedi dos e Usur i o Registrado.
Novamente, voc quer apenas modelar o que faz senti do~ os componentes arqu itetnicos interessantes. Lembre-se de que voc est tentando transmitir informaes especficas atravs de
seus modelos e no simplesmente apresentar modelos por questes de documentao.
A Figura 10. 10 ilustra o diagrama de seqncia atua li zado para o caso de uso Pedido.

FIGURA

10.9

MOI/elo Pedido.

,,

Voc tambm pode criar d iagramas de seqncia e co laborao para modelar as intcraes importantes do sistema.
Quando tiver terminado de criar os modelos, voc dever ter descries de todas as principais estruturas e intcraes encontradas no sistema. Esses mode los dizem como os vrios objetos esto
estruturados, como eles se relacionam e como eles se encaixam para modelar a soluo do problema elaborado durante a an lise,

Dia 10

FIGURA 10.10

Diagrama de
seqiilla de
Pedido.

~~.'" ..
, ,..!
,
", I..,),

Resumo
o

POO continua o trabalho da AOO, pegando o domnio e transformando-o em uma soluo


para seu problema. Atravs do processo de POO, voc pega seu modelo de domnio e constri o
modelo de objetos de sua soluo. O modelo de objetos descreve os aspectos arquitetonicamente
significativos de seu sistema, como a estrutura e os relacionamentos dos objetos - como os objetos se encaixam. No fi nal do POO, voc dever ter uma boa idia do que implementar no cd igo.
A grosso modo, existem cinco passos iterativos que voc pode segui r, enquanto rea li7..a o POO:
Passo I: gerar a lista de objetos inicial.
Passo 2: refinar as responsabilidades de seus objetos atravs de cartes CRC.
Passo 3: desenvolver os pontos de inlerao.
Passo 4: detalhar os relac ionamentos entre os objetos.
Passo 5: construir seu modelo.
Cada passo refina mais seu modelo de objetos e o deixa mais prximo da cpia heliogrfica de
seu sistema.

Perguntas e respostas
P Por que importante projetar o sistema antes de comear a cod ificar?
R Ex istem varios fa tores que tornam o projeto importante. O, projeto o aj uda a prever problemas de implementao, antes de comear a cod ifi car. E muito mais f cil corrigi r um
problema em um modelo do que percorrer todo seu cdigo para corrig-Io.

Introduo ao POO (Projeto Orientado a Objetos)

O projeto tambm garante que todos os desenvolvedores de uma equipe de desenvolvimento estejam na mesma pgina. O projeto esclarecer muitas das suposies arquitetnicas importantes que, de outro modo, teriam sido decididas durante o desenvolv imento.
Deixando as decises arqu itetnicas para o momento da imp lementao, voc corre o
risco de ter cada desenvolvedor tomando suas prprias decises incompatve is.
fi t)or que importante m odela r seu projeto antes de comear a codificar?

R Modelar importante pelo mesmo motivo que a maioria das pessoas redige lima palestra
antes de proferi -la. Modelando o projeto, voc pode ver corno as partes se encaixam.
Tendo urna idia visual do projeto, voc pode decidir se est confortvel com ele. Voc
pode verificar se tudo se encaixa de fonna tranqila e sensata.
,

As vezes, a so luo de um problema parecer simp les, quando voc pensar a respeito
dela. Pegar a soluo e escrev-Ia formalmente o obri ga a se r intelectualmente honesto
quanto a so luo. Ter de transformar fonnalmente um problema o obriga a pensar de forma crtica e exata sobre a soluo. O que parece simples em sua mente pode faz-l o arrancar os cabe los, antes de voc tenninar!
P Como voc sabe quando seu projeto est concludo?
R No existem regras rgidas e rpidas que indiquem quando um projeto est tenn inado. Se
voc se preocuparem ter um projeto perfeito, poder cai r facilmente na paralisia do projeto.
Tudo se resume ao que voc est tentando transm itir atravs de seus modelos, seu nve l
de experincia c o nvel de experincia de sua equipe. Se voc tiver uma equipe experiente, provave lmente poder apenas modelar a arquitetura de alto nivel do sistema. Se voc
Oll os membros de s ua eq uipe so iniciantes nos objetos, provavelmente desejaro passar
mai s tempo projetando. De qualquer modo, voc term ina quando se sente confiante o s uficien te de que pode pegar o projeto e implementar a soluo.
O processo de desenvolvimento 00 iterativo. Voc deve usar isso para seu prove ito e
fazer as iteraes para obter sua arquitetura final.

Workshop
As perguntas e respostas do teste so fornec idas para seu melhor entendimento. Veja as respostas no Apndice A, 'Respostas" .

Teste
I. Q uais so as trs vantagens de um projeto fonnal ?
2. O que Projeto Orientado a Objetos 3. O que

POO?

c modelo de objetos?

4. Qua is so os inconvenientes do projeto em demasia?

Dia 10

5. Como voc sabe quais aspectos de seu sistema so arqllitetollicamente sigllificativos?


6. Quais so os cinco passos bsicos do POO (Projeto Orientado a Objctos)?
7. Como voc gera a lista de objetos inicial?
8. O que um proj eto completo captura?
9. O que os cartes C RC o aj udam a identificar?
10. O que uma colaborao?
I I. Por que um entend imento profundo dos relacionamentos e responsabi lidades de um objeto importante?
12. O que um carto C RC?
13. Descreva um moti vo pelo qual os cm1cs CRC so intencionalmente de baixa tecnologia.
14. Quando voc deve usar cartes CRC?
15. Qual um problema importante dos cartes CRC?
16. O que ponto de interao?
17. Quais so as quatro consideraes que voc pode fazer em relao a um ponto dc interao?
18. O que um agente?
19. O que voc far quando detalhar os relacionamentos complexos entre os objetos e por
que isso importante?
20. Qual tipo de modelos voc poderia criar?

Exerccios
I. No Dia 9, Exercicio 2, voc desenvolveu o seguinte caso de uso:

Remove item

O us urio convidado seleciona um item do carrinho de compras.

O us urio convidado soli cita ao carrinho para que remova o item.

Condies prvias

Condies posteriores

O carrinho contm um item para remover.


O item no aparece mais no carrinho.

Al ternativa: Operao cancelada

O usurio pode optar por cancelar a transao, aps o Passo I.

Para melhorar suas habilidades, use cartes C RC para descobrir as responsabilidades. Quais responsabilidades o Carrinho de Compra s ter?

SEMANA

DIA
Reutilizando projetos atravs de
padres de projeto
No captu lo de ontem , voc viu como o projeto orientado a objclos o ajuda a projetar uma soluo para um problema. Atravs do POO ( Projeto Orientado a Objclos), voc constri uma cpia
hel iogrfica que diagrama os objclos que compreendem seu sistema. Uma vez que tenha esse
projeto, voc pode comear a imp lementar sua soluo.
Entretanto, voc provavelmente tcm algumas perguntas.

Como voc sabe que o seu projeto um bom projeto?


Seu projeto ler conseqncias imprev isveis no futuro?

Como outros projel islas resolveram esse problema ou um problema semelhante no passado?

E quanto reutili zao? A POO (Programao Orientada a Objclos) fornece reutili zao
de cd igo, mas o POO ( Projeto O rientado a Objetos) permite reutilizao?'

Este captu lo o ajudar a responder essas perguntas e mui to mais. quando voc explorar o ass unto 'padres de projeto' .
Hoje voc aprender:

I.

Corno usar padres de projeto

Corno aplicar quatro padres comuns


N.R.T.: Usaremos o POO p..1ra Projcto Orientado a Objetos e a 1'00 para Programallo Oricntada a
Objclos

238

Dia 11

Como um projeto pode ti rar proveito do uso de padres


Como evitar uma annadi lha de padro comum

Reutilizao de projeto
Um objetivo importante da POO a reutilizao de cdigo. Quando reuti liza cdigo, voc ganha
tranqUi lidade, sabendo que seu software est construdo em uma base de cdigo confive l e testada. Alm disso, voc sabe que o cdigo reutilizado reso lver seu problema. Taltranqilidade
enquanto voc programa tima, mas e quanto tranqUi li dade enquanto projeta? Como voc
sabe se seu projeto bom?
Fe lizmente, os ,padres de projeto podem ajudara dirim ir muitas das dvidas que voc encontrar ao projetar. A medida que o tempo passa, muitos projetistas e programadores tm notado que
os mesmos elementos de projeto aparecem repetidamente em todos os se us projetas. A comunidade de 00 resolveu identificar, nomear e descrever esses conceitos de projeto recorrentes. O
resultado uma lista sempre crescente de padres de projeto.
Novo

TERMO

Um padrfla de projeto um conceito de projeto reut ilizvel.

Veri fi ca-se que voc pode reutil izar padres de projeto em todo o seu projeto, exatamente como
se voc reutilizasse uma classe dentro de seu programa. Essa reutilizao traz as vantagens da reut ilizao da POO (Programao Orientada a Objetos) para o POO (Projeto Orientado a Objctos). Quando usa padres de projeto, voc sabe que baseou seu projeto em projetos confiveis e
comprovados pelo uso. Tal reutil izao permite que voc saiba se est na trilha certa para uma
sol uo con fi vel. Quando voc reuti liza um padro de projeto, est usando um projeto que outros usaram com xito, muitas vezes anteriormente.

Padres de projeto
O li vro Desigll Pallems - Elell/ents of Remab/e Objecl-Oriellled Software, de Gamma, Helm,
Johnson e Vli ssides, apresentou pela primeira vez o conceito de padres de projeto para muitos
na com unidade de 00. Esse trabalho de base no apenas definiu um conjunto de padres de projeto reutilizveis, mas tambm defin iu formalmente o padro de projeto.
De acordo com esse trabalho, um padro de proj eto consiste em quatro elementos:

O nome do padrilo
O problema
A soluo
As conseqUncias

Reutilizando projetas atravs de padres de proj et o

239

o nome do padro
Um nome identi fica exclusivamente cada padro de projeto. Assim como a UML fornece uma
linguagem de projeto comu m, os nomes dos pad res fornecem um vocabu lrio com um para descrever os elementos de seu projeto para outros. Outros desenvolvedores podem entender seu
projeto rpida e faci lmente, quando voc usa um vocabulrio comum.
Um simples nome reduz um problema inteiro, a soluo e as conseqncias a um nico termo.
Assim como os objetos oaj udam a programarem um nvel mais alto e abstrato, esses termos permitem que voc projete a partir de um nvel mai s alto e abstrato e no fiq ue preso aos detalhes
que se repetem de um projeto para outro.

o problema
Cada padro de projeto existe para reso lver algum conjunto distinto de prob lemas de projeto e
cada padr.l0 de projeto descreve o conjunto de problemas para o qual foi fei to para resolver. Desse modo, voc pode usar a descrio do problema para determinar se o padro se aplica ao problema especi fico que est enfrentando.

A soluo
A sol uo descreve como o padro de projeto resolve o problema e identi fica os objetos arquitetonicamente significativos na soluo, assim como as responsabilidades e relacionamentos que
esses objetos compartilham.

NOTA

importante notar Que voc pode aplicar um padro de p rojeto a uma classe
inteira de problemas. A soluo uma soluo geral e no apresenta uma resposta para um problema especfico ou concreto.
Su pon ha Que voc Quisesse encontrar a melh or maneira de percorrer os itens
do ca rrinh o de compras d o captulo 10, " Introduo ao POO (Projeto Orientado
a Objetos )". O padro de projeto Iterator prope um modo de fazer justamente
isso; entretanto, a soluo apresentada pelo padro Iterator no dada em termos de ca rrinhos de compras e itens. Em vez disso, a sol uo descreve o processo de varredura de qualquer lista de elementos.
Quando voc comear a usar um padro de projeto, deve m apea r a sol uo
geral para seu problema especifico. s vezes, pode ser difrcil fazer esse mapeamento; entretanto, o prprio padro de projeto precisa permanecer genrico
para que permanea aplicvel a muitos problemas especificos diferentes.

As conseqncias
No existe um projeto perfeito. Todo bom projeto ter bons com prom issos e todo com promisso
assumido ter seu prprio conjuntoespeial de conseqncias. Um padro de projeto enumerar
as principai s conseqUncias inerentes ao projeto.

Dia 11

As conseqncias no so novidades. Voc assume compromissos sempre que opta entre duas
alternat ivas ao programar. Considere a diferena entre usar um array e lIsar uma lista encadeada .
Um array proporciona pesqu isa rpida pelo ndice, mas funciona muito lentamente, quando voc
precisa reduzir ou expandir o array para inserir ou excl uir elementos. Por outro lado, a lista encadeada proporc iona rpidas adies e excl uses, mas tem uma sobrecarga de memria maior e
pesquisas de nd ice mais lentas. Aqui , as conseq ncias de uma lista encadeada so a sobrecarga
de memria e as pesquisas mais lentas. A conseqncia de usar um array O fat o de que o redi mens ionamento do array dispend ioso, mas as pesqu isas indexadas so muito rpidas. O que
voc esco lhe depende da importncia da memria e da velocidade em seu projeto, se voc va i
fazer muitas adies e excluses de elementos e se vai fazer muitas pesqui sas.
sempre importante documentar suas deci ses de projeto, assim corno as conseqncias resu l-

tantes. Ter essas decises documentadas ajuda os outros a entender as escolhas que voc fez e a
determ inar se o projeto pode ajudar a resolver seus prprios problemas. Do mesmo modo, as
conseqUncias do padro de projeto pesaro bastante em sua deci so de usar o padro. Se um padro de projeto tem conseqncias que no correspondem aos objetivos de se u projeto, voc no
deve us-lo - mesmo que ele possa resolver seu problema.

Realidades do padro
Quando voc comea a aprender sobre padres, importante saber o que eles podem e o que no
podem fazer. As listas a seguir podem ajudara manter corretas as intenes por trs dos padres.
Os padres so:
Projetos reutilizve is que provaram funcionar no passado.
So lues abstratas para um problema de projeto geral.
So lues para problemas recorrentes.
Um modo de construi r um vocabulrio de projeto.
Um regiSlro pblico da experincia do projeto.
Uma soluo para um problema.

Os padres no so:
Uma soluo para um problema espec fi co.
A resposta mgica para todos os seus problemas.
Uma muleta, voc mesmo ainda precisa fazer seu projeto funci onar.
Classes concretas, bibliotecas, solues prontas.

Padres por exemplo


Existem muitos livros que catalogam os padres de projeto. No h moti vo para repetir fonnal mente esses catlogos aqui; entretanto, ex iste um conjunto de padres de projeto que voc en-

Reutilizand o pro jetas atravs de padres de proj et o

241

contrar quase que diariamente. Nenhum texto introdutrio sobre 00 ser completo sem
apresentar esses padres para voc.
Em vez de apresentar csses pad res ronnalmente, vamos adotar uma est ratgia mais informal,
atravs de exemplo.
Hoje, este captulo apresentar trs padres importantes:
Adaplcr
Proxy
lterator

o padro Adapter
o Captulo 4, "Herana: obtendo algo para nada", apresentou o conce ito de relacionamentos
com capacidade de subst itu io. O Captulo 6, "Polimorfismo: aprendendo a prever o futuro",
mostrou como voc pode usar esses relacionamentos para adicionar novos objelos em seu siste
ma a qualquer momento. Quando voc usa herana para definir capac idade de substituio, entretanto, seus objetos podem se tornar restritos pelas hi erarquias resultantes. Para poder se
conectar com seu programa, um objeto deve fazer parte da hierarquia com capacidade de substituio.
Ento, o que voc faria se quisesse conectar um objeto em seu programa, mas ele no pertencesse hierarquia correta? Uma soluo seria pegar a classe que voc quisesse usar e, em seguida,
edit-Ia para que ela herde da classe correta. Essa soluo no 6ti ma por alguns motivos.
Nem sempre voc ter o cdigo-fonte das classes que deseja usar. Alm disso, sc essa classe j
usar herana, voc ter problemas se sua linguagem no suportar herana mltipla.
Mesmo que voc tenha o cdigo-fo nte, simplesmente no e prtico ou razovel reescrever um
objeto cada vez que voc quisesse que ele fi zesse parte da hierarq uia 'correta'. A defin io da hierarqu ia 'correta' mudar para cada programa. Se voc tiver uma classe razoave lmente abstrada, no desejar ficar ed itando sempre que qui ser reut il iz-Ia. Em vez disso, voc deve
si mplesmente uti Iiz-la ina lterada. Reesc rev-Ia a cada vez anula os propsitos da reutil izao e
da abstrao. Se voc ficar criando edies especiais de uma classe, podero restar muitas classes redundantes para ma nter.
O padro Adapter apresenta uma soluo alternativa que resolve o problema da incom pat ibilidade, transformando a interface incom patvel naquela que voc precisa. O padro Adapter funciona empacotando o objeto incompativel dentro de um objeto adaptador compativel. O objeto
adaptador contem lima instncia do objeto e expe o objeto atravs da interface que se encaixa
em seu programa. Como a classe adaptadora empacota um objeto, s vezes esse padro referido como padro Empacotador.
Novo TERMO Um adaptador um objelo que lransfonna a interface de outro objeto.

Dia 11

Implementando um adaptador
A Figura 11 . 1 resume a hierarq uia MoodyObject apresentada no Captulo 7, "I>olimorfismo: hora
de escrever cdigo".

FIGURA '1 .1
ii hicl'(lI'(fllitl

r.yd'liootn.tOb;.c:t

M~I

MoodyObject.

..... mln. (ob) , M<XkIyObject)

.. qu.ryModd ( I
I f1fIlMood I J; StrlllQ

*
Happ'j'ObjlCt

C.,ef,lHObJICt

S~1Ct

getMQOd (): Suing

'getMood (): Str ing

'gtlMood II: Sning

Psychi atri stObject 56 pode exami nar um objeto se for um MoodyObject. O mtodo exami nc()
de Psych i atri stObject depende do mtodo queryMood() de MoodyObject. Qualquer outro tipo
de objelo precisar encontrar um psi quiatra diferente.
A Figura 11.2 apresenta a nova hierarquia Pet.
~

FIGURA " .2

ii hierarquia Pet.
..1/1Uk ( 1; SlrinQ

00,

'"

BI,d

.. apeek ( ) : Sning

.. apeek II : String

lpe.k I ) : Snlng

Cada Pet fala de sua prpria maneira espec ializada e fornece sua prpria implementao de speak ().
Ento, qual o problema?
Hoje em dia, at animais de esti mao vo ao psiquiatra. mas o objeto Psychi at ri stObject no
pode examinar um Pet porque um Pet no um objelo MoodyObject. Para que o objelo Psychia tristObject possa examinar um Pet ,voc precisar criar um adaptador Pet.
A Li stagem 11. 1 apresenta um possvel adaptador Pet.

Reutilizando projetos atravs de padres de projeto

243

LISTAGEM 11 .1 PetAdapter.java

public cla ss PetAdapt er extends MoodyObject (


private Pet pet;
publlc PetAdapter( Pet pe t ) {
this.pet pet:
}

protected String getMoodO {


II i mplementando apenas porque exigido por
II MoodyObject . como tambm sObrepe queryMood.
II nAo prec i samos di sso
return pet.speak( ):
}
publ ic yold queryMoodO {
System . out . println( getMood{) }:
}
}

o PetAdapter

empacota uma instncia de Pet. Em vez de expor a interface Pet, o adaptador


oculta essa interface atrs da interface MoodyObject, basicameme transformando a interface de
Pel. Quando chega um pedido no PetAdapter, o adaptador delega para a instncia de Pet, conforme for necessrio.
A Listagem 11 .2 mostra o adaptador cm ao.
LISTAGEM 11 .2 Usando o adaptador

PetAdapter dog new PetAdapter(


PetAdapter cat .. new PetAdapter(
PetAdapter bird new PetAdapter(
PsychiatristObject psychiatrist ..

new Dog () ) ;
new CatO );
new Bird() ) :
new PsychiatristObject{):

psychiatrist . examlne( dog }i


psychiatrist.examine( cat };
psychiatrist.examine( bird );

Uma vez empacotada, a instncia de Pet se parece com qualquer outro MoodyObject para o objeto Psychi a tri s tObject. Essa sol uo mais eficiente do que as al ternativas, pois ela exige que
voc escreva apenas uma classe adaptadora. Essa classe adaptadora pode manipular qualquer
objeto Pet que aparea. A parte complicada garantir que o PetAdapter empacote todas as instnc ias de Pet, antes que voc passe o objeto Pet para o objeto PsychiatristObject.

Dia 11

A implementao fornecida anteriormente cham ada de adapt ador de objeto, pois o


adaptador usa composio para transfor mar a interface d e u ma instncia. Voc tambm pode implementar um adaptador atravs de herana. Tal adaptador conhecido
com o adaptador de classe, pois ele adapta a prpria definio da classe.
Se sua linguagem suporta heranas mltiplas, ent o voc sempre pode herdar da classe que deseja usar, assim como de uma classe da hierarquia.
Se sua linguagem no tem herana mltipla, como Java, suas escolhas podem ser limitadas, dependendo de como a hierarquia foi construrda. Na verdade, talvez voc tenha de se privar da heran a totalmente e usar composio, no ponto em que tambm
pOderia cr iar um adaptador de objeto_
Embora a heran a mltipl a funcione, essa soluo limitada . Criar uma nova subclasse para cada classe que voc quiser usar pode levar a uma proliferao inaceitvel em
classes empacotadora s.
Cada estratgia tem sua prpria limitao. Um adaptador de classe s funcionar para
a classe que herda. Voc precisar de um adaptador separado para cada subclasse.
Do mesmo modo, embora um adaptador de objeto possa fun cionar com cada subclasse, voc precisa r de subclasses do adaptador, se quiser mudar a m aneira como ele
empacota vrias subclasses.

Quando usar o padro Adapter

o padro Adapter lt il quando voc quer usar um objeto que tem uma interface incompatvel. O
pad ro Adapter permite que voc reutili ze diretamentc objetos que, de outro modo, precisaria alterar ou jogar fora.
Os adaptadores tambm so lteis no sentido de uma ao preventiva. De tempos em tempos,
voc precisar empregar bibliotecas de terceiros em seus programas. Infelizmente, as APls das
ferramentas de terce iros podem variar substancia lmente entre as verses, especialmente para novos produtos ou para tecnologias que esto amadurecendo. As APl s tam bm podem variar bastante em relao s bibliotecas de um prod uto concorrente.
O padro Adaptcr pode ajudar a evitar que seu programa tenha que trocar de APl s e que fi que
preso ao fornecedor. Criando uma interface adaptadora que voc controla, possvel trocar para
novas verses de urna bibli oteca a qualquer momento. Basta criar uma subclasse do adaptador
para cada biblioteca que voc queira usar.
Tambm importante notar que um adaptador pode ser simples ou complicado e o nvel de complexidade depende do objeto que est sendo empacotado. Alguns adaptadores se resumem si mplesmente a mapear um pedido para o mtodo correto. Outros precisar.10 realiz,:'lr mais processamento.
Use o padro Adapter, quando:

voc quiser usar objetos incompatveis em seu programa;

voc quiser que seu programa permanea independente de bibliotecas de terceiros .

A Tabela 11.1 destaca o usurio do padro Adapter.

Reutilizando projetos atravs de padres de proj eto

245

TABELA 11 .1 O padro Adapter


Nome do podrf()

Adapter, Wrapper

Problema

Como reut ilizar objetos incompatveis

Solullo

Fornecer um objeto que converta a interface incompatvel em uma compatvel

ConseqUlnc ias

Tomar incompatveis objetos compatveis; resulta em classes extras talvez muitas - , se voc usar herana ou precisar manipular cada subclasse de uma fonna diferente

o padro Proxy
Normalmente, quando um objeto quer interagir com outro, ele faz isso atuando diretamente sobre o outro objeto. Na maioria dos casos, essa estratgia di reta a melhor estratgia, mas existem
ocasies em que voc desejar controlar o acesso entre seus objetos de forma transparente. O padro Proxy trata desses casos.

Publicao/assinatura e o padro Proxy


Considere o problema de um servio de eventos publicao/assinatura onde um objeto vai registrar seu interesse em um evento. Quando o evento ocorrer, o publ icador noti l1car os objetos assinantes do evento.
A Figura 11 .3 ilust ra um possve l relacionamento publicao/assinatura.
FIGURA 11 .3

Um re/lIdol/lImemo
pllblica(io/assilwlllm.

h..,te ....... tot


,egl.C" UI.um : lIscene. l:

publistle.

. "boe.lboo.

I.ht..,.
, eceiV<lEV<lnt ( .... ent : Evenll:

Na Figura 1 1.3, muitos Li s teners reg istram se u interesse nos eventos gerados por um EventGenerator. Quando o EventGenerator gerar um evento, ele colocar o evento em cada um de seus
objetos Usteners.
Embora essa soluo fu ncione, ela coloca uma grande carga sobre o EventGenerator. O Event Generator no tem apenas a responsabil idade de gerar eventos, como tambm responsvel por
controlar todos os l i s teners e colocar os eventos neles.

o padro Proxy apresenta uma soluo elegante para esse problema. Considere a Figura 11 .4.
Em vez de conter seus Listene r s diretamente, o EventGenerator pode conter um ListenerProxy. Quando o gerador precisa disparar um evento, ele o dispara uma vez para o proxy. Ento,
fica por conta do proxy controlar e atualizar todos os l ; stener s.

Dia 11
AtNJ,,_u.r_

FIGURA 11 .4

UlI/lI solutio proxy.


~""'" / ....111 : E..."f / :

u.....-

.--1...,E...,nr ( _nr : ev"nt ):


Subse.jl)e.

Publi~h",

Ev.ntG. n... ror


,egllr.. , (ilor.. n.. , : USl8ne. I :

Publ illhlr

Subserlbe.

Utt.., ..

, _iveEv.nr I.venl: Evem I:

o padro Proxy geral


o cenrio publicao/assi nat ura descreve um possvel uso para um proxy; entretanto, voc pode
usar prox ies em muitos lugares.
Primeiro, o que um proxy?
Um proxy um substituto ou lugar reservado que intermed ia o acesso ao objeto de interesse real.
Voc pode usar um proxy em qualquer lugar onde preci se de um substilUto ou lugar reservado
para outro objeto. Em vez de usar um objeto diretamentc, voc usa o proxy. O proxy cuida de todos os detal hes da comun icao com o objeto (ou objetos) real.
Novo TERMO

Um proxy um substituto ou lugar reservado que interrnedia o acesso ao objeto de


interesse real. Para todos os efeitos, o .mbstitullI indistinguivel do objeto real que

intennedia.
Um substituto intermed ia o acesso a um objeto (ou objetos) subjacente de forma transparente.
Voc pode considerar um subst ituto como um modo de enganar seus objetos. Por exemplo, enquanto o EventGenerator pensa que est se comunicando apenas com um Li s tener, o Li stenerProxy pode, na verdade, di vul gar a mensagem para muitos objctos Listeners diferentes.
Poder enganar seus objetos uma capaci dade importante, pois ela permite que voc realize todos os tipos de mgica nos bastidores. Um substituto pennite que voc coloque responsabilidades nele, sem ter de incorporar essas responsabilidades no usurio do substituto. Mais importante, seu substituto pode executar todas essas responsabilidades sem que os outros objetos sai bam o que voc est fazendo.

Reutilizando projetas atravs de padres de proj et o

247

As responsabilidades que voc pode colocar no substituto so infi nitas; entretanto, o uso comum incl ui ad icionar otimi 7.acs, realizar tarefas de limpeza, fa zer recursos remotos parecerem
locais e adiar operaes dispendiosas.

Ouando usar o padro Proxy


Use subst itutos quando:

Voc quiser ad iar lima operao dispendiosa. Considere um objeto que extrai informaes de um banco de dados. Embora seu programa talvez precise saber ri respeito dos 01>jetos que pode extra ir, ele no precisa extrair todas as informaes at que rea lm ente
acesse o objeto. Um substituto pode representar o objeto rea l e carregar as informaes
extras quando elas forem necessrias.

Outro exemplo um substituto de arquivo, que permite gravar em um arquivo, mas que
apenas realiza a operao de Entrada e Sada no arquivo real, quando voc j tiver term inado. Em vez de fazer vrias gravaes lentas, o substituto far uma nica gravao grande.
Voc quer proteger de fomm transparente o modo como um objeto usado. A maioria dos
objetos mutante, como as classes da linguagem Java. Um substituto protetor poderia tornar uma coleo de classes imutvel, interceptando pedidos que de outro modo al terariam
uma coleo de classes. Filtrando todas as chamadas de mtodo atravs de um substituto,
voc pode governar de fomla transparente as operaes permitidas sobre um objeto.
O objeto real ex iste remotamente, atravs de uma rede Oll processo. Os substitutos so importantes para a computao distribuda. Um substituto pode fazer com que um recurso
distribudo parea como se fosse um recurso local , encaminhando os pedidos atravs de
uma rede ou atravs de um espao de processo.
Quando voc quer executar aes ad ic ionais de forma transparente, ao usar um objeto. Por
exemplo, talvez voc queira contar o numero de vezes que um mtodo chamado sem que
o chamador saiba. Um substituto de contagem poderia controlar a acesso a um objelo.
A Tabela 11 .2 destaca o usurio do padro Proxy.
TABELA 11.2

O padro Proxy

Nome do padro

Proxy, Surrogale

Problema

Precisa controlar o acesso a um objcto

Soluo

Fornecer um objeto que intennedie o acesso a outro objeto de fomla


transparente

Conseqncias

Introduz um nvel de procedimento indireto no uso do objeto

o padro Iterator
Os padres de projeto freqUentemente descrevem solues para problemas comuns. Quando
voc programa, so boas as chances de que v gastar muito tempo escrevendo cdigos que fa -

Dia 11

zem laos (Ioops) sobre objetos de uma hierarquia. Conforme voc aprendeu no Captulo 8
" Introduo UM L", o relacionamento entreobjetos uma agregao. O todo contm partes.
A Listagem 11.3 apresenta um mtodo conhecido que faz um lao sobre o contedo de um mao
de cartas (uma coleo) e constri lima representao de caracteres do mao.

LISTAGEM 11 .3 Fazendo um lao sobre o contedo de um monte de cartas


public String deckToString( Deck deck ) I
String cards .. "" ;
for( i nt i '" O: i < deck.sizeO ; i ++ )
Card ca rd .. deck.get( i };
cards .. cards + card.display( );

I
return cards:

I
Suponha que voc quisesse fazc r um lao sobre um array de cartas. A Listagem I 1.4 mostra o
mtodo que pode manipular justamente esse caso.

LISTAGEM 11 .4

Lao sobre o contedo de um ar ray

publiC String deckToString( Card [] deck ) I


String cards .. "";
for( int i .. O: i < deck.length; i ++ ) (
cards .. ca rd s + deck (i) .displ ay();

I
return cards ;

I
Finalmente, e se voc quiser faze r um lao sobre o mao de cartas na ordem inversa? Voc precisar adicionar um OUl ro mtodo. A Listagem 1 1.5 mostra um mtodo que faz um lao sobre o
mao na ordem inversa.

LISTAGEM 11 .5

Lao sob r e o contedo de um mao de cartas na ordem inversa

public String reverseDeckToString( Deck deck ) (


String cards .. "":
for( in t i .. deck.sizeO - 1: i > -1; i - ) I
Ca rd card = deck.get( i ) ;
ca rds .. cards + card.display();

I
return cards ;

Reutilizando projetas at ravs de padres de projeto

249

Se voc lembrar das Iies sabre acoplamento e responsabil idades, dever ouvir uma voz em sua
mente, gritando, "Cd igo ruim!" Sempre que voc quiser fazer um lao sobre urna coleo de
cartas, precisar adicionar um mtodo que sai ba como faze r um lao sobre esse tipo de coleo
especfico. Na verdade, a lgica no to diferente assim de um caso para outro. Os nicos elementos que mudam so os mtodos e atributos que voc acessa na coleo. Agora voc v um
alerta: cd igo repet ido.
O problema que cada um dos mtodos listados anteriormente dependente da implementao
da coleo, como um Oeck ou um Array. Quando programa, voc sempre quer garant ir que no
fique acoplado a lima im plementao especfica. O acoplamento torna seu programa resistente
mudana.
Pense a respeito. O que acontecer se voc quiser mudar a coleo que contm suas cartas? Voc
precisar atualizar ou adicionar um novo mtodo que faa o lao. Se voc no tiver sorte, simplesmente mudar a implementao da colco poderia necessitar de alteraes por todo o seu programa.

NOTA

Embora um nico objet o possa conter apenas um lao, seu programa inteir o provavelmente vai repetir os laos muitas vezes, em muitos lugares diferentes.

Outro problema com esses


exemplos provm do fato de que os mecanismos de navegao esto
,
cod ificados no mtodo. E por isso que voc precisa de um mtodo para o lao para frente e outro
para o lao inverso. Se voc quiser fazer um lao aleatoriamente pelas cartas, ento precisar de
um terceiro mtodo (e um para cada tipo de coleo). Voc no preci sar apenas de vrios mtodos, como tambm prec isar implementar novamente a lgica de navegao, sem pre que definir
um lao. Infelizmente, tal duplicao de lgica um sintoma de responsabilidade confusa. A lgica de navegao deve aparecer em um e apenas um lugar.
Fe lizmente, o padro Itera to r resolve muitos dos problemas de forte acoplamento e confuso
de responsabi lidade, colocando a lgica do lao ou iterao em seu prprio objeto.
A figura 11.5 ilustra a interface Iterator.
FIGURA 11 .5
II illfeljace Iterator.

/ter.for

+ fim fi ." voId


+nufll."WJId
+ ;,Don" ( J : boalH"
+ ~um",!1rem ( J .. ObjtlCf

A interface 1te rator fornece uma interface genrica para iteragir sobre uma coleo. Em vez de
escrever seus laos e mtodos para usar uma coleo especfica, voc pode si mplesmente programar a interface genrica do I terator. A interface Iterator ocu lta completamente a implementao da coleo subjacente.

Dia 11

NOTA

A l inguagem Java defin e uma interface iteradora ligeiram ente diferente:


Java .utll .1 terator. o I terator J ava define apenas trs mtodos: pub li c boo-

lean hasNeJl.t(). publlc vold remove() e public Obj ect neJl.t{).


A interface Java Iterator per mite que voc faa uma iterao apenas em um a
direo. Ao chegar ao fim. voc no pode vol tar para o inicio. Fora essa defi
cincia, a interface Java Iterator semel hante quela apresentada anteriorm ente.
Ao escrever programas Java, voc deve usar Java. ut i 1 .1 terator para que outros programas Java possam usar suas implem ent aes do Iterador. Para os
propsitos deste livro. entretanto, esta lio continuar sendo verdade para a
definio do Iterado r clssica forn ecida na Figu ra 11.5.

A Listagem 11.6 apresenta um mtodo alternat ivo deckToString (), q ue faz lao sobre urna instnc ia de Iterator.
LISTAGEM

11 .6

l ao sob r e o contedo de uma i nstncia de Iterato r

pub li c Stri ng deckToString( Iterator i ) {


String cards " "";
for ( i. f i r st() ; !i.isOoneO ; i.nextO )
Card card (Card) i.current l tem() ;
ca rds cards + card.displ ay() ;
}
return cards ;

Apenas porque um objeto passa de volta um iterador, no significa que o objelo rea lmente annazena seus itens dentro do iterador. Em vez disso, um iterador dar acesso ao contedo do objeto.
Existem trs vantagens de usar um iterador para percorrer uma coleo.
Primeiro, um iterador no Ovincular a uma coleo especfica. Todos os mtodos origi nais faria m
lao sobre implementaes especficas da co leo. Corno resultado, cada mtodo di fe riria apenas nos mtodos que chama na coleo. Se esses mtodos fi zessem um lao sobre um iterador,
como na Listagem 11 .4, voc s6 precisaria escrever um mtodo deckToStr i ngO.
Segundo, o iterador pode retornar seus elementos em qualquer ordem que achar conveni ente.
Isso sign ifica que uma implementao do iterador poderia retornar os elementos em ordem. Outro iterador poderia retornar os elementos na ordem inversa. Usando um iterador, voc pode escrever a lgica de navegao uma vez e razer com que ela aparea em apenas um lugar: no
prprio iterador.
Finalmente, um iterador torna simples mudar a coleo s ubjacente, quando isso fo r necessrio.
Como voc no programou para uma implementao especfica , pode trocar para uma nova coleo a qualquer momento, desde que a coleosaiba como retornar uma instnc ia de I terator .

Reutilizando projetos atravs de padres de projeto

251

Implementando um Iterado r
A maioria das colees Java j d acesso a um iterador. Por exemplo, a li okedl 1s t usada internamente pelo objeto Deck j tem um mtodo iterat or() que re
t orna um Java. ut i 1 . I t erator; ent retanto, isso ajuda a ver uma implementao
de iterador real e esse padro no especfico da linguagem Java. Assim, ig.
no re o mtodo 1terator() de linkedli st da linguagem Java por uns instant es.

A Listagem 11.7 mostra uma implementao de Ilerator que permi te ao usurio percorrer os elementos de uma coleo LinkedList.
LISTAGEM 11 .7 Uma implementao de Iterator
pub l i C class Forwardlterator implements Iterator {
pr;vate Object [] items;
private int index :
pub l iC ForwardIterato r( ja va.util.Linkedl1st items ) (
this.items items . t oArray():
}
pub l iC bool ean isDone() (
if( index items .length )
return true ;
}
return fal s e :
}
publi c Object currentItem()
if( !isDoneO ) I
return items [index
}
return null:
}
public vo i d next() I
if( !isDoneO ) (
i ndex++:
}
}

pub li c vo i d firstO
index ,. O:
}

I
l:

Dia 11

Outra implementao poderia fornecer uma iterao inversa (veja o cdigo-fonte completo, para
um exemplo disso).
A Listagem I J.8 ilustra as alteraes que voc precisar fazer em Deck para que possa retomar
um hernIaL
LISTAGEM 11 .8 Uma cla ss e Oeck atualizada
public class Deck (
private java.util . UnkedUst deck ;
publiC Deck() {
buildCa rdsO;

I
public Iterator itera torO (
return new ForwardIterator{ deck );

II reduzido por brevidade


I

Alternativamente, to talmente vlido, do ponto de vista da 00, considerar um it erador como uma exten so da coleo a que ele d acesso. Como resultado, voc tem algumas outras opes de implementao.
A linguagem Java possibilita uma construo conhecida como classe interna. Uma
classe interna uma classe definida dentro de outra classe. Como a classe interna definida dentro de outra classe, ela tem total acesso a todos os mtodos pblicos dessa
classe, assim como aos mtodos protegidos e privados, e s variveis internas. A analogia mais prxima na linguagem C++ uma classe fr iend. friend fornece acesso especial a outro objeto confivel.

fcil abusar d a classe friend e da classe interna, pois elas podem destruir o encapsulament o facilm ente; entretanto, um iterador realmente faz parte da coleo. A listagem 11 .9 mostra uma implementao de classe interna do Iterator da classe Deck.

LISTAGEM '1.9 Uma imp l ementao de Iterator de classe interna


public class Oeck {
private java.util.LinkedList deck;
publ ie DedO {
buildCardSO;
I

publ ic Iterator HeratorO {

Reutilizando projetos atravs de padres de projeto

return new ForwardIterator();

I
l/reduzido por brevidade
private class Forwardlterator imp lements Iterator {
int index;
publiC boolean isDoneO {
II note que a classe interna tem acesso
II liberado varivel interna deck de Deck
if(index deck.sizeO ) (
return true;

I
return false:

I
publiC Object currentItem() {
if( !i sDoneO ) (
return deck .get( index ) ;

I
return null;

I
publiC void next() {
if( !isDoneO) (
i ndex++ ;

I
I
public void first() {
index a O'

I
I
I

253

Dia 11

Quando usar o padro Iterator


Existcm vrias razcs para se usar o padro llerator:

Voc podc usar um ilerador quando quiser ocultar a implementao de uma coleo.
Voc pode usar um iterador quando quiser fornecer diferentes tipos de laos sobre uma
coleo (como lao para frente, lao inverso, lao filtrado etc.).
Voc pode usar um iterador para manter a interface de lima coleo si mples. Voc no
preci sar adicionar mtodos para ajudar a fazer o lao sobre o contedo. Basta deixar os
usurios do objeto utilizarem um iterador.
Voc pode defi nir uma classe de coleo base que retome um itcrador. Se todas as suas
colees herdarem dessa base, o iterador pennitir que voc trate todas as suas colees
genericamente. Na verdade, ja va.ut i l.Collecti on faz j ustamente isso. Essa utilizao
tambm a forma geral do padro Iterator. O exemplo Deck uma verso abreviada do
padro I t erat or. A classe Oeck no herda de uma classe de coleo base abstrata; assim,
voc no pode trat-Ia genericamentc.
Os iteradores tambm so lIteis para fornecer acesso otimizado s colees. Algumas estruturas de dados, como a tabela hashing, no fornecem um modo otimi zado de fazer a
iterao sobre os elementos. Um iterador pode fornecer lal ordenao, ao custo de um
pouco de memria exlra. Entretanto, dependendo de seu aplicativo, a economia de tempo
pode mais do que compensar a sobrecarga de memria.
A Tabela 11 .3 destaca o usurio do padro lterator.
T ABELA 11 .3

O padro Iterator

Nome do padro

Iterator, Cursor

Problema

Fazer lao sobre uma coleo sem se tornar dependente da implementao da coleo

SOluo

Fornecer um objeto que manipule os detalhes da iterao, ocultando assim os detalhes do usurio

Conseq6ncias

Navegao desacop lada, interface da coleo mais simples, lgica de


lao encapsulada

Apossando-se de um padro
Alguns padrcs so mais dificeis de entender do que outros; entretanto, a comp lex idade pode ser
enganosa. Antes de poder aplicar ou mesmo pensar sobre a alterao de um padro, voc preci sa
entender o padro: em outras palavras "apossar-se dele". Existem alguns passos que voc deve
dar para poder dominar um padro:
I. Leia o padro.
2. Leia o padro novamente, prestando bastante ateno nos principais participantes e no
exemplo de cd igo.

Reutilizando projetos atravs de padres de projeto

255

3. Pratiq ue a implementao do padro.

4. Aplique o padro cm um problema real.


Q uando voc tiver conclu do esses quatro passos, provavelmente ter um entendimento total do
pad ro. Neste ponto, voc pode comear a alterar o padro de acordo com as necessidades especficas de seu problema; entretanto, voc no deve tentar aumentar um padro com o qual ainda
no esteja familiarizado.

Resumo
Os padres de projeto so uma ajuda til ao projetar suas solues. De sua prpria maneira, os
padres so a conscincia coleti va da comunidade de 00, que tem anos de experincia de projeto. Os padres de projeto podem fornecer diretrizes valiosas durante o proj eto.
Voc precisa ter cm mente os limites dos padres de projeto, quando os utili zar. Um padro de
projeto lrata de um problema abstraiO e de apenas um problema. Um padro de projeto no fo rnece a soluo para um problema especfico. Em vez disso, o padro fornece uma soluo abstrata para um problema geral. Fica por sua conta fornecer o mapeamento entre o problema
abstrato e seu problema especfico.
Mapear um padro de proj eto provavel mente o maior desa fi o que voc enfrentar enquanto

usar padres. E uma habi lidade que vem apenas com o tempo, estudo e prtica.

Perguntas e respostas
P A linguagem Java usa padres?
R Sim, muitas das AP ls Java empregam padres. Na verdade, cada um dos padres que
voc leu a respeito hoje cst representado na linguagem Java. Aqui est uma li sta brcvc
dos padres que voe viu :
Iteralo)": as classes Java Collection
Proxy:

RMI da linguagem Java

Adapte)": usado am plamente por receptores de eve nto

P Todos os padres so traduzidos para todas as linguagens?


R No. Cada linguagem diferente. Alguns pad res so impossveis de implementar em
certas linguagens, enq uanto outros so desnecessrios, dev ido aos recursos internos da
linguagem.

Dia 11

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respostas no Apndice A, "Respostas".

Teste
I.

o que uma classe adaptadora?

2. Qual problema o padro Iterator resolve?


3. Por que voc usaria o padro lterator?
4. Qua l prob lema O padro Adapter reso lve?
5. Por que voc usaria o padro Adapter?
6. Qua l probl ema o padro Proxy resolve?
7. Por que voc usaria o padro Proxy?

8. Considere a sit uao a seguir; qual padro voc usaria e por que?

A Sun Microsystems, IBM e Apache fornecem bibl iotecas para analisar documentos
XML. Voc optou por usar a biblioteca Apache em seu aplicativo XML. No futuro, contudo, voc poderia optar por usar um fornecedor diferente.
9. Considere a situao a seguir; qual padro voc usaria e por que?

Voc deve escrever


um aplicati vo que recupere dados de um armazm de dados baseado
,
em arq ui vo. As vezes, seu aplicativo ser executado de forma loca l e poder acessar o armazm de dados at ravs de meios diretos. Outras vezes, o cliente ser executado de forma remota e precisar se comunicar com um servidor para ler o armazm de dados.
10. O padro Adaptertransfonn a lima interface. O padro Proxy altera a interface de um objeto?

Exerccios
I. As 1istagens I I. \ o c I \. I \ apresentam uma classe de ca rrinho de compras e uma classe
de item. A Listagem 11.12 apresenta uma interface iterator. Use essas defi ni es para
criar um ilerator que permita fa zer a iterao pelo conteudo do carrin ho de compras.
LISTAGEM 11.10

ltem . j ava

publl c cla ss I tem {


prlvate i nt
i d;
pr; vate i nt
quantity ;
private fl oa t unit_pr icc ;

Reutilizando projetos atravs de padres de projeto

LISTAGEM 11 .10 Item.java (continuao)


private String description;
private float discount;

r* Cria um novo item com a quantidade.

*
*
*

preo .
descrio e desconto por unidade dados.
@param id a id do produto
@param quantity o nmero de itens selecionados
@param unit prlce o preo com desconto anterior
@param description a descrio do produto
@param discount o valor em dlar a ser subtrado por item

./
public Item( int id . in t quantity. float unit_price. float discount .
String desc) {
this.id id;
this.quantity quantity;
this.unit_price ~ unit_price;
this.discount discount;
this.description desci
}

@return int a quantidade do item

./

pubhc int getQuantityO {


return quantity;
}

* @param quantity a nova quantidade

./

public void setQuantity( int quantity ) {


this.quantity ~ quantity;
}

r* @return o preo
./

unit~rio

do item

public float getUnitPriceO {


return unit_price;
}

* @return float o preo total do item menos todos os descontos

./

257

Dia 11

LISTAGEM 11 .10 Item.java (continuao)


publiC float getTotalPrice() I
return ( unit_price * quantity ) - ( discount * quantity ) ;
J

,u
* @return String a descrio do produto

"

public String getOescription() I


return description;
J

,u
* @return int a id do produto

"

public int getID() I


return 1d ;
J

LISTAGEM 11 .11 ShoppingCart.java


public class Shopp i ngCart {
java.uti l. linkedList items

'U

new java.util.linkedlist();

* adiciona um item no carrinho


* @param item o item a adicionar

"

public void addItem( Item item) {


items.add( item );
J

,u
* remove o i tem dado do ca rrinho
* @param item o item a remover

"

public void remove Item ( Item item) {


items.remove( item );
J

,u
* @return int o nmero de itens no ca rrinho

"
public int getNumber Items() I
return items.size();
J

Reutilizando projetos atravs de padres de proj eto

LISTAGEM 11 .11

259

ShoPP lngCart . java (continuao)

1
* recupera o item indexado

* @param index o f nd ice do item


* @retun Item o item no indice

<I
public Item getItem( in t index) {
return (Item) items.get( index ) ;
}
}

LISTAGEM 11.12

lterator . java

pub li c interface Iterator {


publ ic vo i d first() ;
publ ic vo i d next();
publ i c boolean isDone() :
pub l ic Dbject currentltem();
}

2. O Pe tAdapter, apresentado anteriormente no captulo, est limitado a apenas empacotar


uma instncia de Pe t . Altere o adaptador de modo que voc possa mudar o objeto que ele
em pacota, a qualquer momento.
Por que voc desejaria um adaptador mutante?

Respostas do teste
I. Uma c lasse adaptadora transforma a interface de um objeto em uma interface esperada
por seu programa. Um adaptador contm um objeto e delega men sagens da nova interface para a interface do objeto cont ido.
2. O padro Iterator descreve um mecanismo para fazer laos pelos elementos de uma coleo.
3. Voc usaria o padro Iterator para conter lgica de navegao cm um lugar, para fo rnecer
um modo padron izado para percorrer colees e para ocu ltar do usurio a implementao da coleo.
4. O padro Adapterdescreve um mecanismo que permilea voc transformar uma interface
de objetos.
5. Voc usaria o padro Adapter quando precisasse uti lizar um objeto que tivesse uma interface incompatvel. Voc tambm pode usar empacotadores preventivamente, para
isolar seu cdigo das alteraes de AP ls.

Dia 11

6. O padro Proxy intennedia de fonna transparente o acesso a um objeto. Os proxies adicionam um procedi mento indireto para uso de objetos.
7. Voc usari a o padro Proxy sempre que quisesse intennediar o acesso a um objeto de
uma maneira que uma referncia simples no permitisse. Exemplos comuns incl uem recursos remotos, oti mizaes e limpeza de objeto geral, como contagem de referncia ou
reunio de estatsticas de utilizao.
8. Nessa situao, voc pode usar o padro Adapter para criar uma interface independente daquela fornecida pela Sun, IBM ou Apache. Criando sua prpria interr.1ce, voc pode pennanecer
independente da APl ligeiramente diferente de cada fornecedor. Empacotando a bibl ioteca,
voc est livre para trocar de bibl ioteca a qualquer momento, seja para migrar para uma nova
verso ou para trocar de fornecedor, pois voc controla a interfce do <Idaptador.
9. Nessa situao, voc pode usar o padro Proxy para ocultar a ident idade do objeto armazm de dados com que seus objetos se comunicam . Dependendo da local izao do cliente, voc pode instanciar um proxy interligado em rede ou um proxy local. De qualquer
modo, o restante do programa no saber a diferena; portanto, todos os seus objetos podem usar uma interface proxy sem terde se preocupar com a implementao subjacente.
10. O padro ])roxy no altera uma interface, no sentido de que ele no retira nada dela.
Entretanto, um proxy est livre para adicionar mais mtodos e atributos na interface.

Respostas dos exerccios


I.
LISTAGEM

11 .13 ShoppingCart.java

publiC class ShoppingCart {


java.util.LinkedList items new java .util .Linked Lis t O ;

* adiciona um item no carr inho


* @param item o item a adicionar

./
pub l ic void addItem( Item item ) {
items. add ( item) ;

* remove o item dado do ca r rinho


*

~param

i tem o item a remover

./
public void removeltem( I tem item) (
items .remove ( item );

Reutilizando projetos atravs de padres de projeto

LISTAGEM 11 .13 ShoppingCart .java (continuao)


}

..

~return

int o nmero de itens no carri nho

./
publi c int getNumber Items() I
return ltems . size();
}

..

* recupera o item indexado


* @param index o lndice do item
* @retun Item o item no ndice

./
public Item getItem( int index) {
return (Item) items.get( index );
}

publ ic Iterator iteratorO {


II ArrayL i st tem um m todo i terator() que retorna um iterador
/1 entretanto, para propS itos de demonstrao , ajuda ver um ite rador
simples
return new Cart I terator ( items );
}

LISTAGEM 11 .14 Cartlterator.java


public class Cartlterator implements Iterator {
private Object [] items;
private int index;
publiC CartIterator( java.util .LinkedList items ) (
this.ltems items.toArray{);
}

publ iC boolean isDoneO (


if(index >- items.length ) {
retu rn true ;
}

return fal se ;
}

public Object currentItemO (


i f( !isDoneO ) {

261

Dia 11
LISTAGEM 11 .14

Ca rtIterator. java (continuao)

return items [index] :


}

return null;
}

publ i c vo1d nex tO I


i ndex++;
}

publ iC void first() I


index O;
}
}

2. Tornando o adaptador mutante, voc pode usar o mesmo empacotador para empacotar
muitos objetos difcrentes e no precisa instanciar um empacotador para cada obj eto que
precise ser empacotado. A reutilizao de empacotadores faz melhor uso da memria e
Iibera seu programa de tcr de pagar o preo da instanciao de muitos empacotadores.
LISTAGEM 11 .15

Mu tableAdapter. j ava

pu bl ic cla ss MutableAdapter extends MoodyObject I


private Pet pet :
publl c Mutabl eAdapter ( Pet pet ) {
setPet ( pe t ):
}

protected St ri ng getMoodO (
II implementando apen as porque ex i gido por
II MoodyObject . como tambm SObrepe queryMood
II no prec i samos dele
return pet . spea k():
}

public yo id queryMood() {
System . out.p r intln( getMood() ) ;
}

public void setPet ( Pet pet ) {


t hi s.pet pet :
}
}

SEMANA

DIA
Padres avanados de projeto
No captulo de ontem, voc viu como os padres de projeto pennitem reutili zar projetas testa
dos. Hoje, voc continuar seu estudo de padres de proj eto, exami nando mais trs padres.
l-laje voc aprender:

Sobre trs im portantes padres de projeto

Co rno garantir que seus objelos permaneam nicos

Como aprimorar um exemplo anterior


A respeito de algumas annadilhas comuns de padro que voc deve evitar

Mais padres por exemplo


Vamos continuar nosso estudo sobre padres de projeto, considerando trs padres importantes:

Abstract Factol')'

Singlelon
Typesafe Enum
Cada um desses padrcs aparece cm quase todos os projetas. Na verdade, voc pode usar opa
dro Typesafe Enurn para corrigir um exemplo do Captulo 3, "Encapsulamento: hora de escrever algum cdigo! "

264

Dia 12

o padro Abstract Factory


o Captulo 7, " Polimorfis mo: hora de escrever algum cd igo", mostrou como voc pode combinar herana e pol imorfi smo para escrever software ' prova de futuro'. Os relacionamentos com
capacidade de conexo da herana, combinados com o polimorfismo, permitem que voc comx:-

te novos objelos em seu programa, a qualquer momento; entretanto, h um inconveniente.


Para que seu programa possa instanciar esses novos objetos, voc deve entrar no cd igo e aliem-lo para que ele instancie os novos objetos, em vez dos antigos. (E voc precisar fa zer isso em
todos os lugares onde os obj elos antigos so instanciados !). No seria timo se houvesse um
modo ma is fcil de coneclar seus novos objetos?
O padro Abstract Factory reso lve esse problema atravs da de legao. Em vez de instanc iar ohjetos atravs de seu programa, voc pode delegar essa responsabilidade para um objeto chamado
jaclory. Quando um objeto precisar criar outro, ele solicita r que o factory faa isso. Usando um
factol)', voc pode isolar toda a criao de objeto em um (mico local. Quando voc preci sar introduzir novos objetos em seu sistema, s precisar atualizar o factory. para que ele crie uma instncia de Sllas novas classes. Os objetos que usam o factory nunca sabero a d ife rena.
A Fig ura 12. 1 ilustra o projeto geral do padro Abstracl FaCIOI)'.
FIGURA 12 .1

4 bsll..,lfeaory

O padnio Abslracl FaclOIy.


factoryMethodA 4J : A
factortMethod8 { J : 8

eo.....-Feetorv1

c onc,.,.Fect0<y2

fectoryMethodA 41: A
feetoryMe1hod8 {): B

.. foctoryMethodA { ) : A
foctoryMethodB rI: B

~<c,eete.:

,
"

cnoe,..

>:>

~ r

"

.. 1/

..',,,,:>

Padres avanados de projeto

265

o padro Abslracl Faclory usa herana e capacidade de conexo. A classe base de

faCI OI)' define todos os mtodos de criao de objcto e cada subclasse fa ctol)' defi ne quais objetos cria, s0brepondo os mtodos.

Implementando um Abstract Factory


Existem ocasies em que voc precisar usar bibliotecas de tercei ros dentro de seu programa.
Infelizmente, quando hora de migrar para uma nova verso, voc pode veriricar que as AP ls
pblicas das bib liotecas mudaram ligeiramente. Felizmente, o padro Abstract Facto l)' ofe rece
uma soluo que torna lranqi la a migrao da bibli oteca.
Imagine que voc esteja traba lhando em um projeto que usa um ana lisador XML. Um ana lisador
XML receber um documento XM L como String e retornar uma representao de objeto do documento, conhecida como Oocument. Se voc sabe que va i atualizar a bibl ioteca no futuro e que a
AP l vai mudar, existem alguns passos que pode dar para se proteger.

XM L
XML, ou Extensible Markup Language, uma linguagem para escrever tag s que descrevem dados. Assim como a HTML oferece tags para formatar e exibir seus dados, a
XML perm ite que voc def ina suas prpria s tags personalizadas para d escrever o significado conceituaI de seus dados.
A HTMl uma maneira excelente de marcar dados para exibio . Entretanto, a HTMl
no tem a capacidade de transmitir o significado dos dados. A HTML pode dizer para
que voc coloque negrito em uma palavra, mas no pode dizer que a palavra negritada
o ttulo do documento. Em vez disso, voc precisa aplicar esse significado externa
mente ao documento.
Po r outro lado, a XML fornece um mecanismo que permite dizer que alguma palavra
em um documento um ttulo. Se voc usar essas tags para marcar seus dados, dife
rentes programas podero ler seus documentos e saber o que significa cada dado.
A ssim, por exemplo, voc pode escrever um programa que sabe formatar titulos com
negrito. Ou ent o, voc pode escrever outro programa que l uma lista de documentos
e formula uma lista de ttulos pa ra sua seleo. Tentar escrever os mesmos programas
para ler um documento HTML seria muito mais d ifcil.
Nos ltimos anos, a XM l se tornou um padro importante para a troca de dados. Duas
entidades no relacionadas podem se comunicar, desde que ambas entendam as tags
XMl. Como resultado, a XM l tem aparecida como o padro para comunicao entre
empresas. Para comprar e vender, duas empresas podem concordar com um conjunto
de tag s comuns. Uma vez que tenham essas l ags, elas podem troca r documentos XML
l ivremente.
Considere o seg uinte documento XML de uma receita:

<Recipe>
<Name>Chlc ken Tacos<j Name>
<Ingredien t s>
<Ingred i ent>
<Name>Chlc ken<j Name>

Dia 12

<Quantity UOM" lb ">I<j Quantity>


<j lngred i ent>
<! - cortado por brevidade - >
<j lngred i ents>
<j Rec i pe>
Esse documento XML tem tags que descrevem os dados de uma recei ta. Se voc entende a marcao de tag, sabe que os dados que esto entre as tags <Name> representam o nome da receita. Todos os dados que esto entre as tags <Ingred i ents> con tm
informaes de ingredientes.
Voc pOde escrever progra mas que reconhecem a marcao Rec i pe. Um programa poderia permitir que voc selecionasse receitas que gostaria de fazer durante uma semana. Esse programa poderia usar os documentos Recipe que voc escolhesse pa ra
formular e imprimir uma lista de compras. Outro prog rama poderia imprimir o menu
da semana.
Para que um programa leia e entenda um documento XML, ele deve analisar o documento. Um analisador de XMl pegar um documento e o converter em uma rvore
de objetos. Cada objeto conter parte do documento. Seu programa pode sim plesmente percorrer esses objetos para extrair informaes do d ocumento. Assim, se voc
escrever um programa que leia receitas, ele poder percorrer todos os objetos Ingredi ent para construir uma lista de ingredientes.
Atualmente, muitos analisadores de XML esto d ispon veis para escolha. Cada analisador tem uma APl ligeiramente diferente, de modo que, uma vez que voc escre va
um programa para usar um analisador especifi co, poder ser dificil trocar de analisador posteriormente. O padro Abstract Factory apresenta uma maneira de evitar que
voc fique preso ao uso de um analisador em particular.

Novo TeRMO Um (II/(Ifisador de X/odL pega um documento XM L e o transfom18 em uma representao de objelo.
In icialmente, voc precisa empacotar o analisador em um objeto que controle.

NO TA

Lembre-se de que um empacotador um adaptor. Um empacotador converte


a interface de um objeto em uma interface alternativa. Norma lmente, voc usa
um empacotador para converter a interface em uma interfa ce esperada por
seu programa.

Como voc controla a APl do empacotador, garante uma APl estvel que seu programa pode
usar. A Li stagem J 2. J ilustra um possvel empacotador analisador.

LISTAGEM 12.1 Parser . java


public interfa ce Parser (
publ ic org.w3c. dom. Oocument pa rse( String document );

Padres ava nados de projeto

NOTA

267

org.w3t.dom.Dotument uma interface definida pelo W3C para representar um


documento XMl como uma estru tura de objetos. Voc pode encontrar mais
informaes sobre a interface Docum ent no endereo http: //'rMW . w3 .org/ TRI
2000/C R-DOH-level - 2- 200D0510/ java-binding.html.

As listagens 12.2 e 12.3 mostram duas possve is implementaes: Vers ionOneParser, que usa a
verso 1.0 da biblioteca, e Vers ionTwoParser, que usa a verso 2.0 da bi blioteca.
LISTAGEM

12.2 Vers i onOneParser .java

public class VersionOneParser implements Parser {


publi C org.w3c.dom.Oocument pa r se( Str i ng document ) (
II instancia a verso 1 do ana l isador
II XMlParser p new XM l Parser{) ;
II passa o documento para o anal i sador e retorna o resultado
II return p.parseXML( document ) ;

I
I

LISTAGEM

12.3 VersionTwoParser.java

public cla ss Vers i onTwoParser impl ements Pa r ser I


public org .w3c.dom.Oocument parse( String document } I
II instancia a verso 2 do ana l isador
II OOMParser parser new DOMParser(} ;
II passa o documento para o ana l isador e retorna o resultado
II return parse r . pa r se( document };

I
I
Seu programa pode usar o padnlo Abslract Factory para criar a verso correta do anal isador, sempre
que ele precisar analisar um documento. A Listagem 12.4 apresenta a interface base de faclol)'.
LISTAGEM

12.4 ParserFactory.java

public interfa ce ParserFactory I


pub l ic Parser createPar ser() ;

I
Voc precisar de duas implementaes concretas de factory, pois existem duas implementaes do analisador. As li stagens 12.5 e 12.6 apresentam essas implemcnlacs.

Dia 12

LISTAGEM 12.5 VerslonOneParserFactory.java


publl C class VerslonOneParserFactory implements ParserFactory I
public Parser create Parser () I
return new VersionOneParser();
}

LISTAGEM 12.6 Vers i onTwoPa rserFactory .java


public class VersionTwoParserFactory implements ParserFactory (
publi c Parser createParser() {
return new VersionTwoParser();
}
}

Agora, em vez de instanciar anali sadores diretamente, seu programa pode usar um a das classes
factory para recuperar objetos analisadores, quando precisar anal isar um documento. Voc precisar simplcsmente instanciar a factory correta no incio do programa e torn-Ia disponvel para
os objetos de seu programa.
o padro Factorv Method est intimamente relacionado ao padro Abstracl Fact ory.
Na verdad e, um Abstract Factory pode usar Factory Method para criar os objetos que
retorna.
Um mtodo Fact ory nada mais do que um mtodo que cria objet os. createParser()
um exemplo de mtodo Factory. Voc tambm pode encontrar exemplos de mtodos
Factory em toda a APl Java.
Class.newlnstance() um exemplo de mtodo Factory.
Conforme voc pode ver, um mtodo Factory pode aparecer em uma classe normal o u
em uma Factory abstrata. Em qualq uer caso, ele cri a objetos, ocultando assim a classe
rea l do objeto criado.

Quando usar o padro Abstract Factory


Use o padro Abstract Factory, quando:

Voc quiser ocultar o modo como um objeto criado.

Voc quiser ocultar a classe atual do objeto criado.

Voc quiser um conj unto de objetos usados jUlllos. Isso evita que voc use objctos incompatveis juntos.

Voc quiser usar d iferentes verses de uma implementao de classe. Um Abstract Factory permite que voc troque essas diferentes verses em seu sistema.

A Tabela 12.1 destaca o usurio do padro Abstracl Factory.

Padres avanados de projeto

T ABELA 12 .1 O pad ro Abstract Fact ory

Nome do padro

Ahstract Factory

Problema

Precisa de uma maneira de trocarobjetos plugveis de ronna transparente

Soluo

Fornecer urna interface abstrata que providencie mtodos para instanciar


os ohjetos

Conseqncias

Pernl ite que voc troque facilmeOle novos tipos de classe em seu sistema; entretanto, dispendioso adicionar tipos no re lacionados

o padro Singleton
Quando projetar seus sistemas, voc ver que algumas classes deveriam ter logicamente ape nas
urna instnc ia, como um factory ou um objeto que acesse algum recurso no com parti lhado (conexo de banco de dados, regio de memria etc.). Nada, entretanto, imped ir que um objeto instancie outro. Como voc impe se u projeto?
O padro Singleton fornece a resposta dessa pergunta. O padro Singleton impe se u projeto colocando a responsabilidade da criao e da intennediao do acesso instncia no prprio objela. Fazer isso garante que apenas uma instncia seja criada, alm de fornece r um unico ponto de
acesso para essa instncia. A Figura 12.2 i lustra a assinatura de uma classe singlclon (carta unica
de detenninado naipe).
FIGURA 12.2
O padrtio Sillglelofl

A Listagem 12.7 ilustra LIma possvel classe singleton.


LISTAGEM 12.7

Uma implementao do padro Singleton

pub l ic class Singleton (

II uma referncia de classe para a instncia sing l eton


private static Singleton instanc ej

II o constru t or deve ser oc ulto para que os objetos no possam instanciar


II protected permite que outras classes herdem de Sing leton
protected Sing letonO ()

II um mtodo de classe usado para recupera r a i nstncia singleton


public static Sing leton getlnstance() (
if( instance nul l ) (
instance new Singleton()j
}

Dia 12

LISTAGEM

12.7 Uma implementa o do padro Sing l eton (continuao)


return i nstance;

}
}

A classe Si ngl eton contm uma instncia esttica de Si ngl eton e d acesso instncia de 51ngl eton atravs do mtodo da classe gctlnslance().

Implementando um Singleton

o Captulo 7, Laboratri o I, apresentou uma classe Payroll. Uma classe de folha de pagamento
' real' provavelmente acessaria um banco de dados de funcionrios. Poderia ser lima boa idia ter
apenas urna instncia de Payroll , para ev itar conflitos dc recurso. A classe Pay ro11 um a boa
candidata para o padro Si ngleton.
A Listagem 12.8 apresenta um singleton Payroll.
llSTAGEM

12.8 Payro 11 Si n9 I eton

publi C cla ss Payroll {

II uma referncia de cl asse para a i nstncia singleton nica


private static Payroll instance ;
total_hours;
pri vate I nt
private Int
total_sales;
private doub l e total_pay;

II oculta o construtor para que outros objetos no possam instanciar


protected Payroll O II

II
II

observe o uso de stat i c: voc no tem uma instncia. quando recupera


uma in st ncia; portanto , o mtodo deve ser um mtodo de cl asse ; daf.

sta ti c
public static Payroll getInstanceO {
if( instance null ) {
in stance = new Payro ] l() ;
}

return instance ;
}

public void payEmployees( Employee [] emps ) {


for ( int i = O: i < emps. length ; i ++ ) (
Employee emp z emps [i];
tota l_pay .- emp.ca l culatePay();
emp.printPaycheck();

II

Padres avanados de projeto

LISTAGEM 12 .8

271

Payroll Si ngleton (continuao)

}
}

public void calculateBonus( Employee [] emps ) (


for( i nt i - O: i < emps.length; i ++ ) I
Employee emp emps [i]:
System .out.println{"Pay bonus to " + emp.getLastName{) + ", " +
emp.getFirstName{) + " $" + emp.calculateBonusO ):
}
}

public void recordEmployeelnfo( CommissionedEmployee emp ) {


total _sales +- emp.getSales():
}

public yoid recordEmpl oyeelnfo( HourlyEmployee emp ) {


total _hours +- emp.getHours():
}

pub l ic void printReport() I


System.out.println{ "Pay roll Report:"
System.out.println{ "Total Hours:
+
System.out.println( "Total Sales: " +
System.out.println( "Total Paid: $" +
II

);
total_hours ):
total _sales );
total_pay ):

}
}

o singleton Payrol l adiciona um mtodo getlnstanceO. Esse mtodo responsvel por criar e
dar acesso instncia singleton. Preste bem ateno ao construtor; aqu i, o construtor protegido
para que outros objctos no possam inadvertidamente instanciar mais objctos Payro 11. Como ele
protegido, outros objelos podem herdar de Payro 11 .
A Listagem 12.9 d um exemplo de como voc pode usar o singleton.
LISTAGEM 12 .9

Usando o singleton Payro ll

II recupera o singleton de folha de pagamento


pay roll payroll - Payroll.getInstanceO;

II cri a e atualiza al guns fun cion6rios


Comm i ssionedEmployee emp! new Commiss i onedEmployee( MMr.", Sales" , 25000 .00,
l OOO.OO} ;

Commi ssionedEmployee emp2 new CommissionedEmployee( "Ms.", "Sa l es", 25000.00 ,


l OOO.OO} ;

empl.addSales{ 7 );

Dia 12

LISTAGEM

12.9 Usando o si ngleton Payroll (conti nuao )

emp2.addSales( 5 }:
Hour 1yEmp1oyee
Hourl yEmployee
emp3.addHours{
emp4.addHou r s(

emp3 new Hour1yEmp 1oyee ( NMr. N. "Mi nimum Wage-, 6.50 ) :


emp4 .. new HourlyEmployee{ NMs . N, "Min imum Wage-, 6.50 ) ;
40 }:
46 );

II

usa os mtodos sobrecarregados


payro 11 . recordEmp 1oyee I nfo ( emp2 ):
payrol1.recordEmployeelnfo( empl ) ;
payrol1 . recordEmployee lnfo( emp3 );
payro 11 . r ecord Emp 1oyee I nfo ( emp4 ) :

Uma vez que voc tenha uma instncia singleton, ela funci onar como qualquer o utra instncia.
O qu interessante a respeito da Listagem 12.9 e:

Payroll pay roll Payro ll .getlnstance() :


Note que voc no escreve mais:

Pay rol l payroll - new Payrol l O:

Herana e o padro Singleton


O padro Singleton apresenta algumas dificuldades de herana. Especificamente, quem gerencia a instncia sing leton, a progenitora ou a filha? Voc tem algumas escolhas.
A primeira escol ha simplesmente criar a subclasse singletoll e atualizar a progenitora para instanciar a filha. As listagens 12. 10 e 12.11 destacam essa estratgia.
LISTAGEM

12.10 Chi l dSing l eton

pub li c class ChildSi ng le ton extends Singleton {


protected Chi ldSing letonO {}
publi c String toString() {
return "I am the child singl eton " ;

I
I

LISTAGEM

12.11 Updated Si ngleton

public cl ass Si ngl eton {

II

uma referncia de classe para a instncia s ingleton

Pad res avanados de projeto

LISTAGEM 12. 11

273

Upda ted Singleto n (continuao)

private static Sing leton i nstance:

II
II

o constructor deve ser oculto para que os objetos no possam i nstanc i ar


protected penmite que out ras classes herdem de Sing1eton
protected ParentS1ngletonO I}

II

um m todo de classe usado para recuperar a instncia sing leton


public s t atic Si ngleton getInstanee() {
if ( ins tance nul 1 ) I
ins tance new ChildSi ngleton():
}
re tu rn instance;
}
publi C Stri ng toString() {
return "I am the si ng1eton" :
}

Essa soluo tcm o inconven iente de exigir alteraes na classe progenitora. Uma soluo alternat iva inclui Fazer com que o sing leton leia uma varivel de confi gurao na primeira vez que
getInstanceO for chamado. O singleton pode instanciar qualquer objeto que seja especificad o
no valor da configurao.
Voc tambm pode pennitir que cada fi lha fornea sua prpria implementao de getInstan eeO. Essa estratgia no exigi r alteraes na progen itora.

Este quadro conta com um truque da linguagem Java, embora exista um anlogo na linguagem C++. Trata-se de um a SOluo interessante que tira proveito do fato de que os
blocos estticos so executados quando uma classe carregada na linguagem Java.
Atravs de outra estratgia, voc pode adicionar um mtodo protegido regi stere Si ngletons ) na progenitora. Voc pode colocar um bloco esttico na fil ha, que a instancie.
Dentro do construtor, a filha pode se registrar na si ngleton progenitora.
Aqui est o cdigo da classe Singleton atualizada:

public class Slngleton (

II uma refernCia de classe para a instncia de singleton


private static Singleton ins tance;

II o construtor deve ser oculto para que os objetos nao possam instanciar
II protected permite que out ras classes herdem de 51ngleton
protected 5ingleton () I)

Dia 12

II um mtodo de classe usado para recuperar a instAncia de singleton


pub l ic static Singleton getInstance() I
If( i nstance null 1 (
Ilvalor pad r<io
Instance new Sing l eton() ;
}

return instance ;
}

protected static void register( Singleton s } (


if( i nstance nu l l ) I
Instance Sj
}
}

}
E a classe ChildSi ng leton atual izada :

pub l lc class ChlldSingleton extends Singleton I


statlc {
new ChildSingleton() j
}

protected ChildSingleton() {
Singleton.register( this );
}
}

Para fazer t udo isso funcionar, voc precisar chamar CI asso forName(

~ChlldSi ngl eton ~

Ant es de cha mar o mtodo get lnstanceO do singleto n. Aqu i est um exemp lo:

Class.forName( "ChildSingleton" };
Singleton 5 Singleton.getlnstance() ;
System.out . prlntln( s. toString() l j

Quando usar o padro Singleton


Use o padro Si ngleton quando voc quiser restringir uma classe a ter apenas urna instncia.
A Tabela 12.2 destaca o usurio do padro Si ngleton.
TABELA 12 .2 O padro Si nglet o n

Nome do padro

Singlclon

Pro blema

Deve existirapenas uma instncia de um objeto no s istema em detenninado momento.

Soluo

Pemlit ir que o objeto gerencie sua prpria criao e acesso atravs de


um mtodo de classe.

Padres ava nad os de proj et o

TABELA 12.2 O padro Singlet on (continuao)

Acesso controlado instnc ia do objcto. Tambm pode dar acesso a um


nmero definido de instncias (como apenas seis instncias), com uma ligeira alterao no padro. um pouco mais dificil herdar um singleton.

Conseq6ncias

o padro Typesafe Enum


A Listagem 12. 121i sta uma seleo da classe Card, apresentada pela primeira vez no Captulo 3,
Laboratrio 3.

de Card.java

LISTAGEM 12.12 Uma seleo

pub li c class Card {


private int rank :
private int suit ;
private boo l ean fa ce_up ;

II constantes usadas para instanci ar


II naipes
pub l i c static
public static
public static
public static
II valores
public static
public st atic
publl c static
public static
public static
publi c static
public static
public static
public static
public static
public static
public statlc
publ ic static

f ina l
fi na 1
final
fi na 1

i nt
i nt
i nt
i nt

OIAMONOS
HEARTS
SPAOES
CLUBS

fi na 1
fi nal
fi na 1
fina 1
final
final
fi nal
fi nal
final
fi nal
final
final
final

i nt
i "t
i nt
i "t
int
i nt
i nt
i nt
i "t
int
i nt
int
fnt

I NO

THREE
FOUR
FIVE
5IX
SEVEN
EIGHT
NINE

- 4;
3;
6;
5;

3;
4;
5;

6;

m
JACK
QUEEN
KING
ACE

7;
8;
9
10 ;
74 ;

81 ;
75 ;

65 ;

II cria uma nova ca rta - usa as constantes apenas para in i cia l izar
pub l ic Card( in t s ult . lnt rank ) {
II Em um programa real . voc precisa ri a fazer a validao nos argumentos.
th i s. suit suft;
this.rank rank ;
J

Dia 12

Ao instanciar objetos Card, voc precisa passar uma constante de nmero e de naipe v lida. A
utilizao de constantes dessa maneira pode levar a mu itos problemas. Nada o impede de passar
qualquer lnl que voc queira. E, embora voc deva referenciar apenas o nome da constante, isso
abre a representao interna de Cardo Por exemplo, para con hecer o naipe da carta (Card), voc
deve recuperar o va lor int e depois com par-lo com as constantes. Embora isso funcione, essa
no uma soluo limpa.
O problema reside no fato de que naipe e nmero so objetos propriamente ditos. i nt no resolve isso, pois voc precisa aplicar um significado a i nl. Novamente, isso confunde a responsabi li dade, pois voc precisar reapl icar esse signi fi cado sempre que encontrar um in l que
represente um nmero ou um naipe.

Li nguagens corno C++ tm uma construo, conhecida como enllmerao; entretanto, as enumeraes se red uzem sim plesmente a um atal ho para declarar urna lisla de constantes inteiras.
Essas constantes so limitadas. Por exemplo, elas no podem fornecer comportamento. Tambm
difici l adicionar mais constantes.
Em vez disso, o padro Typesafe Enum fornece lima maneira 00 de declarar suas constantes.
Em vez de declarar simples constantes inteiras, voc cria classes para cada tipo de constante.
Para o exemplo Card, voc criaria uma classe Rank (nmero) e uma classe SUl l (naipe). Ento,
voc criaria uma instncia para cada valor de constante que quisesse representar e a tomaria publ icamcnte disponivel a partir da classe (atravs de public fina l, cxatamentc como as outras
constantes).

Implementando o padro Typesafe Enum


Vamos vcr a implementao das classes Rank e SUll, nas listagens 12. 13 c 12.14.
LISTAGEM 12.13 SuiLjava
puhl i c f i na l class Suit {
Ilde f ine estaticamente todos os va lo res vl idos de Sui t
public static fi nal Suit OIAMONOS '"w Suit ( (cha r )4 );
public static fi nal Suit HEARTS '"w Sui t e (char)3 );
publ ic static fi nal Suit SPADES n,w Sui te (char)6 ) ;
publ ic static final Suit CLUBS
n,w Suite (char)5 ) ;

II ajuda a fazer a iterao pelos valores da enumerao


pub l ic static final Sui t [] SU IT

= (

OIAMONDS . HEARTS . SPADES . Cl UBS ) ;

II varivel de i nstancia pa ra conter o valor de exibio


private final char disp l ay;

II no permite i nstanciao por ob j etos externos


private Suite char displ ay ) {

Padres ava nados de proj et o

LISTAGEM 12 .13

277

Suit.java (continuao)

thiS.display disp l ay;


}

II

retorna o valor de Suit


publlc String toStringO {
return String.valueOf( d;spl ay };
}

SUl t simples. O construtor recebe um char que representa o SUl t. Corno Su i t um objeto compl eto, ele tambm pode ter mtodos. Aqui, o sua fornece um mtodo toStri ngO. Uma enu merao de typesafe que pode adicionar quaisquer mtodos que se mostrem teis.
Voc tambm notar que a constante privada . Isso impede que os objetos instancicm objetos
SUl t di retmnente. Em vez di sso, voc est restrito a usar apenas as instncias de constante dec laradas pela classe. A classe tambm declarada como final para que outras classes no possam
ser subclasses de la. Ex istem ocasies em que voc permiti r a herana. Nessas ocasies, torne o
construtor protegido e remova a declarao final.
Devido ao m odo como a linguagem Java funcio na, certi f iquese de fornecer
verses f inais de equal sO e hashCode() q ue chamem super, caso voc abra sua
enumerao para a herana. Se no, voc estar abert o a problemas estranhos, caso suas subclasses redefinam esses m t odos incorretam ente.

NOTA

Voc notar que a classe SUl t define vrias instncias de constante, uma para cada um dos na ipes
vlidos. Quando voc preci sa de um valor constante de sua, pode escrever Su;t.DIAMONDS.
A classe Rank, na Listagem 12.14, fu nciona de modo seme lhante a SUl t ; entretanto, ela acrescenta mais alguns mtodos. O mtodo getRank() retoma o valor de Rank. Esse valor pode ser im portante para calc ular o valor de uma jogada. Ao contrrio das constantes originais, voc no
precisa mais apl icar signifi cado s constantes Ra nk ou Su; t. Em vez disso, elas contm seus pr6prios sign ificados, pois so objelos.
LISTAGEM 12 .14

Rank . java

publ;c final class Rank {


pub l ;c
pub l ic
public
public
public
publi c

static
static
static
s tati c
static
stat ic

final
fi nal
final
fi nal
fi nal
fi na 1

Rank
Rank
Rank
Rank
Rank
Rank

new Rank( 2,
'THREE
.O oe.
Rank( 3,
FOUR
FIVE

SI'
SEVEN

ne.
ne.
ne.
ne.

Rank(
Rank(
Rank(
Rank(

"2 M } ;
"3 M } ;

4, "4 M } ;
5 , "5 M };

6, "6~ };
7, "7" };

Dia 12
LISTAGEM 12.14 Rank.java (continuoo)
public
public
publ ic
publlc
publ ic
pu bl ic
publ i c

stati c
s tati c
s tati c
s tatic
s ta tic
s ta tic
static

f inal
fi nal
fi na 1
fi na 1
fi na 1
f ina l
f inal

Rank
Rank
Rank
Rank
Rank
Rank
Rank

EIGHT ne. Rank(


NINE ne. Rank(
TE' ne. Rank(
JACK ne. Rank(
OUE EN ne. Rank(
KING ne. Rank(
ACE ne. Rank(

8. "8- );
9. "9" );
10 . "10" I ;
11. "J " );
12. "O - );
13. " 1(" I ;
14. "A" I ;

public sta ti c fi na l Rank [] RANK "


{ TWO , THREE, FOUR, FIVE, SIX , SEVEN,
EIGHT, NIN E, TEN, JACK, OU EEN, KING, ACE I ;
private f ina l i nt
rank :
pri vate f ina l St r ing disp lay ;
private Rank( int rank, Stri ng display ) {
this.rank r ank:
th i s. di splay di sp lay;

I
publiC int getRank() {
return rank;
}

pubhc St ring toStringO {


return displ ay;
}

I
Por exemplo, voc no precisa mais apl icar sign ificado a i nt 4 e sabe que 4 significa OIAMONOS.
Quando voc prec isar determinar o val or da constante, pode fazer comparaes de objeto usando
equa 1s ().
A Listagem 12.15 mostra as alteraes que voc precisaria fazer em Ca rd para poder usa r as navas constantes. (As classes Oec k e Oea 1er atualizadas esto disponveis no cdigo-fonte deste captu lo).
LISTAGEM 12.15 A classe Ca rd. java atu allzada
publ i c cla ss Card {
private Rank rank ;
private Suit suit:
priva te boolean face_up;

Padres avanados de projeto


LISTAGEM 12.15 A classe Ca r d.java a tua lizada (continuao)

II

cria uma nova ca rt a - usa as cons t antes apena s para inicia l iza r
public Card( Suit s uit , Rank rank ) (
II Em um programa rea l , voc preci saria fazer a validao nos argumentos.
this.suit = s uit;
th i s . rank rank ;
J

publ ic Sult getSuit () {


re tu rn sui t;
J
publi C Rank getRank{) {
return rank;
J
publ ic void f aceUp() (
face_up true ;
J
pub l ic vo i d f aceDown() (
f ace_up false;

J
publiC boolean i sFaceUp() (
return f ace_up;
J
publi C String di splay() (
return rank.toS tr ing() + suit .toStri ng();
J
J

Voc tambm pode ter notado que Ra nk e Sui t declaram arrays de constantes. Isso torna f ci l fazer um lao pelos valores das constantes di sponveis. A Li stagem 12. 16 mostra como esse fato
s implifi ca bastanle o mtodo bui I dCards O de Ded.
lISTAGEM12.16 O m t odo buil dCards{ ) atua lizad o
private void buildCards() (
deck new java . uti l . LinkedList() ;
f or( lnt 1 O; i < Suit.SUIT.length; i ++ ) I
for ( i nt j O; j < Rank.RANK. length; j ++ )

Dia 12
LISTAGEM 12.16 O m todo buildCardsO atualizado (continuao)

deck.add( new Card( Sui t.SUIT

( i ], Rank . RANK

(j]));

}
}
}

Quando usar o padro Typesafe Enum


Use o padrJo Typesa fe Enum, quando:

Voc se achar esc revendo numerosas primitivas pblicas ou constantes de String.


Voc se achar impondo identidade em um va lor, em vez de derivar a identidade do prprio valor. A Tabe la 12.3 destaca o usurio do padro Typesafe Enum.

T ABELA 12.3 O padro Typesafe

Enum

Nome do padro

Typesafe Enum.

Problema

As constantes inteiras so limitadas.

Soluo

Criar uma classe para cada tipo de constante e depois fornecer instncias
de constante para cada valor de constante.

Conseqncias

Constantes 00 extensveis. Constantes teis que tm comportamento.


Voc ainda precisa atualizar cdigo para usar as novas constan tes,
quando elas forem adic ionadas. Ex ige mais memria do que uma constante simples.

Armadilhas do padro
Voc pode abusar dos padres de projeto, assi m como acontece com qualquer outra ferramenta,
usando-os incorretamente. Os padres de projeto no garantem um bom projeto; na verdade, incluir um padro em um lugar onde ele realmente no pertence arruinar seu projeto. Voc precisa ser criterioso em sua deci so de inc luir um padro em seu projeto.
Recentemente, os padres de projeto vm sendo cada vez mai s criticados. Infelizmente, existe
uma tendncia, especialmente entre os iniciantes, de ser pego na tentati va de aplicar o mximo
de padres possivel a um projeto. O entusiasmo de usar padres tem feito muitos desenvolvedores se esquecerem do objelivo dos padres e ate do prprio processo de projeto. No caia nessa
annadilha! No fi que cego com o prazer de aplicar padres e deixe o projeto se reduzir ao mximo de padres possvel. Voc no ganhar pontos de seus colegas por usara mxi mo de padres,
mas ganhar pontos por produzir um projeto limpo e coerente. Tal projeto poderia nem mesmo
usar padres!

Padres ava nad os de proj et o

DIC A

28 1

Existem algum as diretrizes q ue o ajudaro a evitar a armadilha do padro:


Dica 1: colocando parafusos redondos em buracos quadrados. Se voc se
achar pensando, ~como posso usar <insira seu padrlio predlleto aqui:> em
m eu projetor, estar com problem as. Em vez disso, voc deve pensar, ~ j vi
esse projeto antes; acho que existe um padro que o reso l ve~. Agora, v e veja
um livro sobre padres. Sempre com ece do ponto de vista do problema e no
da soluo (o padro).
Dica 2: ataques de amnsia. Voc estar com problemas, caso no possa explicar, em duas frases ou m enos, porq u escol heu um padro e quais as van ta
gens que ele oferece. Voc deve poder explicar facilmente porque incluiu um
padro e para que ele con tribui em um projeto. A situao sem esperana,
caso voc no consiga pensa r em uma explicao.

Existe uma segunda armadi lha, mais sut il, nos padres: tagarelice do padro. No use padres
para tentar parecer inteligente e no tente sugerir o uso de um padro que voc no tenha estuda
do. Voc pode ria mencionar o pad ro, mas sej a c laro, caso no esteja fami li arizado com ele.
Voc no deve apenas usar padres apropriadamente em seu projeto, mas tambm em suas con
versas. No uma boa idia contri buir para os fatores que prejudicam a prtica de usar padres.

Resumo
Os padrcs de projeto so uma aj uda til ao se projetar suas sol ucs. De sua prpria maneim, os
padres so a conscincia colet iva da comunidade de 00, que tem anos de experincia em projeto.
Lembrc se dos limites dos padres de projeto, quando utili z los. Um padro de proj eto tmta de
um e apenas um problema abstmto. Um padro de proj eto no fornece a soluo para um problema especifi co. Em vez disso, o padro fornece uma sol uo abstmta para um problema geral.
Fica por s ua conta fornecer o mapeamento entre o problema abstrato e seu problema especfico.
Mapear um padro de projeto provavelmente o maior desafi o que voc enfrentar ao usar padres. Trata-se de uma habi lidade que s vem com o tempo, estudo e prtica.

Perguntas e respostas
P C omo voc escolhe um padro de projeto?
R Cada padro de projeto tem um problema e padres relacionados. Estude o padro, se a
descrio do problema parece corresponder ao seu caso. Tambm ajudar, se voc exa
minar todos os padres relacionados . Se, aps estudar o padro, ele parecer resolver seu
problema, tente aplicar o padro ao seu caso. Certifiquese de examinar as conseqncias.
Se qualquer lima das conseqncias entrar em conflito com seus requ isitos, voc prova
velmenle dever ignorar O padro.
P C omo voc sabe qua ndo d eve usar um pad ro de projeto?
R No h uma resposta fci I para essa pergunta.

Dia 12

Voc no pode usar um padro, caso no o conhea, e ningum pode conhecer todos os
padres de projeto disponveis. Quando voc projetar, tente obter o mximo de entradas
possvel. Pergunte s pessoas se elas conhecem padres que possam ajudlo a tomar
suas decises de projeto.
Estude os padres. Quanto mai s padres voc conhecer, mais oport un idades ver para
us los.
P A linguagem Java usa quaisquer dos padres abordados hoje?
R Sim. A linguagem Java usa muitos dos padres abordados hoje.
Padro Factory Method: muitas classes Java tm mtodos factory (um padro intima
mente relac ionado ao padro Abstract Facto!)').
Padro Sing leton: java.lang.System um exemplo dc singlcton na linguagcm Java.
Padro Typesa fe Enum: o padro Typesafe Enum ainda no eSlava definido quando mui
tas das APls Java foram criadas. As ad ies futuras na A Pl Java usaro o padro Typesa
fe Enum.

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respos
tas no Apndice A, "Respostas".

Teste
I.

o que uma classe

empacotadora?

2. Qual problema o padro Abstract Factory resolve?


3. Por que voc usaria o padro Abstracl Factory?
4. Qual problema o padro Singleton resolve?
5. Por que voc usaria o padro Singleton?
6. Qual prob lema o padro Typesafe Enum resolve?
7. Por que voc usaria o padro Typesafe Enum?
8. Os padres garantem um projeto perfeito? Por que sim

Oll

por que no?

Exerccios
A Li stagem 12. 17 apresenta a classe Bank do Capitulo 7. Transforme Bank em um singleton.

Padres avanados de projeto

LISTAGEM 12.17

Bank.java

publie elass Bank {


private java.util.Hashtable aeeounts

new java . uti l. Hashtable():

publi e void addAecount( St ring name , BankAceount aeeount ) (


accounts . put( name , account ):
}

public double totalHoldings() {


double total = 0.0:
java.util.Enumeration enum - accounts.elements{):
while( enurn . hasMoreElements() ) {
BankAccount account = (BankAccount) enum.nextElement():
total + ~ account.getBalance( ):
}

return tota 1;
}

pub l ic lnt totalAceounts() (


return accounts.size():
}

publiC void depos ite St r ing name, double ammount ) (


BankAccount account - retr ieveAccount( name );
if( account l- nu11 ) (
account.depositFunds( ammount ) :
}
}

public double balance( String name ) {


BankAccount account - ret r ieveAeeount( name ):
if( aeeount ! - null ) {
return account.getBalanee() :
}

return 0.0;
}

private BankAeeount retrieveAeeount ( Stri ng name ) {


return (BankAceount) aceounts . get( name ) :
}
}

2. Considere a classe Error apresentada na Listagem 12.18. Essa classe define vrias constantes. Aplique o padro Typesafe Enum no projeto dessa classe.

I 284

Dia 12

LISTAGEM 12.18

Errar.java

public class Errar (

II nheis de erro
publ ic final s tati c
publi c fi na I static
public fi na I statlc
publ1c final statlc
private in t leveI ;

i nt
i nt
i "t
i "t

NOISE
INFO
WARNING
ERROR

O
1.
2;
3;

publiC Errar( int level ) {


this. l evel level;

I
public int getlevelO {
return leveI;

I
publ iC String toString() {
switch (level) {
case O: return "NOISE ";
case I: return "INFO " .
case 2: return "WARNING ";
default: return "ERROR ";

I
I

I
3. Projete e crie um Abstract Factol)' para a hierarquia BankAccount apresentada como uma
soluo no Capitulo 7, Laboratrio 3.

Respostas do teste
I. Uma classe em pacotadora transforma a interface de um objelo naquela esperada por seu
programa. Uma classe empacotadora contm um objeto e de lega mensagens da nova interrace para a interface do objeto contido.
2. O padro Abstract Factol)' fornece um mecanismo que instancia instncias de classe descendentes especificas, sem revelar qual descenderue realmente criado. Isso permite que
voc conecte de forma transparente diferentes descendentes em seu sistema.
3. Voc usa o padro Abstract Factol)' para ocultar os detalhes da instanciao, para ocultar
qua l classe de objeto inslanciada e quando quer que um conj unto de objetos sejam usados j untos.
4. O padro Sing leton garante que um objeto seja instanciado apenas uma vez.

Padres avanados de projeto

5. Voc usa o padro Singleton quando quer que um objeto seja instanciadoapenas uma vez.
6. Usar constantes primitivas no uma estratgia de 00 para programao, pois voc precisa aplicar um sign ificado externo constante. Voc viu quantos problemas a decomposio da responsabilidade poderia causar!
O padro Typesafe Enum resolve esse problema, transformando a constante em um objeto de nvel mais alto. Usando um objeto de nvel mais alto, voc pode encapsular melhor
a responsabilidade dentro do objeto constante.
7. Voc deve usar o padro Typcsafe Enum quando se achar declarando constantes pblicas que devem ser objetos propriamente ditos.
8. No, os padres no garantem um projeto perfeito, pois voc poderia acabar usando um
padro incorretamente. Alm disso, usar corretamente um padro no signi fi ca que o restante de seu projeto seja vlido. Muitos projetos v~lid os nem mesmo contm um padro.

Respostas dos exerccios


I.
LISTAGEM 12 .19

Bank .java

publie elass 8ank {


private java.uti l. Hashtable aeeounts

new java .u til.Hashtable()i

private statie 8ank instanee;


proteeted Bank

o {}

publie stat i e Bank getlnstanee() {


if( i nstanee nul1 li
instanee new Bank()i
}

return in stanee :
}

publie void addAeeoun t( Stri ng name . BankAeeount aeeount 1 I


aeeounts.put ( name , aeeount )i
}

pub l ie double total Hold ings() {


double total 0.0;
java.util.Enumeration enum: aeeounts.el ements() ;
while( enum.hasMoreElemen t s() ) {
BankAeeount aeeoun t (BankAeeount )enum. nextEl eme nt() i
total +- aeeoun t.getBalanee () ;

Dia 12

LISTAGEM 12.19 Bank.java (continuoo)


}

return total:
}

publiC int totalAccounts() I


retur n accounts.size():
}

public void deposite String name , double ammount ) I


Ba nkAccoun t account = retri eveAccoun t( name ):
if( account ! - null ) I
account.depositFunds( ammount ):
}
}

publi c double balance( Stri ng name ) {


BankAccount account " retrieveAccount( name ) :
if( account ! - nu11 ) {
return account.getBa l ance{):
}

return 0.0 ;
}

private BankAccount retrieveAccount( String name ) (


return (BankAccount) account s . get( name );
}
}

2.

LISTAGEM 12.20 Level . java


pub li c fina l cla ss leve1 {
pub1i C fi na1
publ ic f i nal
publ ic fi nal
pub l ic fi na l

st at ic
stat ic
static
stat ic

level
level
level
level

NOISE
INFO
WARNING
ERROR

",w
n.w
n.w
" n.w
"
"
"

level (
level (
level (
leve 1 (

pr'iYate i nt level ;
priva te String name;
private leve1 ( int leve l, String name ) (
th i s . level " level :
th i s . name " name;

O, "NOISE" );
1 , "INFa " ) ;
2, "WARNING" ) ;
3, "ERROR" ) ;

Padres avanados de projeto

287

LISTAGEM 12.20 level. j ava (continuao)


}

public lnt getleve l() {


return l evel;
}

public String getName() (


return name ;
}
}

LISTAGEM 12.21 Errar.java


pub li C class Error {
pr;vate level level ;
pub l iC Errar( Level level ) {
th1s.level - level;
}

public level getlevel() {


return level;
}

publl C String taString() (


return l eve l .getName();
}
}

3. A so luo cons iste em uma abstrata Factory de conta bancria (escri ta como uma interface; entretanto, ela tambm pode ser uma classe abstraIa) e lima Concreta Factory de
conta bancria. A Factory tem um mtodo para criar cada tipo de con ta bancria.
Essa Factory oculta os detalhes da instanciao e no necessariamente o subti po do objeto.

LISTAGEM 12.22 AbstractAccountFactory .java


public interface AbstractAccountFactory {
public CheckingAccount crea teCheckingAccount( doubl e initOepos it . int tran s ,
dauble fee )i

Dia 12

LISTAGEM 12.22

AbstractAccountFactory .java (continuao)

publiC OverdraftAccount createOverdraftAccount( double initOeposit. double


rate );
publiC RewardsAccount createRewardsAccount( double initOeposit. double
interest . doubl e min };
public SavingsAccount createSavingsAccount( double init6alance. double
interestRate );
public TimedMaturityAccount createTimedMaturi tyAccount{ double init6alance .
double interestRate. double feeRate );
}

LISTAGEM 12.23

ConcreteAccountFactory .java

public cl ass ConcreteAccountFactory implements AbstractAccountFactory I


pub l ic CheckingAccount createCheckingAccount( double initOeposit . int trans.
double fee ) I
return new CheckingAccount{ i nitOepos i t . trans. fee );
}

public OverdraftAccount createOverdraftAccount( double initOeposit. double


rate) (
return new OverdraftAccount{ initOeposi t . rate );
}

public RewardsAccount createRewardsAccount{ doub l e initOeposit. double


interest. double min ) I
retu r n new RewardsAccount{ initOeposit . i nterest . mi n ) ;
}

publiC SavingsAccount createSavingsAccount{ double initBa l ance. double


interestRate ) I
return new SavingsAccount( initBa l ance. interestRate ) ;
}

pub l iC TimedMaturityAccount createTimedMaturityAccount( double initBa l ance.


doub l e interestRate. double feeRate ){
return new TimedMaturityAccount( initBalance. interestRate. feeRate );
}
}

SEMANA

DIA
00 e programao da interface
, .
com o usuano
A interface com o usurio (U I) forn ece a interface entre o usurio e seu sistema. Quase todo sistema moderno ler alguma fonna de UI , seja gr fi ca, dirigida pela linha de comando ou mesmo
baseada em telefone ou fala. (A lguns sistemas podem combinar todos os quatro tipos!). Em

qua lquer caso, voc preci sa tomar um cuidado especial no projeto e implementao de suas interfaces com o usurio. Fe lizmente, a POO pode trazer as mesmas vantagens para sua UI que

apresenta para Outros aspectos do sistema.


Hoje voc aprender:

Como a POO e a construo da UI se relacionam

Sobre a importncia de uma UI desacoplada

Quais padres o ajudam a desacoplar a UI

POO e a interface com o usurio


Fundamental mente, o processo de projetar e programar interfaces com o usurio no diferente
do processo de projetar e programar qualquer outro aspecto de seu sistema. Talvez voc precise
aprender algumas novas APls para que possa construir suas Uls, mas no fi nal, voc precisa aplicar
na UI os mesmos princpios orientados a objetos que aplicaria nas outras partes do seu sistema.

Dia 13

NOTA

Voc aprender com o encarar o desenvolvimento de UI do ponto de vista de


um desenvolvedor. Como desenvolvedor, voc projetar e implem entar as
classes que constituem e suport am a interface com O usurio.
A lio de hoje no abordar o assunto geral d o projeto de UI. O projeto de UI
abrange todos os aspectos de como os recursos de um programa se tornam
disponveis para um usuri o. O assunto geral do projeto de UI est completam ente removido da programa o e est m ais enraizado nas artes grfi cas e na
psicologia. O ACM Special Interest Group on Computer-Hum an Interaction
(SIGCHI) um recurso excelente de informaes sobre projeto e usabilidade
da UI.

A questo merece nfase: ao projetar e programar s uas interfaces com o usurio, voc deve aplicar em suas Uls os mesmos princpios de 00 que aplicaria no restante do seu sistema! Freqentemente, as interfaces com O us urio so sim plesmente reunidas e jogadas no sistema como uma
cogitao posterior.
Em vez disso. o cdigo de sua UI precisa ser to orientado a obj etos quanto o cdi go do restante
do sistema. A implementao da UI precisa usar encapsulamento, herana e polimorfismo corretamente.
Voc tambm precisa cons iderar a UI enquanto realiza AOO e POO (Projeto O rientado a Objetos). Sem uma anlisee projeto corretos, voc pode perder certos requisi tos e verificar que escreveu uma UI que no suficientemente fl exvel para fornecer o nvel desejado de funci onal idade
ou uma UI que no pode se adaplar s alteraes fut uras.

A importncia das Uls desacopladas


Voc ver que o mesmo sistema freqUentemente exige diversas interfaces di ferentes, muitas vezes no relacionadas. Por exem plo, um sistema de abastec imento pode permitir que as pessoas
faam pedidos pela Web, pelo telefone, atravs de PDA ou de um apl icativo local personalizado.
Cada uma dessas interfaces se ligar ao mesmo sistema; entretanto, cada estratg ia se ligar ao
sistema e apresentar as informaes de sua prpria mane ira.
Voc tambm ver que os requis itos da interface com o usurio podem se tornar um alvo mve l.
Os sistemas am adurecem com O tempo, quando novos rec ursos so adi cionados e quando os
usurios expem reas de deb iIidade. Em resposta, voc precisar alua iizar continuamente a interface com o usurio para poder expor cada novo recurso e corrigir todos os defeitos. Essa real idade pede uma interface com o usurio cujo projeto seja fl exvel e possa aceitar alteraes
prontamente.
A melhor maneira de obter nexi bi lidade projetando um sistema que seja completamente desacopiado de sua UI. Um projeto desacoplado pennite que voc adicione qualquer UI no sistema e
faa alteraes nas Uls existentes, sem ter de fazer alteraes correspondentes no sistema em si.
Um projeto desacoplado tambm permite testar os recursos do sistema, mesmo que voc no te-

00 e prog ramao da interface co m o usu ri o

291

nha lenn inado de desenvolver a UI. Alm disso, um projetodesacoplado permite que voc aponte precisamente erros que so da UI ou que so do sistema.
Felizmente, a POO a soluo perfei ta para esses problemas. Isolando as responsabilidades corretamente, voc pode di minuir o impacto das alteraes em partes no relacionadas do sistema.
Isolando funcionalidade, voc deve consegui r adicionar qua lquer interface em seu sistema, a
qua lquer momento, sem fazer alteraes no sistema subjacente. O segredo no incorporar o cdigo da UI dentro do prprio sistema. Os dois devem ser separados.
Vamos ver um exemplo que desacopla incorretamentc a UI. A Listagem 13. 1 mostra como lIo
se deve escrever urna UI.

LISTAGEM 13.1 Vis ualBankAccou nt.ja va


i mport
import
import
i mport
i mport
i mport
i mpo rt

javax . swing.J Pane1i


ja vax . swing.J l abel;
java.awt.BorderLayout ;
java.awt.event.Actionl istener ;
java.awt.event.Act ionEven t;
javax.swing. JText Field ;
javax.swing.JButton i

publ i c cl ass V1sualBankAccount extends JPane l implernents Ac t ionlis t ener {

II dados privados
private doub l e balance ;

II el ementos da UI
private
private
private
private

Jlabel
JTextfield
Jbutton
Jbutton

balancelabel = new JLabelO i


amountField z new JTextField( 10 };
deposHButton = new Jbu tton( "OeposH" ) i
wHh drawButton = new Jbutton( "Withdraw" ) ;

public VisualBa nkAccoun t( double initOepos i t ) (


setBala nce( i nitOeposit )i
buil dUIO j

1/ manipula os eventos dos botes


pub l ic voi d actionPerfonmed( ActionEvent e ) (
if( e.getSource() aa depositButton ) {
doubl e amoun t Ooubl e. pa rseOoub le ( amountFi eld.getText(} l j
depositFunds( amou nt };
}else if ( e.ge t Source() .~ wi t hdrawBut t on } (
double amount = Ooub l e.parseOouble( amountFiel d.getText() )i
if( amoun t > getBa l ance() ) {
amount getBala nce() ;

Dia 13

LISTAGEM

13.1 VisualBankAccount.java (continuao )

I
withdrawFunds( amount ):

I
I
pr ivate void bUildUI() I
se tLayout( new 80rderLayout() ):

II constr i a tela
JPa ne l buttons .. new Jpanel ( new BorderLayout() ):
JPanel balance .. new Jpanel ( new BorderLayout() ):
buttons.add( deposit8utton , BorderLayout .WEST ):
buttons.add( withdrawButton, BorderLayout.EAST l:
balance.add( balanceLabe l , 80rderLayout.NORTH );
balance.add( amountField, Borderlayout.SOUTH l:
add( balance, BorderLayout.NORTH l :
add( buttons , BorderLayout.SOUTH );

II configura os ca llbacks para que os botes fa am algo


II o boto de depsito deve chamar depositFunds()
depositButton.addAc t ionli stener( this ):
II o boto de saque deve chamar withdrawFunds
withdrawButton.addActionListener( this ):

I
public void depositFunds( double amount ) I
set8alance( get8alance() + amoun t );

I
publiC double getBalance() {
return balance :

I
protected vo i d setBalance( double newBalance ) {
balance newBalance;
balanceLabel.setText( "Balance: " + balance):

I
public double withdrawFunds( double amount } I
setBala nce( getBalance() - amount };
return amount;

00 e prog ra m ao da inte rface com o usurio

293

VisualBankAccount usa a biblioteca Swing d a linguagem Java para se apresent ar. Toda
linguagem 00 tem bibl iotecas para cri ar e exibir i nterfaces grficas com o usuri o
(GUI). No se preocupe se voc no ent ender t udo q ue h neste exemplo. ~ importante
apenas que voc entenda o significado geral do exemplo.
Um pouco de experincia pOde ajudar. Swing fo rn ece uma classe para cada elemento
importante da GUI, como botes (J Buttonl, rtulos (JLabel) e campos de ent rada
(JTextfield). Voc coloca esses elementos juntos, d entro de painis (JPanel), para
construir sua UI.
Cada elemento da GU I t em um m todo addAct ionLi stener(). Esse mtodo permite que
voc registre um objeto que implementa a interface Act i onL is tener como u m callback.
Quando o elemento da GU I gera r um event o (norm almente como resu ltado de um clique de mouse), ele informar cada um de seus receptores de ao. Aqui, VisualBankAccount at ua como receptor. Quando recebe u m event o de um dos botes, ele
executa a ao corr et a e, em seguida, deposita o u saca di nheiro.

Vi sua 1BankAccount fomece Ioda a funcionalidade da classe BankAccount, apresentada em lies


anteriores. Vi sual BankAccount tambm sabe como se apresentar, como se v na Figura 13. 1.
FIGURA 13.1
VisualBankAccount dentro

de um freme.

Quando voc digitar um va ia r e clicar no boto Deposit ou Withdraw, a conta bancria exlrair o
va lor do campo de entrada e chamar seu mtodo wi thdrawFunds () ou depas i tFund s () , com o
valor.
Como VisualBankAccount um Jpanel ,voc pode incorpor-lo em qualquer OU I Java. Infelizmente, a UI no est desacoplada da classe de conta bancria. Tal acoplamento forte toma impossvel usar a conta bancria em outras fonnas de interfaces com o usurio ou para fornecer uma
UI diferente, scm ler de allerar a prpria classe Vi sua 1BankAeount, Na verdade, voc precisar criar
uma verso separada da classe para cada tipo de UI dentro da qual que ira que ela participe.

Como desacoplar a UI usando o padro


Model View Controller
o padro de projeto MVC (Modcl Vicw Comroller) fornece uma estratgia para o projeto de interfaces com o usurio que desacoplam com pletamente o sistema subjacente da interrace com o
usurio.

Dia 13

NOTA

MVC apenas uma estratgia para o projeto de int erfaces com o usurio orientadas a objetos. Existem outras estratgias vlidas para o projeto de interface
com o usurio; entretanto, a MVC uma estratgia testada que popular no
setor do software. Se voc acabar realizando o trabalho da interface com o
usurio, especialm ente em relao Web e ao J2EE da Sun, encontrar o
MVC.
O DocumentNiew Model, popularizado pelas Microsoft Foundation Classes e
o padro de projeto PAC (PresentationAbstraction Controf), forn ecem alterna
tivas MVC. Veja o livro Pattern-Oriented Sohware Architecture A Sysrem of
Parterns, de Frank Buschmann et ai, para uma apresentao comple ta dessas
alternati vas.

o padro MVC desacopla a UI do sistema, dividindo o projeto da UI em trs partes separadas:


o modelo, que represe nta o sistema

O modo de v isua lizao, que exibe o modelo

O controlador, que processa as entradas do usurio

Cada parte da trade MVC tem seu conjunto prprio de responsabilidades exclusivas.

o modelo
o modelo responsvel por fornecer:

Acesso funcionalidade bsica do sistema

Acesso s informaes de estado do sistema

Um sistema de noti ficao de mudana de estado

O modelo a camada da trade MVC que gerencia o comportamento bsico e o estado do sistema. O modelo responde s consultas sobre seu estado a part ir do modo de visualizao e do controlador e aos pedidos de mudana de estado do controlador.
Um sistema poda ter muitos modelos diferentes. Por exemplo, um sistema de
banco pOde ser constitudo de um modelo de con ta e um modelo de cai xa. Vrios modelos pequenos repartem melhor a responsabi lidade do que um nico
modelo grande.
No deixe o t ermo modelo confundi-lo. Um modelo apenas um objeto que
representa o sistema.

o controlador a camada da trade MVC q ue interpreta a entrada do usurio. Em resposta entrada do usurio, o controlador pode comandar o modelo ou o modo de visualizao para que
mude ou execute alguma ao.
O modo de visualizao a camada da trade MVC que exibe a representao grfica a li text ual
do modelo. O modo de visual izao recupera todas as infonnaes de estado a respeito do modelo, a partir do modelo.

00 e p rog ra m ao da inte rface com o u s u rio

295

Em qua lquer caso, o modelo no sabe absolutamente que um modo de visualizao ou controlador est fazendo uma chamada de mtodo. O modelo s sabe que um objeto est chamando um
de seus mtodos. A nica conexo que um modelo mantm com a UI atravs do sistema de noti ficao de mudana de estado.
Se um modo de vis ualizao o u controladorestiver interessado na noti ficao de mudana de estado, ele se registrar no modelo. Q uando o modelo mudar de estado, percorrer s ua lista de objetos registrados (freqUentemente chamados de receptores ou observadores) e informar cada
objeto da mudana de estado. Para construir esse sistema de notificao, os modelos normalmente empregaro o padro Observer.
o padro Observer
O padro Observer f orn ece um projet o para um mecanismo de publicao/assi natu ra
entre objetos. O padro Observe r perm ite que um objeto (o observador) registre seu
interesse em outro objeto (o observvel). Quando o o bservvel q uiser notifica r os seus
observadores de uma alterao, ele chama r um m todo update() em cada observador.
A Listagem 13.2 define a interface Observer. Todos os observadores que quiserem se
registrar com O objeto observvel devem im plementar a interface Observer.
LISTAGEM 13.2

Observer . jovo

publlc interface Observer I


publ ic vold update();
}
Um observvel fornecer um m t odo, atravs d o q ual os observadores podem regis
trar e anular o registro de seu interesse em atualizaes. A Listagem 13.3 apresenta
um a classe que im plementa o padro Observer.

Implementando o modelo
Aplicar o padnl0 MVC no Vi suai BankAccount pode torn-l o mu ito mai s nexve l. Vamos comear reti rando a funcio nalidade bsica do 'sistema' do cdigo de exibio, para podermos criar o
modelo.
A Listagem 13.3 apresenta a funcionalidade bs ica da conta bancria LISTAGEM 13.3

BankAccountModel . java

i mpo r t java.util.ArrayList
import java.util.lterator
public class BankAccountModel {

II

dados privados
private double
balance;

o modelo.

Dia 13

LISTAGE M

13.3 BankAccountModel .java

prlvate ArrayList l isteners

new Arraylist();

public BankAccountHodel( doub le initOeposit } {


setBala nce( initOeposlt };
J

public void depositFunds( double amount ) {


setBalance( get8alance() + amount ):
J

publi C double getBalance() {


return balance:
J

protected vo id setBalance( double newBalance ) {


balance newBalance:
updateObservers():
J

public double withdrawFunds( double amou nt } {


if( amount > getBalanceO ) {
amoun t get8a lance();

J
set8alance(get8alanceO - amount );
return amount;
J

publiC void register( Observe r o ) {


receptores.add( o );
o.updateO;
J

publi c void deregister( Observer o )


receptores.remove( o );
J

private void updateObservers() {


lterator i receptores.iterator();
while( i .hasNextO )
Observer o " ( Observer) i .next();
o.update() ;

J
J

0 0 e prog ramao da interface co m o usu ri o

297

A BankAccount Mode 1 semel hante classe Ba nkAccount original, apresentada em lies anteriores; enlretanlO, o mode lo tambm usa o padro ObselVer para adicionar suporte ao registro e atual izao de objetos que estejam interessados na not ifi cao de mudana de estado.
Voc tambm notar que essa classe contm toda a lgica do sistema. Agora,
wi thdrawFunds()
,
veri fi ca o valor do saq ue para garanti r que ele no seja maior do que o saldo. E fu ndamental manter tais regras de domfn io dentro do modelo. Se essas regras fossem obedecidas no modo de vi sualizao ou no controlador. cada modo de visualizao e controlador dcsse modelo precisaria
manter a regra. Confonne voc j viu, ter cada modo de visualizao ou controlador impondo
essa regra uma mistura de responsabi lidades e algo propenso a erros. A mistura de responsabil idades tambm torna di fic il mudar a regra, pois voc precisa mud-Ia em cada lugar.
Os relacionamentos com capacidade de substituio tambm tornam a colocao de regras no
modo de visuali zao uma prtica perigosa. Devido aos re lacionamentos com capacidade de
substituio, um modo de visualizao funci onar para qualquer subclasse; entretanto, se voc
colocar as regras de saque no modo de visua lizao, este no funcionar mais para um objcto
OverdraftAccount. Isso porque os objetos OverOraftAccount penn item que voc saque valores
maiores do que o saldo corrente.

o modo de visualizao
O modo de visualizao responsvel por:

Apresentar o mode lo para o usurio


Registrar no mode lo noti fi cao de mudana de estado
Recuperar informae s de estado do modelo

O modo de visualizao a camada da trade MVC que ex ibe in formaes para o usurio. O
modo de visuali zao obtm info rmaes de exibio do modelo, usando a interface pub lica
deste, e tambm se registrar no modelo para que ele possa ser infonnado da mudana de estado
e se atualize de acordo.

NDTA

Um un ico modelo pode ter mu itos modos de visualizao diferentes.

Implementando o modo de visualizao


Agora que existe um modelo, hora de implementar o modo de visualizao da conta bancria.
A Listagem 13.4 apresenta o modo de visualizao de BankAccountModel.
LISTAG EM

13.4 BankAccountView.java

impo rt javax.swing.JPanel;
impo rt javax. swing .J l abe l;

Dia 13

LISTAGEM

13.4 BankAccountView. java (continuao)

import java.awt.Borderlayout;
import javax.swing.JTextField;
import javax.swing .JButton;
public class BankAccountView extends JPanel implements Observer I
public final static String DEPOSIT "-Deposit";
public final static String WITHDRAW " Withdraw";
private BankAccountModel model;
private BankAccountController cont rol ler;

II

El ementos da GUI . aloca tudo prev i amente para evitar valores nulos
private JButton depositButton " new Jbu t ton( DEPOSI T ) ;
private JButton withdrawButton new Jbutton( WITHDRAW };
private JTextField amountField new JTextFie l d() ;
private Jlabel balancelabel
"new JlabelO;
pub l ic BankAccountView( BankAccountModel mode l ) I
th i s.model z model o
th i s.model.register( this l i
attachController( makeCon t rol l er() ) ;
buildUI O;
J

II

chamado pelo mode l o quando este muda


publ ic void updateO I
balancelabe l .setText( "Balance: " + model.getBalanceO );
J

II

d acesso ao valor introduzido no campo


public double getAmount() 1
II supe que o usuri o in t roduziu um nme ro vlido
ret urn Oouble.parseDouble( amoun t Fie l d. getText() ) ;
J

II

insere o controlador dado no modo de vi sua l izao . permite que um objeto


externo configure o controlador
pub l ic void attachController( BankAccountCont roller controller ) I
II cada modo de visualizao s pode ter um cont rolador; portanto. remove
o antigo primeiro
if( th i s.control ler Jw nu l l ) ( Il remove o contro l ador antigo
depositButton.removeActionlistener( cont roller );
withdrawButton . removeActionlistener( controller );
J

00 e prog ra m ao da inte rface com o usurio

LISTAGEM 13 .4

299

BankAccountView. java (continuao)

thiS.contro11er control l er;


deposi tButton.addActi onListener( contro1ler );
withdrawButton . addActi onListener( contro1 l er lj
I

protected BankAccountContro11er makeContro11er() {


return new BankAccountController( this , mode1 )j
}

private void buildUIO {


setLayout( new BorderLayout() ) i

II as socia cada boto a uma st r i ng encomendada


II o controlador usar! essa stri ng para i nterpretar eventos
depositButton.setActionCommand( DEPOSIT )i
wit hdrawButton.setAct ionCommand( WITHORAW l;

II constri a tel a
J Panel buttons new Jpanel ( new BorderlayoutO ) i
J Panel balan ce new Jpanel( new Borde rlayout() ) j
buttons .add( depositButton, BorderLayout.WES T lj
buttons. add( withdrawButton , BorderLayout.EAST };
balance.add( balanceLabel, BorderLayout.HORTH );
ba lance.add( amountField, Borderlayout.SOUTH );
add( balance , Borderlayout . NORTH );
add( buttons , Borderlayout.SOUTH ) ;
}
}

o construtor dc BankAccountV iewaceita uma refe rncia para um BankAccount Model. Na criao,
BankAccountView se regi stra no modelo, cria e se anexa ao seu controlador e constri sua UI. O
modo de visua li zao usa o modelo para recuperar todas as informaes de que necessita para a
exibio. Quando saldo mudar, o mode lo chamar o mtodo updateO do modo de visual izao. Quando esse mtodo for chamado, o modo de visualizao atualizarn sua tela de sa ldo.

Normalmente, um modo de visualizao criar seu prprio controlador, como BankACcountView


faz dentro do mtodo factory makeControll erO. As subclasses podem sobrepor esse mtodo
factory para criar um controlador diferente. Dentro do mtodo attachControll er(), o modo de
visualizao registra o controlador nos botes de depsito e saque, para que o controlador possa
receber eventos do usurio.

Voc notar, entretanto, quc o modo de visualizao primeiro remove qualquer control ador previamente existente. Um modo de visual izao normalmente ler apenas um controlador.

Dia 13

Voc tambm notar que attachControll er() um mtodo publico. Usando esse mtodo, voc
pode trocar de cOluroladorsem ter que faze r uma subclasse do modo de visualizao. Esse mtodo pennite que voc crie diferentes cont roladores e passe-os para o modo de visualizao. O
controlador que voc ver na prxima seo interpretar os eventos do usurio exatamente como
Vi sua 1BankAccount os interprelava (apenas com uma ligeira mod ificao). Nada o impede de escrever controladores que bloqueiem o usurio ou limitem o que ele pode fazer.
Ao contrrio de um modo de visuali zao, que s pode ter um controlador por vez, um modelo
pode ter muitos modos de visualizao diferentes. A Listagem 13.5 apresenta um segundo modo
de visualizao para a conta bancria.
LISTAGEM

13.5 BankAccount CLV . java

pub l i C class BankAccountCLV implements Observe r {


private BankAccountModel model :
publ ic BankAccountCLV( BankAccountModel mode l ) {
this.model mode l :
th i s.mode l. register( this ) ;
}

pub l ic voi d updateO {


System.out.println(

~Current

Balance: $" + model.getBalanceO ) :

}
}

BankAccountCLV si mplesmente imprime o saldo na li nha de comando. Embora esse comportamento seja si mples, BankAccountCLV um modo de visualizao alternativo para BankAccountModel. Voc notar que esse modo de visualizao no ex ige um controlador, pois ele no acei la
eventos do usurio. Nem sempre voc precisa fornecer um contro lador.
DICA

Um m odo de visualizao pode nem sempre aparecer na tela.


Tome como exemplo um processador de textos. O modelo do processador de
textos controlar o texto introduzido, a formatao, notas de p d e pgina etc.
Um m odo de visualizao exi bir o texto no editor principal; entretanto, outro
modo de visual izao poder converter os dados do modelo para o formato
POF, HTMl ou Post script e, em seguida, grav-lo em um arquivo. O modo de
visualizao que gra va em um arquivo no aparece na tela; em vez disso, o
m odo de visualizao exibe em um arquivo. Outros programas podem ent o
abrir, ler e exibir os dados do arqu ivo.

00 e prog ramao da interface com o usurio

301

o controlador
o controlador responsvel por:
Interceptar os eventos do usurio do modo de visualizao
Interpretar o evento e chamar os mtodos corretos do modelo ou modo de visualizao
Regist rar-se no modelo para notificao de mudana de estado, se estiver interessado

O controlador atua como a cola entre o modo de visualizao c o mode lo. O controlador intercepta eventos do modo de visualizao e depois os transrorma em pedidos do modelo ou do
modo de visualizao.

NOTA

Um m odo de visualizao t em apenas um controlador e um controlad o tem


apenas um modo de visualizao. Alguns modos de visualizao permitem
que voc config ure seu controlador diretamente.

Cada modo de vi sualizao tem um controlador e toda a interao com o usurio passa por esse
controlador. Se o controlador ror dependente das inronnaes de estado, ele tambm ser registrado no modelo para notificao de mudana de estado.

Implementando o controlador
Com um modelo e um modo de visualizao j criados, resta apenas construir o controlador de
BankAccountView. A Listagem 13.6 apresenta o controlador do modo de visualizao.
LISTAGEM 13,6 BankAccountControll er . java
import java.awt.evento.Actionlistener;
import java . awt.evento.Act ionEvent;
public class BankAccountCon troller imp l ements Actionlistener {
private BankAc countView view ;
private BankAccountModel model o
publiC BankAccountController( BankAccountView view, BankAccountModel mode l )

I
this.view ~ view;
this. mode l model;
}

publiC void actionPerfonmed( ActionEven t e ) {


Str i ng command z e.getActionCommand() ;
double amount view , getAmount();
if( command .equals( view.W ITHDRAW ) ) {

Dia 13

LISTAGEM

13.6 BankAccountController.java (continuao)


mode l. withdrawFunds( amount };
}else 1f( command.equals( view.OEPOSIT ) } {
model .depositFunds( amount };
J

J
Na construo, o controlador aceita uma referncia para o modo de visualizao e para o modelo. O controlador usar o modo de visuali zao para obter os valores introduzidos no campo de
entrada. O contro lador usar o modelo para realmente sacar e depositar dinheiro na conta.
BankAccountControlle r em si muito simples. O controlador implementa a interface Actionli stener de modo que possa receber eventos do modo de visualizao. O modo de visuali zao
cuida do regi stro do cont rolador para eventos, de modo que o controlador no precisa faze r nada
a no ser interpretar eventos, quando os receber.
Quando o controlador recebe um evento, ele verifica o comando do evento para determinar se o
evento um saque ou um depsito. Em qualquer caso, ele faza chamada correspondente no modelo. Ao contrrio do VisualBankAccount original, o controlador s precisa chamar depositFunds() ou wi thdrawFunds () . Ele no precisa mais se certificar de que o valor do saq ue no seja
maior que o saldo, pois agora o modelo cuida desse detal he do domin io.

Reunindo o modo de visualizao e o controlador


A Li stagem 13.7 apresenta um pequeno metodo main que relne o modelo e dois modos de vi suaIizao. O mtodo ma i n no precisa fazer nada no controlador, poi s o modo de visualizao cuida
desse detal he.
LISTAGEM

import
import
import
import

13.7 Reuni ndo o modelo , modos de visualizao e o controlador

java.awt.eve nto.Windowlistener;
java.awt.eve nto.WindowAdapter i
java.awt.evento.WindowEvent;
javax.swing.J Frame i

public class MVCOriver (


pub l i c static void main( St ring [] args ) {
BankAccountModel model new BankAccountModel( 10000.00 };
BankAccountView view " new BankAccountView( model );
BankAccountCLV clv
~ new BankAccountC l V( mode l )i
J Fr ame frame

new JFrame();

00 e prog ramao da interface com o usurio

LISTAGEM 13 .7

303

Reunindo o modelo, modos de visualizao e o controlador (cont . )

WindowAdapter wa new WindowAdapter() {


publ1c void windowClosing( Wi ndowEvent e ) I
Sys tem.e xit( O l i

I
frame.addWind owlistener( wa )i
frame .getContentPane().add( view li
frame . pack() ;
frame. showO i

I
I

o pri meiro mtodo ma i n cria uma instncia do modelo. Quando o mtodo mai n tem o modelo,
pode ento criar vrios modos de visualizao. No caso de BankAccountView, o mtodo mai n tam
bm preci sa incorporar o modo de visualizao em um quadro, para que o modo de visualizao
possa ser exibido. A Figura 13.2 ilustra a sada resultante.
FIGURA 13 .2

Um ",odeio de COI/Ia
bol/cria com ,rias modos
de I"isllali:a(;Q.

Se voc executar MVCOri . . er, ver dois modos de visua lizao separados no mesmo modelo.
Usando o padro MVC, voc pode criar quantos modos de visua lizao de seus modelos subja
cernes preci sar.

Problemas com o MVC


Assim como acontece com qualquer projeto, o MVC tem suas deficincias e tambm seus pon
tos crticos. Os problemas incluem:

Uma nrase nos dados


Um rorte acoplamento entre o modo de visualizao/controlador e o modelo
Uma oportun idade de ineficincia

Dia 13

A gravidade dessas de fi cincias depende do problema que se est resolvendo e seus requisi tos.

Uma nfase nos dados


Em uma escala 00 de pureza, o padro MVC no se classifica prximo ao topo, devido a sua
nfase nos dados. Em vez de pedir a um objeto para que faa algo com seus dados, o modo de visualizao pede seus dados ao modelo e depois os ex ibe.
Voc pode di minuira gravidade desse problema, exibindo apenas os dados que retirado modelo.
No reali ze processamento adicional nos dados. Se voc se achar realizando processamento extra nos dados, aps recuper-l os ou antes de chamar um mtodo no modelo, si'lo boas as cha nces
de que o modelo deve faze r esse trabalho para voc. Existe uma linha tnue entre faze r muito e
fazer o que necessri o nos dados. Com o passar do tempo, voc aprende r a diferenciar entre
fazer muito com os dados e fazer ape nas o que necessrio.

DICA

Se voc verificar que repete o mesmo Cd igo em cada modo de visualizao,


considere a colocao dessa lg ica no modelo.

Evitar o padro MVC unicamente por motivos de pureza pode insultar algumas realidades da
programao. Tome como exem plo um site Web. Algumas empresas impem uma scparai'lo
clara entre apresentai'lo (o modo de visualizao) e a lgica corporati va (o mode lo). A imposio de tal separao tem uma base corporativa v lida: os programadores podem programar e o
pessoal ligado ao contedo pode escrever contedo. Retirar o contedo da camada de programao signi fi ca que quem no for programador pode criar contedo. Impor o contedo na camada
de programao significa que a pessoa que est escrevendo contedo deve ser um programador
ou que um programador prec isa pegar o contedo e incorpor- lo dent ro do cdigo. muito mais
dificil atualizar um si te, se voc incorporar contedo no cd igo.
A realidade tambm di z que os requisitos no so defin iti vos, muito menos conhecidos. Novamente, o site Web se constitui em um exemplo excelente. Um site Web prec isa gerar cdigo
HTM L para ex ibir em um navegador da Web. E quanto aos POA s, telefones celulares e outros
di spositivos de exibio? Nenhum deles usa I-ITML bsica. E quanto daqui a se is meses? So
boas as chances de que vo existir outras formas de exibio. Para satisfazer requisitos desconhecidos, voc precisa de um projeto que seja fl exvel. Se voc tiver um sistema muito esttico,
com requisitos bem definidos, poder usar uma allemativa, como um PAC. Se voc no tiver
sorte sufici ente para ter tais requisitos claros, precisar considerar o MVC.

Acoplamento forte

o modo de visualizao e o cont rolador so forteme nteacoplados interfa ce pblica do modelo.


As alteracs na interfa ce do modelo exigiro alteraes no modo dc visualizao e no controlador. Quando lisa o padro MVC. voc supe implicitamente que o modelo estvel, e provvel

00 e prog ramao da interface com o usurio

305

que o modo de visualizao mude. Se esse no for o caso, voc precisar escol her um projeto diferente ou estar preparado para fazer alteraes no modo de visualizao e no controlador.
O modo de visualizao e o controlador tambm so intimamente relacionados entre si. Um controlador quase sempre usado exclusivamente com um modo de visualizao especifico. Voc
pode tentar encontrar reut il izao atravs de um projeto cuidadoso; mas mcsmo que no encontre, o padro MVC ainda fornece uma boa diviso de responsabil idades entre os objetos. A 00
no simplesmente um meio de reuti lizao.

Ineficincia
Voc deve tomara cuidado de evitar ineficincias ao projetar e implementar uma UI baseada em
MVC. As ine licincias podem aparecer no sistema em qualquer parte da tdade MV C.
O modelo deve evi tar a propagui'o de notificaes de mudana de estado desnecessrias para
seus observadores. Um modelo pode enfi leirar notificaes de mudana relacionadas para que
uma notificao possa sign ilicar muitas mudanas de estado. O model o de evento A WT (Abstract
Window Toolkit) da linguagem Java usa essa estratgia para redesenhar a tela. Em vez de redesenhar aps cada evento, A WT enfi leira os eventos e realiza uma nica operao para redesenhar.

Ao projetar o controlador e o modo de visualizao, talvez voc que ira considerar a colocao
dos dados na memria cache, caso a recuperao de dados do modelo seja lenta. Aps uma notificao de mudana de estado, recupere apenas o estado que mudou. Voc pode aumentar o padro do observador para que o modelo passe um identificador para o mtodo update(). O modo
de visualizao pode usar esse identificador para decidi r se precisa ou no se atualizar.

Resumo
A interface com O usurio uma parte importante de qualquer sistema. Para alguns, ela pode ser
a nica parte do sistema com a qual eles interagem; para esses, a UI ri o sistema. Voc sempre
deve encarar a anlise, o projeto e a implementao da UI exatamente como encara qua lquer outra parte do sistema . Uma UI nunca deve ser uma cogitao posterior ou algo co locado no sistema no ltim o momento.
Embora existam muitas estratgias para o projeto da UI, o padro MVC fornece um projeto que
oferece Oex ibilidade, desacoplando a UI do sistema subjace nte. Mas, assim como acontece com
qualquer outra decisi'lo de projeto, voc ai nda precisa ponderar os prs e contras do MVC, antes
de decidir utiliz- lo. O MVC no o exime das realidades de seu sistema.

Perguntas e respostas
P Sua classe BankAccountModel contm toda a lgica do sistema. O modelo sempre precisa conter a lgica ou ele pode atuar como um gateway para o sistema real?

Dia 13
,

R Depende. As vezes, o modelo agir como um gateway para o sistema; outras vezes, o
modelo ser incorporado dentro do sistema real. Tudo se resume a uma deciso de projeto. Em qualq uer caso, a UI no tem meios de saber se o modelo alua como um gateway ou
no.
P Na Listagem 13.6, voc escreveu:
i f( command.equals( vlew.WITHORAW ) ) I
model.withdrawFunds( amount ) ;
I else if( command.equals( view.DEPOSIT ) ) I
model.depositFunds( amount );
J

Isso no lgica com estruturas condicionais? Achei que voc tinha dito que lgica
com estruturas condicionais considerada 'm' 00.

R Si m. Esse um exemplo de lgica com estruturas condicionais.


Para manter esse exemplo simples, decid imos tornar o controlador um Act i onL is tener
que manipulasse os dois eventos. Em uma implementao rea l, voc pode evi tar a lgica
com estruturas condicionais capturando o evento original dentro do prprio modo de visualizao e fazendo com que o modo de vi suali zao gere seus prprios eventos persona lizados. Por exemplo, o modo de visualizao poderia gerar eventos de deps ito e
saq ue. O cont rolador poderia receber cada um desses evelllOS separadamente. Talvez o
controlador implementasse os mtodos depos i tPerformed () e wi thdrawPerformed (). O
modo de visualizao chamaria o mtodo correto no control ador, dependendo do evento;
assim, no haveria mais nenhuma estrutura condicional, mas um exemplo muito mais di ficil de eruender.
P Certo. Sua resposta anterior me fez sentir um pouco melhor. Mas se voc implementar o controlador conforme explicado anteriormente, o modo de visualizao
no ter de executar lgica com estrutura condicional para descobrir qual boto
chamou o evento?

R No. O modo de visuali zao pode ev itar a lgica com estruturas cond icionais fornece ndo um receptor separado para cada boto. Quando existe uma correspondncia de um
para um entre um elemento e seu receptor, voc no precisa usar lgica com estrut uras
condi cionais para descobrir onde o evento se origina. (Veja no Exercicio 2 a im plementao alternativa.)

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respostas no Apndice A, "Respostas".

00 e prog ramao da interface com o usurio

307

Teste
I. Como a anlise, o projeto e a implementao da UI so diferentes do restante do sistema?
2. Por que voc deve desacoplar a UI do sistema s ubjacente?
3. Qua is so os tres componentes da trade MVC?
4. Quais so as duas alternativas para o padro MVC?
5. Descreva as responsabi lidades do modelo.
6. Descreva as responsabi lidades do modo de visua li zao.
7. Descreva as responsabi lidades do controlador.
8. Quantos modelos um sistema pode ter? Quantos modos de visual izao um modelo pode
ter? Quantos controladores um modo de visualizao pode ler?
9. Quais ine fi c incias voc deve evitar ao usar o padro MVC?
10. Quai s suposics o padro MVC faz ?
I I. Qua l a hi stria do padro MVC? (Note que esta pergunta exige que voc reali ze uma
rpida pesquisa na Web.)

Exerccios
I. A Listagem 13.8 apresenta uma classe Employee. Altere a classe Empl oyee de modo que
ela possa registrar e reti rar o registro de receptores, assi m como inform-los de alteraes de estado. A Li slagem 13.2 apresenta uma interface Obse r ver que voc pode usar
para este exercic io.
LISTAGEM

13.8 Emp l oyeeMode l. java

publiC abs tract class Employee (


private Stri ng first_name :
private Stri ng la st_name :
pr;vate double wage:
public Employee(String first_name , String last_name.double wage) (
this.first_name = first_name;
th i s.last name l ast_name :
th i s.wage wage :
}
publ ic double getWage() (
return wage:
}

Dia 13

LISTAGEM 13.8 Empl oyeeMode l. java (continuao)

publiC void setWage( double wage ) (


this . wage wage:
J
publiC String getFi r stName() (
return first_name :
J
public String getlastName(){
return la st_name ;
J
public abstract double calcu latePay{):
publ ic abstract double calculateBonus() :
publiC void pri ntPaycheck() (
String full _name last_name + ", " + first_name;
System . ouLprintln( MPay: " + full name + " $" + calculatePayO ) :

J
J

2. Usando as listagens 13.9 e 13. IOcomo ponto de partida, escreva um novo BankAccountControl 1er q ue implemente a nova interface BankActiv i tyl i stener e man ipule os eventos sem lgica com estruturas condicionais.
A Li stagem 13.9 apresenta um BankAc t i v i tyEvent e seu BankAc t i v i tyl is tener correspondente.
LISTAGEM 13.9 BankActivitylistener.java e BankActivityEvent.java

pub l ic inter fa ce Ba nkActivitylis tener {


public vold withdrawPerformed( BankActivityEvent e ):
pUbli c vo i d depositPerformed ( BankActivityEvent e ):
J

pub l ic c l ass BankActivityEvent (


private double amount:
pUblic BankActivityEvent( doubl e amount ) {
thls.amount amount;

00 e prog ramao da interface com o usurio

LISTAGEM 13 .9

309

BankAc tivitylistene r.ja va e BankAct iv ityEve nt. java (continuao)

public double getAmount() {


return amount:
}
}

Li stagem 13. IOapresenta lima BankAccount Vi ew atual izada. Esse BankAccountVi ew intercepta os eventos ActionEvent do boto e encarnin ha o novo evento BankActivityEvent para o controlador.
A

LISTAGEM 13 .10

import
i mport
i mport
i mport
i mport
i mpo rt
i mpo rt
import

BankAccountView.java

javax .swlng .JPanel :


javax. swing.J l abel :
java.awt .Bo rderlayout :
javax .swing.J Text Field :
javax.swing.JButton :
java.util.Arraylist:
java.awt.event.Actionlistener;
java.awt.event .Ac t ionEvent;

publiC class BankAccountView extends JPane l implemen t s Obse rver I


public final static String DEPOSIT "Deposit" :
public final static String WITHDRAW " Withdraw";
private BankAccountModel mode l :
private BankAccountController cont rol leri

II Elementos da GUI , aloca tudo previament e para ev i tar valores nulos


private
private
private
private

J8utton depositButton - new Jbutton( DEPOSI T ):


J8utton wit hdrawBu tton - new Jbu t ton( WITHDRAW )i
JTextFleld amountField ~ new JTextFie l d() :
~ new Jlabel ():
Jlabel balancelabel

pub l ic 8ankAcceuntView( BankAccountModel mede l ) (


this.model mode l:
th i s. model.register( this ) :
attachController( makeControl l er() ) :
bu ildUI O;
}

II chamado pelo mode lo, quando este muda

Dia 13

LISTAGEM 13.10 BankAccountView .java (continuao)


publiC vo id update() {
balancelabel.setText( "Ba lance:

model.getBalanceO );

II

codifica o cont rol ador dados no modo de visualizao. permite que objet o
externo con fi gure o controlador
public voi d attachController ( BankAccount Controll er controller ) {
this . control ler cont roller:
J

pro tected Ba nkAccou ntController makeCont rolle r () {


return new BankAccountController( this. model );
J

II

d acesso ao valor i ntrod uzido no campo


private double getAmoun t() {
II pres supe que o usurio i ntroduz i u um nmero vlido
return Double.parseDouble( amount Field .getText() ) ;

J
private void fireDeposHEventO {
BankActivityEvent e new BankActivityEvent ( getAmount() );
control l er.depositPerformed ( e ) :
J

pr ivate voi d fireWHhdrawEventO {


BankActivityEvent e " new BankActiv i tyEvent ( getAmount() ) ;
control l er.withdrawPerformed( e )i
J

private void build UI () {


setLayout( new BorderLayoutO }i

II

assoc ia cada boto a uma string de encomenda


depositButton . setAc ti onCommand( DEPDS IT li
withdrawButton.setActionCommand( WI THORAW l i
II const ri a tela
JPa ne l buttons new Jpa nel ( new BorderLayoutO ) i
JPa nel balance" new Jpanel ( new BorderlayoutO l;
buttons.add( depos itButton . Borde rlayout.WEST l:
but t ons . add( wit hdrawBu t ton. Borderlayout.EAST );
bal ance .add( ba l ancelabel, BorderLayout.NORTH )i
bala nce.add( amountF ield . BorderLayout. SOUTH };
add( balance . Borderlayout.NORTH ) ;

00 e prog ramao da interface com o usurio

LISTAGEM 13.10 BankAccountView .java (continuao)


add( buttons. BorderLayout.SOUTH );
depositButton.addAct ion Li stener(
new ActionListenerO I
publi c voi d actionPer formed( Action[vent e ) {
f ireOeposit[vent();
J
J

J;
withdrawButton.addAction Listener(
new ActionListenerO I
public void actionPerformed( Act i onEvent e ) {
fireWithdraw[vent() ;
J
J

J;
J
J

3 11

PAGINA E

NCO

SEMANA

DIA
Construindo software confivel
atravs de testes
Quando voc usa programao orientada a objetos, se esfora para escrever software natural,
confivel, reutilizvel, manutenvel, extensvel e oportuno. Para atingir esses objetivos, voc
deve entender que a 'boa' 00 no acontece por acidente. Voc deve atacar seus problemas atra-

vs de uma anlise c um projeto cuidadosos, e ao mesmo tempo nunca perder de vista os princpios bsicos da POO. Somente enloa 00 pooe comear a cumpri r suas promessas. Mesmocom
uma anlise e um projeto cuidadosos, en tretanto, a POO no uma fnnuta mgica. Ela no o

proteger de seus prprios erros ou dos erros dos outros. E erros acontecero! Para produzir software confive l, voc prec isa test-lo.
Hoje voc aprender:

Onde os testes entram no processo iterativo

Sobre os diferentes tipos de testes

Como testar suas classes

Como testar software incompleto

O que voc pode fazcr para escrever cd igo mai s confivel

Como tornar seus testes mais eficazes

Dia 14

Testando software 00
A 00 no evitar que erros aconteam em seu software. Mesmo os melhores programadores cometem erros. Os erros so nonnalmente considerados como um defeito de software que surge de
um erro de digitao, de um erro na lgica ou apenas por um engano bobo comet ido d urante a codi ficao. Embora a implementao de um objeto seja uma fon te de erros comum, eles aparecem
em outras formas.
Erros tambm podem resultar quando um objeto usa outro incorrctamente. Os erros podem at
ser provenientes de fa lhas bsicas na an! ise ou no prprio projeto. Por sua prpria natureza, um
sistema 00 repleto de objetos interagi ndo. Essas interaes podem ser a fonte de todos os tipos de erros.
Fe lizmente. voc pode proteger se u software de erros, atravs de testes de software , onde possvel validar a an lise, o projeto e a imp lementao de se u software.
Assim com o a 00, o t est e no uma soluo mgica; extremamente difcil
testar seu software completamente . O nmero total de caminhos possiveis
atravs de um programa no trivial torn a difci l e demorado obt er cobertura total do cdigo. Assim, mesmo um cdigo testado pode abri gar erros ocultos.
O melhor que voc pode fazer realizar uma quantidade de testes que garantam a qualidade de seu cdigo, enquant o tambm permitam cumprir seus pralOS finais e permanecer dentro do oramen to. A 'quantidade' real de t estes que
voc realizar depender da abrangncia do projeto e de seus prprios nveis
de bem-estar.

Testes e o processo de desenvolvimento de


software iterativo
A Figura 14. I ilustra a iterao apresentada pela primeira vez no Captulo 9, " I ntroduo anl ise orientada a objetos". O teste a lti ma etapa de uma iterao.
Antes de voc sair de lima iterao, o teste uma etapa im portante. O estgio de testes verifica se
todas as alteraes fe itas por voc durante essa iterao no dan ificaram qualquer func iona lidade existente. O estgio de testes lambm verifica se toda nova funci onalidade adicionada agora
funci ona corretamente. Por esses motivos, os testes realizados antes de se sair de uma iterao
so freqent emente referidos como testesfimcionais Oll de aceitao.

Construind o softwa re confivel atravs de testes

FIGURA 14.1
Uma ileratio.

Inicio da itera60

3 15

'\
An6li..

..-..j

Projlll1O

Implementalo

Testa

...
NOTA

Fim di itlra60

o test e no fi nal de uma iterao um marco importante. Para sair da iterao,


seu sistema deve passar pelos testes; entretanto, t ambm devem ocorrer testes durante outros estgios de uma it erao. As lies de hoje mostraro a
voc como usar testes eficientemente, durante a implementao e estgios de
t estes da iterao.
Torn e os testes um objetivo e algo que voc faz por todo o desenvolvimento.
Se voc no pensar nos testes at o final do d esenvolvimento, poder descobrir que no possivel testar seu software. Em vez disso, voc precisa desenvolver pensando nos testes. Voc deve tornar os testes uma parte integrante
do processo de desenvolvimento.

Se erros forem encontrados, voc dever voltar e corrigi-l os. Norma lmen te, voc voltar para a

implementao e tentar corrigi r o problema no cdigo. As vezes, isso tudo que voc preci sar
faze r: bastar corrigir a implementao, testar tudo novamente e prossegu ir. Entretanto, os erros
podem ser provenientes de uma fal ha de projeto ou mesmo de um requi si to ignorado ou
mal -entendido. Talvez voc precise voltar ao projeto ou anli se, antes de poder corrigir um
erro na imp lementao.
ApS corrigir um erro, no suficiente apenas testar o erro corrigido. Em vez
disso, voc precisa realizar todos os testes. Ao corrigir um erro, voc pode introduzir facil m ente um ou mais erros novos!

Um mal-entendido na anlise signi fi ca que o sistema no funcionar confonne o cl iente espera.


Um sistema deve funcionar confomle o esperado e o cliente que conduz o sistema deve concordar com o que esperado do comportamento. No apenas voc precisa testar o cdigo quanto a

Dia 14

fa lhas de implementao, como tambm precisa testar o cdigo para ver se ele func iona conforme o esperado.
Para testar um sistema, voc precisa escrever e executar casos de teste. Cada caso de teste testar
um aspecto especifico do sistema.
Um caso de teste o bloco de construo bsico do processo de teste. O processo de
teste executa vrios casos de teste para poder validar completamente um sistema .
Cada caso de teste consiste em um conj unto de entradas e sadas esperadas. O teste executar um
caminho especifico atravs do sistema (caixa branca) ou testar algum comportamento de fi nido
(ca ixa preta).

Novo

TERMO

Um caso de teste exerci ta uma fu ncionalidade especfi ca para ver se o sistema se comporta como
deveria. Se o sistema se comportar conforme o esperado, o caso de teste passa. Se o sistema no
se comportar conforme o esperado, o caso de teste falha. Um caso de teste falho indica que existe
um erro no sistema. Voc sempre quer que todos os seus casos de teste passem 100% das vezes.
No tente ignorar um caso de teste fa lho, se cem outros casos passarem. Todo teste deve passar
ou voc no poder cont inuar seu trabalho!
Ex istem duas maneiras de basear seus casos de teste: teste de caixa preta e de caixa branca. Uma
estratgia de teste efi caz ter uma mi stura de casos de teste baseados em ca ixa preta e em caixa
branca.
O teste de caixa preta testa se o sistema fun ciona confonne o esperado. Dada uma
entrada especlica, o teste de caixa preta testa se a sada ou comportamento correto,
vis vel externamente, resulta confonne definido pe la especi fi cao da classe ou do sistema.

Novo

TeRMO

Novo

TERMO

No lesle de caixa branca. os testes so baseados unicamente na implementao de


um mtodo. Os testes de caixa branca ten tam atingir 100010 de cobertura do cdigo.

Ao testar classes indi viduais, o teste de ca ixa preta baseado nos requisitos funcionais da classe.
Ao testara sistema inteiro, o teste de caixa preta baseado nos casos de uso. Em qualquer caso, o
teste de ca ixa preta verifica se um objeto ou sistema se comporta conforme o esperado. Por
exemplo, se um mtodo deve somar dois nm eros, um teste de caixa preta enviar dois n(J meros
para o mtodo e, em seguida, verificar se a sada ou no a soma correta dos dois nmeros. Se
um sistema deve permi tir que voc adicione e remova itens de um carrinho de compras, um teste
de caixa preta tentar adicionar e remover itens do carri nho.
O teste de caixa branca, por outro lado, baseado na implementao de um mtodo. Seu objetivo
garanti r que cada desvio do cdigo seja executado. O teste de caixa preta avaliado para cobrir
apenas de um tero metade do cdigo real. Com o teste de caixa branca, voc projeta seus testes
de modo a exercitar cada desvio do cd igo e na esperana de el im inar todos os erros latentes.

Construind o softwa re confivel atravs de testes

DICA

3 17

Os testes de caixa branca, exceto quanto aos programas mais simples, raram ente podem alcanar uma cobertura razovel da combinao de caminhos
atravs do programa. Existem dois passos que voc pOde dar para melhorar a
eficincia de seus testes:
Escreva seus programas de m odo que eles tenham um numero mnimo de
caminhos .
Identifique caminhos crticos e certifique-se de test-los.

Por exemplo, se um mtodo divide dois nmeros e existe um desvio de erro que executado
quando voc tenta dividir por 0, ser preciso garantir que exista um caso de teste que exerci te
essa condio de erro. A no ser que seja especificado na documentao da interface, voc saberia a respeito desse desvio examinando o prpri o cdigo. Assi m, os testes de caixa branca devem
ser baseados no prprio cdigo.
Em qualquer caso, os testes de caixa preta e de caixa branca governam o modo como voc cria
seus casos de teste. Cada um desempenha um papel importante na forma de teste que voc pode
executar.

Formas de teste
No todo. ex istem quatro fOnllaS importantes de teste. Esses testes variam de testes de nvel mais
baixo, que examinam osobjetos individuais, at os testes de nvel mais alto, que exami nam o sislema inteiro. A execuo de cada um ajudar a garanti r a qualidade global de seu soft ware.

Teste de unidade

o teste de unidade a unidade de nvel mai s baixo dos testes. Um leste de unidade examina apenas um recurso por vez.
Um leslede unidade o dispositivo de teste de nve l mais baixo. Um leste de unidade
envia uma mensagem para um objeto e depoi s veri fica se ele recebe o resultado esperado do objeto. Um teste de unidade verifica apenas um recurso por vez.

Novo

TERMO

Em termos de 00, ulllteste de unidade exam ina uma n ica classe de objeto. Um teste de unidade
verifica um objeto enviando uma mensagem e verifica se ele retorna o resultado esperado. Voc
pode basear os testes de unidade no teste de caixa preta e no de caixa branca. Na verdade, voc
deve realizar ambos, para garantir que seus objetos funcionem corretamente. Embora cada classe escrita deva ter um teste de unidade correspondente, voc provavelmente deve escrcvcrocaso
de teste antes de escrever a classe. Voc vai ler mais sobre esse ponto posteriomlcnte .
Hoje, focalizaremos o teste de unidade, pois ele fundam ental para a escrita de software 00
confivel. Na verdade, voc deve realizar os testes de unidade por todo O desenvolvimento.

Dia 14

Teste de integrao
Os sistemas 00 so constituidos de objetos que interagem. Enquanto os testes de unidade examinam cada classe de objeto isoladamente, os testes de integrao verificam se os objetos que
compem seu sistema interagem corretamente. O que poderia funcionar isoladamente pode no
funci onar quando com binado com outros objetos! As fontes comuns de erros de integrao so
provenientes de erros ou mal-entendidos a respei to dos fomlatos de entrada/sada, confl itos de
recurso e seqinc ia incorreta de chamadas de mtodo.
Novo

TERMO

Um leSle de inlegraiio verifica se dois ou mais objetos funcionam em conjunto cor-

relam ente.

Assim como os testes de un idade, os testes real izados durante os testes de integrao podem ser
baseados nos conceitos de caixa branca e de caixa preta. Voc deve ter um teste de integrao
para cada iterao importante no sistema.

Teste de sistema
Os testes de sistema veri fi cam se o sistema inteiro fun ciona conforme descri to pe los casos de
uso. Enquanto executa testes de sistema, voc tambm deve testar o sistema de maneiras no
descritas pelos casos de uso. Fazendo isso, voc pode veri fi car se o sistema manipula e se recupera nonnalmente de condies imprevistas.

DICA

Tente fazer estes testes em seu sistema:


Testes de ao aleat ri a
Os testes de ao aleatria consistem em tentar executar operaOes em ordem
aleatria.
Testes de banco de dados vazio
Os testes de banco de dados vazio garantem que o sistema pode falhar norm almen te, caso exista um problema maior no banco de dados.
Casos de uso mutantes
Um caso de uso mutante tran sforma um caso de uso vlido em um caso de uso
invlido e ga rante que o sistema possa se recuperar corret am ente da interao.

Voc fi caria surpreso com o que um usurio pode tentar fazer com seu sistema . Ele pode no cair
sob um dos casos de uso ' normais'; portanto, melhor estar preparado para o pi or.
Um leste de sistema examina o sistema inteiro. Um teste de sistema verifica se o sistema fu nciona confonne mencionado nos casos de uso e se ete pode man ipular normalmente situacs incomuns e inesperadas.

Novo

TERMO

Os testes de sistema tam bm incluem testes de esforo e de desem pen ho. Esses testes garantem
que o sistema satisfaa quaisquer requisitos de desempenho e possa funcionar sob as cargas es-

Construind o softwa re confivel atravs de testes

3 19

peradas. Se possivel, melhor executar esses testes em um ambiente que corresponda o mxi mo
possvel ao ambiente de produo.
Os testes de sistema so um aspecto importante dos testes de aceitao. Os testes de sistema veri
ficam unidades funcionais inteiras si multaneamente, de modo que um unico teste pode mexer
com muitos objetos e subsistemas diferentes. Para sai r de uma iterao, o sistema deve passar
nesses testes com xi to.

Teste de regresso
Um teste vlido apenas enquanto o que for testado no mudar. Quando um aspecto do sistema
mudar, essa parte - assim como todas as partes dependentes - dever ser novamente testada.
Teste de regresso o processo de repetio dos testes de unidade, integrao e de sistema aps
as alteraes serem feitas.
Os te.ltes de regresso examinam as alteraes nas partes do sistema que j foram
validadas. Quando uma alterao feita, a pane que foi alterada - ass im corno to
das as partes dependentes - deve ser novamente testada.

Novo

TERMO

absol utamente fundamental testar novamente, mesmo depois de uma pequena alterao. Uma
pequena alterao pode introduzir um erro que poderia danificar o sistema inteiro. Fel izmente,
para executar o teste de regresso basta executar novamente seus testes de unidade, integrao e
sistema.

Um guia para escrever cdigo confivel


Embora cada forma de teste seja importante para a qualidade global de seu software, hoje voc
vai foca lizar o que pode fazer de melhor em seu trabal ho dirio para garantir a qualidade dos sis
temas que escreve. Para escrever cdigo confivel, voc precisa fazer o teste de unidade, apren
der a diferenciar entre condies de erro e erros, e escrever documentao til .

Combinando desenvolvimento e teste


Um fato esq uecido na Figura 14.1 que os testes devem ser um processo dinmico. O teste no
deve ser algo a ser evitado, inserido somente no final , feit o por outra pessoa ou completamente
ignorado. Na verdade, podc scr impossvel comear a testar de repente, quando o sistema esti ver
pronto. Em vez disso, voc precisa aprender a comear a testar enq uanto desenvolve. Para testar
enq uanto desenvolve, voc preci sa escrever testes de unidade para cada classe que criar.

Um exemplo de teste de unidade


Vamos ver um teste de unidade para a classe SavingsAccount, apresentada pela primcira vcz no
Captulo 5, "Herana: hora de escrever algum cdigo". A Listagem 14. 1 apresenta a classe Sa vi ng sAccountTes t.

Dia 14

LISTAGEM 14.1 SavingsAccountTest.java


public class Sav ingsAccou ntTest (
public s tati c voi d main( St r ing [] args ) I
Savi ngsAccountTest sat : new SavingsAccountTest();
sat.test_applyinglnterest();
J
public vo1d test_applyinglnterest() (
SavingsAccount acct new SavingsAccount( 10000.00 , 0.05 );
acct.addlnterestO ;
print_getBalanceResult( acct . getBalan ce() , 10500 .00 , 1 );
J

private void print_getBa lanceResult( double actua l, double expected, int


- test ) (
if( actual

==

expected ) (

II

passou

System.out.pr i ntln ( "PASS : test I" + test +. interes t applied


- properly ) ;
System .out . println();
) else ( II f alhou
Sys tem.out.println( "FAIl: test '" + test + " interest applied
- incorrectly " ) :
System.out.println( "Val ue returned: " + actual );
System.out.pr in tln ( "Expected value: " + expected ,;
System.out. pri ntl nO;
J

J
J

SavingsAccountTest um teste de unidade que exami na a classe SavingsAccount. Um teste de


unidade pode ser constit uido de vrios casos de teste. Aqui, a classe Sav ingsAccoun tTest s6 tem
um caso de teste: tes t _app l yi ng Interest. O caso de teste test_app l yi nglnteresl verifica se uma
instncia de Sav ingsAccount aplica corretamente os juros em seu saldo. Um teste de unidade pode
ter mui tos casos de teste, mas cada caso de teste deve verifica r apenas um recurso do objeto.

Construind o softwa re confivel atravs de testes

321

Sav; ngsAccountTest referido como teste de unidade porque exami na o bloco de construo ou
unidade de nvel mais baixo no mundo 00: o objeto. Um teste de unidade deve exami nar apenas
um objeto por vez. Isso significa que cada objeto deve ser testado, assim como uma ent idade independente. Se no for assim, voc no poder testar o objeto. Mesmo que isso seja possvel.
voc poder acabar testando inadvertidamente muitos objetos ao mesmo tempo.
Ao esc rever testes de unidade, voc deve evitar o mximo possvel a va lidao manual da sada.
Confonne voc pode ver cm test app lyinglnterest, o caso de teste rea liza toda a validao necessria automaticamente. FreqUentemente, a validao manual demorada e propensa a erros.
Ao executar casos de teste, voc quer resultados precisos o mais rpido possvel e com o menor
esforo. Caso contrrio, voc poder comear a neg li genciar os testes.

Por que voc deve escrever testes de unidade


Os testes de unidade o ajudam a detectar erros. Se voc danificar algo em sua classe, saber imedi atamente, pois o teste de unidade lhe in formar. O teste de unidade sua primeira linha de defe sa contra erros. A captura de um erro em nvel de un idade muito mais fcil de manipular do
que tentar rastrear um erro d urante o teste de integrao ou de sistema.
Os testes de unidade tambm pennitem que voc saiba quando tenn inou de escrever uma classe:
uma classe est pronta quando todos os seus testes de unidade passam! Como desenvolvedor,
pode ser extremamente til ter ta l ponto fina l bem defin ido. Caso contrrio, poder ser di ficil saber quando uma classe est ' pronta '. Saber que voc terminou e pode prosseguir evita que fiq ue
tentado a acrescentar mais funcionalidade do que precisa em uma classe.
A escrita de testes de unidade pode ajud-lo a pensar a respe ito do projeto de suas classes, especi al mente se voc escrever seu caso de teste antes de escrever a classe; entretanto, para escrever
o caso de teste, voc prec isa usar sua imaginao e fing ir que a classe j existe. Fazer isso proporciona a voc muita liberdade para experimentar a interface de suas classes. Quando terminar
de escrever O teste, voc poder escrever a classe e, em segu ida, tudo ser compilado.
,

Os testes de unidade podem aj ud-lo a refazer seu cdigo. E mais fcil fa zer alteraes em seu
cdigo, se voc ti ve r um teste de unidade, pois assim tem um retorno instantneo em relao s
s uas alteraes. Voc no precisa se preocupar muito quanto introduo de erros; voc pode
simplesmente executar seu teste novamente, para ver se a lgo foi danificado. Usando testes de
unidade, voc no precisa ficar assombrado com a aborrecida pergunta, ;'ser que eu danifiquei
algo?" Voc pode fazer alteraes com mais confiana.
Finalmentc, voc ncm sempre pode estar por peno para testar o sistema. Voc pode mudar para
outros projetas ou outros membros de sua equipe podem precisar reali zar os testes. Os lestes de
unidade penn item que outra pessoa, que no seja o autor, teste um objeto.

Dia 14

Escrevendo testes de unidade


Sav; ngsAccountT es t e tes t _app 1yi n9 Interes t () so exem plos muito simpl es de teste de unida
de e de caso de teste; entretanto, escrever testes de un idade desde o incio para cada classe, pode
se tornar demorado. Imagi ne um sistema onde voc precise escrever centenas de casos de teste.
Se escrever cada teste de unidade desde o in cio, voc acabar fazendo muito trabalho redundan
te. Voc precisa criar ou reut ili zar uma estrutura de teste.
Novo TERMO Uma /wr lllllr(l um modelo de domnio reutilizvel. A estrutura contm todas as
classes com uns a um dom nio inteiro de problemas e serve como a base para um apti
cati vo especifico no domnio.
As classes de uma estrutura de li nem o projeto geral de um ap li cativo. Como desenvolvedor,
voc sim plesmente estende essas classes e, em seguida, fornece suas prprias classes especifica s
para o prob lema, para cri ar um apl icativo.
No caso de uma estrutura de teste, a estrutura define um esqueleto que voc pode reut il izar para
escrever e executar testes de unidade. Uma estrutura de teste permite que voc escreva testes de
unidade rpi da e convenientemente, eliminando trabalho redundante e propenso a erros. Lem
brese de que ludo que voc programa pode conter erros, at seu cdigo de leste. Ter uma estru
tura bem testada pode resolver muitos erros de teste. Sem uma estrutura, a sobrecarga extra dos
testes poderia ser suficiente para imped ilo de faz los.
Uma estrutura de teste completa conter classes base para escrever testes de unidade, suporte in
terno para automao do teste e ut il itrios para ajudar a interpretar c relatar a sada. Hoje, voc
aprender a usar JU nit, uma estrutura de teste gratuita, lanada sob a " IBM Public License", para
testar classes Java. Voc pode fazer download da J Uni! a parti r do endereo http://www.jun it.orgl.

NOTA

o download de JUnit inclui o cdig o-fonte. JU nit tem um projeto excelente e


voc faria muito bem em estudar o cdigo e a documentao includa. Em par
ticu lar, a documentao realiza um excelent e trabalho de documentar os pa
dres de projeto usados para escrever JUnit.

JUnit
A JUnit fornece classes para escrever testes de unidade, para vali dar a sada e para executar os
casos de teste em urna GU i ou em um ambiente de linha de comando. j uni t. framework.TeslCase
a classe base para defi nir testes de unidade. Para escrever lestes de unidade, voc simplesmente
escreve lima classe que herda de TestCase, sobrepe alguns mtodos e fornece seus prprios m
todos de caso de teste.

Construind o softwa re co nfi vel atravs de testes

NO TA

323

Ao escrever casos de teste JUn it, voc deve iniciar o nome de qualquer mtodo de caso de t est e com testo A JUnit fornece um m ecanismo que carregar e
executar autom aticamente qualquer mtodo que comece com testo

A Listagem 14.2 apresenta uma verso JUnit de Sav i ngsAeeountTest.


LISTAGEM 14 ,2

SavingsAecountTest.java

import junit.framework.TestCase ;
import junit.framework,Assert;
publie elass SavingsAeeountTest extends TestCase {
publie void test_applyinglnterest () {
SavingsAceount aeet new SavingsAeeount(10000 .00 , 0,05 );
aect.addlnte rest() ;
Assert.assertTrue( "interest app l ied ineorreetly", aeet.getBalaneeO
- 10500 .00 };

}
public SavingsAecountTest( St r ing name } I
super( name );

}
}
A verso J Un it de Sav i ngsAecountTes t mu ito mais simples do que a origi nal. Ao se usar J Un ir,
no h mot ivo para reproduzir cd igo de exibio ou testes lgicos. Voc pode simplesmente
usar a classe Assert fornec ida pela JUn it. A classe Assert fornece vrios mtodos que recebem
um valor booleano como argumento. Se o valor boo leano for fa lso, um erro ser gravado. Ass im,
aqu i, o teste passa para Assert o va lor booleano retornado pela comparao aeet . getBa 1ance ()
z= 10500 .00. Se a comparao for avali ada como falsa, JUnit sinalizar um erro.
Ento, como voc execula esses testes?
A JUnit oferece a voc vrias opes para a execuo de seus casos de leste. Essas opes caem
em duas categorias: es/a/icas e dinmicas. Se voc optar por usar o mlodo esttico, precisar
sobrepor o mtodo ru nTest() para chamar o teste que deseja executar.
Na linguagem Java, o modo mais conveniente escrever lima classe ann ima para que voc no
precise criar uma classe separada para cada leste que queira executar. A Listagem 14.3 mostra a
de larao annima:

I 324

Dia 14

LISTAGEM 14.3 Uma

Anonymous SavingsAccountTest

SavingsAccountTest test
new Sav ingsAccoun tTest( "tes t _applyi nglnterest" ) (
public void runTest() I
test_applyinglnterest();
J
J;

test. run() j
As classes ann irnas so convenientes porque elas permitem que voc sobreponha um mtodo
ao instanciar um objeto, tudo sem ter de criar uma classe nomeada em um arqu ivo separado.
Aqui, o mtodo principal instancia um Savi ngsAccountT es t , mas sobrepe o mtodo run Tes t O
para executar o caso de teste tes t _app1yi ng Interes t ().
Uma c/asse annima uma classe que no tem um nome. As classes anni mas no
tm nome porq ue elas so simplesmente definidas ao serem instanciadas. Elas no
so declaradas em um arquivo separado ou como uma classe interna.

Novo

TERMO

As classes anni mas so uma excelente escolha para classes usadas uma lmica vez (se a classe
for pequena). Usando uma classe ann ima, voc evita a necessidade de criar uma classe nomeada separada.
Apesar de serem to convenientes, as classes annimas tm defi cincias. Voc precisar criar
uma para cada mtodo de caso de teste que queira chamar. Se voc tiver muitos casos de teste, o
uso de classes ann imas pode exigir muito cdigo redundante.
Para superar essa defic incia, a JUnit tambm fornece um mecanismo dinmico, que procurar e
executar qualquer mtodo que comece com testo Para os propsitos da lio de hoje, contaremos com esse mecanismo dinmico.
A JUnit tambm forn ece um mecanismo, conhecido como conjunto de teste,
para executar vrios casos de teste. A JUnit forn ece um meca nismo para definir estaticamente a bateria de testes a serem executados como um con junto;
entretanto, o mecan ismo dinmico pesq uisar e encontra r cada mtodo de
teste. Hoje, contaremos com esse mecanismo automtico para encontrar e
executar os testes.
A JUnit tambm fornece alguns outros recursos convenientes. Considere a verso atualizada de
Sav ingsAccountTes t , na Listagem 14.4, que tambm testa o mtodo wHhdrawFundsO.
LISTAGEM 14.4 SavingsAccountTest.java
import junit.framework.TestCasej
import junit.framework .Assertj

Construindo softwa re confivel atravs de testes

LISTAGEM 14.4

325

SavingsAeeountTest.java (continuao)

publiC class SavingsAecountTest extends TestCase (


private SavingsAccount aeet;
publi e void tes t_applyinglnterest() (
aeet.addlnterest();
Assert . assertTrue( "interest applied
- 10500.00 );

ineorrectly~.

acet . getBalance()

I
publi c void test_withdrawFunds() t
aect.withdrawFunds( 500.00 )i
Assert . assertTrue ( "i neorreet amount wi thdrawn", acct . getBa 1ance ()
- 9500.00 );

I
proteeted void setUpO (
ace t new Sav ingsAeeount( 10000.00. 0.05 );

I
publie SavingsAeeountTest(String name) I
supere name ):

}
}
Nessa verso, voc notar que o teste contm dois mtodos novos: test_withdrawFundsO e
setup(). setup() sobrepe um mtodo na classe base TestCase. Sempre que a JUni t chamar um
mtodo de teste, primeiro ela far urna chamada a setup(} para estabelecer o acessrio de teste.
Um acessrio de teste define o conjunto de objetos sobre os quais um teste operar. Estabelecer um
acessrio de leste pode consumira maior parte do tempo que leva para escrever casos de teste.
Novo TERMO

o acessrio de teste prepara o conjunto de objetos sobre os quais um caso de teste

aluar. Os acessrios tambm so convenientes, pois eles permitem que voc compartilhe o mesmo acessrio dentre um conjunto inteiro de casos de tesle, sem ter de duplicar cdigo.

Dia 14

A JUnit garante que os objetos acessrios estaro em um estado conhecido, chamando setup()
antes de executar cada teste. A JUnitlambm fornece um mtodo tearOown{) correspondente,
para realizar toda limpeza do acessrio, depois que o teste for executado.
Para executar seus casos de teste, a J Unit fornece executores de teste para exerci tar e reunir os resultados de um teste. A JUnit fornece uma verso grfi ca e urna verso baseada em linha de comando desse utilitrio.
Para executar SavlngsAccountTest graficamente, basta digitar:
java ju ni t.swingu l .TestRunner
A Figura 14.2 ilustra ajanela principal de lUnit.
FtGURA 14.2
A UllJrincipal de JUII;I.

Usando a UI, voc pode navegar at a classe SavingsAccoun tTest. Uma vez carregada, voc
pode simplesmente executar o teste, pressionando o boto Run.
Conforme a Figura 14.3 mostra, a UI da lUnit exibe o nmero de testes executados, assim como
o nmero de testes fa lhos. A UI tam bm fo rnece uma barra grfica que mostra se os testes falharam ou no.
A J Unit uma fermmenta excelente, pois ela penn ite que voc receba retorno claro e instantneo
de seus casos de teste. Assim, se aque la voz em sua mente importun-l o com, "e se eu dan ifiq uei
algoT', voc pode descobrir rapidamente, executando novamente seus testes de unidade.

Escrevendo testes de unidade avanados


Vamos considerar um exemplo ligeiramente mais com plicado. O Exercicio I do Capitulo I I,
"Reutili zando projetas atravs de padres de projeto", apresentou uma possvel implementao
de um I tem. Atualmente, para apresentar um I tem,voc deve chamar vrios mtodos de obteno

Construind o softwa re confivel atravs de testes

327

e processar os dados para exibio. Infe lizmente, solici tar os dados para um objeto no a melhor estratgia de 00. Voc deve ped ir ao objeto para que faa algo com seus dados.

FIGURA 14.3
A UI,)riIICipal de JUllil. o/Js

e.T.ecular com xito os casos


de leSfe.

IHt.'PI"'''''''''''
-.-...".""

Considere a Listagem 14.5, que apresenta uma implementao a lternat iva de Item.

LISTAGEM 14.5 Item.java


publlC class Item {
private
private
private
private
private

in t
int
float
Stri ng
float

i d;

quantity;
un1tPrl ce ;
descri pti on ;
di scount ;

publiC Item( int id . int quantity. float unitPrice . fl oat disco unt. String
- desc) {
this.ld i d;
th i s.quantity quantity;
this.unitPrice unitPrice;
th i s.d i scount discount;
th i s.descript i on desc;
2

publ ic void displ ay( ItemOisplayFonmatter format ) {


fonmat .quantity( quantity );

I 328

Dia 14

L ISTAGEM

14.5

Item.java (continuao)

format.id( i d );
format.unitPrice( un i tPrice );
format.di scount( discount ) ;
format.de sc ription( desc ripti on );
format.adju s tedPri ce( getTotaIPrice() ) ;
}

publi c float getTotalPrice() {


return ( unitPrice * quantity ) - ( discount * quantity ):
}
}

Aqui, voc pode pedir a Itempara que se apresente, usando um formatador de exibio. O formatador cuidar da formatao dos dados para ex ibio. Ter um objeto de formatao separado
uma estratgia mel hor do que fazer com que outro objeto chame mtodos de obteno o u incorporar a lgica de exibio no prprio objeto Item. Quando os requi sitos de exibio mudarem,
voc poder sim plesmente criar novas implementaes de ItemDispl ayFonnatte r.
A Listagem 14.6 define a interface Iten)1splayFonna tter e a Listagem 14.7 apresenta uma possivel implementao da interface.
LISTAGEM

14.6 I temDispl ayFormatter . java

publi c interface ItemDisp layForma tter {


public void quant i ty( int quantity ) :
public void ide in t ld ):
publ ic void unitPri ce( float unitPrice }:
publi c vo i d disco unt( float discount ):
publi c void descri ption( String desc r iption ):
publi c void adj us tedPri ce( float total }:
publi c Stri ng formatO :
}

LISTAGEM

14.7 ItemTableRow. ja va

publi C cla ss I temTabl eRow impl ements ItemDisplayfonnatter


private
private
private
pri vate

i "t

quantity:

i nt
i d ,'
float un1tPr ice ;
fl oat di scoun t ;

Construindo softwa re confivel atravs de testes

329

LISTAGEM 14.7 ItemTableRow.java (continuao)


private String description;
private float adjPrice:
publlC void quantity( lnt quantity ) (
this .quantity z quantity;
J

publ ic vo1d id(intid){


this.1d 1d:
J

publiC void unitPrice( float unitPrice ) (


this.unitPrice un i tPrice :
J

publ ic void discount( float discount ) {


this.discount discount;
J

public void descri pt ion{ String descripti on ) {


this.description description:

J
publiC void adjustedPrice( float total ) (
this . adjPrice total:
J

publiC String format() {


String row "<tr>";
row row + "<td>" +
cow row + "<td>" +
cow row + "<td>" +
cow row + "<td>$" +
cow o row + "<td>$" +
cow row + "</tr>" ;
return row:
J

id
+ "</td>":
quantity
+ "</td>":
description + "</td>";
unitPrice + "<jtd>" ;
adjPri ce + "<jtd>" ;

o formatador I temTabl eRow cria uma representao de linha de tabela HTML para o Item, usando smbolos da moeda norte-americana. Outros formatadores poderiam formatar as dados de outras maneiras,

Dia 14

Esse exemplo apresenta alguns desafios de teste interessantes, assim como algumas oportunidades. Para essas classes, si mplesmente chamar um mtodo e verifi car uma sada no resolver.
O teste do mtodo di splay() de Item de especial interesse, pois um teste de unidade s deve
verificar uma classe isoladamente; entretanto, para testar di sp 1ay () , voc tambm deve passar
para ele um ItemOispl ayFonnatter.
Fe li zmente, os objetos fa lsificados oferecem uma alternativa que ainda pennitir a voc testar
I tem isoladamente.

Um objelOfa/sificado um substituto simplista de um objeto real. Ele chamado de


objeto ralsificado porque o objeto roi ralsificado para propsitos de teste. Embora o
objeto falsificado possa ter uma implementao simplista, ele pode conter funciona lidade extra
para ajudar nos testes.

Novo

TERMO

Os objetos falsificados so int imamente relacionados aos objelos s tubs. Objetos s tubs real izam
apenas trocas de mensagens enquanto que os objelos fa lsificados se diferem no sentido de que
eles realmente executam alguma funo, em vez de si mplesmente aceitarem uma chamada e retomarem algum valor prvio.
s vezes, os objctos fa lsificad os so chamados de simuladores.
Um objeto fals ificado fornece um substituto si mplista para um objelo real. Esse subst ituto no
aparecer no sistema real, apenas no cdigo de teste.
O objetivo de um objeto fa lsificado no fornecera funcionalidade real do objelo que imita. Em
vez disso. o objeto fa lsificado deve fornecer uma implementao simplista que pode ter mais suporte para leste.
Mantenha os objetos fatsifi cados o mais simples possivel. Normalmente, um
objeto falsificado deve ser um objeto independente que no con ta com quaisquer outros objetos falsificados. Se seu objeto falsificado tiver dependncias
demais, provavelmente ele muito complicado.

Por exemplo, considere um acessar de banco de dados que retoma objetos Item. Voc codificaria o
acessor fa lsificado para retomar Omesmo objelo I tem repetidamente; entretanto, se voc fizer testes de unidade em um objeto que recupera objetos Itemusando o acessor, ele no saber a diferena. Tal estratgia isola o objcto que est sendo testado dos defeitos nos objetos que utiliza.
Voc pode usar um objelo fa lsificado para testar se o mtodo di spl ay() de Item usa objetos ItemOi sp 1ayFonna tter corretamente. A Listagem 14.8 apresenta um I tenOi sp1ayForma tter fa lsificado.
LISTA GEM

14.8 MockOi spl ayFonnatter ,java

impo rt j un1t.framewor k.Assert;


public cl ass MockOisplayFormatter impl ements It emO i splayFormatter I

Construind o softwa re confivel atravs de testes

LISTAGEM 14.8

331

MockDlsplayFormatter.java (continuao )

private
priva te
private
private
pri vate
private

test_quantity;
test_id ;
float test_unitPrice ;
float test_discount;
String test_description;
float test_adjPrlce;

private
private
private
private
private
private

fnt
fnt
float
float
Stri ng
float

; "t
; "t

quantity;
id-o

unitPri ce ;
di scount;
de scription ;
adjPri ce ;

publ ic void verify() {


Assert. assertTrue ( "quanti ty set i ncorrectly" , test quanl i ty "" quant i ty
);

Assert.assertTrue(
Assert.assertTrue(
_ un i tPri ce );
Assert.assertTrue(
Assert.assertTrue(
- description );
Assert.assertTrue(

"id se t i nc orrectly ", test_id id );


"unitPrice se t incorrectly", test_unitPrice
"d i scount set incorrectly". test_discount discount);
"desc ription set incorrect l y", test_description
"adjPrice set i ncorrectl y . test_adjPrlce .... adjPrice) ;

}
pubhc void test_quantity( int quantity ) {
test_quantity quantity;
)

publi C void test_id ( int id ) {


test id .. ido

}
publiC void test_unitPrice( f loat unitPrice ) {
test unitPrice unitPrice;

}
publiC void test_discount( float discount ) {
test_discount di scount;
}

publiC void tes t _description( String description ) {


test_description descr ipt ion ;
}

Dia 14

LISTAGEM 14.8

MockDlspl ayFonnatter.java (continuao)

public void test_adjustedPrice( float total ) I


test_adjPrice total;
}

public void quant1ty( int quantity ) {


this.quantity quantity ;
}

public vo i d i de int id ) {
this. id = id;
}

public void unitPrice( float unitPrice ) {


this.unitPrice unitPrice;
}

pub l iC void discount( float discount ) (


th i s.d l scount discount;
}

public void descrip t lon ( String description ) {


this.description description;
}

publi c void adjustedPrice( float total) {


this.adjPrice = total;
}

public String fonnat() ( II no estamos testando funcionalidade de fonnatador


return "NOT IMPLEMENTED";
}
}

De certa forma, MockOi spl ayFormatter semelhante implementao real; entretanto, voc notar que ele no implementa um verdadeiro mtodo formatO. Voc tambm notar que ele
acrescenta vrios mtodos para confi gurar os valores esperados, assim como um mtodo para
verificar as entradas de Item em relao a esses valores.
A Listagem 14.9 ilustra como voc poderia usar a ex ibio fals ificada para fazer o teste de un idade da classe I tem.

Construind o softwa re confivel atravs de testes

LISTAGEM 14 .9

ItemTest.java

import junit.framework.TestCase;
import junit.framework.Assert;
publiC class ItemTest extends Tes t Case {
private Item item;

II constantes para valores do construtor


private
private
private
priva te
private

f1 na 1
fi na 1
final
final
fina 1

statlc
static
static
static
static

1nt lO
int QUANTITY
float UNIT- PRICE
float DISCOUNT
St ring OESCRIPTION

1;
10;

100 . 00f;
5. 00f;
"ITEM_TEST";
-

protected void setUp O {


item new Item( lO , QUANTITY, UNIT_PRICE, OISCOUNT , OESCRIPTION li

I
publiC void test_displayValues() {
MockDisplayFonmatter formatter : new MockOispl ayFormatter();
formatter.test_id( 10);
fonmatter. test_quantlty( QUANTITY );
fonmatter.test_unitPri ce( UNIT_PRICE ,;
fonmatter.test_discount( OISCOUNT }i
fonmatter.test_description( OESCRIPTION );
fl oat adj_total = ( UNIT_PRICE * QUANTITY ) - ( OISCOUN T * QUANTITY );
formatter.test_adjustedPrice( adj_total l;
item.display( formatter l;
formatter . verify();

I
publiC ItemTest( String name ){
supere name }i
I

333

Dia 14

o mtodo

test_di spl ayYa l uesO de ItemTest cria um MockOi spl ayFormatter, configura as entradas es peradas, passa isso para o objeto Iteme usa o fomlatador para validar a entrada. Internamente, o mtodo veri fy() do formatador usaa classe Assert de JUn it para va lidar a entrada.

Os objetos falsificados so um conceito poderoso, pois voc pode program-los para qualquer
coisa. Voc pode ter obj etos fal sificados que contm o nmero de vezes que um mtodo chamado ou um que controle o volume de dados que um objeto envia por urna rede. Tudo depende
de seu aplicativo e do que voc precisa monitorar. Os objetos fa lsificados pennitem que voc realize todos os tipos de monitoramento e teste que no so possveis, caso um objeto simplesmente
cri e todos os objetos de que precisa.
Isso levanta a questo, "e se meus obj etos criarem os objetos de que precisam ?" A maior parte
dos exemp los deste livro cai nessa categoria (espera-se, contudo, que os exemplos tenham permanecido mais inteligveis !). Uma soluo editar as classes para que os obj etos instanciem um
objeto fal sifi cado, em vez do objeto real. Tal estratg ia, entretanto, no limpa, pois o obriga a
alterar o cd igo que voc est testando. Se voc mudar a implementao do cdigo antes de testar, no estar realmente testando a classe que entrar em se u sistema. A melhor soluo escrever cdigo quc seja fcil de testar.
Tal conselho pode parecer retrgrado. A sabedoria convenc ional diz que normal mente voc
escreve testes para testar cd igo que j escreveu . Voc no escreve cd igo para que possa testar! O exem plo Item ilustra uma lio importante. Projetar suas classes de modo que elas sejam
fce is de testar pode res ultarem um cdigo ma is OO! Nesse caso, passaras objetos dependentes tornou oobj eto menos dependente de uma classe espec fica. tornando-o. assim. mai s afeito
conexo.

DICA

DICA

Projete suas classes de modo que voc possa t est -Ias facilmente. Projete
lembrando dos objetos falsificados. Seu cdigo pode se t ornar mais orientado
a objetosl

Escreva suas classes de modo Que os objetos dependentes seja m passados e


no i nstanciados dentro do prprio objeto. Essa prtica leva a ob jetos independentes.

Embora seja verdade que o mtodo d"isp layO de Item seja dependenle da interface ItemOispl ayFonnatter, ele no dependente de uma implementao especfica da interface, como TahleRowFonnatter ou mesmo MockOi splay Formatte r . Em vez disso, Item est livre para usar
q ualquer imp lementao de I t enl i sp layFormat ter, pois ele no se obriga a usar qualquer uma
especfica, criando a instncia por si mesmo.

Construind o softwa re confivel atravs de testes

DICA

335

Dicas para testes efi cazes:


Voc deve otimizar a velocidade de seus testes. Testes rpidos fo rnecem
retorno instant neo; portanto, voc poderia esta r mais apto a us-los.
Compile seus casos de teste junto com suas classes normai s. Essa prtica
o obrigar a manter seus casos de teste atualizados com o cdigo.
Evite val idao visuaVmanual de sada de t este, pois ela propensa a erros. Em vez disso, use algum m ecanismo automtico.
Se voc precisa manter uma base de cdigo q ue no possui testes de unidade,
escreva os test es med ida que precisar deles.

Escrevendo cdigo excepcional


Tesla r uma maneira importante de garantir a qualidade do cdigo que voc escreve; entretanto,
esse no o nico passo que voc pode dar. Voc tambm precisa aprender a identificar a diferena entre uma cond io de erro e um erro. Uma condio de erro e um erro no so a Illesma
coisa!
Voc sabe o que um erro; um erro um defeito. Uma condio de erro li geiramente diferente.
Uma condio de erro ou exceo um a falha previsvel que acontece sob ccrtas circunstncias
no domnio. Pegue como exemplo a loja on-line. Perodos de inatividade da rede acontecem o tempo todo. Um periodo de inatividade da rede no um erro (a no ser que seu cdigo tenha causado
isso!). Em vez de tratar condies de crro como erros, voc precisa codificar em tomo delas.
Por exemplo, se sua conexo com o banco de dados falha, voc precis.1. tentar reconectar. Se ela
ai nda estiver inativa. voc prec isar tratar da cond io nonnalmente e infonnar o usurio do erro.
Toda li nguagem tem sua prpria maneira de relatar cond ies de erro. As linguagens Java e C++
empregam um mecanismo conhec ido como excees para sinal izar condies de erro. Linguagens como C contam com cdigos de retorno. Qualquer que seja a linguagem usada, voc deve
escrever seu cd igo para detectar e se recuperar nonnal mente de condies de erro.
As excees Java e C++ funcionam de modo seme lhante. As excees so apenas outro tipo de
objeto; entretanto, o compilador Java o obriga a tratar delas, se dctcnninar que uma exceo
pode ocorrer e voc no tratar dela.
Aqui est um dos mtodos da classe URL da linguagem Java:
publi c URLConnection openCon nection( ) throws IOExceptlon
Voc v que o mtodo tem algumas infonnacs extras. O mtodo indica que pode lanar
IOException, significando que, sob condies nonnais, o mtodo retomar um objeto URlConnect i on. Se houver um erro na abertura da conexo. entretanto. o mtodo lanar lima exceo
rOException.
Na linguagem Java, voc trata de excees em blocos t ry/ catch. A Listagem 14. 10 mostra
como voc poderia manipular uma chamada de openConnection.

Dia 14

LISTAGEM 14.10 Tratando de uma exceo

java . net.URL url .. new java.net.URL( .. http: //www.samspubl ish i ng.com/ .. ) ;


java.net. URLConnection conn;
try I
conn = url.openConnection();
I catch ( j ava. lo .IOExcept ion e ) { II um erro ocorreu
II registra um erro , escreve al go na te l a
II faz algo para trata r do erro

I
Quando voc faz uma chamada para openConnect i on, faz isso normalmente; erllretanto, voc
deve faze r a chamada dentro de blocos try/catch ou d izer explici tamente que o mtodo no qua l
a chamada fei ta tambm lana uma exceo IOException.
Se a chamada para openConnection () resultar no lanamento de uma exceo, conn no ser con*
figurado. Em vez di sso, a execuo conti nuar dentro do bloco ca t ch, onde voc pode tentar re*
cuperar, registrar um erro, impri mir uma mensagem na tela o u lanar outra exceo.
Se voc no capturar a cxceo expl icitamente ou lanar urna nova exceo, a exceo subir
como bolha na pil ha de chamadas, at chegar ao topo ou que algum fina lmente a capture.

O importante que voc programe para condies de erro, usando o mecanismo incorporado
sua linguagem. Isso signi lica que, quando voc projetar suas classes, tambm dever considerar
as d iversas cond ies de erro, model*las atravs de objetos exceo e faze r com que seus mtodos as lancem.

Escrevendo documentao eficaz


H mais um passo que voc pode dar para melhorar a qualidade de seu trabalho: document* lo.
Existem mui tas formas de documentao, cada uma com seu prprio nve l de eficcia.

Cdigo-fonte como documentao


O cdigo*fonte, at seus testes de unidade, urna fo nna de documentao. Qua ndooutras pessoas precisam pegar e manter se u cd igo, importante que ele seja legve l e bem organizado. Caso
contrrio, ningum poder ter idia do que ele faz .

O cdigo-fonte a forma mais importante de documentao, pois a nica documentao que


voc tem de manter.

Conve nes d e codific ao


O primei ro passo que voc pode dar para transformar seu cd igo em boa documentao escolher uma conveno de codi fi cao e fi car com ela. As convenes de codificao podem cobri r
tudo, desde corno voc endenta suas chaves at corno nomeia suas variveis. A conveno espe-

Construind o softwa re confivel atravs de testes

337

cfica no to importante assim. O importante que sua equipe de projeto, e preferi velmente
sua empresa, escolha uma conveno e fique com ela. Desse modo, qualquer um pode pegar um
trecho de cdigo e acompanhlo - bem, pelo menos no se atrapalhar com a fonnatao.
A Li stagem 14.1 1 apresenta uma maneira de declarar classes Java.

LISTAGEM 14.11

Um exempl o de cla sse

public class <C la ssName>


extends <ParentClassName>
implements <lIST OF INTERFACES>
(

II
II
II
II

vari vei s pblicas


variveis protegidas
varilivei s privadas
constantes

II
II
II

mtodos pblicos
mtodos protegidos
mtodos privados

DI CA

Os nomes de classe sempre devem comear com uma letra maiscula. Os nom es de mtodo sempre devem comear com uma letra minscula. Os nomes
de varivel sempre devem com ear com uma letra minscula.
Qualquer nome contendo vrias palavras deve ter as palavras reunidas e cada
palavra comear com letra maiscula.
Po r exemplo o mtodo someMethod() e a classe HappyObj ect.
As constantes sempre devem aparecer em MAISCULAS. As variveis normais
devem aparecer em minsculas.
(Not e que essas convenes so voltadas li nguagem Java . A s convenes
para Smalltalk e C++ podem ser diferentes.)

Aqui est uma maneira de declarar mtodos e instrues i f /e 1se aninhadas:

public void method() {


if ( co ndicional) {
I else {

I
I

Dia 14

Constantes
As constantes lambm podem serv ir corno uma forma de documentao. Use constantes quando
voc se achar ut ilizando um va lor cod ificado. Uma constante bem nomeada pode dar uma idia
do objetivo de seu cdigo.

Comentrios
Assim como uma constante bem colocada, nada aj uda a tomar o cdigo mais intel igivel do que
um comentrio bem colocado; entretanto, voc precisa encontrar um equilbrio em seus comen~
trios. Co loq ue comentrios demais e eles perdero o sign ifi cado.
Aqui est um erro de comentrio intil, mas comum:

pub l i c voi d i d( int id ) {


thi s . 1d 1d ; II configu ra id
}

Comentri os inteis informam o que o cd igo est fazendo. Se voc precisa explicar cd igo, e n~
to ele pode eSlareompli cado demais. Os comentrios devem dizer para q ue serve o cdigo. Eles
devem descrever impl ementaes no intuiti vas.

NOTA

Note que um comentri o sob uma assinatura de m todo no substi tui um bom
e ctaro nome de m todo.

Nomes
Os nomes de varivel, mtodo e classe devem ser significativos. S ol elre~os e seja consistente em
s ua gra fi a. I)or exemplo, sem pre co loque inicia l maiscula na segunda palavra de um nome com
vrias pa lavras, como em testCase. Como alternativa, voc pode dividi r as palavras com um hi~
fen (-), corn o cm test -case. Novamente, o aspecto mais importante a consistnc ia. Torne sua
regra de atribuio de nomes parte de sua conveno e ento a uti lize consistentemente.

Cabealhos de mtodo e classe


Quando voc escrever uma classe ou um mtodo, sempre se cert ifique de incluir um cabealho.
Um cabealho de mtodo incluir uma descrio, uma lista de argumentos, uma descrio do re~
torno, assim como condies de lima exceo e efeitos colaterai s. Um cabealho pode al incluir
condies prvias. Um cabea lho de classe nonnalmente incluir uma descrio, o nmero da
verso, a lista de aUlores e o histrico de reviso.
Quando voc programar em Java, cert ifi que~se de tirar proveito do Javadoc. (Veja o Apndice B
para mai s informaes.) O Javadoc fornece vrias tags para escrever cabeal hos. Se voc usar
Javadoc, poder si mplesmente executar suas classes atravs de um processador, que far automaticamente documentao da AP l baseado na Web, conven iente para suas classes.

Construind o softwa re confivel atravs de testes

DICA

339

Quando voc ti ver documentado algo, ter se comprometido a manter essa


documentao atualizada, seja com o Javadoc, um documento de projeto ou
um com entr io. Uma documentao obsoleta intil. Mantenha -a atualizada!

Resumo
Hoje, voc aprendeu sobre os testes e o que pode fazer como desenvolvedor para garantir a qualidade de seu trabalho. Ao todo, existem quatro fonnas gerais de teste:

Teste de unidade

Teste de integrao

Teste de sistema

Teste de regresso

Em se u trabalho dirio, o teste de unidade sua primeira li nha de defesa cont ra erros. O teste de
unidade tambm tem as vantagens de obrig-lo a considerar seu projeto do ponto de vista do teste e de fornecer a voc um mecanismo que torna mais fcil refazer as coisas.
Voc tambm viu a importncia do tratamento correto das condics de erro e da manuteno da
documentao. Todas essas prticas aumentam a qualidade de seu cdigo.

Perguntas e respostas
P Por que os desenvolvedores detestam testar?
R Parece haver uma cultura do 'ev itar teste' entre os programadores. Achamos que esse
um problema cu ltural. Na maioria das empresas, o pessoal de controle de qualidade um
grupo separado dos desenvolvedores. Eles vm, testam o sistema e redigem relatrios de
erro. Essa estratgia co loca o programador na defensiva, especialmente se o gerente de
projeto pressionar o desenvolvedor a refazer o trabalho. De certa forma, os testes se tornam uma punio e uma fonte de trabal ho extra.
Ver os testes como trabalho extra tambm faz parte do problema. Muitas equipes de projeto deixam os testes para o tinal do desenvolvimento; assi m, ele se torna algo que voc
faz quando j terminou de fazer o trabalho 'real'. Infel izmente, quanto mai s voc retarda
os testes, mais difceis eles sero de fazer. Quando voc comear a testar, provavelmente
encontrar um grande nmero de erros, pois no tinha testado at esse ponto. Isso o leva
de volta fase de punio, especial mente porq ue voc, provave lmente, est perto de seu
prazo final. E se voc estiver prximo ao seu prazo final , a presso do gerente de projeto
aumentar.

o evitar teste UIll problema que se auto-alimenta.

Dia 14

P 110r que os testes so feitos freqcntcmente por um grupo de controle de qualidade


separado?
R Testes independentes ajudam a garamir que o pessoal de teste no evite, subconsciente
mente, reas onde podem ex istir problemas - uma fal ha na qual os desenvolvedores p0dem estar propensos.

P Em todas as lies de hoje, voc usou JUnit. Por que voc escolheu J Unit?
R JUnit uma fe rmmenta de teste gmtuila que faz bem seu tmbalho. A J Un it bem projeta
da e suficientemente pequena para que voc possa por suas mos no proj eto faci lmente.
Ela ta mbm no possui os detal hes que muitos outros prod utos tm.
Em nossa op inio, ev itar os detal hes durante os testes de unidade uma vantagem. A
JUnit o co loca mais perto do cdigo, pois voc preci sa escrever se us prprios lestes, confi g umr os dados e vali dar a sada. Ela o obriga a considerar seu projeto e at a aumen
t- lo, para que seja fcil testar.
Com algumas das ferra mentas de teste mai s automatizadas, voc pode perder essas vantagens; entretanto, a J U nit uma estrutura de teste de unidade. Voc prec isar encontrar
outras ferramentas para alguns dos testes de integrao c de sistema.
P O teste de unidade parece um fardo. No tenho tempo para fazer o teste de unidade.
O que devo fazer?
R Os testes de unidade podem parecer um fardo na pri me ira vez que voc escreve um deles.
Com todo honest idade, s vezes, os testes de unidade so dispend iosos para escrever.
Eles se pagam com o passar do tempo. Quando voc escreve um teste, pode reutiliz-lo
repet idamente. Sem pre que voc mudar a implementoo de sua classe, bastor executar
novamente seu teste de un idade. Os testes de unidade tornam mui to ma is fc il fazer alteraes em seu cdigo.
No ter tempo um argum ento fraco. Imagine quanto ser mais demorado encontrar, rastrear e corrigir erros, se voc de ixar os testes para o fi m - um momento em que voc
normalmente est sob ainda mais presso.
P Como voc sabe se j testou o suficiente?
R Voc j testo u em um nvel mnimo, quando ti ver um teste de unidade para cada classe,
um teste de integrao para cada interao importante no sistema e um leste de sistema
para cada caso de uso. Se voc vai o u no fazer testes ad icionais depende de seu pmzo finai, assim como de seu nvel de bemestar.

Construind o softwa re confivel atravs de testes

341

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respostas no Apndice A, " Respostas".

Teste
I. Como erros podem entrar em seu software? (Ou talvez a pergunta deveria ser, ;;como
voc causa erros em se u software?")
2. O que um caso de teste?
3. Quai s so as duas maneiras nas quais voc pode basear seus testes?
4. Defi na teste de caixa branca e de caixa preta.
5. Quai s so as quatro forma s de teste?
6. Defina teste de l/IIidade.
7. Qual o objeti vo por trs dos testes de integrao e dos testes de sistema?
8. Por que voc deve ev itar ler de deixar os testes para o fina l de um projeto?
9. Por que voc deve ev itar validao manual ou visual ao testar? Qual a alternativa?
10. O que uma estrutura?
I I. O que um objeto fal sificado?
12. Por que voc deve usar objetos fa lsificados?
13. Qual a diferena entre um erro e uma condio de erro?
14. Ao escrever seu cdigo, como voc pode garantir sua qua lidade?

Exerccos
I. Faa down load da JUn it c leia cooks t our, que encontrado no d iretri o doc.
2. Escreva um teste de unidade para HourlyEmployee do Captulo 7, " Po limorfi smo: hora
de escrever algum cd igo", que testa o mtodo cal culatcPay().

SEMANA

Em reviso
Nesta semana, voc aprendeu a respeito da estratgia iterativa para o processo de desenvolvimento de software. O processo de desenvol vimento de software incl ui os estgios de anlise,
projeto, implementao e teste. Voc aprendeu que a estratgia iterai i va para Odesenvol vimento
de software perm ite voltar e re finar qualquer estgio do processo. Esse refinamento contnuo
leva a lima soluo mais completa e correta para seu prob lema.
O Dia 8 apresentou a Unified Modeling Language. No Dia 9, voc aprendeu sobre AOO (Anlise Orientada a Objctos), o primeiro passo do processo de desenvo lvimento. A AOO pcnni te que
voc entenda o problema que est tentando resolver. Um mtodo de ADO atravs do uso de casos de li SO para descrever como os usurios utilizaro o sistema. Uma vez que voc tenha seus
casos de uso mapeados, pode usar linguagens de modelagem, como a UML, para visua lizar graficamente o domnio de seu problema.
O Dia 10 descreveu o POO ( Projeto O rientado a Objetos), o processo de pegar o modelo de domnio e criar o modelo de objetos que voc usar durante a implementao. A lista a seguir apresenta os passos bsicos necessrios para completar o roo.
I. Gere uma lista de objetos inicial.
2. Refine as responsabilidades de seus objetos.
3. Desenvolva os pontos de interao.
4 . Detalhe os relacionamentos entre objetos.
5. Construa seu modelo.
Os cartes CRC o ajudam no mapeamento das responsabilidades e das interaes entre cada obj eto. Os dois dias seguintes abordaram os padres de projeto, conceitos de projeto reutil izvel
que rornecem atal hos para o POO. Voc aprendeu sobre padres, como Adapter, Proxy, Iterator, Abstract Factory, Singleton e Typesare Enum, e quando apropriado us-los.
O Dia 13 explicou o projeto de UI com o padro MVC. O pad ro MVC rornece nexibilidade, desacoplandoa UI do sistema subjacente. Ele tambm enratiza a necessidade de executar o processo de projeto de software para a UI como para qualquer outra pane do sistema.

Construind o softwa re confivel atravs de testes

343

Finalmente, o Dia 14 apresentou os testes nos estgios de implementao e lestes de cada iterao. Voc aprendeu a respeito das duas mane iras de testar seu cdigo: teste de caixa branca e teste de caixa preta. Voc tambm aprendeu as quatro formas de teste: teste de unidade, de
integrao, de sistema c de regresso. O teste a maneira fi nal de garantir a qualidade de seu cdigo. Se ele no for levado em considerao durante todo o processo de desenvolvimento, voc
poder se deparar com srias conseqncias.
Agora que voc tenni noll as lies desta semana, deve entendera processo de desenvolvimento
de software.

SEMANA

Reunindo tudo:
um projeto 00 completo
15 Aprendendo a combinar teoria e processo
16 Iterao 2 do j ogo vinte-c-um: adicionando regras
17 Iterao 3 do jogo vinte-c-um: adicionando aposta

18 Iterao 4 do jogo vinte-c-um: adicionando uma GUJ


19 Aplicando uma alternativa ao MVC
20 Divertindo-se com o j ogo vi nte-c-um

21 O ltimo quilmetro

Panorama
Na pri meira semana, voc aprendeu a teoria por trs da POO. A segunda semana forneceu um
processo para segu ir ao aplicar essa teoria. Nesta semana, voc reuni r as lies das duas primeiras semanas, em um projeto de POO completo. Esse projeto fa r voc percorrer todas as fases do
desenvolvi mento - do incio ao fim do projeto.
Seu projeto fin al ser o desenvolvimento dojogo de cartas vinte-c-um. O Dia 15, o primei ro dia
desta semana, o conduzi r na pri meira iterao do j ogo e adicionar as funci onalidades bsicas
da ADO, atravs de im plernentaoe leste. Nos dias 16 e 17, voc vai adicionar mais funcionalidades no jogo, atravs de mai s duas iteraes. O Dia 18 mostrar como se acrescenta uma GUI
ao sistema.

o Dia 19 forn ecer uma outra maneira de imp lementar uma GUI, atravs do padro de projeto
PA C. No Dia 20, voc vai aprender a adicionar vrios jogadores no-humanos e ver como
transformar seu jogo em um simulador. Finalmente, o Dia 21 reunir tudo e retirar todas as aparas.

SEMANA

DIA
Aprendendo a combinar teoria e
processo
A Semana I o ajudou a entender a teoria por trs da POO. A Semana 2 forneceu um processo

para segui r ao aplicar essa teoria. A Semana 3 mostrar a voc como reunir as lies das semanas
I e 2, apresentando um projeto de POO completo. Esse projeto o conduzir por Iodas as rases do
desenvolvimento, do incio ao fim do projeto.
A lio de hoje apresentar o jogo vinte-c-um, um jogo de cartas popu lar. No fin al da lio de
hoje, voc completar a anlise, projeto e implementao funcional iniciais do jogo. Voc no

criar um jogo virllc-c-um inteiro em uma nica etapa grande. Em vez disso, voc vai aplicar o
processo iterat ivo durante a semana, medida que completa o jogo vi nte-c-um.
Hoje voc aprender como:

Aplicar anlise e projeto 00 em um jogo de carias real

Usar o processo iterativo para obter e ver resultados rpidos

Evitar muitas tentaes comuns do desenvolvimento


Evitar caractersticas procedurais que podem peneirar em seu programa

Jogo Vinte-e-um
o vi llle-e-um um jogo de cartas popular, onde o objetivo obter a contagem mais alta de cartas
do que a banca, sem ultrapassar 21. O objetivo desta semana criar um jogo vi nte-e-um bastante

Dia 15

com pleto, escrito em Java, usando os conceitos de POO que voc aprendeu por todo o livro.
Embora alguns recursos sejam omitidos por mot ivos de ctareza e brev idade, voc dever ter um
j ogo to viciante e demorado quanto os jogos de pacincia ou FreeCell que acompanham muitos
sistemas operacionais populares.

ALERTA

o autor no se responsabiliza pelo t empo perdido enquanto se joga este joga i

Por que vinte-e-um7


A pergunta pode vir mente, "por que vinte-e-um ?"
O objet ivo de programar o vi nte-e- um no transform- lo em um jogador profi ssional. Ex istem
dois mot ivos pam se usar o vinte-e-um como um projeto de roo introdutrio:
Quase todo mundo est familiarizado com pelo menos um jogo de cartas.
Acontece que o jogo vi nte-e-um se encaixa bem no parad igma da roo.
Em geral, a maioria das pessoas est fami liarizada com o domnio do jogo de cartas. Uma parte
importante da AOO e do POO ter um especialista no domn io presente, enquanto se identifica
os casos de uso e o modelo de domnio. Si mplesmente no possvel conseguir um especialista
no domn io como parte da conct uso destas lies.
Um jogo de cartas no exige um especialista no domnio. Em vez disso, sua prpria experincia e
um bom li vro de regras ou site Web fornece tudo de que voc precisa para completar a anl ise e o
projeto por conta prpria. Se ficar confuso, voc pode at pegar um baralho e simular um cenrio.
Como resultado, um jogo de cartas muito mais acessve l do quc tentar aprender um domnio
completamente desconhecido. Um dom nio conhecido no o desviar do obj eti vo rea l destas lies - aprender a aplicar os princpios da 00.
O vinte-c-um - na verdade, como a maioria dos jogos de cartas cm gera l - tambm tende a se
encaixar bem no paradigma da roo. As interaes entre bancas, jogadores, suas mos e as cartas podem ajud-lo a ver que um sistema 00 constitudo das interaes entre os vrios objetos.
Os jogos de cartas tambm tendem a manter caractersticas procedurais suficientes para que seja
fcil ver como uma estratgia de roo pode ser muito diferente de uma procedural, especialmente ao se aplicar regras de jogo.

Declarao da viso
Ao se iniciar um projeto, freqUentemente aj uda comear com uma dcctarao da viso ou objetivoo O objetivo da declarao formar o propsi to gera l do sistema que voc va i criar. O objetivo

Apre nde ndo a combina r teoria e processo

349

da declarao no capturar cada aspecto do problema que voc est tentando resolver. Em vez
disso, a declarao simplesmente infonna o intento e fornece um ponto de partida para a anlise.
Novo

TERMO

A declaralio da viso forma o propsito geral do sistema que voc vai criar e do
problema que est tentando resolver.

Aqui est a declarao da viso do sistema do j ogo vinte-c-um:


O jogo vinte-e-um penni te que um jogador partic ipe dele, de acordo com regras de cassino comuns.
Embora seja aparentemente evidente, essa declarao serve como um catalisador excelente para
a anlise.

Requisitos de sobreposio
Antes de iniciar a anlise, ajuda enumerar todos os requisitos de sobreposio. Exi stem apenas
algumas restries no jogo vinte-e-um. A n ica restrio im portante agora como o us urio vai
interagi r com O sistema.
O j ogo vi nte-e- um permite que o usurio interaja com o sistema atravs de uma linha de comando ou UI grfi ca. claro que a iteraes iniciais penn itiro apenas uma interao atravs de uma
interface de li nha de comando.
O jogo vinte-e-um tambm deve ser implementado na linguagem de programao Java.

importante listar tais restries antecipadamente, para que voc no aparea com um projeto
que tome a obedincia a essas restries impossvel.

Anlise inicial do jogo vinte-e-um


O Captu lo 9, " Introduo (AOO) Anlise O rientada a Objetos", apresentou a AOO, assim
cama o processo de desenvolvimento iterativo. De acordo cam as inrormaes do Cap tulo 9,
este projeto segu ir um processo de desenvol vi mento iterativo e iniciar cada iterao desse processo com a anlise.
Ao se iniciar a an lise, freqentemente util comear com a declarao da viso mencionada anteriormente:
O jogo vinte-e-um permitc que um jogador participe dele, de acordo com as regras dc cassino comuns.
Voc pode usar a declarao para gerar uma lista in icial de perguntas. So essas perguntas que
dirigiro sua anlise.

350

Dia 15

As regras do jogo vinte-e-um


A partir da declarao da viso do jogo vinte-c-um, voc pode naturalmente perguntar, "q uais
so as regras de cassino comuns dojogo vi nte-c-um?" Voc vai usar essas regras para mode lar o
jogo vi nte-c-um.
O objclivo pri ncipal do j ogo vi nte-c-um reunir uma mo de cartas cujo va lor seja maior que a
mo da banca, sem ultrapassar 2 1. Cada carta recebe um valor numrico de 1 a II , onde os va le
I Oll 11 (dependendo do que orerea a voc uma mo mel hor), as cartas numricas valem os seus
respectivos nmeros e todas as cartas de fi g ura valem 10. O naipe no tem relao com o va lor da

carta.
A Figura 15. 1 mostra alguns exemplos de mos.

clara que o jogo real um pouco mais comp licado. Vamos ver cada componente importante do

Jogo.

Aposta
Antes quea banca distribua as cartas, cada jogador deve fazer uma aposta. Nonnalmente, a aposta est sujeita a algum li mite, como USS25 Oll USS50 por jogo.

Distribuindo as carta s
APS cada jogador ter fe ilo uma aposta, a banca pode distribuir as cartas. Comeando com o pri-

meiro jogador, a banca distribui urna carta aberta, para cada jogador, terminando consigo mesmo.
Ento, a banca repete esse processo, mas distribui sua prpria carta fechada. A carta fechada da
banca conhec ida como carta ocu lta.

A distribuio de cartas termina quando a banca servir a cada jogador, incluindo ela mesma,
duas cartas. O jogo comea quando a di stribuio terminar.

Jogando

o jogo pode diferir dependendo da carta aberta da banca . Se a carta aberta da banca valer

10
(chamado de valor 10) ou for um s (valor I I), a banca dever verificar sua carlaoculla. Se a carta oculta resul tar em um total de 2 I (chamado de 21 ou vi nte-e- um natural), o jogo tenninar automaticamente e se passar para o pagamento. Se a carta oculta no resultar em um total de 21 , o
jogo comear nonnalmente.
Se a carta aberta da banca no for de valor 10 ou um s, o jogo passar automaticamente para o
primeiro j ogador. Se o jogador tiver um 21 natural, ele tcr bat ido e o jogo passa para o jogador
seguinte. Se o j ogador no tiver 21, ter d uas escolhas: receber mai s cartas ou parar:

Aprendendo a combinar teoria e processo

FIGURA 15.1

ExemlJ/o de II/(ios do jogo


rime-e-11m.

10 de Copas

10

s de Paus

...

10

= 21

5 de Ouros

2 de Copas

Damas de
Copas

=17

s de
Espadas

9 de Espadas

6 de Paus

10

10 de Espadas

10

5
Rei de
Ouros

35 1

= 21

Valete de Espadas

...

=25

receber mais cartas - Se Ojogador no estiver satisfe ito com sua mo, ele pode optar por
tirar outra carta, o que chamado de receber mais cartas. O jogador pode receber ma is cartas
at ultrapassar 21 (estouro) ou parar (no precisa de mai s cartas).
parar - Se o jogador estiver satisfeito com sua mo, ele pode optar por parar e no receber
mais cartas.
Aps o jogador estourar ou parar, o jogo passa para o jogador seguinte. Esse processo se repete
at que cada jogador tenha jogado. Aps cada jogador participar, a banca ento joga suas cartas.
Quando a banca completa sua vez, o jogo passa para o pagamento, onde ocorre a contagem de
pontos e o pagamento.

Dia 15

Pagamento
Aps a banca tcnninar sua vez (ou saber que tem vinte-e-um pontos), o jogo passa para o pagamento. Durante o pagamento, cada jogador que estourou perde sua aposta; cada jogador com
uma mo menor que a da banca perde s ua aposta; cada j ogador com uma mo melhor que a da
banca ganha s ua aposta; e cada j ogador com uma contagem igual da b..1nca empata e nenhum
pagamento feito. As apostas so pagas unifonnemente.
Se um j ogador ti ver um vinte-e-um e a banca no, ojogador receber uma vez e meia o que apostou. Por exemplo, se o j ogador tivesse apostado US$ IOO, receberia US$ 150 ([ I 00 3]/2).

Miscelnea
Precisamos menc ionar mais alguns detalhes importantes sobre o jogo virlle-e-um:

O bara lho - O jogo vinte-c-um jogado com quatro baral hos padro de 52 cartas. Esses
quatro baralhos so combinados em uma unica pilha de cartas grande.
N mero de jogadores -

De um a sete jogadores podem j ogar vi nte-e-um .

Dobrando - Aps receber suas duas cartas, o jogador pode opiar por dobrar. Quando o jogador dobra, ele duplica sua aposta, recebe mais uma carta e termina sua vez.
Seguro - Quando a carta aberta da banca um s, o j ogador pode optar por fazer uma aposta
segura. A aposta segura igual metade da aposta original. Se a carta ocu lta da banca fornecer banca um 21 natural, o jogador no ganha nem perde. Se a carta oculta da banca no fornecer a ela o 21 , o jogador perder sua aposta segura.
Dividindo pares - Diz-se que um jogador tem um par, se as duas cartas iniciai s distribudas
tiverem o mesmo valor. Se o j ogador recebeu um par, ele pode optar por desdobrar as cartas
em duas novas mos. Se o jogador dividir o par, a banca di stri buir a cada nova mo mais
uma carta e, em seguida, o jogador dever colocar uma aposta igual na nova mo. Um j ogador pode dividir qualquer par que resulte de urna divi so subseqllente (exceto quanto a um
par de ases). Digno de nota tambm o fato de que qualquer contagem 21 resultante de uma
di viso no tratada como um 2 1 natural. Uma vez fei ta a div iso, o j ogador aposta normalmente ou pra, para cada mo.

Identificando os atores
Existem dois mot ivos para se fazer a anlise . Atravs da anlise, voc cria o modelo de caso de
uso: a descrio de como o usurio vai usar o sistema. Atravs da anlise, voc tambm cria o
modelo de domnio: uma descrio do vocabulrio princi pal do sistema.

O pri meiro passo na defini o de seus casos de uso defi nir os atores que usaro o sistema. A
part ir da descrio da ltima seo, fcil ver que existem dois atores principai s no jogo vinte-e-um - 0(5) j ogador(es) e a banca.

Apre nde ndo a combinar teoria e processo

353

Esses dois atares respondem pergunta, "quem usar principalmente o sistema?" Atravs dos
casos de uso, voc pode defi nir como esses atores usaro o sistema.

Criando uma lista preliminar de casos de uso


Uma mane ira efi caz de gerar os casos de uso in ic iais perguntar o que cada um desses atores
pode fazer.
Os jogadores podem fazer o segu inte:
I. Fazer apostas.

2. Pedir mai s cartas.


J. Parar.

4. Estourar.
5. Consegu ir um vinte-e-um.

6. Fazer um seguro.

7. Divid ir pares.

8. Dobrar.
9. Decid ir jogar novamente.
10. Sa ir.
A banca pode fazer o segui nte:
I. Di stribu ir cartas.

,-.

Efetuar o jogo.

J. Receber ma is cartas.

4. Parar.

5. Esto urar.
6. Consegu ir um vinte-e-um.

Podem existi r mais casos de uso, mas essa lista fornece muito material inicial.

Planejando as iteraes
o Captulo 9 apresentou o processo de desenvolvimento iterativo. Segu ir um processo de desenvolvimento iterat ivo permi tir que voc construa rapidamcntc uma implemental'lo de vinte-e-um simples. Cada iterao continuar a acrescentar mais fu ncionalidades no jogo.

Dia 15

Tal estratgia possi bilita resultados rpidos e quamificveis. Seguir tal estratgia permite a voc
tratar dos problemas confonne eles apareerem - no tudo de uma vez, no fina l do desenvolvimento. Uma estratgia iterativa impede que voc seja atropelado por uma avalanche de problemas no final do desenvolvi mento.
Fundamental para um desenvolvimento iterativo o planejamento das iteraes o melhor que
voc puder, desde o incio. Quando novos fatos se apresentarem, totalmente aceitvel rever o
plano; entretanto, um esboo das iteraes desde o incio, proporciona uma orientao para o
projeto, objetivos e, mais importante, d uma idia do que se vai obter quando os objet ivos forem
at ingidos.
Normalmente, voc planeja suas iteraes classificando os casos de uso pela importncia. Ao
trabalhar com um cli ente, melhor deix-lo classificar a importncia de cada caso de uso. No
caso do jogo vinte-e-um, voc deve classificar os casos de uso com base em sua importncia
para o jogo. Escolha os casos de uso absolutamente necessrios para jogar e faa esses casos de
uso primeiro. Outros casos de uso podem esperar iteraes posteriores. Tal estratgia permite
que voc crie um jogo runcional o mais rpido possvel.
Para os propsitos do projeto do jogo vi nte-e-um, existiro quatro iteraes principais.

Iterao 1: jogo bsico


A Iterao I criar o jogo bsico. Ela refinar e implementar os casos de uso preliminares a segui r.
Casos de uso do jogador:
I. Receber mai s cartas.
2. Parar.
3. Estourar.
Casos de uso da banca:
I. Di stribuir cartas.
2. Receber mais erutas.
3. Parar.
4. Estourar.
No final da Iterao I, voc dever ter um jogo que jogado na linha de comando. O jogo ter
dois participantes: a banca e um jogador. A banca distribuir as cartas e pcnn itir que cada jogador receba mais cartas, at decidir parar ou estourar. Aps cada jogador jogar, o jogo terminar.

Aprendendo a combinar teoria e processo

355

Iterao 2: regras
A Iterao 2 adicionar regras ao jogo. A Iterao 2 refinar e implementar os casos de uso preliminares a seguir:
Casos de uso do jogador:
1. Consegui r um vinte-e-um .

A banca pode:
1. Efetuar o jogo (detectar ganhadores, perdedores e empates).

2. Conseguir um vinte-e-unt.
No final da Iterao 2, tudo da iterao I ainda func ionar. Alm d isso, o jogo detectar e ind icar quando um jogador ti ver um vinte-e-um, estourar, parar, ganhar, perder e empntar.

Iterao 3: aposta
A Iterao 3 acrescentar aposta bsica e em dobro ao jogo. A Iterao 3 refinar e implementar
os casos de uso preliminares a seguir:
Casos de uso do jogador:
1. Fazer apostas.

2. Dobrar.
Casos de uso da banca:
1. Efetuar o jogo (para aposta).

No final da lterao 3, tudo dns Iteraes 2 e 1 ainda funcionar. Alm di sso, o jogo permiti r
aposta bsica e em dobro.

Iterao 4: interface com o usurio


Alterao 4 dar nlg uns toques fi nais na UI de linha de comando e construi r uma UI grfica. A
lterao 4 refinar e implementar os casos de uso preli minares a seguir:
Casos de uso do jogador:
1. Decidir jogar novamente.

2. Sair.

Dia 15

NO TA

Para os propSitos d este projeto, a aposta segura e a diviso de pares fo ram


om itidas. Esses recursos so deixados com o exerccio para o leitor . Vinte-e-um u m jogo com muitas v ariantes. Freqentem ente, o seguro no permitido e a diviso complica demasiadamente o sistema. Considere essa
vari ante como um novo livro d este, dedicado ao jogo vin te-e-uml
l embre-se apenas de que voc o uviu fa la r sobre isso primeiro aqui.

Iterao 1: jogo bsico


A lio de hoje o conduzir atravs da prim eira iterao dojogo de cartas vinte-e-um . No fina l da
lio de hoje, voc ter o esque leto bs ico de um j ogo vi nte-c-um.

NO TA

Antes de ca da seo. talvez voc queira deixar o livro d e lado e l entar faz er a
anlise, projeto o u impl ementao.
Se voc fizer su as prprias experincias, certifiquese de vo ltar, ler cad a seo
e comparar seu trabalho com o material apresentad o, antes de continuar. Tente avaliar criteri osamente to das as discrepncias entre sua sO luo e a sol uo
do livro. Embora voc possa ter uma soluo superior (existem mu itas maneiras de enca rar esse jogo). Certifiq ue-se de estar correto e de que sua soluo
seg ue os princpios da poa.

Anlise do jogo vinte-e-um


A iterao de hoje refinar e implementar os casos de uso a seguir:

Casos de uso do jogador:

1. Receber mais cartas.


2. Parar.
3. Estourar.
Casos de uso da banca:
I . Distribuir ca rtas.
2. Receber ma is cartas.

3. Parar.

4. Estourar.
Aps ter um conj unto de casos de li SO refinados, voc pode criar um modelo in icial do domnio e
iniciar o projeto.

Apre nde ndo a combinar teoria e processo

357

Refinando os casos de uso


Vamos comear com o caso de uso de distri buio de cartas da banca, pois essa ao inicia o
Jogo.
Primeiro, voc precisa descrever o caso de uso em um pargrafo:
Comeando com o pri meiro jogador, a banca distri bui uma carta aberta para cada j ogador,
term inando com ela mesma. Ento, a banca repete esse processo, mas d istri bui sua prpria
carta fechada. A distribuio de cartas tennina e ento o j ogo comea, quando a banca tiver
distribudo para cada jogador, incluindo ela mesma, duas cartas.

Distribuio de cartas:
I. A banca di stribui uma carta aberta para cada jogador, inclu indo ela mesma.
2. A banca distribui uma segunda carta aberta para lodos os jogadores, menos para e la
mesma.
3. A banca di stribui uma carta fechada para ela mesma .

Condies prvias:

Novo jogo.

Condies posleriores:

Todos os j ogadores e a banca tm uma mo com duas cartas.

Os casos de uso Jogador recebe mais carIas e Jogador pra seguem natural mente. Vamos comear com o caso de uso Jogador recebe mais carlOs:
O jogador decide que no est satisfeito com sua mo. O jogador ai nda no esto urou; portanto,
ele decide receber mais cartas. Se o j ogador no estourar, ele pode optar por receber mais cartas
novamente ou parar. Se o jogador estourar, o jogo passar para o j ogador seguinte.

Jogador recebe mais cartas:


1. O jogador decide que no est satisfeito com sua mo.
2. O jogador solicita outra carta da banca.
3. O jogador pode dec idir receber mais cartas novamente ou parar, se o lotai em sua mo
for menor ou igual a 21.

Condies prvias:

Condies posteriores:

O jogador tem uma mo cuj o valor total menor ou igual a 21.


Uma nova carta acrescentada na mo do jogador.

Alternativa: o j ogador estoura


Uma nova carta faz a mo do jogador ultrapassar 21 . O jogador estoura (perde). Em seguida, comea a vez do prx imo jogadorlbanca.

Dia 15

Jogador pra um caso de uso simples:


O jogador decide que est satisfeito com sua mo e pra.

Jogador pra:
1. O jogador decide que est contente com sua mo e pra.
Condies prvias:
O jogador tem uma mo cujo valor menor ali igual a 2 1.
Condies posteriores:
A vez do jogador termina.
Neste ponto, est se tornando claro que Jogador/Banca estoura no um caso de uso, pois isso
um subproduto de outras aes. A banca e o jogador nunca executaro uma ao de estouro; en~
tretanto, os jogadores optaro por receber mais cartas ou parar.
Com os casos de uso E:Nouro removidos, apenas os casos de uso Banca recebe mais carias e
Bal1ca pra permanecem. Vamos comear com o caso de uso Banca recebe mais carIas:
A banca deve receber mais cartas se o total em sua mo for menor que 17. Se a banca no estou~
rar aps receber mai s cartas e o total em sua mo ainda for menor que 17, ela deve receber mais
cartas novamente. A banca deve parar em qualquer total maior ou igual a 17. Quandoa banca es~
toura ou pra, o jogo termina.

Banca recebe mais cartas:


I. A banca recebe mais cartas se sua mo menor que 17.
2. Nova carta acrescentada na mo da banca.
3. Se o talaI for menor que 17, a banca deve receber mais cartas novamente.

Condies prvias:
A banca tem uma mo cujo total menor que 17.
Condies posteriores:
Nova carta na mo da banca.
O jogo termina.
Alternativa: banca estoura

A nova carta faz a mo da banca ser maior que 2 1. A banca estOura.


Alternativa: banca pra
A nova carta faz a mo da banca ser maior ou igual a 17. A banca pra.

Assi m como Jogador pra, Banca pra relativamente si mples:


A banca tem na mo um total maior ou igual a 17 e pra.

A banca pra:

Aprendendo a combinar teoria e processo

359

4. A mo da banca tem um total maior ou igual a 17 e pra.


Condies prvias:
Mo da banca maior Oll igua l a 17 .
Condies posleriores:
Jogo tennina.

Modelando os casos de uso


Para a Iterao 1, os casos de LI SO so mui to simples. Os modelos de caso de uso se riam mais pesados do que interessantes; portanto, eles sero om itidos.
As interaes entre a banca e os jogadores so um pouco mais in teressantes. A Figura 15.2 mostra a seq Uncia de eventos seguida dentro do caso de uso Distribuir carias. A Figura 15.3 mostra
a seqncia de eventos seguida dentro do caso de uso Jogador recebe mais carias.
FIGURA 15.2
M ICO de Cartas

O diagrama da .eqll/lcia
do caso de liSO Di stribui

cartas.

,,

J ogador

rl-~ __R~:~f: ~~a


\-

___

.
DistribuI carta aberta
Recupera carta

-1- ____________ -O

..:.
_I
.

,
uma carta

D'

~-----------_._------ --- --_~

,:
Oistribui carta abarta ,
I

uma carta

f-

,
,I

:,
- - - - - - - - - - - - '- - - Distribui carta aberta

-u;;:';c~;a

- - -

-1],
,,
,,
,,,
,,

Dia 15

FIGURA 15.3
O diagra/J/a da seqiil!lIcia do
caso de liSO Jogador recebe
mais cartas.

*-,,

Jogador

,,,

..*-,,,

MI'; "I '11l1::!

,,
,,,

,,

Solicita uma nova ca rta


Recupera uma Ctlrta

------- -----<,J
uma ca rta

Adic iona carta na mo

,,
,,
,,
,

,,
,,
,
Modelando o dominio
Usando os casos de uso como base para o modelo de domnio, voc pode isolar sete objetos do
domn io diferentes: BlackjackGame, Oealer, Player , Card, Oeck, OeckPile e Hand (Jogo vinte-e-um, Banca, Jogador, Carta, Baral ho, Mao de cartas e Mo). A Figura 15.4 mostra o diagrama do modelo de domnio resultante.

Projeto do jogo vinte-e-um


Aplicando projeto orientado a objetos na anlise anteri or, voc chegar a um modelo das classes
principa is do projeto, suas responsabi Iidades e uma definio de como elas vo interag ir e obter
suas in formae s. Voc pode ento pegar o projeto e trabalhar na implementao.

Cartes CRC

o modelo de domnio fornece um bom ponto de partida para urna li sta inicial de objetos. Com
essa lista de objetos, voc pode usar cartes CRC para mostrar as vrias responsabilidades e colaboraes dos objetos.
Antes de conti nuar, pode ser um bom exercicio para voc, tent ar gerar uma lista de cartes CAC por conta prpria.

36 ,

Apre nde ndo a combinar teoria e processo

FIGURA 15 .4

Vinte-e-um

O /1/odelo de
domnjo do jogo

7' ~

villle-e-/l/1/.

1... 7
Jogador

,
,

MOo

Banca

Mao de cartas

,<

0 ... 19

Carta

52

Baralho

As fi guras 15.5 a 15. 11 ilustram a possvel sada de uma sesso de ca rto CRC.
FIGURA 15 .5

Vinte-e-um

O C(m(io CRC do

jogo

l,jllle-e-lIl11.

~
~decartas

Oiiii

~
~ ~ ~ ~decertBS
I

~.
Banca

Dia 15

FIGURA 15.6

O caru10 CRC
Baralho.

FIGURA

15.7

O camio CRC Corra.

Banca

Carta

Aprendendo a combinar teoria e processo

FIGURA 15.8

O caru10 CRC

Jogador

Jogador.

FIGURA 15.9

O cllrll10 CRC
Banca.

Banca herda de jogador

363

Dia 15

FIGURA 15.10
O caru10 CRC Mt1o.

FIGURA 15.11
O cllrll10 Mao de
cOrlas.

Mo

Mao de cartas

A UI de linha de comando

o Captulo 13, ';00 e programao de interface com o usurio", apresentou o padro de projeto
MVC. A UI do jogo vinte-c-um utili zar o padro de projeto MVC. Como resu ltado dessa deciso de projeto, voc precisa adici onar um mecanismo observador no Jogador, assim como um
objeto Console para apresentar os jogadores e recuperar entrada do usurio.
Como existe apenas um Conso l e, o objeto Consol e um candidato para o pad ro Singleton.

o modelo do jogo vinte-e-um


Ao todo, nove classes e d uas interfa ces constituem o modelo de classe Blackj ack (vinte-e-um)
completo. A Figura 15. 12 ilustra o modelo.

Aprendendo a combinar teoria e processo

365

FIGURA 15.12

O modelo de
classe

alackjack.

MO"'"

'MI ):booI"
_PiOre< 1";1'1 .,.,,, )

newG.omel )

A prxima seo detalhar a implementao desse modelo.

A implementao
As sees a seguir fornecem a implementao das partes principais do modelo ilustrado na Figura 15. 12.

NeTA

Todo o cdigo-fonte est disponvel para download na pgina da Web deste livro. Visite o endere o www.samspubl i shi ng. com e na guia BookSt ore digite o numero ISBN 0672321092; em seguida, na pgina do livro Sam s Teach Yourself
Object Oriented Programm ing in 21 Days, d um clique no link Downloads e
depois em Source Code.

A classe Card
A classe Card (Carta) implementada de fo nna muito parecida cam a classe Card apresentada
no Captulo 12, Pad res avanados de projeto" . A classe Rank (Nmero) mudou um pouco. A
Listagem 15.1 apresenta a nova implementao da classe Rank (Nmero).

Dia 15

LISTAGEM 15.1 Rank.java


i mpo rt java.utll.Col l ections;
impo rt java.utll.list;
impo rt java.ut il.Arrays ;
public final cl ass Rank (
publ i c
public
public
public
pu bl ic
publi c
pub 1i c
pu bli c
publ ic
publ ic
publ ic
pub l ic
publ ic

static
static
sta ti c
static
static
static
static
static
static
static
static
static
stat i c

final
fina l
fi na l
final
fi na l
fi na1
fi na l
fi nal
fi na1
final
fi nal
fina l
final

Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank

TWO

THREE
FOUR
FIVE
SI X
SEVEN
EIGHT
NINE
TEN

JACK
QUEEN
KING
ACE

oew
new
new
new
new
new
new
new
new
new
new
new
new

Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(

2, "2" ) ;
3, " 3" ) ;

);
);
);
7 , "7" ) ;
8, "8" ) ;
4, "4"
5, " 5"
6, "6"

9, "9" );
10, " 10" ) ;
10, "J" ) ;

lO, "Q" ) ;
l O, " K" );
11,

"A"

);

private stati c fina l Rank [] VAl UES =


I TWO. THREE , FOUR, FI VE , SIX, SEVEN,
EI GHT. NINE, TEN. JACK, QUE EN, KING, AC E I ;

II fornece uma lista nao modif ic ve l para fa zer lao


publ ic sta tic final llst RANKS ,.
Collections .unmodif iable Li st( Arrays . asList( VAl UES ) ) ;
rank;
private fi nal int
private fi nal St ring di splay ;
private Rank ( lnt rank,String display ) {
this.rank a rank;
this.display = di spl ay;
)

public i nt getRank() {
return rank;

I
publi C Stri ng toSt ring() {
return di spl ay ;
I
)

Aprendendo a combinar teoria e processo

367

Voc notar que as constantes da classe Rank (Nmero) foram atualiL1das para refletiras valores numricos do jogo vinte-e-um. A classe tambm foi alterada para comer um objeto pblico l ist no
modificve l, em vez do array modificve l apresentado no Capitulo 12. Usar um objeto l is t
no mod ificvel impede mod ificaes inadvert idas da enumerao li sL

As classes Deck e Deckpil e


A classe Deck (Baralho) mudou consideravel mente em relao ao apresentado no Capitulo 12. A
Listagem 15.2 apresenta a nova im plementao.
LISTAGEM 15.2 Deck.java
import java.uti l .lterator:
import ja va.util . Ra ndom:
pub li c class Deck (
private Card [) deck:
private int index:
pub l ic DedO {
buildCardsO:
}

public void addToStack( Deckpile stack) {


stack.addCards( deck ):
}

private voi d bui ldCardS() (


deck new Card [52):
Iterator suits

Su it. SUITS.iterator() :

in t counter O:
while( s uit s .hasNext() ) (
Sui t suit (Suit) suits .next();
Iterator ranks Rank.RANKS .itera tor() ;
whi l e( rank s . ha sNext() ) (
Rank rank (Ra nk)ranks . next():
deck[cou nter ] new Ca rd( su'it, rank ) :
counter++:
}
}
}
}

Dia 15

A classe Deck (Baralho) si mplesmente sabe como construir seus objelos Card (Cartas) e depois
inseri r-se em Deckpi l e (Mao de cartas). A Listagem 15.3 apresenta Deckpi 1e (Mao de cartas).
LISTAG EM 15.3 Deckp il e . java

impo rt java.ut i l.Arraylist ;


import java.ut i l . l t erator;
import java . util.Random ;
publiC class Deckpile (
private Arraylis t stack - new Arraylist () ;
private int index ;
private Random rand = new Random() ;
public void addCards{ Card [] cards ) {
for( lnt i O; i < cards.lengt h; i ++ ) {
stack.add{ cards [i] ) i
}
}

pub l ic void shuf f le()


reset();
randomizeO;
randomizeO;
randomi ze O ;
randomizeO;
}

pub l ic Card dealUp() (


Card ca r d a deal() ;
if( card la nul1 ) {
card.se tFaceUp{ true
}
re turn card ;
}

l;

public Card deal0ownO (


Card card a deal();
i f( card ! - null )(
card . setFaceUp( false );
}
return cardi
}
publi C void resetO {
index - O;

Aprendendo a combinar teoria e processo

LISTAGEM 15.3

369

Oeckpile.java (continuao)

lterator i .. stack.iterator();
while( 1.hasNext() ) I
Ca rd card - (Card) i.next() ;
card.setFaceUp(false);
J
J

private Card deal () {


if( index ,- stack.size() ) I
Card card - (Card) stack.get( index , ;
i ndex++;
return card ;
J
return null;
J
private void randomize() {
int num_cards .. stack.size();
for( int 1 - O; i < num_cards; i ++ ) (
int index ~ rand.nextlnt( num_cards ) ;
Card card_i .. (Card) stack.get( i };
Ca rd card_lndex .. (Card) stack.get( index );
stack.set( I, card_index }i
stack.set( index, card_i };

J
J
J

A classe Deckpi le (Mao de cartas) sabe como em baralhar seus objetos Card (Cartas), di stribu-los e acrescelllar objetos Card (Cartas) para si mesmo. Ao contrrio da classe Deck (Baralho)
origina l, Deckpile (Mao de carias) mantm uma referncia para todos os objetos Card (Carta)
que retorna. Desse modo, e le pode recuperar faci lmente todos os objetos Card (Carta) c se reconfigurar. Embora isso no modele completamente o mundo real, simplifica muito o gerenciamento de cartas.
Entender o raciocnio existente por trs dessas alteraes importante. Oec k (Baralho) e Deckpi1e (Mao de cartas) implementam apenas os comportamentos de que o j ogo precisa. Essas classes no fornecem funcionalidade adicional ' apenas para o caso de precisarmos algum dia'.
impossvel prever o futuro e voc no tem quaisq uer requi sitos de funciona lidade extra; portanto, voc no deve acrescent-Ia at saber que precisa dela.
Se voc tentar implementar toda possi bi lidade de ' e se' ou realizar uma abslrao prematura,
nunca acabar de implementar suas classes. Se voc conseguir temlin- Ias, so boas as chances

Dia 15

de que a funcionalidade ou abstrao acrescentada no esteja correta. Alm disso, voc s ter
mai s trabalho a fa7.er, pois preci sar manter uma funcionalidade que ningum mais precisa ou
usa.
Tentar programar toda hiptese 'e se ' um problema comum, encontrado por programadores
in iciantes em 00. Voc deve evi tara tentao de adicionar mais funcional idade do que a absolutamente exigida para seus objetos! Entretanto, voc deve isolar as partes do s istema que sabe que
mudaro.

As classes Player e HumanPlayer


A classe PI aye r (Jogador) contm um objeto Hand (Mo). A Listagem 15.4 aprese nta a classe
Hand.
LISTAGEM

15.4 Hand.j ava

import java.util . ArrayList:


i mport java.ut i l.lterator:
publi c cla ss Hand {
private ArrayList ca rtas new ArrayList();
private sta t ic fina l i nt BLACKJACK z 21:
publiC void addCard( Ca rd card )1
cards.add( card ):
J
publi c boolean bust() {
i f( total() > BlACKJACK ) {
return true:
J
return fa lse :
J
public vo 1d re se t() {
cards . clear() ;
J
publi c void turnOver(){
lterator i z cards. ite rator();
while( i.hasNext() ) {
Card card (Card)i.next{) :
card. se tFaceUp ( true } :

J
J

Apre nde ndo a combinar teoria e processo

LISTAGEM 15 .4

37 1

Hand.java (continuao)

publiC String toString() {


Iterator i cards.iterator()j
String string - ."j
whi l e( i.hasNext() ) {
Card card (Card) i .next()j
str ing string + " " + card.toStringOj
}

return stringj
}

publi C int total () {


int total Oj
Iterato r i cards .i ter ator() j
wh i le( i .hasNext() ) {
Card card - (Card) i.next{)j
total +- ca rd . getRank() .getRank() j
}
return t ot a I j
}
}

A classe Hand (Mo) sabe como adicionar objetos Card (Can as) em si mesma, reconfigurar-se,
virar suas canas, calcular seu total e representar-se como uma String. Voc pode notar que a
classe Hand (Mo) conta ases apenas como II. A prxima iterao acrescentar supone para contagem de ases como I ou I I .
As listagens 15.5 e 15.6 apresentam as classes PI ayer (Jogador) c HumanPI ayer (Jogador Humano), respectivamente.
LISTAGEM 15 .5

Playe r .java

impor t java.uti l . ArrayList j


import java.util.rterator j
pub l ic abst ract class Pl ayer {
private Hand hand j
private String name j
private ArrayList l isteners new ArrayList()j
public Pl ayer( St ring name , Hand hand ) {
this . name name j
this . hand hand j
}

Dia 15

LISTAGEM 15.5 P1ayer.java (continuao)


publi C vo id addCard{ Ca rd card ) I
hand. addCa rd( card ) ;
notifyLis teners();
}

public void play( Dealer dealer ) {


II como antes, joga at que o jogador estoure ou pare
while( !isBusted() &&hit() ) (
dealer.hlt( this );
}

II mas, agora, diz banca que o jogador te rminou , caso contrrio, nada
II acontecer qua ndo o jogador retornar
stopPlay( dealer );
}

publi c vo i d re set() {
hand.rese tO;
}

publi c boolean isBusted() (


return hand.bu st();
}

publiC void addL is tener{ PlayerListener 1 ) (


lis teners.add( 1 );
}

publ iC String toString() {


return ( name + ":" + hand.toString() };
}

protected Hand getHand() {


return hand;
}

protected void notify Lis teners() {


Iterator i l i steners . iterator();
while( i .hasNext() ) {
PlayerListener pl (PlayerListener)i.next() ;
pl.handChanged( th is ) ;
}
}

lU
A chamada de pas sT urn DEVE ser dentro de um mtodo proteg i do. Oealer

Apre nde ndo a combinar teoria e processo

LISTAGEM 15.5

373

P1ayer.java (continuao)

* precisa sObrepor esse compor tamento! Caso contrrio, O l ao ser infinito.

"/
protected void stopPlay( Dea l er dea l er ) {
dea l er.passTurn();
J

protected abstract bool ean hit();


J

LISTAGEM 15 .6

HumanPlaye r .java

pub l ic class HumanPlayer extends Player {


private
private
private
private

fi na 1
f i na 1
final
final

static
static
static
static

String
String
String
String

, "H" ;
STAND , "S" ;
MSG
"[H] it or [5] t ay' ;
DEFAULT , "inva l id":

HIT

pub l ic HumanPlayer( String name, Hand hand ) I


supere name , hand );
J

protected boolean hi t() {


while( true ) I
Console.lNSTANCE.printMessage( MSG );
String response Console.INSTANCE.readI nput( DE FAULT ):
if( response.equalslgnoreCase( HIT ) ) {
return true;
I else if{ response.equalsIgnoreCase( STANO ) ) I
return f alse :
J

II se chegarmos aqui , faz um lao at obtermos entrada significat i va


J
J
J

A classe abstrata Player(Jogador) define todos os comportamentos e atributos comuns a objetos


Player (Jogador) e Dealer (Banca). Esses comportamentos incl uem mani pular a classe Hand
(Mo), controlar objetos Pl ayerli stener e jogar uma rodada.
Pl ayer de fi ne um mtodo abstrato: public bool ean hit(). Durante o jogo, a classe base Pl ayer
(Jogador) fa r uma chamada para esse mtodo, para detenni nar se deve continuar a receber carIas ou parar. Subclasses podem implementar esse mtodo para fornecer seus prprios comporta-

Dia 15

mentos especfi cos. Por exemplo, HumanPlaye r (Jogador Humano) pergunta ao usurio se vai
conti nuar recebendo cartas ou no ou se va i parar. Quando o objeto Pl aye r (Jogador) acaba de
jogar, ele informa o objeto Oealer (Banca), chamando o mtodo pass TurnO de Oeal er (Banca).
Quando o objeto Pl ayer (Jogador) chama esse mtodo, Oea ler ( Banca) diz a next Player (Jogador) para que jogue.

Dea 1er - Banca


Deal er (Banca) uma interface que especi fica os mtodos extras que um objeto Dea 1er (Banca)
vai expor. A Li stagem 15.7 apresenta a interface Dea ler (Banca).
LISTAGEM 15.7 Deale r .java
pub l ic interface Dealer (
publ ic vo i d hlt( Player jog ador )i
publ iC void passTurn( );

I
A Li stagem 15.8 apresenta Bl ackjackOealer.
LISTAGEM 15.8 BlackjackOealer.java
import java . utl1.Arrayl is ti
import java. ut i l . l terator;
public class Bl ackjackDealer extends Player i mplemen t s Dealer (
private Deckpile ca rdsi
private Arraylist players new Arraylist()i
private int player_ l ndex i
publi C Bl ackjackDea l er( Stri ng name , Ha nd hand , Deckpl1e cards ) (
super( name, hand )i
this.cards card s i

I
pub l ic void passTurn() (
i f( player index != players.size() ) (
Player pl aye r (Player) players.get( playe r_index )i
player_index++i
player.play( th is ) i
) el se {

Aprendendo a combinar teoria e processo

375

LISTAGEM 15.8 8lackjackDealer.ja va (continuao)


this.play( this li

I
I
publiC void addPlayer( Player player l I
players.add( player )i

I
public vold hlt( Player player l {
player.addCard( cards . dealUp() )i

II sobrepe para que a banca mostre suas cartas antes que comece a jogar
public void play( Dealer dealer ) I
exposeCardsO j
super.play( dealer )i

I
pub l iC void newGame() I
II dis tribui as cartas e diz ao primeiro jogador para comea r

d"'(};
passTurnO i

I
publ i c void deal () I
cards.shuff le();
II reconfigura cada jogador e distribui uma carta aberta para cada um e
para si mesma
Pl ayer [] player new Player [players.size()] i
players.toA rray( player li
for( int i Oi i < player. length i i ++ ) {
player [1].resetO i
player [1] .addCard( cards.dealUpO l i

I
this.addCard( ca rd s.dealUp() ) i

II dis tribui mais uma ca rta aberta para cada jogador e uma fechada para si
mesma
for( int i ., Oi i < pl ayer . length i i ++ ) {
player (i]. addCard( cards.dealUp() )i

I
this . addCard( cards.dealDown(l li

Dia 15

LISTAGEM

15.8 8lackjackDea l er.java (continuao)

}
protected vo1d stopPl ay ( Oealer dea ler ) {
II no faz nada aqui , na banca, s i mplesmente deixa o jogo parar
II se i sso no fo sse sobreposto , chamaria passTurn() e
II faria um lao infinito
}

protected boo l ean hit() {


if( getHand().total()
return true;
}
return false ;
}

<-

16 ) {

private vo1d exposeCards ( ) {


getHand() . tu r nOver() ;
notifylisteners() ;
}
}

BlackjackOea ler ( Banca21 ) herda de PI ayer (Jogador) porque um objeto Oea ler ( Banca) tam~
bm um objeto Pl ayer (Jogador). Alm dos comportamentos forn ecidos por um objeto PI ayer
(Jogador), a banca tambm contm o objeto PI ayer (Jogador), que di stribui canas para esses objetos PI ayer (Jogador) e diz a cada um para que j ogue, quando chega s ua vez. Quando um objeto
PI ayer (Jogador) chama o mtodo passTu rn () de Oealer (Banca), ele sabe deixar o prx imo objeto PI ayer (Jogador) j ogar.
A Figura 15. 13 il ustra a interao entre a banca e os jogadores.
8lackjack Dea ler (Banca2 1) sobrepe seu mtodo stopPI ay () para q ue ele term ine de jogar. A
banca tambm implementa o mtodo hit ( ) para que e le retorne t rue quando a mo fo r menor
que 17 e false quando a mi'lo for igual ou maior que 17.

BlackjackGame (Jogo 211


As listagens 15.9 e 15. 10 apresentam as classes Bl ack j ack e Conso l e, respectivamente.
LISTAGEM

15.9 81ac kj ack . java

publ; c cl ass Blackjack {


publ ic s tat; c vo1d ma in ( St r ing [J args )
Oec kp ile cards

new Oeckpi le() ;

Aprendendo a combinar teoria e processo

377

LISTAGEM 15.9 8la ckj ack.java (continuao)


for{ int i O; i < 4; i ++ )
ca rds .shuffle () ;
Oeck deck new Deck{ ) ;
deck.addToStack ( cards );
cards.shuffle () ;

Hand dealer hand new Hand();


Blac kjackDealer dea ler new BlackjackDealer( "Dealer", dea le r_hand,
cards );
Hand human_hand new Hand();
Pl ayer pl ayer new HumanPlayer( "Human", human hand );
dealer.addlistener( Conso le.INSTANCE ) ;
player.addlistener( Console. INSTANCE ) i
dealer . addPlayer( player );
dealer.newGame( );
J
J

FIGURA 15.13
II illferalio elllre jogadores
e a bal/ca.

Banca v inte-eum

O
,

plaV Idealer)

Jogador

>

n.

,,
,

O,

,,

Jogador

/
hitO

Enquanto
estourado
e pedindo
maiscartu
hil()

hit (plaver)

;
addCard (card)

,,
,,

passTurn( )

'r'
r'l-

stopPlav()

,,
,,
,,

,,
plav (dealer)

,,

Dia 15

LISTAGEM 15.10

Console.java

i mpo rt java.io . BufferedReader;


i mpo rt java.io . InputStreamReader;
impo rt java.io . IOException;
publi C cla ss Console implements Playerlistener (

II console si ngl eton


public final static Console INSTANCE

new Con sole() ;

private BufferedReader in
new BufferedReader( new InputStreamReader( System.in ) };
K

public void printMess age( String message ) {


System .out.print l n{ message };

I
publiC String readlnput( String default_input ) (
String response ;
try (
return in.read li ne() ;
) ca tch (IOException ioe) {
return default_input;

I
I
public void handChanged( Player player ) I
printMessage( player.toString() };

II pri vate para impedir instancia o


private Console() {I

I
A classe Blackjack constri objetos Dea ler (Banca), Hand (Mo), Deckpile (Mao de cartas),

Deck (Baralho) e conecta todos eles. Uma vez conectados, ela comea o jogo dizendo ao objeto
Oea1er (Banca) para que inicie um novo jogo.
Consol e um si ngleton que d acesso linha de comando. Ele tambm recebe dados dos objetos
Player (Jogador) e, em seguida, os imprime na tela, sempre que eles so atualizados.

Uma armadilha procedural


Se voc vem de uma base procedural, poderia ser tentador implementar o mtodo newGame () de
BlackjackDeal er como ilustrado na Listagem 15.11.

Aprendendo a combinar teoria e processo

LISTAGEM 15.11

379

Uma impl ementao procedural de BlackjackOea l er

publ1c void newGameO {


cards . shuffle();

II
II

reconfi gura cada jogador e distribui uma carta aberta para cada um e para
si mesma
Player [) player new Player [players . size():
players.toArray( player ) :
for( i nt 1 O: i < player.length: i ++ ) {
player [i).reset();
player [i].addCard( cards.deaIUp() ) ;

I
this.addCard( cards .dealUp() ):

II

distribui mais uma carta aberta para cada jogador e uma fechada para si mesma
for( int i O; 1 < player.length; i ++ ) {
player [i ].addCard( cards.dealUp() l;

I
this . addCard( cards.dealOown() ) :

II

cada jogado r joga e depo i s a banca


for( int i O; i < player.length : i ++ )
player [l).play(this):

I
exposeCa rd s ();
this.play( this ) ;

I
Essa implementao e limi na a necess idade do mtodo passTurn () ; entretanto, essa uma estratgia procedural para o lao do j ogo. Em vez dos objctos PI ayer (Jogador) comuni carem ao objeto Dealer (Banca) que terminaram de jogar, Dealer (Banca) simplesmente faz um lao
seqUencia l atravs dos PI ayers (Jogadores).
A Figura 15. 14 ilustra a interao entre Oea 1er ( Banca) e seus objetos PI ayer (Jogador).

Voc notar que as interacs da Figura 15. 13 so muito mais dinmicas do que as interacs
que ocorrem na Figura 15. 14. A Figura 15.13 verdadeiramente um sistema de objetos interagindo. Na Figura 15. 14, Dea l er ( Banca) simplesmente espera que o objeto PI ayer (Jogador) retome e, ento, chama seq Uencial mente o prximo objeto PI ayer (Jogador). No h nenhuma
interao alm de Oea l er ( Banca) dizer estaticamente para que cada objeto PI ayer (Jogador)jogue em sua vez. Embora essa estratgia func ione, ela no muito nexvel e certamente no to
orientada a obj etos quanto a estratgia apresentada na Figura 15. 13.

380

Dia 15

FIGURA 15 .14
A illlera(io procedI/mI

elflre Players Oogadores)


e Dealer (bal/ca).

Banca

Jogador
play (deaferl

Jogador
loap at
estourar

ou parar

---.J hit ()
hit (playe r)
addCard (card)
play (deaferl

hit ()

hit (playar)
addCard (card)

play (deaferl

,,
,,

,
,,
,,

Testando
Confonne mostrou o Captulo 14, "Construindo software confi vel atravs de testes", os testes
devem ser um processo di nmico. Um conjunto completo de testes est disponvel,j unto com o
cd igo-fonte, para download. Esses testes consistem em um conj unto de testes de unidade e objetos fa lsificados que testam com pletamente o jogo vinte-c-um. O estudo dos testes ser deixado
COmO um exercc io importante para o leitor.

Resumo
Hoje, voc ana lisou, projetou e implementou um jogo vinteeum bsico. Usando uma estratgia
iterativa, voc obteve os resultados que puderam ser vistos rapidamente. No decorrer da semana,
voc continuar a acrescentar funcionalidades nesse jogo vinte-e-um.
Voc tambm aprendeu algumas lies novas hoje. Ao programar, voc precisa evitar cair nas
annadi lhas procedura is, mesmo que uma estratgia procedural possa parecer a soluo nat ural.
Voc tambm deve aprender a evi tar a tentao de acrescentar mais detalhes em uma defin io
de classe do que precisa.

Aprendendo a combinar teoria e processo

381

Perguntas e respostas
P Se os testes so to importantes, por que voc os pulou ?
R No pu lamos os testes. Todos os cd igos-fonte que podem ser carregados por download
esto repletos de casos de teste.
O texto pu lou a discusso dos testes por restries de espao e eficcia. No achamos que
voc teria gostado, se fosse obrigado a ler incontveis pginas de cdigo de teste. O estudo e o entendimento do cd igo de teste (e, na verdade, todo o cdigo) so deixados como
exercicio para o lei tor.
P Parece huver muito mais cd igo do que o publicado no captulo -o que aconteceu?
R H muito mais cd igo. Simpl esmente no possve l abordar todo o cdigo efi cientemente dentro do texto. Cons idere o tcxto como o 'fi lme dos destaqucs' do cdigo. Voc
precisar dedicar uma quantidade considervel de estudo pessoal para entender o cdigo
comp letamente.
O objetivo destes capt ulos finais apresentar um projeto global, do qual o cdigo apenas
um componente. A anlise e o projeto so igualmente importantes. Voc precisar dedicar
um tempo extra dentro dessa estrutura, estudando o cdigo, se quiser entend-lo totalmente.

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respostas no Apndice A, "Respostas",

Teste
J. Liste dois dos padres de projeto que voc viu hoje. Onde os padres foram usados?
2. Encontre um exemplo de polimorfismo no cdigo-fon te.
3. Encontre um exemplo de herana no cd igo-fonte.
4. Como a classe Oeck (Bara lho) encapsula suas cartas?
5. Como 61 ackjackOea l er (Banca 21) e HumanP1 ayer (J ogador Humano) aluam de forma
polimrfica?

Exerccios
I. Faa o down load do cdigo-fonte da iterao de hoje. Aps tero cd igo, compile-o, faa-o
funcionar executando o jogo vinte-c-um e, depois, tente entender como ele funciona. Ter
um entendimento lotai do cdigo exigir algum tempo e pacincia.
2. A lio de hoje foi bastante longa. No h outros exerccios. Examine o cdigo-fome e
reveja a lio.

SEMANA

DIA
Iterao 2 do jogo vinte-e-um:
adicionando regras
Ontem, voc rea lizou a anlise e projeto iniciais de um jogo vi lllceuTn . Hoje, voc conti nuar
esse processo e vai adicionar mais regras no jogo vinte-c- um.
Hoje voc aprender como:

Modelar os estados do jogo vi nte-c-um

Usar estados para rem over lgica cond icional

Regras do jogo vinte-e-um


Ontem, voc construi LI um jogo vinte-c-um simples. O jogo que voc projetou e construi u di stribua canas e pennit ia a um jogador jogar at parar ou estourar. Umjogo vinte-c-um rea l far um
pouco mais. Em um jogo vi nte-c-um real, os ases valem I ou 11 pontos. Osjogadores podem obter um vi nte-e-um, estourar, empatar, perder ou ganhar. A banca nem mesmo jogar se todos os
jogadores estourarem ou se receber uma mo que d vinte-e-um.
Hoje, voc vai adicionar a lgica necessria para suportar esses e outros recursos adicionai s no
jogo. Como sem pre, voc comear anali sando os casos de uso.

Dia 16

Anlise das regras


Para entender com pletamente todas as regras do j ogo vinte-eum, voc precisar rever cada um
dos casos de uso de ontem e acrescentar todos os novos casos de uso exigidos. Uma vez identi fi
cados os casos de uso, voc precisar atualizar o modelo de domn io.

Anlise de caso de uso das regras do jogo vinte-e-um


A adio de regras afeta muitos dos casos de uso identificados ontem. Existe tambm um novo
caso de uso: Banca efelllajogo. Vamos comear com o caso de uso Distribuir cartas, que voc
descobriu ontem:
Comeando com o prime iro jogador, a banca distribu i uma carta aberta para cada jogador, terminando consigo mesma. A banca repete ento esse processo, mas di stribui sua prpria carta fechada. A distri bu io de cartas termina e ento o jogo comea, quando a banca tiver distribudo para
cada j ogador, inc luindo ela mesma, duas cartas.
o

Distribuir cartas
I. A banca distribu i uma carla aberta para cada j ogador, incluindo ela mesma.
2. A banca d istribui uma segunda carta aberta para todos os jogadores, menos para ela.
3. A banca distribui uma carta fechada para e la mesma.

Condies prvias
o

Novo j ogo.

Condies posteriores

Todos os jogadores e a banca tm uma mo com duas cartas.

A vez do primei ro j ogador que no tenha vinte-e-um (d uas cartas totalizando 2 1), comea.

O j ogo cont inua para cada j ogador que no tenha vi nte-c-um.

Alternativa: A banca tem vi ntee-ulll


Se a banca tiver um 2 1 natural, o jogo passar para o cumpri mento. Os jogadores no tero s ua vez.

O caso de uso Distribuir cartas acrescenta agora vrias novas condies posteriores, assim
como uma alternati va. O importante a notar que, se a banca tiver vinte-e- um , o jogo term inar
automaticamente. Do mesmo modo, qualquer jogador com vinte-e-um no joga.
Em seguida, reveja Jogador recebe mais cartas:
O jogador decide q ue no est satisfeito com sua mo. O j ogador ainda no estourou, de modo
que decide receber mais cartas. Se o jogador no estourar, ele pode optar por receber mais cartas
novamente ou parar. Se o jogador estourar, o jogo passar para o j ogador segui nte.

Iterao 2 do j ogo v inte-e-um: adicionando regras

385

Jogador recebe mais cartas


I. O jogador decide que no est satisfeito com sua mo.
2. O jogador soli cita outra carta da banca.
3. O jogador pode dec idir receber mais cartas novamente Oll parar, se o total em sua mo
for menor Oll igual a 2l.

Condies prvias
O jogador tem lima mo cujo valor tOlal menor ou igual a 2 J.
o
O jogador no tem vinte-c-um.
o
A banca no tem vinte-e-um.
o
Condies posteriores
o
Uma nova carta ac rescentada na mo do jogador.
o
Alternat iva: O jogador estoura

A nova carta faz a mo do jogador ser maior que 21. O jogador estoura (perde); a vez do
prxi mo jogador/banca comea.
Alternativa: mo do jogador > 21, mas o jogador tem um s
A nova carta faz a mo do jogador ser maior que 21. O jogador tem um s. O valor do s
muda de II para I, fazendo a mo do jogador ser menor ou igual a 21. O jogador pode decidir receber cartas novamente ou parar.

Digno de nOla o fato de que um jogador s pode jogar se ele ou a banca no tiver vinte-c-um.
Esse caso de uso tambm introduz o fato de que um s pode ter um valor igual a I ou I I, dependendo do que toma a mo mel hor.

Jogador pra tambm recebe mais algumas cond ics prvias.


O jogador dec ide que est sat isfeito com sua mo e pra.
o

Jogador pra
1. O jogador decide que est contente com sua mo e pra.

Condies prvias
o
O jogador tem uma mo cujo valor menor ou igual a 21.
o
O jogador no tem vinte-e-um.
o
A banca no tem vinte-e-um.
Condies posteriores
o
A vez do jogador tcnnina.

Assim como em Jogador recebe mais carias, voc precisar alUalizar Banca recebe mais carias:
A banca deve receber mais cartas se o total de sua mo for < 17. Se a banca no estourar,
aps receber mais cartas, e o lotai de sua mo ainda fo r < 17, ela dever receber mais car-

Dia 16

tas novamente. A banca deve parar em qualquer total >= 17. Quando a banca estourar ou
parar, o jogo termina.
Banca recebe mais cartas
I. A banca recebe mais cartas se sua mo for menor que 17.

2. Nova carta acrescentada na mo da banca.


3. O total menor que 17, a banca deve receber mais cartas novamente.
Condies prvias
A banca tem uma mo cujo total menor que 17.
Deve ser um jogador no estado de parada.
Condies posteri ores
Nova carta na mo da banca.
Jogo termina.
Alternati va: Banca esloura

A nova carta faz a mo da banca ser maior que 21; a banca estoura.
Alternativa: Banca pra
A nova carta faz a mo da banca ser maior ou igual a 17; a banca pra.

Alternativa: Banca lem s, pra


A nova carta faz a mo da banca ser maior ou igua l a 2 1, mas incl ui um s. O valor do s
muda de I I para I, fazendo o lotai da banca ser 17; a banca pra.

Alternativa: Banca tem s, recebe mais cartas


A nova carta faz a mo da banca ser maior ou igual a 21, mas inclui um s. O valordos muda
de I I para I, fazendo o talai da banca ser menor que 17; a banca recebe mais cartas.

Esse caso de li SO acrescenta vrias condies prvias e variantes . A condio prvia, "Deve ser
um jogador no estado de parada", signifi ca que a banca s receber mais cartas se houver um jogador para bater. Se nen hum jogador esti ver parado, isso signifi ca que todos os jogadores estoufaram ou tm vinte-C-um . Alm disso, as novas alternati vas levam em conta o t to de que um s
pode ser contado como J ou como I I.
Do mesmo modo, a banca parar automat"icamente, se no houver nenh um oUlrojogador parado.
A banca tem uma mo cujo total >-= 17 e pra.

Banca pra
I. A mo da banca d um talai maior ou igual a 17 e pra.

Cond ies prvias


Mo da banca maior ou igual a 17.
Deve ser um jogador no estado de parada.

Iterao 2 do j og o v inte-e-um: adicionando reg ras

Cond ies posteriores

387

Jogo tenn ina.

Alternativa: nenhum j ogador parado


Se no houver nenhum jogador parado, a banca parar automaticamente, independente da
contagem da mo.

Quandoojogo tiver terminado, a banca precisar descobrir quem ganhou, quem perdeu e os em pates. O caso de uso Banca efelllajogo trata desse uso:
Aps todo o j ogo ter terminado, a banca verifica cada mo e determi na, para cada jogador, se e le
ganhou ou perdeu, ou se o j ogo deu empate.

Banca efet ua jogo


I. A banca veri fi ca a mo do primei ro jogador e a compara com a s ua prpri a.
2. A mo do jogador maior que a da banca, mas no estourou; o j ogador ganha.
3. A banca repete essa comparao para todos os jogadores.

Cond ies prvias

Cada jogador passou por sua vez.

A banca passou por sua vez.

Condies posteriores

Al ternativa: Jogador perde

A banca verifica a mo do jogador e a compara com a sua prpria. A milo do jogador


menor que a da banca . O j ogador perde.

Alternativa: Empate

Resultados fi nais do j ogador detenn inado.

A banca verifica a mo do j ogador e a compara com a sua prpria. A mo do jogador


igua l da banca. O jogo deu em pate.

Alternat iva: Banca estoura

Se a banca estourou, cada j ogador que esti ver parado e com vinte-e-um, ganha. Todos
os outros perdem.

Modelando os casos de uso


A maior parte das alteraes nos casos de uso simples. Entretanto, pode ser ti l desenhar a seqncia de eventos para Banca elewajogo. A Figura 16 .1 ilustra a seqncia de eventos encontrada no caso de uso Banca ele/lia jogo.

388

Dia 16

FIGURA 16 .1

O diagrama da seqiil!l1cia do
caso de liSO Banca cfctua jogo.

..*',

*',

*',

Jogado,

Jogador

Solic:ite mio

~---- - --- --mio- Compara mios

,,
,,
,,,
,,
,

'O,,
,

Informa togado. do resultado I

,,
,,
,
,,
I

n.

Atualizando

Compa re mAas

Informa j ogador do resultado

mo

,,
,,

modelo de dominio do jogo vinte-e-um

Da perspectiva do domnio, esses casos de uso novos e atualizados no o aheram.

Projeto das regras


Neste ponto, pode ser extremamente tentador ir diretamente para a implementao. Superfi cial mente, parece q ue voc pode implementar as regras atravs de condicionais. Na verdade, voc
pode impl ement- Ias atravs de cond icionais. A Li stagem 16. 1 apresenta como poderi a ser uma
dessas condiciona is.
LISTAGEM 16.1 Reg r as condicionais den t r o de Bl ac kjackOealer ( Banca 21)

prot ec t ed voi d stop Pl ay ( Deal er deale r ) {

1/ o j ogo termi nou , i dent i f i ca os ganha do res e os pe rdedores


i f ( isBusted () ) {
Iterator i .. playe rs . i t era to r () ;
whil e( 1. hasNext () ) {
Player playe r .. (P l ayer) i . nex tO ;
1f( !player. i sBus ted() ) {
Console. INSTANCE . prin tMessage( player. toSt r ing() .. " WINN ER!!" ) ;

I
I
} else {

Iterao 2 do j ogo v inte-e-u m : adicionando regras

389

LISTAGEM 16. 1 Regras condicionai s dentro de BlackjackDealer (Banca 2I) (cont . )

;t( hasBlackjackO ) (

lterator; players.iterator()i
while( i.hasNext() ) (
Player pl ayer = (Player) i.next() i
i f( player.hasBlackjack() ) (
Console. INSTANCE . printMessage( player.toString() +
" STANOOF F!!- )i
I else (
Console.INSTANCE.p rintMessage( player.toStr1ng() +
" LOSER!! " )i

I
I

I else ( II a ban ca no estourou e no tem vinte-e - um

"
"
"

Iterator i players.iteratorO ;
wh1 1e( 1. hasNext() ) (
Player player (Player) i .next();
if( player.hasBlackjack() ) {
Console .I NSTANCE.prin tMessage( player . toString() +
WINNER WITH BLACKJACK!!" );
I el se if( pl ayer.isBusted() ) (
Console.INSTANCE.pr intMessage ( player.toStri ng() +
BUSTED! !" );
I else if( pl ayer.getHand().greaterThan( getHand() ) )(
Console.INSTANCE.p r intMessage( player.toString() +
WINNER! !" );
I else if( pl ayer .getHand().equalTo(getHand() ) ) (
Console.INSTANCE. printMessage( player.toString() +
STANDOFF! !" ) i
I else (
Console.INSTANCE .printMessage( player.toString() +
LOSER !!" );

I
I
I
I
I
claro que essa condicional trata apenas do cum primento do jogo. A banca precisar de muito
mais condicionais para saber se deve ou no comearajogar aps a distri buio e se deve ou no
deixar que um jogador jogue. Por exemplo, se a banca tiver uma mo com vinte-e-um, o jogo dever terminar automaticamente. Voc precisar de uma condicional para esse e todos os outros
desv ios do jogo.

Dia 16

Tal estratgia frgi l, difici I de manter, propensa a erros e simplesmente ho rrvel. Ao tratar com
condiciona is, voc freq Uentemente ver que o acrscimo de uma nova condicional faz um antigo
comportamento fa lhar. Tambm extremamente dific il entender cdigo repleto de cond icionais.
Boa sorte para aqueles que precisam manter tal baguna condic ional.
As estruturas cond icionais no so pa rt iculannente orientadas a objetos. O uso incorreto de condicionais estraga as div ises corretas de responsabi lidades, que so to importantes para a POO.
Ao usar condic ionais, a banca degenera para uma funo procedural que verifica um fi ag no jogador, toma uma deciso e, ento, diz ao j ogador o que fazer. A 00 no funciona assim! As cond icionais tm seus usos; entretanto, elas nunca devem extrair responsabilidades de um objeto.
Em vez di sso, o conhecimento de se um jogador estourou ou se tem vinte-c-um deve estar contido dentro do prprio objeto Pl ayer (Jogador); ento, quando um desses eventos ocorrer, o objeto
Player (Jogador) poder executar a ao correta e informar a BlackjackDeal er ( Banca 2 1), se
apropriado. Em vez da banca instruir os jogadores sobre o que fa zer, os jogadores devem usar
seus prprios estados internos para tomar essas deci ses. Tal estratg ia mode la mais preci samente o jogo vinte-e-um real.
O pri meiro passo para se desfazer das condicionais perceber quai s eventos e estados di rigem o
jogo vinte-e-um. Por todo o j ogo vinte-e-um, os vrios jogadores se movem atravs de estados.
Em um ponto o jogador est esperando; depois est j ogando. Aps j ogar, o jogador passa para
um estado dc espcra ou de estouro. Do mesmo modo, a banca passa da distribuio para a espera
por sua vez, para o jogo e, fi nalmente, para a parada ou estouro.
Tambm existem transies de estado alternativas. Aps receber s uas cartas, a banca ou o jogador pode mudar automaticamente para o estado de vinte-c-um, se receber uma mo quc totalize
v inte-e- um.
Para ter total entend imento dos vrios estados. assim como dos eventos que movem o jogador de
um estado para outro, ajuda modelar os diversos estados atravs de um diagrama de estado.

Diagramas de estado
A UM L defi ne um rico conj unto de notaes para modelar diagramas de estado . Em vez de
nos perdermos nos deta lhes, usaremos apenas os aspectos necessri os para modelar o j ogo
vi nte-e-um.
Para os propsitos da mode lagem do j ogo vinte-e-um, ex istem estados, transies, eventos, atividades e condies.
No jogo vinte-e-um, um estado a cond io de jogo corrente de um jogador. Tais condies incluem espera, j ogo, estouro, parada e vi nte-e-um , dentre outras.
As transies ocorrem q uando um j ogador se move entre seus estados. Por exemplo, um jogador
muda do estado de j ogo para o estado de estouro, quando ele estoura.

Ite rao 2 d o jog o v inte-e-um : adic io nando reg ras

391

Os eventos so um tipo de estmulo que pode fazer um jogador mudar entre seus estados. Por
exemplo, quando a mo do jogador causar um estouro, o jogador mudar do estado de jogo para
estouro.
A tividades so as aes executadas quando se est em um estado. Por exemplo, ao j ogar no estado de jogo, um jogador optar por receber mais cartas at decidi r parar ou estourar.
Cond ies de guarda so uma expresso booleana que coloca algum tipo de restrio em uma
transio. Por exemplo, um jogador mudar para o estado de parada, se decidi r no receber mais
cartas.
A Figura 16.2 apresenta a notao que voc usar para mode lar os estados do jogo vinte-e-um.

FIGURA 16.2

A //O/(/r70 do diagrama
de estado.

~;E;"~'d~O~~'~"~'~'~~~'->I(~E~"~'d~O~] __-;.~~
( alividade

..

No modelo, as transies so simbolizadas atravs de setas. As transies podem ocorrer como


resultado de um evento ou de uma condio (ou uma combinao dos dois). O evento e a condio devem aparecer na seta de tronsio para que seja bvio o motivo da ocorrncia da transio.
Voc tambm notar q ue uma transio pode voltar paro o estado corrente. Tal transio conhecida como outotrollsio.
Finalmente, se o obj eto exccuta cena ao quando est no estado, a ao regi strada como uma
atividade dentro do smbolo de estado. completamente vlido paro um estado no ter uma atividade.

Modelando os estados do jogador


A Figuro 16.3 apresenta o d iagrama de estado do jogador.
O jogador tem ci nco estados princ ipais: Espero, Vinte-c-um , Jogo, Parado e Estouro. O jogador
comea no estado Espcra. Aps a distribuio de cartas, o j ogador muda para o estado Vinte-c-um o u Jogo, dependendo da mo de canas recebida .
Quando sua vez de jogar, o jogador faz isso (a atividade do estado Jogo). Ao jogar, o jogador
dec ide receber mais canas ou parar. Se o jogador decidir parar, ele mudar para o estado Parado.
Se o jogador receber mais cartas, mudar para o estado Estouro, se sua mo causar estouro, ou
voltar para o estado Jogo, se der para jogar com a mo. Isso continua at que o jogador estoure
ou pare.

Dia 16

FIGURA

16.3

O diagrama de
eSfado
do jogador.

Espers

m60 vinte-e-um [mo __ 211

Vint_um
informs barlCll

Id PI1l jogar com s mo Imlo < 211

Jogo
recebe cartas ou p'ra

I lhitOJ

h..

Psrsds

informs banca
d' para jogar com
a mo Imo < 211

Estouro
Informa banca

Modelando os estados da banca


A Figura 16.4 apresenta o diagrama de eSlado da banca.
A banca lem seis eSlados principais: Dislribuio, Espera, Vinle-e-um, Jogo, Parado e Estouro.
A banca comea no eSlado Distribuio e d istribui cartas para cada jogador e para si mesma.
Aps a dislri buio, a banca muda para o estado Vinte-e-um ou Espera, dependendo da mo recebida.
Enquanto est no eslado Espera, a banca espera que todos osjogadores lerm inem sua vez. Quando lodos osjogadores tiverem tenninado, a banca mudar para o eSlado Jogoe comear sua vez.
Assim como o jogador, a banca decide se vai receber mais cartas ou parar, no eSlado Jogo. Ao
cOlllrri o dos jogadores, cnlrctanlo, a banca est reslri la a receber mais cartas quando sua mo
for menor que 17 e a parar quando sua mo for maior o u igual a 17.
Assim como o jogador, se a banca receber mais cartas e estourar, ela mudar aulomalicamente
para o eSlado Estouro. Se a banca decidir parar, mudar para o eSlado Parado.
Dignas de nota so as alividades nos eSlados Vinle-e-um, ESlouro e Parado. Enquanlo eSl nesses estados, a banca efelua o jogo e termina de jogar.

o modelo do jogo

vinte-e-um atualizado

Quando os estados do jogo eSliverem modelados e completamente entendidos, voc precisar


dec idi r como vai encaix-los no projeto. Comece colocando cada estado do jogo em sua prpria
classe. Em seguida, voc precisar descobri r o que gera os eventos.

393

Iterao 2 do j ogo v inte-e-um: adicionando reg ras

FIGURA 16.4

Odiagramll
de eslado
da bal/ca.

1 m""

v;nU!-fHIm
1m60- 211

Oillribui .....

1M'. ~ jogador~nc.
[da

.~

p'. jog... c:om a ...... [m'" < 211


[nenhum Jogado,
espe'andol

Eope..

1M'. cada

_.

llim_.....

TI'

p,,, joga'

[jogadorn "5perand<>1

.....

Jog~"

Imao,. 16 < 221

'&cabe

C.i: ~
d~

pa'. Jogar c<>m

"mao [mlo< 111

Pa,ado

.flt".l
mio e'ulII 1110"' 0
[mio,. 21[

ESI<>ur<>
af.lua

Esse uso do termoeslado se encaixa na defi nio original apresenlada anteriormente. Aqui, voc
apenas baseia um objeto em tomo de cada estado que o objeto Pl ayer (Jogador) deve ter em determi nado momento. Isso o libera de ter mui tas variveis intemasd iferentes. Em vez disso, o obj eto estado encapsula perfei tamente todos esses di ferentes valores dentro de um objeto, que tem
estado e comportamento.
Voc perceber rapidamente que todos os eventos giram em tomo do estado da mo. Assim,
voc provavelmente deve deixar que o objeto Hand (Mo) gere e envie esses eventos medida
que objetos Card (Cana) sejam adicionados no objeto Hand (Mo). Voc tambm precisar estabelecer um mecanismo para que os estados recebam eventos de Hand (Mo).
Os estados em si so muito simples e tm trs responsabi li dades. Os estados so responsveis por:
Executar todas as atividades.
Receber e responder aos eventos.
Saber para qual estado ir. em resposta a um evento ou condio.
A Fi gura 16.5 iluSlra o diagrama de classe St ate.
Voc notar que cada evento tem um mtodo correspondente no State (Estado). O objeto Hand
(Mo) chamar um desses mtodos, dependendo do estado que Hand (Mo) gostaria de reponar.
O objeto State (Estado) tambm acrescenta um mtodo executeO. Esse mtodo chamado
quando State (Estado) deve executar suas aes.
A Figura 16.6 modela os relacionamentos entre os objetos Pl ayer (Jogador), Hand (Mo) e State
(Estado).

Dia 16

FIGURA 16.5

H.ndUst.n.,

O diagrama de c/asse
de State (&Iado).

... h. ndPI.yeble O
... handBleckjack O
+ handBusted II
+ handChanged I)

o\>

PI.yritate
+ elCecute Id: Delaer)

FIGURA 16.6
H.naUstene,

O diagrama
de classe da

eSfrllf/lra

State
(&/(Ido) .

h.ndPl..,.bl. n
hendBltdtjtclc II
"-ndBUfled li
"-ndCh'''IIed (I

PleyerState
He nd
WlHoIdet" \I: H.ndUsl_,1
ed<lCerd te , card}
IIIEQU.I\h : H.ndl : boole.n
ItG,"~,Th.n \h : ~ndl : bool. ."
.1OIa1 0: IM
I.BIKkjKk 1): b<IoIe.n

~-

Play.,

. _.td : OHwl

,
,_bed.

ImplCl ass

o objeto Pl ayer (Jogador) mantm um objcto 5tate (Estado). Quando for a vez do objeto Pl ayer
(Jogador) fazer algo, ele simplesmente executar o mtodo execute () de 5tate (Estado). Ento,
State (Estado) executar todas as atividades, receber de Hand (Mo) e mudar para o prximo State
(Estado), confonne for apropriado. Uma vez feita a transio, o prx imo State (Estado) executar todas as alividades. receber de Hand (Mo) e mudar, conforme for apropriado. Esse padro
se repeli r at que o jogo termine.
A Figura 16.7 il ustra o diagrama de classes completo do jogo de cartas vi nte-e-um .

395

Iterao 2 do j og o v inte-e-um: adicionando reg ras

16.7
O diagramll de
classes completo
de 61 ackjack,
FIGURA

C nn""

Em bora a ad io de urna estrutura 5ta te (Estado) seja urna alterao i mportante ocorrida durante essa ilerao, outras interraces e classes roram atual izadas para poder supol1ar o relato e a ex ibio das novas condies do jogo.

Implementao das regras


Para suportaras novos recursos do jogo, so necessrias mudanas nas classes PI ayer (Jogador),
Dealer (Banca), Bl ackjackOeale r (Banca 21) e Hand (Mo). Vrias novas classes e interfaces
tambm preci sam ser acrescentadas. As seesa seguir examinarnocada mudana importante.

Mudanas na Classe Hand


Para suportaras novos recursos dojogo, a classe Hand (Mo) deve relatar seu estado para um receptor. A Listagem 16.2 apresenta a nova interface HandUs t ener.

Dia 16
LISTAGEM 16.2

HandListener.java

public interface Handl is tener I


public void handPlayab l e();
publiC void handBlackjack() ;
public void handBusted();
public void handChanged();
J

A Listagem 16.3 apresenta a classe Hand (Mo) atuali zada.


LISTAGEM 16.3

Hand .java

i mport java.util.Arraylist
i mport java.uti 1 .lterator;
pub l ic cl ass Hand I
private
private
private
private

Arraylist cards = new Arraylis t () ;


stati c f i nal int BlACKJACK = 21;
Handlistener hol der;
int number_aces;

public Hand() I
II configura o portador como um receptor em branco para que ele no
seja nulo . caso
II no seja configurado externamente
setHolder(
new Handlistener() I
public void handPlayable() II
publi c vo i d handBlackjack() II
publi c vo i d handBusted() {I
publ ic vo i d handChanged() I}
J

);
J

publiC void setHolder( Handlistener holder ) I


th i s .holder holder;
J

publi C Iterator getCardsO I

Iterao 2 do j ogo v inte-e-um: adicion ando regras

LISTAGEM 16.3 Hand.java (continuao)


return cards.iterator();
}

publlC void addCard( Ca rd card ) {


cards . add( card };
hol der.handChanged();
i f( card. ge tRank() Rank.ACE ) {
}
if( bustO} (

holder.handBusted() ;
return ;
}

if( blackjac k() ) (


holder . handBlack jack();
return;
}

if ( ca rds.size() ~ . 2 ) (
holder.handPlayab le ();
return:
}
}

pubhc boo l ean isEqual ( Hand hand ) I


H(hand.totalO this.totalO) {
return true;
}

return false;
}

pub l iC boolean isGreaterThan( Ha nd hand ) {


return th i s . total () > hand. tota 1() :
}

publ ic boolean bl ackjackO (


if( ca rds.size() 2 &&total() BLACKJACK ) {
return true;
}

return fa 1se ;
}

public vo1d reset() I

397

Dia 16

LISTAGEM

16.3 Hand.java (continuao)


ca rds. clearO;
number aces - O;

publlC void turnOver() I


Ite ra tor i - cards.iterator() ;
while( i.hasNext() ) I
Card card - (Card) i .nextO;
card.setFaceUp( true ,;
J
J

public Stri ng toString() (


Iterator i cards .iterator();
String string "";
while( LhasNext() ) (
Card ca rd - (Card) i . next();
string - string + " " + card.toString();
J

return st r ing;

J
publ ic int total () I
int total - O;
Iterator i - cards.iterator() ;
while( i.hasNex t() ) I
Card card z(Card) i.next();
total +- card.getRank().getRank() ;
J

int temp_aces - number_aces;


while( total> BLACKJACK && temp_aces
total - total
10;
w

return tota 1;

J
private boolean bust() (
if(total() > BLACKJACK ) {
retu rn true;

J
return false ;
J

>

O) I

Iterao 2 do jogo v inte-e-um : adic ionando reg ras

399

Agora, as alteraes no mtodo total () de Hand (Mo) tomam possvel que um s tenha o valor
I ou II . Do mesmo modo, as alteraes no mtodo addCard{} perm item agora que Hand (Mo)
informe ao seu receptor das alteraes no seu contedo, quando elas acontecerem.
Final mente, a ad io dos mtodos 1sEqua I {} e lsGrea terThanO possibilita a comparao fci l e
encapsulada de obj etos Hand ( Mo).

Mudanas na Classe PI ayer


A maior al terao na hierarquia PI ayer (Jogador) gira em tomo do acrsci mo de States (Estados). A Listagem 16.4 apresenta a nova interface PlayerState.
LISTAGEM

16.4 Playe r State.java

pub li c interface PlayerState extends HandListener 1


publi c vo i d execute{ Oealer dealer };
}

PlayerState herda de HandUstener e acrescenta um mtodo executeO. Uma implementao


de PlayerState implementar Playe r State, responder apropriadamente a qualq uer um dos
eventos HandU stener e executar s uas atividades dentro de executeO.

o objeto Player (Jogador) mantm uma referencia para seu estado corrente, atravs da varivel
current s t at e. O mtodo playO foi alterado para si mplesmente executar o estado corrente:
publ1c void play{ Oea l er dealer ) 1
current_state .execute{ dealer };
}
Em vez de defin ir algum comportamento dentro do mtodo playO, o objeto P1ayer (Jogador)
simplesmente de lega para seu estado. Desse modo, voc pode fomecer comportamento novo
si mplesmente trocando objetos de d ife rentes estados. A troca por diferentes estados uma soluo muito mais elegante do que a troca atravs de uma li sta de lg ica cond icional.
As listagens 16.5 a 16.9 apresentam as impl ementaes padro de PI ayer e PI ayerState. Esses
estados implementam diretamente os modelos de estado da seo anterior.
LISTAGEM

16.5 O estado de espera padro

private class Waiting implements Pl ayerState {


publ ic void handChanged{) I
notifyChanged();
}

public voi d handPlayab le () I


setCurrentState( ge tP layingState() };
/1 t ransio
}

Dia 16

LISTAGEM 16.5 O

estado de espera padro (continuao)

publiC void handB lackjack() {


setCurrentState( getBlackjackState() );
noti fyB lackjack() ;

II

t ransi~o

pu bl ic void hand BustedO 1


II impossvel no es tado de espera
J

public void execute( Oealer dea ler ) {


II no faz nada enquanto espera
J
J

LISTAGEM 16.6 O

est ado de estouro padro

private class Busted impl ements PlayerState (


pub l ic void handChanged() (
II impossvel no estado de estouro

public voi d hand Playable() I


II impossivel no es tado de estouro
J

public voi d handBlackjack() 1


II impossivel no es tado de estouro
J

public void handBusted() 1


II impossvel no estado de estouro
J

public void execute( Oea ler dea ler ) {


dealer.bu sted( Player . thi s ) ;
I I termi na
J

LISTAGEM 16.7 O

estado

vinte-e-um pad ro

private class Blackjack implements Pl ayerState I


pub l ic void handChanged{) I
Il impossvel no estado de vin te-e - um
J

public voi d handPlayable{) I


Il impossve l no estado de vinte-e-um
J

Iterao 2 do j ogo v inte-e-um: adicionando regras

LISTAGEM 16.7 O estado

vinte -e- um padro (continuao)

publiC vold handBlackjack() {


II lmposs fvel no estado de vinte-e- um
J

publlc void handBustedO {


II imposs vel no estado de vinte-e - um
J

public void execute( Oealer dealer ) {


dealer.blackjack( Pl ayer.this );
I I tenni na
J
J

LISTAGEM 16.8 O estado de parada padro


private class Standing implements PlayerState {
publ ic void handChanged() {
II impossfvel no estado de parada

J
pub l ic void handPlayab le () {
II impossfvel no estado de parada
J

public vold handB lac kjack O I


II impossfvel no estado de parada
J

public vold handBusted() {


II imposs 1vel no estado de parada
J

publi c void execute( Oealer dealer ) {


dealer.standlng( Player.this ) ;
I I tenni na
J
J

LISTAGEM 16.9 O estado de jogo padro


private class Playlng imp lements PlayerState {
pub l ic void handChanged() I
notlfyC hanged();

public void handP layab le( ) I


II pode ignorar no estado de jogo
J

publi c void handBlac kjack () I

401

Dia 16
LISTAGEM 16.9 O estado de jogo padro (continuao)

II

impossfvel no estado de jogo

}
publ ic vo i d handBustedO {
setCurrentState( getBus t edState() );
not i fyBus ted () ;
}
public voi d execute( Oealer dea l er ) (
1f( hno } (
dealer.hit( Player.this ) ;
} el se {
setCu rrentS ta te ( getS tandi ngS t a te O
noti fyS t anding();
}
current_state.execute( dealer ) ;
II trans io
}

);

Todos esses estados so implementados como classes internas de Pl ayer (Jogador) pois, basicamente, elas so extenses da classe Pl ayer (Jogador). Co mo classes internas, esses estados tm
tOlal acesso a todos os mtodos e varivei s da classe PI ayer (Jogador). As classes internas permitem que voc encapsule e fi cientemente a lgica de estado dentro de sua prpria classe, sem ler
de danificar o encapsulamento da classe Player (Jogador).
Subclasses podem fornecer s ua prpria implementao de estado, sobrepondo os seguintes mtodos em Pl ayer (Jogador):
protected Pl ayerState getBustedState() (
return new Busted() ;
}
protected PlayerState getStandingStateO (
return new Stan ding() ;
}

protected PlayerState getPlayingState() (


return new Playing();
}
protected PlayerState getWa i t i ngState() (
return new Waiting{);
}
protec ted PlayerState getB l ack j ackState() {
return new Blackj ac k();
}

protected PlayerState get In i t i alState()


return new Wa i tingState();
}

Iterao 2 d o jogo v inte-e-um: adic ionando reg ras

403

Desde que os estados usem esses mtodos para recuperar os outros estados, as subclasses podem
introduzir seus prprios estados personalizados. getInitia lS tateO usado pe la classe base
Player (Jogador) para configurar o estado inicial de Pl ayer (Jogador). Se uma s ubclasse comear em outro estado, ela tambm precisar sobrepor esse mtodo.
Final mente, vrios mtodos de noti licao roram adicionados na classe Pl ayer (Jogador). Os estados usam esses mtodos para inrormar o receptor das alteraes. Esses mtodos correspondem
aos novos mtodos encontrados na interrace PlayerListener. Novos mtodos roram ad icionados no receptor para suportar a nova runcionalidade dojogo. A Listagem 16. 10 apresenta a interface Playerlistener atualizada.
LISTAGEM

16.10 Pl ayerListene r. java

pub l i C interface PlayerListener {


publi c vo i d playerChanged( Playe r player l :
publ ic vo i d playerBusted( Player player )i
publiC void playerBlackj ack( Player pl ayer ) :
pub l ic void playerS ta nd ing( Playe r player ):
publiC vo1d playerWon( Player pl ayer );
public void playerLost ( Player player ):
publiC void playerStandoff( Player pl ayer );
J

Como Console um Playerlistener, os mtodos a seguir roram acresce ntados em Console:


pub li c void playerChanged( Player playe r ) {
pri ntMessage( player.toS t ring() ):
J
public void playerSusted( Player player ) (
printMessage( player.toStringO + " SUS TED!!" ) :
J
public void playerSla ckjack ( Player player ) {
prin t Message( playe r. toStringO + " SLACKJACK! ! " );

Dia 16

public yoid playerStanding( Player player ) (


printMessage( player.toString() + STANDING

}i

I
publiC yoid playerWon( Player playe r ) (
printMessage( player.toStringO + WINNER!!" );

I
public void playerLost( Player player ) (
printMessage( player.toString() + LOSER !! " }i

I
publiC void playerStandoff( Pl ayer player ) {
prin tMessage( player.toStringO + " STANDOFF " )i

I
Essas alteraes perm item que Console apresente todos os pri nci pais eventos do jogo.
Alguns mtodos novos tambm foram acrescentados em PI ayer (Jogador):
publ i c Yoid winO (
notifyWi nO;

I
publiC yoid lose() I
noti fyLoseO i

I
publiC void standoffO {
notifyStandoff();

I
publi c void blackjack() I
notifyBlackjack() i

I
Esses mtodos pe rmitem que Oeal er(Banca) informe a PI ayer(Jogador) se ga nhou, perdeu, empatou ou ti nha vinte-e-u m.

Mudanas em Dealer e BlackjackDealer


Dealer (Banca) e Bl ackjackOea I er (Banca 2 1) precisam ser atualizados para se encaixar na nova
estrutura de estado. A Listagem 16. 11 apresenta a interface Dea 1er (Banca) atua lizada.
LISTAGEM 16.11

Oea l er . java

publ i c interface Oealer I


II usado pelo jogador para in terag ir com a banca

Iterao 2 do jogo vinte-e-um: adicionando regras

LISTAGEM 16.11

405

Dea l er.ja va (c on t inuao)

publiC void hit( Playe r player };

II usado pelo jogador para se comunic ar com a banca


public void blackjack( Player playe r };
public void busted( Player pl ayer };
public void standing( Player player };
}

Pl ayer (Jogador) usa esses novos mtodos para relatar o estado para Deal er (Banca). Assim, por
exemplo, quando Pl ayer (Jogador) tiver vinte-e um , chamar o mtodo bl ackjack () de Dea ler
(Banca). Ento, oea l er (Banca) pode passar a vez para o prximo jogador. Esses mtodos so
parecidos com o mtodo passTurnO anterior. Eles apenas so mai s especficos.
Dea 1er (Banca) usa cham adas para esses mtodos, para filtrar os objetos Pl ayer (Jogador) em recipientes, baseado em seu estado. Isso torna o cumprimento dojogo muito mai s f cil para Dealer
(Banca).
Por exem plo, aqui est uma implementao de busted() de Bl ackjackDea l er:
public void busted( Player pl ayer ) (
busted pl ayers.add( player ) ;
play( t his );
}

Os outros mtodos funcionam de manei ra semelhante.


BlackjackDeal er (Banca 2 1) adi ciona um estado oealerDeal ing. Ela tambm persona liza mui
tos dos estados padro de Pl ayer (Jogador). As listagens 16. 12 a 16. 16 apresentam esses estados
modificados.
LISTAGEM 16.12 O

estado de estoura da banca personal izado

private cl ass oealerBusted implemen t s PlayerState {


pu bl ic void han dCha nged() {
II impossfvel no estado de estouro
}

publ ic vo i d handPlayable() {
I I imposslvel no estado de estou ro
}

pub l ic voi d handB lackjack() {


II imposslvel no es t ado de estouro
}

pub l ic voi d handBustedO {


II imposslvel no es t ado de estouro
}

Dia 16

LISTAGEM 16.12 O estado de estoura da banca pe rsonalizado (continuao)


pub l iC void execute{ Dealer dea ler ) I
Iterator 1 standing_players.iterator {):
while{ i. hasNext() ) I
Player player = (Pl ayer) i .next();
player .winO:
J

i blackjack_p l ayers. iterator() ;


while( 1. hasNext() ) I
Player player (Player) i .next() :
player.win():
J

i busted_players.iterator():
while( i.hasNext() ) I
Player player (Player) i . next() ;
player. l oseO ;
lO

J
J

LISTAGEM 16.13 O estado de banca com vinte -e- um persona l izado


pr iva te cla ss OealerBlackjack implements PlayerState {
public void handChanged() {
noti fyC hangedO:
J

public void handPlayable(} {


II impossvel no estado de vinte-e-um
J

publi c void handBlackjack() {


II impossvel no estado de vinte-e -um
J

public void han dBusted () (


II impossvel no estado de vinte-e -um
J

publ iC void execute( Dealer dealer ) I


exposeHand ();
Iterator i players.ite rator () :
whl1e( i .hasNext() ) (
Pl ayer pl aye r (Player)i.next() :
if( player.getHand () . blackjack() } I
player.stando ff() :
I else {
player.lose() ;
K

Iterao 2 do j ogo v inte-e-um: adicionando regras

LISTAGEM 16.13 O

estado de banca com vinte -e- um personalizado (continuao)

}
}
}

LISTAGE M 16.14 O

estado de banca pa rada personalizado

pri vate class OealerStanding implements PlayerState (


publi c v01d handChanged() {
II impossfvel no estado de parada
}

public void handPlayable() {


II impossfve l no estado de parada
}

pub l ic vo i d handBlackjack() {
II impossfvel no estado de parada
}

pub l ic vo i d handBustedO {
II impossfvel no estado de parada
}

public void execute( Oealer dea l er ) I


Iterator i standing_pl ayers.ite rato r ();
while( i.hasNext() ) I
Player player = (Pl ayer) i .next();
H( pl ayer.getHand(). is Equal( getHandO ) ) I
player .standoff() ;
I else if( player.getHand() . isGreaterThan( getHand() ) ) {
player.winO;
I e I se {
player.loseO ;
}
}

blackjack_players . iterator{) ;
while( i .hasNext() ) {
Player player = (Player) i . nex t () ;
player.win() ;
i

busted_p l aye rs.iterator() ;


while( i.ha sNext() ) I
Pl ayer pl ayer (Pl ayer) LnextO;
p1ayer.loseO;
i =

}
}
}

407

Dia 16

LISTAGEM 16.15 O estado da banca esperando personal izado


pr ivate cla ss OealerWa i t i ng i mpl ements PlayerState {
public void handChanged() I
II i mposs fve l no estado de espera
}

publi C void handPlayab le( ) I


II imposs1vel no estado de espera
}

publ ic vo1d handBlackjack() {


II imposs fvel no es tado de espera
}

publi C vo i d handBusted() {
II impossfvel no estado de espera
}

publi c vo i d execute( Dealer dealer ) {


;t( !wa1ting_players . i sEmpty() ) {
Player pl ayer (Player) waiting players.get( O )i
wa i ting_players. remove( player );
player. play( dea ler )i
) el se {
setCurrentState( getPlayingState () ) ;
exposeHand()i
getCurrentState().execute( dealer );
II faz a tran sio e executa
}
}
}

LISTAGEM 16.16 O estado da banca distribuindo personal izado


private cla ss DealerDealing implements PlayerState {
pu blic void han dChanged() (
notifyChanged();
}

publi C vo i d handPl ayab l e() (


se t Current State( getWaitingS tate() );
II tran si lio
}

pub l iC void handB l ackjack() {


se tCurrentState( getBlackjackState() li
noti fyBl ackjack (l;
II transi o
}

public void handBusted() {


II imposs i vel no estado de di stribu iao

Iterao 2 do jogo vinte-e-um: adicionando regras

LISTAGEM

409

16.16 O estado da banca distribuindo personalizado (continuao)

public void execute( Oealer dea ler ) {


deal();

getCurrentState().execute( dealer ) ;
II faz a transiao e executa
}
}

Voc pode notar que Bl ackjackOeal er (Banca 21 ) no define seu prprio estado dej ogo. Em vez
disso, ele lisa o estado de jogo padro de PI ayer (Jogador); entretamo, para usa r seus estados persanai izados, BI ackj ac kOea I er (Banca 2 I) precisa sobrepor os receptores de estado encontrados
na classe base PI ayer (Jogador):
protected PlayerStale getBlackjackState() {
return new OealerBlackjack() ;
}

protected PlayerState getBustedState() (


return new OealerBusted();
}

protected PlayerState getStandingState() {


return new OealerStanding();
}

protected PlayerState getWaitingState() I


return new OealerWaiting();
}

Teste
Assim como no cdigo do Ca ptulo 15, "Aprendendo a combinar teoria e processo", uma bateria
completa de testes est disponve l para download no endereo www.samspublishing.com. junto
com o cd igo-fonte deste captulo. Esses lestes consistem em um conjunto de lestes de unidade e
objetos fa lsifi cados, que testam completamente o sistema do jogo vinte-e-um.
O teste ullla parte importante do processo de desenvolvimento; entretanto, o estudo do cdigo
de teste deixado como exerccio para o leitor.

Resumo
Hoje, voc conclui u a segunda iterao do jogo vinte-c-um. Fazendo esse exerccio, voc viu
pela primeira vez como poderia usara processo iterat ivo para conseguir paulatinamente uma soluo completa.

Dia 16

Cada iterao anterior atua como base ou fundamento para a seguinte. Em vez de comear uma
nova anli se ou projeto, hoje voc comeou construindo os casos de uso e projeto descobertos
ontem.
Amanh, voc complementar melhor essa base, quando adicionar recursos de aposta no programa do jogo vinte-e-um.

Perguntas e respostas
I) Se os estados so to importantes, por que voc quis esperar at essa iterao para
inclu-los?

R A iterao inicial era simples. A iterao inicial usava um jogo vinte-e-um bs ico que
no detectava mos de vinte-e-um natural, ganhadores ou pe rdedores (embora detectasse
estouros). No havia motivos para atacar o probl ema com uma soluo complexa. Os requi sitos dessa iterao justi ficam uma soluo mais com plicada, pois ela acrescenta deteco de vinte-e-um, assim como cumprimento do jogo.
P Voe poderill ter implementado os estados fora de Pl ayer (Jogado r) e 81 ackjackDea1er (Banca 2 1) ou eles devem ser classes in ternas?

R Voc pode implementar os estados fora da classe. Mas se voc os definir fora de Pl ayer
(Jogador), talvez prec ise adicionar alguns mtodos novos para que os estados possam recuperar todos os dados de que precisam.
Gostaramos de desaconselhar tal estratgia, por trs mot ivos:
Primeiro, mover a defin io de estado para rara da classe no resolve muito. Na verdade,
isso ca usa traba lho extra, devido aos mtodos que voc prec isar adicionar.
Segundo, a adio de mtodos extras para que os estados possam recuperar dados estraga
o encapsu lamento.
Finalmente, mover os estados para fora da classe Pl ayer (J ogador) no modela o relacionamento estado/jogador muito bem. Basicamente, os estados so lima extenso de Pl ayer (Jogador). Desse modo, os estados aluam como os crebros de Pl ayer (Jogador).
melhor que os crebros fiqu em dentro do corpo.
,

E importante nOlar que a im plementao de estados como classes internas funci ona perfe itamente na linguagem Java. Oulras linguagens podem exigi r uma estratgia li geiramente diferente.

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respostas no Apndice A, 'Respostas".

Iterao 2 do j ogo v inte-e-u m : adicionando regras

411

Teste
I. Quando as condicionais so perigosas?
2. Liste duas maneiras de remover condicionais.
3. A verso de Hand (Mo) apresenlada hoje melhor encapsulada do que a de ontem.
Como a nova verso de Hand (Mo) se encapsu la?
4. Que padro Hand (Mo) e HandListener implementam?
5. Procure na Web mais informaes sobre o padro State.

Exerccios
I. Faa down load do cdigo-fonte da iterao de hoje. Quando voc tiver o cdigo, compile-o, faa-o funcionar executando o jogo vinte-e-um e, depois, tente entender como ele
funciona. Ter um entendimento total do cdigo exigir algum tempo e pacincia.
2. O cd igo a seguir aparece na definio da classe PI ayer (J ogador):
protected yoid notlfyChanged() (
Iterator i listeners .iterator();
while( i .hasNex t() ) (
PlayerListener pi (PlayerListener) i . next();
pl.playerChanged( th is ) ;
}

protected yoid notify8usted () (


Iterator i listeners. iterator();
while( i.hasNext() ) (
PlayerListener pl a (PlayerListener) i.next();
pl . player8usted( this ) ;
}
}

protected yoi d notify8lackjack() (


Iterator f 11steners.iterator();
wh i le{ i.hasNext() ) (
Playerlistener pi = (PlayerL i stener) i . next() ;
pl . player81ackjack( this );
}

protected yoid notifyStanding() (


Ite rator i = listeners. iterator();
while( i.hasNext() ) {

Dia 16

Playerlistener pl (Playerlistener) i.next();


pl.playerStanding( this );
}
}

protected yoid notifyStandoff() {


Iterator i l i steners.iterator{);
while( i.hasNext() ) {
Playerlistener pl z (Playerlistener) i.next();
pl. playerStandoff{ this );
}
}

protected void notifyWinO {


l terator i 1 isteners . iterator{) ;
whi l e( i.hasNext{) ) {
PlayerUstener pl (Playerlistener) i.next();
pl.playerWon( thi s );
}
}
protected void notifyloseO {
Iterator i = l i steners. ite ratorO;
while( i . hasNext() ) {
Playerlistener pl ( Pl ayerlistener) i.next();
pl.playerlost{ this );
}
}

Os mtodos funcionam. Funcionalmente, no h nada de errado com eles; entretanto, cada mtodo
executa exalamente a mesma ao, at o ponto em que uma chamada fe ita em Pl ayerli stener.
Como voc poderia usar objetos de modo que precisasse escrever apenas um mtodo de notificao? Projete e implemente uma so luo.

SEMANA

DIA
Iterao 3 do jogo vinte-e-um:
adicionando aposta
No captulo de OIlIem, voc viu como pegar lima implementao bastante primit iva do jogo vintc-c-um e fazer sua iterao para obter umjogo mais amadurecido. Hoj e, voc vai complementar
o mesmo j ogo vinte-c-um, adicionando suporte para aposta simpl es.
A lio de hoje dar a voc mai s experincia com o processo iterativo, ass im como com ADO e
POO ( Projeto Orientado a Objeto). No final da lio de hoje, voc tambm dever comear a se
senti r mai s vontade com a arq uitclu ra baseada em estado apresentada ontem. Na verdade, um
dos exerccios de hoje ped ir para que voc ad icione um novo estado no s istema.

Hoj e voc aprender:

Como estender a arquitetura de estado do jogo vinte-c-um para ad icionar func ional idade

Sobre as vantagens que lima verdadei ra estratgia 00 pode trazer para um sistema, trabalhando em um sistema baseado em 00

Aposta no jogo vinte-e-um


A iterao de ontem produziu um jogo vinte-e-um bastante completo. Quase todos os recursos
no relacionados com aposta agora fazem parte do j ogo. Hoje, voc vai acrescentar alguns dos
recursos de aposta ausentes.

Dia 17

Assi m como nas outras lies desta semana, segui remos o processo del ineado no Capitulo 9,
" Introduo AOO (Anlise Orientada a Objetos)". Vamos comear explorando os casos de
uso de aposta.

Anlise da aposta
Para entender completamente a aposta, voc precisar finalizar os casos de uso Fazer apostas e
Dabrar, identi fi cados durante a anl ise inicial do jogo vinte-c-um. Voc tambm precisar rever
os outros casos de uso para ter certeza de que eles no precisam de atual iz.."to. Uma vez que tiver term inado os casos de uso, voc precisar atuali zar o mode lo de domnio.

Anlise do caso de uso de aposta no jogo vinte-eum


Vamos comea r com o novo caso de uso Jogador faz aposta:
Os jogadores comeam o jogo com U$$ 1000 no pote. Antes que quaisq uer cartas sej am distribudas, cada jogador deve faze r uma aposta. Comeando com o primei ro jogador, cada um aposta
um valor de USS IO, US$50 ou U$$ IOO.
Jogador faz aposta
I. Jogador faz uma aposta de US$ IO, US$SO ou US$IOO.

2. J)assa para o prx imo jogador e repete at que todos os jogadores tenham feito lima
aposta.
Condies prvias
Novo jogo.
Condies posteriores
Jogador fez aposta.
O jogo villle-e-um rea l, como todo jogo, tem suas prprias regras sobre aposta. Essas regras
incl uiro uma aposta minima, uma aposta mxima e o incremento da aposta. Neste jogo vinte-e-um ,
um jogador pode apostar U$$ l 0, US$SO ou U$$ I00. Por simpl icidade, este jogo oferecer ao
jogador uma lin ha de crdi to ili mitada. Cada jogador comear com US$ I000. Quando o jogador esvaziar seu pote, seu saldo se tornar negativo; entretanto, o jogador pode jogar, desde que
queira.
O outro novo caso de uso de aposta Jogador dobra:
O jogador decide que no est satisfei to com sua mo inicial. Em vez de simplesmente receber
mais cartas, o jogador decide dobrar. Isso duplica a aposta do jogador e acrescenta uma carta na
mo. A vez do jogador term ina e o jogo passa para o jogador/banca seguinte.
Jogador dobra
I. O jogador decide que no est satisfeito com sua mo in icia l.

Iterao 3 do jogo vinte-e-um: adicionando aposta

415

2. O jogador quer dobrar.


3. A aposta do jogador duplicada.
4. A banca acrescenta outra carla em s ua mo.
o

Condies prvias
o

Essa a mo in icial do jogador e ainda no recebeu mais carias nem parou.

O j ogado r no tem vinte-c-um.

A banca no tem vinte-e-um.

Condies posteriores
o

A mo do jogador tem trs carias.

A vez do jogador termina.

Alternativa: Jogador estoura


A nova carta faz a mo do jogador estourar (perde).

Alternativa: a mo do jogador maior que 21, mas o jogador tem um s.

A nova carta faz a mo do jogador ser maior que 21. O jogador tem um s. O valor do s muda de
II para I, fazendo com que a mo do j ogador seja menor ou igual a 21.
Os nicos casos de uso prev iamente existentes, afetad os pela adio da aposta, so o caso de uso
Distribuir carias e o caso de uso Banca ejeluajogo. Os outros casos de uso permanecem inal terados:
Comeando com o primeiro jogador, a banca distri bui uma cana abena para cada jogador,
terminando consigo mesma. Ento, a banca repete esse processo, mas distribu i s ua prpria
carta fechada. A distribuio termina e o jogo comea quando a banca tiver distri budo para
cada jogador, incluindo ela mesma, duas cartas.
o

Distribuir cartas
I. A banca distribui uma carta aberta para cada jogador, inclu indo ela mesma.
2. A banca distribui uma segunda carta aberta para todos os jogadores, menos para ela.
3. A banca distribui uma carta fechada para si mesma.

Condies prvias
o

Condies posteriores
o

Todos os jogadores fizeram suas apostas.


Todos os jogadores e a banca tm uma mo com duas cartas.

Alternativa: a banca tem vinte-c-um


Se a banca tiver um 21 natural. o j ogo passa para o cumprimento. Os jogadores no tero
sua vez.

Dia 17

Agora, a distribuio no comear at que cada j ogador tenha feito uma aposta. Vamos ver
como a aposta muda o cumpri mento do jogo:
Aps todo ojogo ser fei to, a banca veri fica cada mo e detenn ina, para cada jogador, se ele ga
nhou ou perdeu, ou se o j ogo deu empate.

A banca efelua o jogo


I. A banca verifica a mo do primeiro jogador e a com para com a s ua prpria.
2. A mo do jogador maior que a da banca, mas no estourou; o jogador ganha.

3. O va lor da aposta adi cionado ao pote do jogador.


4. A banca repete essa comparao para todos os jogadores.

Condies prv ias

Cada jogador teve sua vez.

A banca teve sua vez.

Condies posteriores

Resultado fi nal do jogador foi detenn inado.

Alternativa: o jogador perde


A banca veri fi ca a mo do jogador e a compara com a sua prpria. A mo do j ogador
menor que a da banca. O jogador perde. A aposta retirada do pote do jogador.

Alternativa: empate
A banca veri fi ca a mo do j ogador e a compara com a sua prpria. A mo do j ogador
igual da banca. O j ogo deu empate. Nada acrescentado ou subtrado do pote do joga
dor.

Alternativa: a banca estoura


Se a banca estourou, todo j ogador que esti ver parado e com vintee-um ganha. Todos os
outros perdem. Os gan hadores recebem o valor apostado.

Alternativa: os jogadores ganham com vinte-eum


Se o jogador tiver vinte-eum e a banca no, o jogador ganha r e receber na proporo de
3:2 (por exem plo, se o jogador apostasse US$ IOO, receberia US$ I 50).

J sso

conclui as al teraes nos casos de uso. Todos esses casos de uso so relativamente si mples.
Os diagramas de interao provavel mente seriam complicados. Vamos ver como esses casos de
uso atualizados mudaram o modelo de domnio.

Atualizando

modelo de domnio do jogo vinte-e-um

A anlise da aposta ex ige q ue voc atualize o modelo de domnio, mas apenas ligeiramente.
Voc precisar adicionar mais um objelo de domnio: Bank ( Banco). Todo objeto Player (Jogador) no jogo tem seu prprio objeto Bank (Banco) pessoal. A Figura 17. 1 ilustra o modelo de do-mnio atualizado.

Iterao 3 do jogo vinte-e-um: adicionando aposta

FIGURA 17.1
O II/Ol/elo de domnio
do jogo lilfle-e-/lIII.

417

J"" '

,
1... 7

,
M'o

,
Carta

Projeto da aposta
Voc deve comeara projeto projetando a nova classe Bank (Banco). Quando Bank (Banco) estiver pronta, voc precisar descobrir como apostar no jogo. Para os propsitos da Iio de hoje, o
caso de uso Jogador dobra deixado como exercc io no fina l da lio.

Projetando a classe 8ank


Ao comear a projetar Bank (Banco),voc deve primeiro identifica r suas responsabi lidades. A
Figura 17.2 ilustra o carto CRC resultante para a classe Bank (Banco).
A boa 00 ex ige a diviso correta das responsabilidades. Desse modo, Bank (Banco) responsvel por controlar Iodas as atividades de aposta. Bank (Banco) mantm lodos os detalhes da aposta
internamcnte e d acesso aposta e ao saldo atravs de uma interface bem de fi nida. A Fi gura
17.3 ilustra O diagrama da classe Bank (Banco), assim como o relacionamento de Ba nk (Banco)
com PI ayer (Jogador).

o projeto da aposta
Como se v, a aposta deve se encaixar bem na arqu itetura de estado que vi mos ontem. O jogador
e a banca precisaro de mais um estado para suportar aposta bsica. A banca precisar de um estado Co 11 cct i ngBcts (Coletar Apostas) e o jogador precisar de um estado Aposta. As fig uras 17.4
e 17.5 ilustram os novos diagramas de estado para a banca e para o jogador, respectivamente.

Dia 17

FIGURA 17.2

Banco

O ca,.to CRC de Bank

~~=

(Banco).

Banco

FIGURA 17.3

O diagrama da classe Ba nk

.. pl_, OOBetU:
.. pl_SOS.' (I:
.. pl_l08e10:

(Bal/co).

.. winO:

.. lose(l:
bh,,:kj.ck(l;

.. mndoffll;

FIGURA 17.4

O diagrama de
estado de Oea 1er
(Bal1ca).

mio'

la mio ' boII pa,a iOlla, Imlo < 21J

(mio> 11 < 221

ijogldo<H esperandoJ

mio' """ pao-I joglf


Imlo < 111

mio estouro ...

Iterao 3 do jogo vi nte-e-um: ad icio nando apost a

41 9

FIGURA 17.5

O diagrama
de estado
de P/(lj'e,.s

(Jogado,.es).

Apo
aposta

IJogo I.ito)

Esper.

mio' vint. ... um (mo __ 2 I I

I!

mo

boI!

Vint.-eum

parI! jogar (mio .. 21)

jogo

a mio booI ""rI Joglr


[mio ... 211

Jlhi@

I mio estourou
[mio:>2 11

Estoulo

Confonne voc pode ver, agora o jogador comea no estado Aposta, enquanto a banca comea
no estado Co 11 ec t i ngBets (Coletar Apostas). Quando todas as apostas forem colctadas, a banca
passar para o estado Distribuio. como antes. Quando termi narem as apostas, os jogadores
passaro para o estado Espera.

Refazendo a hierarquia de Player (Jogador)


Neste ponto do projeto, parece que PI ayer (Jogador) e Bl ackjackDea I er (Banca 21) esto divergindo. Embora BlackjackDealer (Banca 21) estenda Player (Jogador), ela no precisa de Bank
(Banco). Isso diferente de HumanPI ayer (Jogador Humano), pois a banca no aposta. Se voc
adicionar suporte para aposta diretamente em Player (Jogador), BlackjackOealer (Banca 21)
herdar lodos os tipos de comportamento int il , que precisar sobrepor (alm de Pl ayer (Jogador) fica r demasiadamente congestionado).
Este um bom momento para refazer a hierarquia de herana PI ayer (Jogador), dividindo os elementos comuns em subclasses. Na nova hierarquia, nenhum suporte para apostas deve ser ad icionado na classe base PI ayer (Jogador). Em vez disso, uma nova classe, Bet t; ngPI ayer, deve herdar
de Pl ayer (Jogador) e, ento, adicionar os estados e mtodos necessrios para o suporte de apostas.

Dia 17

B1ackj ackOealer (Banca 21) pode continuar a herdar de Pl ayer (Jogador); entretanto, Hl.manPlayer
(Jogador Humano) deve agora herdar de Sett i ngP1 ayer. A Figura 17.6 ilustra a hierarquia resultante.
FIGURA 17.6
II hierarquia de

PllJyer

Player ljogadOl).

oodCa,d le ; canil
play (d ;
,ddlistanar (I; Playerlistane.)
win (J

De".,)

. 1058 O
+ SIDndoff O
+ blaekjaek O

# gel/nllllllS/lla (J : PI,~,SllIle
I hil (I ; boa/fllln

Dealer
+ hlt (P: PI, ver)
+ blaekjeek (p : Plavar)
+ buSled (p ; Plavar)
+ standing (p: Player)
+ doneSaning (p: Piava. )

~
BetfingPllJyer

BlackjackDealer
, hil O : boolean
, gM!nilialStata n : PI,y&rStata
-.tdf'I ..... r Ip : Pla.....1
newGame

.. win O
lou ti
+ l tandOtf II
blacljack CI
, getlnill.tSl"e II: PI..... rState

,li fi

HumanPlayer
... hil () : boolean
... bel ((

o modelo do jogo vintee-um atualizado


Agora que voc terminou o projeto, uma boa idia atuali zar o diagrama da classe B1 ackjack. A
Figura 17.7 ilustra o diagrama da classe.
Agora, voc est pronto para passar para a implementao.

Implementao da aposta
A implementao da aposta ex igir a criao das classes Bank e BettingPlayer, assim como alteraes em BlackjackOealer, Oea1er e HumanPlayer. Vamos comear com a classe Bank.

Ite rao 3 do jogo v inte-e-um : ad icio na ndo aposta

42 1

A implementao de Bank
Confonne voc descobriu, Bank (Banco) responsvel por conler um 10lal, assim como por gerendar as apostas. A Listagem 17. 1 apresenta uma passivei implementao de Bank (Banco).

FIGURA 17.7
O diagrllllla
da classe

Blackj ack.

,
1 ... 7

re<:,be d' _ _

,
81nk
di.uiblll de

c..,

LISTAGEM 17.1 Bank.java


pub l ic class Bank (
private int total;
private int bet;
pub l ic Bank( int amount ) I
tota I amount;
}

public void placelOOBet() {


placeBet( 100 ,;
}

Dia 17

LISTAGEM 17.1

Bank.java (continuao)

publiC void placeSOBet() {


placeBet( 50 li
J

publi c void placelOBetO {


placeBe t( 10 )i
J

public void winO {


total +- ( 2 * bet ) i
bet = Oi
J

publi c vo i d lose() (
II j extrafdo do total
bet .. Oi

J
pub l ic void blackjack() {
tota 1 +'" ( ( ( 3 * bet )
bet .. Oi

2 ) + bet ) i

J
publiC void standoff() {
t ota l +.. beti
bet .. Oi
J

public String toString() {


return ( "$" + total + ".00" ) i
J

private void placeBet( int amount ) {


bet .. amounti
total . = amounti
J

Quando o jogador prcdsa fazer uma aposta, ele faz isso atravs da interface Bank. Digno de nota
o modo como Bank ocu lta completamente os detalhes da aposta. Quando o jogador ganha, perde, atinge vinte-c-um ou empata, ele si mplesmente informa a Bank. Bank faz o resto.

Iterao 3 do jogo vinte-e-um: adicionando aposta

423

A implementao de BettingPlayer
Bet t i ngPl ayer preci sa herdar de PI ayer, defi nir um estado Apost (Bett ing), garant ir que seu estado inicia l seja configurado como o estado Aposta e adicionar suporte para Bank (assim como
atua liz- Io corretamente). A Listagem 17.2 apresenta a nova classe BettingPlayer.
LISTAGEM17.2 BettingPlayer.java
public abstract class BettingPlayer extends Player {
private Bank banki
public BettingPlayer( String name, Hand hand, Bank bank ) {
supere name, hand )i
this.bank banki

// **.* ** *** *.**.* ** *

// comportamento sobreposto
pub li c String toString() {
return ( getNameO +
bank . toString() )i
M :

+ getHandO.toStringO + -\n" +

I
public void win() {
bank .winOi
super.winO i
I
public void lose() I
bank.loseO;
super.lose() j

I
publi c yoid standoffO {
bank.standoff()i
super.standoff()i
I
pub l ic yoid blackjack() I
bank.blackjack()i
super.blackjack();

I
protected PlayerState getlnitia l State() {
return getBettingState()i

Dia 17

LISTAGEM 17.2

BettingPlayer.java (continuao)

11**************************************************** **********************
II ad ic ionado recentemente para BettingPlayer
protected final Bank getBank() (
return bank;
J

protected PlayerState getBettingState() {


return new Betting()j
J

protected abstract void bet() j


private class Betting implemen t s PlayerSt ate (
public vo i d handChanged() (
II 1mpossfvel no es t ado de estouro
J

publ ic void handPlayable() (


II impossve l no estado de estouro
J

public vo id handBlackjac k() (


II impossvel no estado de estouro

J
public void handBusted() (
II impossvel no estado de es t ouro

J
public vo i d execute( Dealer dea l e r ) {
bel ();

setCurrentState( getWaitingState() )j
dealer.doneBett1ng( BettingPlayer.th i s ) j
I I termi na
J
J

Voc tambm notar que Betti ngPl ayer acrescenta um novo mtodo abstrato: protected abstract voi d bet (). O mtodo bet () chamado dentro da ativi dadc do estado Betti ng (Aposta).
Cada subclasse deve sobrepor esse mtodo, como achar melhor.

Mudanas em Oealer e HumanPlayer


A parti r do exame do cd igo de BettingPlayer,voc provavel mente notou que um novo mtodo
foi adicionado em Oea l er: public voi d doneBet t i ng( Pl ayer p ).

Ite rao 3 do jogo v inte-e-um: adici o nando aposta

425

BettingPlayer chama esse mtodo para informar a Dea l er que ele terminou a aposta. Desse
modo, o objeto Dea l er pode saber que o jogador tenninoll e que o prxi mo jogador pode comear a apostar.
As alteraes em HumanPI ayer so muito sem graa. A Listagem 17.3 lista a nova classe HumanPI ayer.
LISTAGEM

17.3 HumanP l ayer.java

public class HumanPlayer extends 8ettingPlayer {


private
private
private
private
private
private
private
private

f i na I
final
fina I
fina I
fina I
fi na I
final
f i nal

static
statlc
s tatl c
static
stat i c
statlc
static
static

String
St r ing
St ring
St ring
String
String
String
String

HIT

STAND
PLAY MSG
BET- MSG
8ET- 10
BEl 50
BET 100
DEFAULT

"H'"
"S";
.. [H] it or [S] tay";

"Place BeqlO] [50] or [100]";


"10";
"50";
"100'"
"inval id'"

pub l ic HumanPlayer( String name , Hand hand. Bank bank } {


supere name, hand. bank );
}

protected boolean hit() {


while( true ) {
Co nsole . INSTANCE.printMessage( PLAY_MSG };
String response s Console.INSTANCE . readInput( DEFAULT );
lf(response.equals lgnoreCase( HIT ) ) {
return true ;
J else if( response . equalsIgnoreCase( STAND ) ) {
return fal se ;
}

II
II

se chegarmos at aqul , faz um


s i gnifi cativa

lao at obtermo s entrada

}
}

protected void bet() (


while( true ) I
Console.INSTANCE.printMessage( BET MSG );
St ring response Conso l e.INSTANCE . readInput( OEFAULT ) ;
if( response.equa l s( BET_10 ) } {
getBank(} . placel0Bet() ;
return;
}

Dia 17

LISTAGEM 17.3

HumanP1ayer.java (continuao)

if( response.equal s ( BET_50 ) ) (


getBank(}.place50Bet();
return ;
J

if( re sponse.equal s ( BET_IOO } ) {


get Ban k(}. place IOOBe t(};
return;
J

/1 se chegarmos at aqui, faz um lao at obtermos entrada


/1 significativa
J
J
J

Agora, HumanPlayer herda de BettingP layer, em vez de diretamente de Playe r. HumanPl ayer
tambm fornece uma implementao de bet (). Quando bet() chamado, ele consulta a linha de
comando para ver retorno do usurio.

Mudanas em 81ackjackDealer
Bl ack jackOeal er (Banca 2 1) implementa o novo mtodo doneBett i ng D, definido em Dealer.
Quando esse mtodo chamado, Blackj ackDea ler pega o jogador e o insere em um rec ipiente de
jogadores esperando.
BI ackjac kDea 1er tambm define um novo estado: Dea 1erCo I Iec t i ngBets . A lm disso, Dea I erCo 11 ect ; ngBet s atua como o novo estado ini cial de Bl ackj ackDea I er. A Listagem 17.4 apresenta o novo estado.
LISTAGEM 17.4 O

novo estado de DealerCollectingBets

pr;vate cl ass OealerCollectingBets imp lements PlayerState \


publi c vo i d handChanged() i
II imposs fve l no estado de aposta

J
publ ic void hand Playable () (
II impossfvel no estado de aposta

pub l ic void handB lackjack () t


/1 imposs fve l no estado de aposta
J

public void hand Bus tedO {


II i mposs fve l no es tado de apost a

Iterao 3 do jogo v inte-e-um: ad icio nando apost a

LISTAGEM 17.4 O

427

novo estado de OealerCollectingBets} (continuao)

publiC vold execute{ Dealer dea l er } I


if( !betting_pl ayers.isEmpty() ) {
Player player (Pl ayer) betting players.get( O } );
betting pl ayers .rernove( pl ayer )j
player . play( dealer };
I else I
setCurrentState( getDealingState() ) j
getCurrentState().execute( dealer ) ;
II faz a trans io e executa
J
J
J

o novo estado chega ao fi m e diz a cada jogador para q ue aposte. Digno de nota que esse estado
no faz lao. Em vez di sso, a atividade executada sempre que um jogador indica que acabou de
apostar. Esse comportamento est defi nido dentro do mtodo doneBettingO:
public void doneBetting( Player player ) {
waiting_playe rs.add( player );
play( thls ) j
J
Lembre-se de que uma chamada a play() executa o estado correntc.

Miscelnea de mudanas
A nica outra alterao digna de nota o falo de que o mtodo getInitialStateO de Player
agora declarado como abstraIo na classe base PI ayer. Tornar o mtodo abstrato funciona como
uma forma de documentao que pennite a qualq uer um, que faa subclasses da classe, saber
que deve fornecer sua prpria definio de estado inicial.
A prtica de tornar um mtodo abstrato para que ele funcione como uma forma de documentao
uma maneira eficiente de estabe lecer um protocolo de herana.

Um pequeno teste: um objeto falsificado


Como sempre, casos de teste esto disponiveis junto com o cdigo-fonte; entretanto, interessante dar uma olhada em um uso inteligente de objetos fal sificados. A Li stagem 17.5 apresenta
um objeto fa lsi fi cado Deckpile que garante q ue a banca recebe um vinte-e-um.
LISTAGEM 17.5

Oea l erBlackjackP i le.java

publ i C class DealerBl ack jack Pile extends Deckpile


pr; vate Card [] cards j

Dia 17

LISTAGEM 17.5 OealerBlackjackP i le.java (continuao)


private lnt index -I:
public OealerBlackjackPi l e() {
ca rd s " new Ca rd (4];
card s (OJ new Ca rd ( Suit. HEARTS , Rank.TWO ) ;
cards ( lJ new Card( Suit. HEARTS, Rank.ACE ) ;
cards (2J new Card( Suit. HEARTS, Rank. TH REE ):
card s (3J new Card( Suit.HEARTS. Rank.KING );

I
publi C vo i d shuffle() (
II no faz nada

I
publ ic Card dealUp() (
index++;
cards[index].setFaceUp( true ) ;
return cards [index]:

I
pub l iC Card dealOown O (
index++;
return cards (index]:

I
public voi d reset() (
I I no faz nada

I
I
Voc pode usar esse objeto falsificado para testar se o jogo responde corretam ente quando a banca recebe uma mo de vi nte-e-um. Esse objeto fa lsificado realmente prepara o baral ho para roubar no jogo.

Resumo
Hoje. voc concl uiu a terceira iterao do projeto do jogo vinte-e-um - resta apenas mais uma!
Neste capt ulo, voc viu como poderia estender a arquitetura de estado para suportar aposta simples nojogo. Voc tambm viu que s vezes necessrio rever e refazer lima hierarq uia, quando
novos requisitos se apresentam. Refazer pensadamente representa um pouco de trabalho extra
alllecipado; refazer quando apropriado tende a compensar quando voc prosseguir.

Iterao 3 do jogo vinte-e-um: adicionando aposta

429

Como voc refez as hierarquias agora, a base de cdigo ser muito mai s fc il de entender, estender e manter posteriormente.
Amanh, voc colocar uma UI grfica no jogo.

Perguntas e respostas
P I'or que voc no modelou o cumprimento como um estado?
R Voc poderia ter modelado o cum primento como um estado; entretanto, um estado de
cumprimento teria signi fi cado rudo no projeto. As atividades dentro dos estados Busled,
B/ackjack e Slanding podem efet uar o jogo adequadamente. Alm disso, esses estados
podem efetuar o jogo mu ito especificamente.

Se a banca fizesse a transio para um estado de cumprimento, ela perderia suas informaes de estado anteriores. Se voc efetuar dentro de um estado especfi co, entretanto, a
banca poder fazer a contagem dojogo facilmente, pois saber em que estado term inou.

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respostas no Apndice A, ' Respostas".

Teste
I. Como voc pode estabelecer protocolos de herana efic ientemente?

2. A lio sobre herana, na Semana I, d isse que as hierarquias de herana so freqlien temente descobertas e no planejadas desde o incio. Qual hierarquia voc descobriu hoje?

3. Dada a Pergunta 2 do teste, por que voc deve esperar para realizar a abstrao at ter fe ito algo algumas vezes?
4. Hoje, voc refez a hierarqu ia Pl ayer. Liste duas vantagens que voc obteve fazendo as
alteraes.

Exerccios
I . Faa download do cdigo-fonte da iterao de hoje. Quando voc tiver o cdigo, compile-o, faa-o funcionar executando o jogo vinte-e-um e, depois, tente entender como ele
funciona. Ter um entendimento talai do cdigo exigir algum tempo e pacincia.

2. Projete e implemente o caso de uso Jogador dobra. Baseie sua soluo no cdigo-fonte
da lio de hoje.

SEMANA

DIA

Iterao 4 do jogo vinte-e-um:


adicionando uma GUI
At aqui nesta semana, voc anal isou, projetou e construi u um jogo de cartas vi nte-c-um. Trabalhandoa partir de uma implementao simples e faze ndo iteraes para obter um aplicativo mais
complexo, voc ad icionou regras e recursos de aposta no jogo. Hoje, voc continuar o processo
iterativo e fa r melhorias na camada de apresentao do jogo.
Hoj e voc aprender como:

Aplicar an lise, projeto e im plementao ao escrever interfaces com o usurio

Aplicar o padro MVC no jogo vinte-c-um

Apresentao do jogo vinte-e-um


At aqui, a n ica interface para ojogo de canas vinte-e-um tcm sido uma rudimentar interface com
o usurio (U I) baseada em linha de comando. No foi falado muito a respeito dessa UI. Na verdade, mu ito pouco, se que houve, anlise ou projeto aplicado a UI, apenas foi dito que voc usar o
padro MVC. Em vez de fazer a anlise e o projeto da UI de linha de comando, a UI mais simples
possvel foi criada para pennitir que voc interagisse com o sistema do jogo vinte-e-um.
Durante o desenvolvimento, voc freqOentemente ver que precisa desenvolver materiais de suporte, como objetos stubs ou partes de interao do sistema com o usurio, como a UI. Freq entemente, esses materiais no sero orientados pela anlise. Em vez disso, esses itens so
orientados por necessidades que se apresentam durante a implementao. No caso do jogo vin-

Dia 18

te-e-um , voc precisa absolutamente de uma maneira para interagir com o sistema; entretanto,
escrever uma UI grfica desde o incio si mplesmente no era prtico. Como a UI de linha de comando no se destinava a fazer parte do sistema fina l, no houve necessidade de realizar anlise
adiciona l para ela.
Hoje, voc far uma ltima olimizao na UI de linha de comando origi nal e depois passar para
a anlise, projeto e implementao de lima UI grfica (GU I) completa para ojogovinte-e-um.

Otimizaes da linha de comando


Antes de passarm os para o trabalho na GUI do jogo vinte-e-um, interessante fa zer uma ltima
otim izao na UI de linha de comando.

urna inconven incia ter de reiniciar o jogo cada vez que voc quer j ogar. A Listagem 18. 1
apresenta um novo mtodo principal que permite a voc jogar quantos jogos vinte-c-um quiser,
sem ter de reiniciar.

LISTAGEM 18.1 Blackja ck.java


publi c cla ss Blackjack I
public stati c vold ma i n( String [] args ) I
Dec kpil e cards new Deckpile(} i
for{ i nt i = O; i < 4; i ++ ) I
cards .shuffle{) ;
Oeck deck new Deck()i
deck.addToStack ( card s )i
cards.shuff1e() ;
J

Hand dea ler hand = new Hand();


BlackjackDealer dealer new BlackjackDealer( "Dealer" ,
ca rd s );
Bank human_bank new Bank{ 1000 ) ;
Hand human_hand new Hand{);
Pl ayer player new CorrmandLinePl ayer{ "Human" , human_hand, human bank
);

dealer.addL istener{ Console.INSTANCE );


player. addL istener( Console. INSTANCE );
dealer.addPlayer{ playe r )i
do

dealer.newGame();
I while( playAga in () };

Iterao 4 do jogo vinte-e-um: adicionando uma GUI

433

LISTAGEM 18 .1 Bla ckjac k.j ava {conti nuao}

Consol e. INSTANCE.print Message { MThank you for playing'M } ;

}
pri vate sta t ic boolean pl ayAgai n{} {
Conso le . INSTANCLp ri ntMessage ( "Would you like to pl ay again? [Y) es

[Nl o };
St ri ng response Conso l e.INSTANCE.read I nput{ "i nvalid" };
if( response . equa ls IgnoreCase{ "y" } ) {
return true;
}
return fal se ;

}
}

Adicionar essa funciona lidade no mtodo principal do jogo vinte-c-um tem um valor prtico,
pois ela nos ajuda a detectar todos os erros que possam estar ocu ltos no programa, quando voc
jogar vrias vezes. Por exem plo, cada mo prec isa ser correlamente reconfi gurada, antes do pr-ximo jogo. Levantando todos os erros agora, voc no ser pego pelo erro posterionncnte e no
achar. que a nova GUI a culpada.

Anlise da GUI do jogo vinte-e-um


Para completar a an lise da GU I, voc deve rea lizar a anlise de caso de uso, exatamenle como
fez durante as iteraes anteriores. Ao se realizar a anlise da GU I, tambm fundamental que
voc se sente com seus clientes, usuri os e especialistas na util izao, para projetar o layout da
GUI. Na realidade, quanto menos palpite voc der como desenvolvedor no layout da GU I, melhor. Todo mundo tem sua prpria especialidade. Como descnvolvedor, sua espec ialidade normalmente anal isar probl emas, projetar solues e implementar essas solues. Quando voc se
sentar com seu cliente, va i descobrir como ele quer sua OUI configurada.
Infeli zmente. os especialistas em uti lizao, clientes e usurios no aparecem na fonna conveniente de um livro; portanto, voc precisar passar sem eles hoje. Em vez disso, trabalharemos em
um esboo da te la, antes de passarmos para o projeto.

Casos de uso da GUI


Ao contrrio dos casos de uso do jogo vinte-e-um que voc analisou durante as iteraes anteriores.,
os casos de uso da GU l no afetam o domnio do jogo em si. Em vez disso, os casos de liSO da
GUI ajudam a estabe lecer como o usurio vai manipular o jogo vinte-e-um atravs da UI.

Dia 18

Desse modo, o primeiro caso de uso que voc precisa invest igar aquele que inicia um novo

Jogo:
Quando o programa est iniciando pela primeira vez ou o jogador acabou de jogar um jogo,
ele pode optar por jogar um novo jogo.
Novo jogo com GU I
I. O jogador clica no boto New Game e um novo jogo comea.
Condies prvias
o jogador deve ter acabado de iniciar o programaOll acabado de tenninar um jogo.
Condies posteriores
Novo jogo iniciado.
Conforme voc pode ver, esse caso de uso no altera o domnio do jogo vinte-e-um . Ele sim plesmente configura as regras bsicas da UI. O prximo caso de LISO da UI analisa as apostas:
Os jogadores comeam o jogo com US$ I000 em seu pote. Antes que qualquer carta seja distribuda, cada jogador deve fazer uma aposta. Comeando com o primeiro jogador, cadajogador aposta um valor de US$IO, USSSO ou US$ IOO. Se um jogador ficar abaixo de USSO,
ele ainda poder jogar. O valor em seu pote refletido como um nmero negativo.
Jogador faz aposta com GU I
I. O jogador se leciona um dos seguintes nveis de aposta: 10.50 ou 100 e faz a aposta
imediatamente.
2. A aposta passa para o jogador seguinte e se repete at que todos os jogadores tenham
feito uma aposta.
Condies prvias
Novo jogo in iciado.
Condies posteriores.
O jogador fez uma aposta.
A banca pode comear a dar as cartas
Voc ainda precisa de suporte para dar mais cartas e para parar. O prximo caso de uso
identi fica o ato de dar mais cartas:
O jogador decide que no est satisfeito com sua mo. O jogador ainda no estourou; portanto, ele decide receber mais cartas. Se ojogador no estourar, ele pode optar por receber
ma is cartas novamente ou parar. Se o jogador estourar, o jogo passa para o jogador scguinte.
Jogador recebe mais cartas com GU I
I. O jogador decide que no est satisfeito com sua mo.
2. O jogador clica no boto Hit, que solicita outra carta da banca.

Iterao 4 do jogo vinte-e-um: adicionando uma GUI

435

3. O jogador pode optar por receber mais cartas novamente ou parar, caso o total em sua
mo seja menor ou igual a 2 1.
o

Cond ies prvias


o

O jogador tem uma mo cujo valor total menor que 2 1.

O jogador no tem vinte-c-um.

A banca no tem vinte-e-um.

Condies posteriores

Uma nova carta acrescentada na mo do jogador.

Alternativa: Jogador estoura


A nova carta faz com que a mo do jogador seja maior do que 21. O jogador estoura (perde). Comea a vez do jogador seguinte/ banca.

Alternat iva: a mo do jogador maior do que 2 1, mas ele tem um s


A nova carta faz com que a mo dojogador seja maior que 21. O jogador tem um s. O valor do s muda de II para I, fazendo a mo do jogador ser menor ou igual a 2 1. O jogador
pode optar por receber mai s cartas novamente ou parar.

Se um jogador no quer receber mai s cartas, ele deve parar. O prx imo caso de uso analisa o uso
da QU I para parar:
O jogador decide que est satisfeito com sua mo e pra.
o

Jogador pra.
1. O jogador decide que est contente com sua mo e clica no boto Stand.

Condies prvias

O j ogador tem uma mo cujo valor menor ou igual a 21.

O j ogador no tem vinte-e-um.

A banca no tem vinte-e-um.

Condies posteriores

A vez do j ogador termina.

E, por ltimo, mais no menos importante, voc precisa considerar a sada do j ogo:
O jogador decide que no quer mais jogar e sai.

Jogador sai do j ogo com QU I


I. O jogador clica no boto Quit.

2. O jogo se fec ha.


o

Condies prvias

O jogo no deve estar em andamento (nenhum jogo foi iniciado ou o jogo foi concludo).

1 436

Dia 18

Condies posteriores

Desligamento do j ogo.

Modelos visuais de GUI


Com base nos casos de uso enumerados na seo anterior, voc precisar projetar o layout da
GUI. A Figura 18. 1 apresenta uma possvel GU I que preenche todos os requisitos descobertos
durante a anli se.

FIGURA 18 .1
li CU! dojogo
\'il1le-e-lIl11.

Deale r (Banca)

Ica na ll cana l "


Nome do jogador S Banco

I
..
El
Icana

II
I
I USS10 I I
I Hit I I Stand I INewG.me I I Qu i. I
USSO

US5100

Existem alguns comportamentos ad iciona is da GUI com que voc pode traba lhar agora. A Figura 18.2 ilustra o status dos botes quando o usurio inicia o jogo pela primeira vez.

FIGURA 18 .2
O stafll.\" inicial

do.\" bales.

US$10

Hit

II

II

US$SO

S!a nd

II

US$l 00

I lN_Gamai I

I
Quit

Todos os botes so vi sveis quando o jogo comea; entretanto, apenas New Game e Quit esto
ativos. A Figura 18.3 ilustra o status dos botes aps um clique em New Game.

FIGURA 18 ,3

O stallls dos bOIOes aps


clicll/" em New Game.

Hit

US$1O

II

USS50

II Stand I I

II

New

US5100

Gam.1I

I
Qui!

Ite rao 4 do jogo vinte-e-um: adicionando uma GUI

437

o jogador deve fazer uma aposta aps clicar em New Game. Como resultado, apenas os botes
de aposta esto ati vos. A Figura 18.4 ilustra o status dos botes aps ter fe ito a aposta.
FIGURA 18.4

I us." II

O SllIfltS dos botes


aps !a=er

IIIIIlt

H't

II

U"",,

Stand

II

II uss", I

New Gama i

Qu 't

apoS/(I.

Aps fazer uma aposta, um usurio pode receber mais cartas ou parar. Assim, apenas os botes
Hit e Stand esto ati vos. Todos os outros botes so desativados. Os botes permanecem nesse
estado at que o jogador pare ou estoure, no ponto em que o jogo termina os botes voltam para
o status ilustrado na Figura 18.2.
Aps a conc luso de um jogo, as cartas permanecem na te la at que o usurio clique em New
Game. As cartas so ento removidas da tela. Durante o jogo, a mo grfica do jogador atual izada, quando uma carta distribu da para ele.
Esse layout de OU I afetar fortemen te os modos de visua lizao que voc vai projetar na prxima seo.

Projeto da GUI do jogo vinte-e-um


Projetar as classes que compem uma OU I no diferente de projetar qualquer outro tipo de
classe. Voc deve identi fi car as classes individuais e suas responsabilidades.
Usando a Figura 18. 1 como ponto de partida, voc pode gerar uma lista inicial de classes. Voc
precisar de uma classe para a tela principa l, uma classe para ver um jogador e uma classe para
visua li zar as opes do jogador.

Cartes CRC da GUI


Uma sesso de carto CRC pode ou no ser garantida aqu i. Tudo depende de seu nvel prprio de
bem-estar. Para uma GU I maior, voc definitivamente desejar passar por um nmero de sesses, para garantir que tenha fei to um bom traba lho na diviso das responsabilidades.
Para nossos propsitos, a OUI do jogo vinte-e-um suficientemente simples para que se possa
pular uma sesso de CRC completa. Em vez disso, listaremos as responsabilidades aqui.

PlaverView
PI ayerView responsvel por visualizar um objeto Player no jogo vi nte-e-um. O modo de visualizao deve apresentar a mo, o nome e o saldo do pote de Player (se aplicvel). Pl ayerView

si mplesmente um veiculo de visual izao. Desse modo, ele no exige um controlador. Ele preci sa simplesmente receber e apresentar seu objeto PI ayer.

Dia 18

OptionView e OptionViewController
Opt i onVi ew responsvel por visualizar as opes do jogador humano. Opt ionVi ew tambm preci
sa responder interao do llSlk'irio, de modo que exige um controlador: Opt i onVi ewContro 11er.

CardView
CardVi ew responsvel por visualizar os objetos Card individuai s. CardVi ew no interativo; as
si m, ele no exige um controlador. PlayerV i ew usar CardV i ew para vi sualizar Hand.

BlackjackGUI
B1ackjackGU I responsvel por agregar e apresentar todos os diversos modos de visual izao.
Como BlackjackGUI at ua como um shell simples, ele no exige um controlador.

Miscelnea
CardVi ew precisar de um modo para mapear um objeto Card em uma imagem, para exibio.
Voc pode implementar um longo iflelse ou case para mapear o objeto Card dentro de CardView;
entretanto, tal estratgia horrvel (para no mencionar que lenta).
Em vez de criar uma estrutura condicional, voc deve faze r uma subclasse de Oeck e Cardo Voc
pode chamar as duas classes resullantes de VDeck. e VCard, respct ivamente. VCard receber um
argumento construtor extra, o nome de um arquivo bitmap. VOeck construir objetos VCa rd.
Como voc passa Oeckpi 1e para Bl ackjackDealer, em vez de permit ir que BlackjackOeal er crie
seu prprio mao de cartas, pode passar as carias visuais de fo nna transparente para a banca.
Voc tambm precisar criar um novo jogador humano para a OU I. Esse novo objelo GU IPl ayer
pode herdar diretamente de Bet t i ngPl ayer; entretanto, ele precisar fornecer seus prprios esta
dos Aposta e Jogo personal izados.
Em vez de basear uma deciso no mtodo hi t () ou bet(), o objeto GUIP l ayer precisar obter
essa informao da OU I. Como resultado, voc prec isar de mtodos que a OU I possa chamar
para apostar, receber mais cartas e para r. Quando esses mtodos forem chamados, eles colocan1o
o jogador nos estados corretos e com un icaro qualquer informao para a banca.
Ao todo, voc precisar adicionar ou sobrepor os seguintes mtodos em GUIPlaye r: placel()'BetO. place50Bet() , placelOOBet(), takeCard() , stand(), getBettingState() e getPlayingState().

Estrutura da GUI

As vezes, ao se trabalhar com uma GUI, aj uda esboar o modo como as panes se encaixaro.
Como a prpria GUI visual, seu esboo pode ser realmente um pouco mais poderoso do que os
diagramas de classe padro. A Figura 18.5 visualiza Pl ayerView.

Iterao 4 do jogo vinte-e-um: adicionando uma GUI

439

FIGURA 18.5

Vislfoli:olldo

Pl ayerV i ew.

Voc v que, na Figura 18.5, PI ayerVi ew constitudo de vrios objetos CardView. PI ayerView
tambm desenha uma borda em torno de si mesmo, com o nome e o saldo do pote (se aplicvel)
de PI ayer, no canto superior esquerdo.
Fe lizmente, o pacote Java javax . swing .JPanel fornece toda a funciona lidade que voc precisa
para dispor componentes, assi m como para desenhar uma borda rotu lada.
Continuando, a Figura 18.6 visual iza OptionView.
Oplion View

FIGURA 18.6

Visl/a!i:olldo

OptionView.

Controles de aposta

r - - - - - - - -

-A.- - - - - - - -

--I

II
II
1\ :,
, ~
:I
II
I I G.mel I
I:
:

U5$10

Hit

U5$5O

Stand

U5$100

N8W

Qui!

:_\ ___ ~ ___ ~f!: ___ ~----~ ~


Controles do jogador

Controlei do ioga

OptlonView si mplesmente um conjunto de botes. Uma combinao de javax.swing.JPanel


(para an inharas botes) e j avax. swi ng .JButton deve fornecer tudo que voc precisa para implementar esse modo de visualizao.
A Figura 18.7 rene visualmente todas as partes.
As fi guras anteriores devem ajudar a visualizar como todos os modos de visualizao se encaixam. Entendercomo as partes se encaixam pode ajudar durante a implementao de urna GU J.

Refazendo
Agora que existem dois tipos de jogadores humanos -GU I e CLUJ - provavelmente faz sentido renomear HumanPlayer como ConmandUnePlayer. Voc deve fazer essa alterao hoje.

Dia 18

FIGURA 18.7
A j(me/a I>rincifXIl
dividida por 1II0dos de
ris/lali=ac7o.

Modo de visualizao
da carta: vislvel

GUI do jogo vinte-eum

-------------------,
I

Modos de
visualizao
do jogador

Banca

,,
,,

,,
,,

<------~'

~---

--------

---

______ I

-----------------,
I Nome do jogador $ Banco

Icarta I l ca rta
M odo de
visueli zao
de opo

~--

I...

--------

----

_____ I

Diagrama de classes da GUI


Agora que todas as novas classes esto identificadas, voc pode mode lar a estrutura de classes
resultante. Assim como o diagrama de classes do Capitulo 17, lterao 3 do jogo vintee-um:
adicionando aposta", o modelo aprese.uado na Figura 18.8 focaliza a estrutura.

Implementao da GUI do jogo vinte-e-um


Ao se implementar uma OU I, em geral, mais fcil traba lhar de ba ixo para cima. Nesse sent ido,
voc deve implementar na seguinte ordem: VCard, VDeck, CardView, PlayerVlew, OptlonView,
Opt i onVi ewCont ro 11er, GU I P1 ayer e B1 ac kjackGU I. Vamos exam inar os destaques de cada classe.

Implementando VCard, VDeck e CardVi ew


VCard tem uma implementao relativamente simples, pois apenas acrescenta mais um atributo
classe Cardo A Listagem 18.2 apresenta a nova definio da classe VCard.

Iterao 4 do jogo v inte-e-um: adicionando um a GUI

FIGURA 18.8

441

BI"CkjlM'k GUI

A esrrulllra de
classes da GUI.

Jt..bel

2. .B
,=:-=
,

r:-:---:-:-=---'
Option ViewConlro II

uibe

comrola

VCfld

manipu la.

recebe dto

..,.nipul, a
r,..,.be dto

B.ttingPl. "..

diouibul dto

"
I diciona cartas 1m
QU IPI ..... .

LISTAGEM 18.2 VCard.java


pub l ic class VCard extends Card {
String image;
publi C Vcard( Sui t suit, Rank rank , String image ) (
supere sui t , rank );
t his. image .. image;
}

publ ic Str i ng getl mage () {


i f( i s Fa ceUp() ) I
return image;

Dia 18

LISTAGEM 18.2 VCard.java (continuao)


} else {
return N/ bltmaps/ empty pile.xbm N:
}
}

A implementao de VOeck si mples. Para criar objetos VCa rd. em vez de Card, voc preci sar
sobrepor Omtodo bui l dCards() de Deck. Para sobrepor o mtodo, primeiro voc precisar mudar o mtodo para protegido em Oeck. Originalmente, o mtodo era privado. A Listagem 18.3
moma uma li stagem parcial da implementao de VOeck.
LISTAGEM 18.3 VOeck.java
pub l iC cla ss VOeck extends Oeck {
protected void buildCards() {

II Isso

horrvel , mas melhor do que a alternativa lao/ if/ else

Ca rd () deck new Card (S2):


setOeck( deck l:
deck [O] new Vcard ( SuH.HEARTS ,
deck [1] new Vcard( Suit. HEARTS ,
deck [2] new Vca rd ( Suit. HEARTS,
deck [3] new Vcard ( Suit. HEARTS,
deck [4] o Vcard( Suit. HEARTS,
deck [5] new Vcard( Sui t.HEARTS,
deck [6] new Vcard( Suit.HEARTS,
II restante cortado por brevidade

Rank . TWO , "/ bi tmaps/ h2 " ):


Rank. THREE, N/ bitmaps / h3N ) ;
Rank . FOUR, "/b itmap s/ h4~ ):
Rank . FIVE , "/bHmaps/ hS- l:
Rank.S IX, "/ bHmaps/ h6" ,;
Rank.SEVEN, "/bitmaps/h7" ) ;
Rank . EIGHT, "/bitmaps/h8" ):

Para a GU I, usaremos um conjunto de bitmaps que est contido no diretrio bitmaps,j unto com
o download do cd igo-fonte. Os nomes dos bitmaps seguem uma conveno de atribuio de
nomes especl1ca; ponanto, voc tambm pode implementar bui 1dCards () como um lao.
Embora seja horrvel, simplesmente codificar os valores um pouco mai s fcil de entender (e
manter).

Iterao 4 do jogo vinte-e-um: adicionando uma GUI

ALERTA

443

Codificar a cri ao da carta tambm pode no ser a soluo mais f cil de manler . O problema que cada estratgia que voc possa adol ar tem uma deficincia. VDeck um exemplo de uma dessas ocasies em que voc deve fa zer uma
escolha entre d ois males e conv iver com ele.
A soluo delineada anterior mente fa lha. devido aos erros inerentes na d igit ao de t odas as chamadas. Alm d isso. se o construtor mudar. voc precisar atualizar cada chamada .
Co m o altern ativa. voc poderia fa zer um lao pela rep resen tao de List de
Ranks. Tal sOluo o o briga a supo r uma ordem especfica dos elementos na
li sla (para que voc possa gerar corretamente o nome de arqui vo da imagem).
Se a ordenao mudar. o lao ser desfeito misteriosamente. Qualquer um
qu e mantiver o cdigo ter dificuldade para encon trar a fonte do erro. Evi ta mos a estratgia do lao porque alteraes em uma classe no rela cionada poderia danificar VOeck.

CardVi ew ex ibir o bitmap VCa rd. j avax . swi ng. JLabel fornece a funci onalidade necessria para
exibir um bitmap. A Listagem 18.4 apresen ta a im plementao de CardVi ew.
LISTAGEM 18.4

Ca rdV iew.java

.
. *:
i mpor t Javax.
SWlng.
.
t .*;
i mport Java.aw
publiC cla ss Ca rd View ex tends JLabel {
private ImageI con icon;
publi c CardView( VCard card ) I
getImage( card.get Image{) ) ;
setIcon( i con ) ;
setBackground( Colo r.white ) ;
setOpaque( tru e );

pri vate voi d get Image( String name ) I


ja va.ne t.URL url thi s.ge tClass().getResource ( name );
icon new Image Icon( url ) ;

CardVi ew recebe um objeto VCard, extrai o caminho do bitmap, converte O cami nho em uma url,
cri a um ImageIcon e ad iciona o cone em si mesmo. Isso tudo que voc precisa para carregar e
exibi r um bi tmap!

Dia 18

Implementando PI ayerVi ew
PJayerView exibir qualquer subc lasse de pj aye r. Ao contrrio de OptionView, que voc ver na
prx ima seo, pj ayerV l ew s precisa apresentar o objeto PI ayer; ele no aceita interao do
usurio. Como resu ltado, a implementao muito simples. A Listagem 18.5 apresenta o mtodo que chamado quando o objeto PI ayer muda.
LISTAGEM 18.5 O cdigo atual izado de PlayerView
publiC void playerChanged( Player player ) (
border . setTitle( player.getName() ) ;
cards . removeAll();
Hand ha nd player . getHa nd() ;
Iterator i hand.getCa r ds() ;
while(i . hasNext{) ) (
VCard vcard (Vcard) i.next() ;
JLabel card new Ca rdView( vcard l ;
cards.add( card li

I
reval i dateO;
repai nt () i

I
Como voc pode ver, o mtodo pl ayerChangedO extrai os objetos VCard de PJayer e cria um
CardView para cada um . Finalmente, ele adiciona o modo de visualizao em si mesmo, para que
o objeto VCard seja apresentado.
A implementao apresentada aqui no a mais eficiente, pois ela cria um novo CardVi ew para
cada objeto VCard, sempre que o objeto PI ayer muda. Uma implementao mais efic iente poderia usar alguma cache do modo de visualizao. Como voc est usando objetos, pode mudar a
implementao para outra mais eficiente, a qualq uer momento. O desempenho parece estar normal, de modo que a sobrecarga da ad io do uso de cache simplesmente no va le a pena neste
ponto.
Pl ayerVi ew tambm precisa apresentar o resultado do jogo de Pl aye r. A Listagem 18.6 apresenta
dois mtodos que so chamados no fi na l do jogo de Pl ayer.
LISTAGEM 18.6 Um exemplo dos mtodos PJ ayerL i stene r de Pl ayerVi ew
public void pl ayerBusted( Player pl ayer ) (
border.setTitle( pl ayer.getNameO + " BUSTEO!! " )i
card s .repa i nt()i

I
publ i c void pl ayerBlackjack( Player player ) {

Ite rao 4 do jogo vinte-e-um: adicionando uma GUI

LISTAGEM

445

18.6 Um exempl o dos mtodos Player Listener de Pl ayerV i ew (continuao)

border.setTit le( playe r.getNameO + " 8lACKJACK !" );


cards.repaf nt( );

Esses mtodos con fig uram a borda do modo de visualizao com o resullado do jogo. PI ayerListener defi ne mais do que dois mtodos, mas assim como os dois listados aq ui, a impl ementao dos mtodos de PI ayerVi ew segue um padro semelhante para todos. Exam ine o
cdigo- font e, se voc esti ver interessado em ver a lista intei ra de mtodos de atuali zao.

Implementando OptionView e OptionViewController


Opti onView herda de JPanel e acrescenta vrios botes em si mesmo. Opti onV iew no recebe do
modelo. Em vez di sso, Opt i onViewControll er recebe do modelo e ativa ou desativa os botes
em OptionView, conforme for apropriado.
Nenhuma das duas classes muito interessante do ponto de vista da implementao. Se voc estiver interessado nos detalhes especificas, faa download e leia o cd igo.

Implementando GUIPlayer
GU IPI aye r provavel mente a classe mais interessante dessa iterao. Ao implementar uma GUI,
voc deve lembrar que toda interao com o usurio assncrona - ela pode surgir a qualquer
momento.
Escrever um jogador de linha de comando foi muito fcil . Voc s6 teve que sobrepor hl te) ou
bet() para que ele fosse lido da linha de comando. Como a linha de comando fi ca bloqueada at
receber a entrada do usurio, o jogador foi muito fci l de implementar. Um jogador com GUI
um pouco mais dificit de esc rever.
Em vez de chamar um mtodo e bloquear at recebermos a entrada, GU IP layer prec isa esperar
at que o usuri o dec ida cl icar em um boto. Como resultado, todos os estmu los vm de/ora do
jogador.
Em resposta a essa rea lidade, voc precisa adicionar vrios mtodos que a GU I possa chamar
para GUIPl ayer. A Li stagem 18.7 lista os mtodos de aposta que voc deve ad icionar.
LISTAGEM

18.7 Mtodos de aposta de GU I Player

II esses mtodos de aposta sero chamados pe lo controlador da GUI


II para cada um: faz a aposta co rreta, muda o es tado, permite que a
II banca sai ba que o jogador t erminou de aposta r
public void pl acel08et() (
get8an kO . pI ace 108et () ;
setCurrentState( getWaitingState() ) ;

Dia 18

LISTAGEM 18.7 Mtodos de aposta de GUIPlayer (continuao)

dealer.doneBetting( this );

publiC void pla ce50Bet() I


getBank() . place50Bet();
setCurrentState( getWaitingState() );
dealer.doneBetting( this };

pUblic void placelOOBet() {


getBank().placelOOBet();
setCurrentState( getWa i tingState() );
dea l er.doneBetting( th1s );

Voc notar que esses mtodos precisam fazer apostas e configurar o usurio com o estado correto. A Listagem 18.8 li sta os mtodos para receber mais cartas e para parar.
LISTAGEM 18.8 Mtodos para receber mais cartas e para parar de GUIPlayer

II takeCard ser chamado pelo control ador da GUI , quando o jogador


II decidi r receber mais cartas
public void takeCardO {
dealer.hit( thi s );

II stand ser chamado pelo controlador da GUI . quando o jogador optar


II por parar, quando a parada mudar de estado , deixa o mundo saber, e ento
II diz banca
public void stand{) {
setCurrentState( getStand1ngState() l;
notifyStanding();
getCurrentStateO .execute( deale r );

Assim como os mtodos de aposta, os mtodos da Listagem 18.8 devem executar sua ao e atualizar o estado. Como o estado no pode simplesmente chamar hi t () ou bet() para jogar ou apostar, voc precisar fornecer alguns estados Jogo e Aposta personalizados. A Listagem 18.9
apresenta os metodos getPlayingStateO e getBettingStateO sobrepostos.
LISTAGEM 18.9 Mtodos de obteno de estado sobrepostos de GU I Player
protected PlayerState getPlayingState() I
return new Playing();

Iterao 4 do jogo vinte-e-um: adicionando uma GUI

LISTAGEM 18.9

447

Mtodos de obteno de estado sobrepostos de GU IPl ayer (conto)

I
protected PlayerState getBett i ngState() I
return new Betting();

I
Sobrepondo esses mtodos, GUIPlayer pode fornecer seus prprios estados personalizados. A
Listagem 18. 10 apresenta o estado Jogo personalizado de GUIPl ayer.
NOTA

LISTAGEM 18.10

Mtodos como getPlayingState() e getBettingStateO so mtodos faclory.

Estado de Jogo personalizado de GUIPlayer

private class Playing implements PlayerState I


pub l iC void handPlayab l e() I
II no faz nada
I
public void handBlack jack() I
setCurrentState( getBl ackjackState() );
notifyBlackjack ();
getCurrentS t ate().execu te( dea l er );
I
publi c vo i d handBusted() (
setCurrentState( getBustedState() );
not ifyBusted () ;
getCurrentState().execute( dealer };

I
public void handChanged() (
notifyChanged();

I
public void execute( Dealer d ) {
II no faz nada aqui , as aes viro da GUI, que
II externa ao estado, mas quando eventos chegarem. certifica-se de
II impor a transi o de estado imediatamente

I
I

Dia 18

Quando executado, o estado Jogo personalizado no faz nada. Em vez disso, GU IPlayer precisa
esperar pela interao assncrona da GUI. Voc notar que o esradoJogo ainda faz transiesem
resposta aos eventos de Hand.
A Listagem 18.1 1 apresenta o estadoAposla personalizado. Voc notar que esse estado no faz
nada. Em vez disso, GUIPl ayer deve esperar que ojogador pressione algum boto na GUI. Quando

isso acontecer, o boto chamar o mtodo de aposta correto em GUIPlayer.


LISTAGEM

18.11 Estado Aposta personalizado de GUIPlayer

private class Bett1 ng implements P1ayerState {


pub1ic void handChanged() {
II impossvel no estado de estouro

I
public void handPlayab1e () {
II impossvel no estado de estouro

I
publ ic void handBlackjackO {
II impossvel no estado de estou ro

I
public void handBusted{) {
II impossvel no estado de estouro

I
public void execute( Oea l er d ) (
II no faz nada aqui , as aes Vl rao da GUI, que
II externa ao estado, pois nenhum evento vem como parte da
II aposta: o estado precisar ser mudado externamente pa ra este estado

I
I

Reunindo tudo com BlackjackGUI


B1 ackjackGU I cria e ex ibe o sistema de jogo vinte-c-um. A Li stagem 18. 12 deslaca o mtodo
setUpO de Blac kjackGUI.
LISTAGEM

18.12 Mtodo setUpO de BlackjackGUI

private void setUp() {


BlackjackOealer dea1er getOealer():
PlayerView vI getP1ayerView( dealer ) :
GUIPlayer human = getHuman() ;
P1ayerView v2 z getPlayerView( human );
PlayerView [] views { vI , v2 }:

Iterao 4 do jogo vinte-e-um: adicionando uma GUI

LISTAGEM 18.12

449

Mtodo setUp() de BlackjakGUI (continuao)

addPlayers( views )i
dealer.addPlayer( human li
addOpt ionV iew ( human , dea ler )i
}

o mtodo setupO cria cada jogador, os modos de visualizao e coloca tudo junto. Os outros
mtodos principalmente constroem os vrios objetos. Se voc estiver interessado no cdigo-fonte completo, exam ine o cd igo. A Figura 18.9 ilustra a tela fina l do jogo.

FIGURA 18.9

;/ GVI dojogo
,ill/e-e-lIl11.

Resumo
Hoje, voc viu o padro MVC aplicado a um programa rea l. s vezes, ajuda ver um exemplo estendido, para poder entender completamente um padro. A lio de hoje tambm apresentou a
questo de que uma GU I no algo a ser pensado posteriormente. A GUI merece o mesmo nvel
de anlise e projeto que qualquer outra parte de um sistema.
A lio de hoje conclui o jogo vinte-e-um. Amanh, voc ver um projeto e implementao alternativos da GUI do jogo vinle-e-um .

Dia 18

Perguntas e respostas
P Voc mencionou anteriormente que no deve simplesmente anexar a GUI no final.
Bcm, essa foi a ltima iterao e estamos adicionando uma GUI . Isso no vai contra
o que voc disse anteriormente?

R No, absolutamente, no !
Quando dissemos ' anexar', queramos dizer adicionar uma GUI sem realizar qualquer
projeto. Ns planejamos uma GU I desde o incio. No comeo, dissemos que poderamos
usar MVC. Esse foi todo o projeto que prec isamos realizar, at estarmos fin a lmente
prontos para adicionar a GUI. Uma vez prontos para ad icionar a GU I, fizemos mais um
projeto, em uma iterao totalmente dedicada GUI.
Dizer anteriormente que usaramos MVC e adicionar um mecani smo observador era
tudo que prec isvamos fazer para saber que pudesscmos s uportar uma GU I.
P Onde/quais esto/so as diferentes partes do MVC (encontramos meno de vrios
modos de \'is ualizao e de um controlador)? Desenvolva o que so o modelo e o
controlador.

R O modelo o sistema. Neste caso, Bl ackjackOea l er, BettingPl ayers etc., consti tuem a
camada do modelo.
O projeto pedi u apenas um contro lador mu ito a dizer sobre controladores.

Opt "i onViewCon t rol l er -

assim, no havia

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as res postas no Apndice A, " Respostas".

Teste
I. Como voc usou herana e polimorfismo para introduzir uma carta " vi sual"?
2 . Na lio sobre herana, foi mencionado que, se um mtodo no necessrio para as classes externas e no exi stem requisitos para uma subclasse usar o mtodo, ento voc deve
defini-lo como privado. Se uma subc lasse precisar dele, voc pode torn-lo protegido
nesse momento, mas no anteriormente. Encontre um exemplo dessa recomendao no
projeto do jogo vinte-c-um .

Ite rao 4 do jogo vinte-e-um: adic ionando uma GUI

451

Exerccios
I. Faa downl oad do cdigo-fonte da iterao de hoje. O cd igo est dividido em dois direlrios separados: mvc_9u i e exercise_2.
mvc_gui contm o cd igo da GUI que foi criada durante a iterao de hoje.
exerci se_2 contm os arqu ivos que voc precisar para o Exercc io 2, ass im como as solues.
Estude o cd igo cm mvc gui. Tente entender como tudo func iona e depois complete o
Exerccio 2.
2. O Exerccio 2 do Captulo 17 pediu para que voc adicionasse o recurso de apostar em dobro no j ogo vi nte-e-um. Voc precisa adicionar esse recurso no jogo novamente. Desta
vez, ad icione-o na versao grfica do jogo que voc carregou por downl oad para o Exerccio I. O download inclui lodosos arquivos que voc precisar para comear este exerccio.

SEMANA

DIA
Aplicando uma alternativa ao MVC
Ontem, voc ana lisou, projetou e implementou uma GUI para o jogo vinte-e-um. Hoje, voc vai
usar uma outra estratgia para o projeto e implementao da OUI.
l-laje voc aprender:

Sobre uma alternativa para o padro de projeto MVC

Co mo apl icar uma OU I altemat iva no jogo vinte-c-um

Quando basear s uas QUIs no MVC e quando no fazer isso

Uma GUI alternativa do jogo vinte-e-um


Ontem, voc criou uma OUI para o jogo viIHe-e-urn baseada no MVC. O MVC apenas uma estratgia para o projeto de GU I. Hoje, voc va i reprojetar e reimplementar a GU [, usando uma estratgia diferente.
A estratgia que voc vai empregar hoje uma especializao do padro de projeto PAC (Presellfalioll Absfraclion Con/rol). Assim carnoo padro de projeto MVC, o padnl0 de projeto PAC
divide o projeto da GUI em trs camadas separadas:

A camada de apresentao, que exibe o sistema

A camada de abstrao, que representa o sistema

A camada de controle, que monta todos os componentes da camada de apresentao

Dia 19

As semel hanas do PAC com o padro de projeto MVC so ilusrias. Na verdade, o PAC segue
uma fi losofia totalmente di ferente daquela seguida pelo padro MVC.

As camadas do PAC
A camada de abstrao do PAC semel hante camada de modelo no padro MVC. A camada de
abstrao abriga a func ionalidade bsica do sistema. essa funcionalidade que a camada de
apresentao exi be e manipula. A camada de abstrao tambm responsvel por dar acesso aos
objetos do nve l de apresentao.
No PAC, as funcionalidades das camadas de visua lizao e controladora do MVC no so dividi das; cm vez disso, essas duas entidades so combinadas dentro da apresentao. A camada de
apresentao responsvel por exib ir e manipular a camada de abstrao, assim como por responder interao do usurio.
Corno o comrole e o modo de visualizao MVC so combi nados na camada de apresentao, o
controle tem um objetivo totalmente diferente no PAC. No PAC, o controle monta todas as diferemes apresentaes. Ele no recebe e responde interao do usurio, corno o controlador MVC.

A filosofia do PAC

o MVC faz todo o possvel para desacoplar completameme cada parle de seu projeto. Quando
voc lisa o padro MVC, fcil trocar para novos modos de visual i7..aoem seu sistema, a qual quer momento; assim, usaro padro MVC proporciona a voc muita liberdade sobre como exibe
seu sistema. Entretanto, o Captulo 13, "00 e programao de interface com o usurio", informa
que a maior liberdade tem o preo do encapsulamento.
A estratgia do PAC diferente. O PAC no desacopla as camadas de apresentao e abstrao.
Em vez disso, as duas camadas so forte mente acopladas. Isso no quer dizer, por exemplo, que
PI ayer estender JComponen t diretamente . Isso quer di zer que a camada de abstrao criar e retornar sua apresentao. Assim , PI ayer e sua apresentao ai nda so dois objetos separados.
Para obter uma aprese ntao diferente de uma parte da abslrao, voc prec isar al terar a defini o da abstrao para que ela relorne um objeto de apresentao d iferente. um pouco mais d ifiei l alterar a apresentao ou fornecer dois ou mais modos de visua lizao difere ntes do mesmo
sistema.
A construo da GU I mais fci l, entretanto. Quando a camada de controle montar a tela, ela solicitar a cada membro da camada de abstrao sua apresentao. Tudo que a camada de controle
precisa fazer adicionar essa apresentao na tela principal. No h modo de visual izao e controlador para reuni r.

Aplica ndo uma alte rna tiva ao MVC

Quando usar o padro de projeto PAC


A suposio s ubjacente do PAC que voc no precisar fornece r vrios modos de visua lizao
do sistema. Em vez disso, quando usa o PAC, voc precisa cert ifi car-se de que o sistema tenha
apenas uma interface bem definida. Se seu sistema vai ter apenas uma interface, o PAC pode fornecer uma alternativa mu ito elegante ao MVC.

O PAC tem vrias vantagens. Como a camada de abstrao pode criar sua apresentao, voc
no precisa destrui r o encapsulamento de seu sistema. Em vez disso, voc pode defini r as classes
de apresentao como classes internas. Como lima classe interna, a apresentao pode ter talai
acesso a s ua classe de abstrao progeni tora. Quando ela precisa visualizar a abstrao, pode
acessar e exibir diretamente o estado da abstrao.

O uso de PAC si mpli fi ca a comun icao entre a apresentao e sua abstrao. Quando a abstrao mudar, ela pode simplesmente chamar um mtodo de atua lizao na apresentao que tiver
criado.
Quando voc usa o padro PA C, pode considerar a apresentao como urna extenso direta da
abstrao. Atuando na apresentao, voc atua d iretamente no sistema s ubjacente. De certa fo rma, a apresentao age de forma muito parecida com um proxy para o sistema. Tal manipulao
direta simplifica muito o projeto global.

Analisando a GUI PAC do jogo vinte-e-um


Para aplicaro padro de projeto PAC na aUI do jogo vinte-e- um, voc pode simplesmente reuti liz.1r a anlise que fez ontem. Nada muda quanto anlise, pois voc decide usar o padrJo PAC
em vez do MVC.

Projetando a GUI PAC do jogo vinte-e-um


Para o jogo vinte-e-um ex iste apenas uma interface principal: uma aU I. Voc no vai distribu ir
esse jogo como um ap licativo HT ML da Web (embora voc pudesse transform- lo em um applet
fac ilmente) ou como um POA; assim, seguro usar o padro de projeto PAC.
,

E importante notar que nada o obriga a remover os mecanismos receptores que j construiu no
sistema. Ainda possvel ter uma aUI baseada em linha de comando e uma aU I baseada no
PAC, simultaneamente. Na verdade, atravs do uso cuidadoso de subclasses, voc pode deixar
Iodas asdefin ies de classe originais intactas. Quando voc quiser uma aU I, pode si mplesmente instanciar as classes que suportam uma OUI. Quando voc quiser um jogo de linha de comando. pode instanciar as classes ant igas. Escolher MVC ou PAC no o impede necessariamente de
usar o outro.
Assi m como no Capitulo 18, " Iterao 4 do j ogo vinte-e-um: ad icionando uma aUI", voc pode
pegar o projeto e implementao completos do Capitulo 17, " Iterao 3 do jogo vinte-e-um: adi-

Dia 19

cionando aposta", como base para a nova GU I. O que voc precisa fazer descobrir q ua is dessas
classes precisam de seus prpriosobjetos de apresentao. Quando voc tiver essas classes identificadas, precisar projetar a camada de abstrao. Q uando isso estiver fei to, voc poder projetar a camada de controle.

Identificando os componentes da camada de apresentao


Para identificar os componentes da camada de apresentao, ajuda fazer alguns esboos da GU I.
Desta vez, voc deve associar partes da tela classe subjacente, em vez de associ-Ias a um
modo de vis ualizao separado.
A Figura 19.1 isola uma part e da GU I. Dissecando cui dadosamente esse segmento da tela, voc
pode identifica r alguns componentes da apresentao.

FIGURA 19. 1

Um .egmelllo
da tela.

Jogador

M'o
,
--- .\
-Noma
- - L - - - - - -,
, ,,- __
,
, ,
,, , r rta r
,
,
,, ,r ____
,
---- - - - -,
Carta

:8 :D:

,
,,
,
,

,,
,

~ -- ------ ----------

Dividi ndoo segmento da tela em partes, voc pode ver que Card, Ha nd e Player precisal""ao fornecer objetos de apresentao. A Figura 19.2 d isseca a parte restante da te la.

FIGURA 19.2

Os botes (/(1 GUI.

Jogador

----~--------------- ,,

Hit

USS10

II

II

US$50

Stand

II

New

US0100

Gam,ll

Quit

-- ------ -- ----------Todos OS botes pertencem ao objeto Player humano; portanto, a classe que representa o jogador humano prec isar estender a apresentao de PI ayer e adicionar botes. GU IP l aye r deve ter
um projeto igual q uele criado para o Captulo 18. Em vez de repetir esse projeto aqui, volte e
leia a seo " Implementando GUI Player" , no Captulo 18, se voc precisar de um lembrete. A

Aplica ndo uma alternativa ao MVC

nica d iferena entre a GUIPlayer do Captulo 18 e esta q ue esta tambm fornecer uma apresemao de si mesma.

Projetando os componentes da camada de abstrao


Na seo anterior, voc identificou Card, Hand e as diversas subclasses de PI ayer necessrias
para fornecer uma apresentao delas mesmas.
Para cada uma dessas classes, voc precisa criar uma subclasse de abstrao. Em part icular, voc
prec isa ter uma subclasse de BlackjackOeale r, BettingPlayer, Hand c Ca rdo Alm di sso, voc
precisa criar uma GUIPl aye r, como no Captulo 18. Entretanto, essa GUI Pl ayer tam bm precisa
fornecer uma apresentao.
A Figura 19.3 ilustra a hierarquia de herana Player res ultante.

19.3
A hierarquia
dI! abslra(io
FIGURA

PlIly9r

Pla)'er
(Jogador) .
81acJcjacJcOeala

BettingPlllyer
JPanal

VBlockjackPlayer

JPanel

V8ettingPlsyer

cria

, ,

tria

OealerView

GUIPlayer cria

BettingView

,
,

tontm

GUIVllJw

,~,~

Voc precisa criar uma s ubclasse VBlackjackDealer BlackjackDealer. Voc tambm preci sa
criar uma s ubclasse VBetti ngPl ayer Bett i ngPl ayer. Essas s ubclasses adicionaro s uporte para
criar e retornar objetos de apresentao.
A Figura 19.4 il ustra as hierarq uias Hand e Car<! resultante.

Dia 19

FIGURA 19 .4

A hierarquia de absrra(io
Hand (Meio) e

Card (Ca,.w).

JllI bel

J llIbel

Voc precisar criar lima subclasse YCard Card, assim como um a subc lasse VHand Hand. Essas

subclasses visualizaro Card e Hand, respectivamente. Como no projeto de ontem, voc tambm
precisa de um VDeck. O VDeck criar um mao de objetos VCard .

Projetando a camada de controle


O controle uma classe relativamente simples. Uma instncia do controle recuperar um objeto
VBla ckjackOea le r, assim como os vrios jogadores. De cada um desses objctos, o controle soli citar um objeto de apresentao. O controle pegar esse objeto de apresentao e o ad icionar
na ex ibio.
Voc precisar projetar um mecanismo que o console possa usar para solicitar camada de abs-

trao a apresentao de seus objetos. A estratgia mais fcil defin ir uma interface - vamos
cham-la de Di sp' ayab 1e. Di sp 1ayab I e tem um mtodo: pub I i c JComponen t vi ew (), que recupera a apresentao de um objeto. Cada classe de abstrao que fornece uma apresentao precisar implementar esse mtodo.
As figuras 19.5 e 19.6 mostram as hierarquias alual izadas. Agora, as classes de abstrao percebem a interface Displayable.

Usando o padro Factory para evitar erros comuns


Existe um pequeno problema na hi erarqu ia resultante: nada o impede de criar um objeto Deckpi1e de objctos Card que no possam ser ex ibidos e pass-los para a banca. Os relacionamentos
com capacidade de substituio permitem tal substituio. Infelizmente, voc experimentar erros de tempo de execuo, se misturare com binar as classes GU I e no-GU I incorretamente.
O Capitulo 12, "Padres avanados de projeto", apresentou o padITio de projeto Abstract Factory. Um motivo para usar esse padro era para garantir que um conjunto de objetos fossem usados juntos. Isso o impede de usar objetos incompatveis juntos.

Aplica ndo uma alte rnativa ao MVC

459

FIGURA 19 .5

A hierarquia de
absfratio Pl ayer
alllali:ada.

BllICkjackDealer

8ertingPfayer

Displayab le
vi!Wf}:JCompot1enr

VBlackjackPlayer

JPanal

V8ertingPIByer

8otringViow

cria

DealerView

GUIPlayer

,
,

conlm

cria=-_~~~~~

Mio

FIGURA 19 .6

A hierarquia de
abslrac70 Hand e
Card allfali: ada.

VCard

JLebel

conlm

JLlbel

t..__{C~'~'d~V~"~W}.__~oo=nlm HandView

Voc pode usar factory para garanl irque os objelos correiOS sejam usadosjunlos. Voc precisar
criar factory que retome um objeto VBl ackjackOeal er e um objeto GUIPlayer que tenham sido
instanci ados com os tipos corretos de argumentos. Quando o controle for recuperar os jogadores
e a banca. ele dever fazer isso apenas atravs de factory. Essa camada extra garantir que todos
os objetos sejam instanciados corretamente.

Dia 19

Implementando a GUI PAC do jogo


vinte-e-um
A lio de ontem mostrou que, ao se implementar uma GU I, freqUentemente mais fcil trabalhar de cima para baixo. Segui ndo essa recomendao, voc deve implementar na seguinte ordem : VCard, VHand, VBettingPlayer, VBlackjackGUI e GUIPlayer. Vamos examinar cada
implementao.

Implementando VCard e VHand


VCard herda de Card e se representa atravs da classe interna: CardView. A Li stagem 19.1 apresenta a imp lementao de VCard.
LISTAGEM 19.1

VCard. java

public class VCard extends Card implements Oisplayable {


private String image;
private CardView view;
publiC Vcard( Suit suit. Rank rank . String image ) (
supere su i t. rank ) ;
this.image image;
view new CardView( getImageO );
J

publiC void setFaceUp( boolean up ) (


super.setFaceUp( up );
vi ew. changed O;
J

public JComponent view() (


return view;
J

private String getlmage() (


if( isFaceUp() ) (
return image;
) else {
return M/bitmaps/ empty_pile.xbm-;

J
J
private class CardView extends Jlabel {

Aplicando uma alternativa ao MVC

LISTAGEM 19.1

46 1

VCard.java (continuao)

publiC Ca rdView( String image ) I


setlmage( image )i
setBackg round( Co l or.white li
setOpaque( true );
J

public void changed() {


se tI mage( get lmage() )j
J

private void set lmage( String image ) {


java . net.URL url z this .getClass().getResource(image l i
Imagelcon icon new ImageIcon(url l i
se tI con( icon l:
J
J
J

Essa implementao de VCard muito parecida com aquela apresentada anlerionnente, com exceo da classe de apresentao interna. Na criao, VCard cria e contm um modo de apresentao de si mesmo.
Voc tambm notar que o novo atri bula agora fica completamente encapsulado dentro de

VCard . Para lima entidade externa exibir a imagem, ela precisa solicitar um modo de visualizao
a VCard. Alm disso, quando a carta virada, VCa rd diz automaticamente ao seu modo de apresentao para que se atualize, chamando changed () no modo de visua lizao. Ao contrrio do
padro MVC. todo o controle mantido dentro da prpria abstrao.
VHand semelhante a VCard. Na cri ao, VHand cria um modo de apresentao de si mesmo. A
Listagem 19.2 apresenta a implementao de VHand.
LISTAGEM 19.2

VHand. java

pub l i C cl ass VHand extends Hand implements Displayable {


private HandV iew view new HandV iew()i
pub 1i c JComponent vi ewO {
return view ;
J

II voc precisa SOb repo r addCa rd e reconfigurar para que quando a


II al terao se propague para o modo de visualizao

~o

mudar, a

Dia 19

LISTAGEM 19.2 VHand.java (continuao)


public void addCard{ Ca rd card ) I
super.addCard( card );
view.changed();
J

public void reset() (


super . reset () ;
view.changed();
J

private class HandView extends JPanel (


public HandView () (
super{ new Fl owLayou t(FlowLayout . LEFT ) ,;
setBackground{ new Color{ 35 . 142. 35) ,;
J

publiC void ch anged() (


removeAll ();
Iterator 1 getCards O;
while{ i.hasNext() ) (
VCard card (Vcard) i .next() ;
add( ca rd . view() ,;

J
revalidateO;

J
J
J

Assim como VCard, VHand diz ao seu modo de visualizao para que se atualize quando VHand
mudar.

Implementando VBetti ngPl ayer

o conceito por trs de VBet ti ngPl ayer o mesmo de VHa nd e VCard. A Li stagem 19.3 apresenta a
im plementao de VBett i ngPl ayer.
LISTAGEM 19.3 VBettingPlayer.java
publi c abstract class VBettingPlaye r extends BettingPlayer imp lement s
Disp layabl e (
private BettingV1ew v1ew;
publi C VBettingPlayer( String name, VHand hand, Bank bank ) {

Aplica ndo uma alte rnativa ao MVC

LISTAGEM 19.3 VBettingPlayer.java (continuao)


supere name. hand. bank )i
}

publi c JComponent view() {


if(view z. null ) I
view new BettingView( (VHand)ge tHand() );
addLi stener( view ) ;
}

return view ;
}

pri vate class BettingView extends JPanel implements Pl ayerListener I


private TitledBorder border ;
public BettingView( VHand hand ) {
supere new FlowLayout( Fl owLayou t. LEFT ) ) :
buildGU I( hand.view() );
}

pub l ic void playerChanged( Player p ) {


St r ing name VBettingPl ayer.this.getName():
border.setTille( name );
repaint()i
}

publi c void playerBusted( Playe r p ) {


String name VBettingPlayer. t his.getName() ;
border . setTitle( name + BUSTED!!") i
repaint():
M

II o resto dos mtodos PlayerListener foi cortado por brevidade


II todos eles seguem o mesmo pad ro : vej a a listagem completa no
II cdigo-fonte
private void bUildGUI( JComponent hand ) {
border new TitledBorder{ VBettingPlayer.this.getName() ) ;
setBorder( border ) i
set8ackground( new Color( 35 . 142 . 35 ) ) :
border.setTitleCol or( Col or.b l ack ) ;
add( hand ):
}
}
}

Dia 19

VBetti ngPl ayer cria seu modo de visualizao e o configura como um receptor. Quando o jogador muda, o modo de visualizao sabe atualizar-se automaticamente. De interesse o mtodo
bUl l dGUI (). O mtodo bu i IdGUI () configura o modo de visualizao.
Voc notar que, em vez de pegar cada carta na mo e constru ir um modo de visualizao, Bet-

t i ngV iewsimplesmente pega o modo de visualizao de VHand e o insere em si mesmo. VHand gerenciar a exibio das cartas. Tudo que Bett i ngView tem de fazer inseri r o modo de
visua lizao em si mesmo e manter o status do ttulo atualizado.

Implementando VBl ackjackDea 1er


VB I ackjackDeal er funciona exatamente como VBett i ngPI ayer. A Listagem 19.4 aprese nta a impl ementao de VBlackjackDea l er.
LISTAGEM 19.4

VBlackjackOealer . j ava

pub l ic class VBlackjackDealer extends BlackjackOealer implements Oisp l ayabl e {


private Oea l erView view;
pub l iC VBlackjackDeale r ( String name , VHand hand , Oeckpile ca rds ) {
supere name , hand , ca rds );
J

publi c JComponent view() {


if( view nul l ) (
view new Oea l erV iew( (Vhand) ge t Hand() }:
addL i stener( view l i
E

return viewi
J

private TitledBorder border i


public DealerView( VHand hand ) {
supere new Flow Layout( Fl owLayou t.L EFT ) ) i
String name VBlackjackOealer.this.ge t Name() ;
borde r new TitledBorder( name l :
setBorde r ( borde r );
setBackground( new COlor(35 . 142. 35 ) );
border.set TitleColor( Color.bl ack ) ;
add( hand.view() li
repaintO:
J

publ ic void playerChanged( Pl ayer p } {

Aplica ndo uma a lte rna tiva ao MVC

LISTAGEM 19.4

VBlackjackOea l er . java (continuao)

String name z VBlackjackDealer.this.getName();


border.setTitle( name ):
repaintO;
}

public void playerBusted( Player p ) {


St ring name VBlackjackDea l er.this .getName();
border.setTitle( name + ~ BUSTEO!!" };
repaintO;
}

II o res to dos mtodos Playerlistener foi cortado por brev i dade


II todos eles seguem o mesmo padrao : veja a listagem completa no
II cdigo- fonte
}
}

Dea 1erVi ew recebe as alteracs cm vaI ackjackDea 1er. medida que essas alteracs ocorrem,
o modo de visualizao atualiza seu ttulo. VHand cuida de manter o modo de visual izao da carIa alualizado.

Implementando GUIPlayer
Todos os aspectos no relativos a GU I da classe GUIPlayer so iguais queles apresentados ontem. Assim como as outras classes da camada de abstrao, GUIPlayer defi ne urna classe de
apresentao interna.
Essa classe com bina as classes Opt i onVi ew e Opt 1onV i ewCont ro 11 er do Captulo 18. O cdigo de
apresentao no to diferente das classes de modo de visualizao e controle originais. Para
ver a listagem completa, faa download do cdigo-fonte do dia de hoje, no endereo www.samspublishing . com.

Reunindo tudo com o Controle


A ntes de criar o controle, voc precisa criar uma factory de jogador. A Listagem 19.5 apresenta a
implementao de VPl ayerFactory.
LISTAGEM 19.5

VPlayerFactory.java

public cla ss VPlayerFactory I


private VBlackjackDealer dealer;
private GUIPlayer human;
private Deckpile pile:

Dia 19
LISTAGEM 19.5 VPlayerFactory.java (continuao)
publiC VBlackjackDealer getDealer() {
II cri a e retorna apenas um
;t( dealer null } (
VHand dea ler_hand = getHand() ;
Deckpi l e cards z getCards();
dealer new VBlackjackDealer( "0 ea l er R. dealer_hand . cards }:
}

return dealer:
}

publiC GUIPlayer getHuman() (


II cr ia e retorna apenas um
if( human a. null ) (
VHand human_hand ~ getHand() ;
Bank bank new Bank( 1000 );
human new GUIPlayer( "Human". human_hand . bank. getDealer()}:
}

return human;
}

pub l i C Deckpile getCards() {


II cria e retorna apenas um
if( pile null } (
pile new Oeckpi l e();
for( int i O; i < 4; i ++) (
pil e.shuffleO ;
Oeck deck = new VOeck() ;
deck.addToStack( pile ) ;
plle.shuffleO;
}
}

re tu rn pile ;
}

private VHa nd getHand() (


return new VHand():
}

VPlayerFac t ory garante que VBlackjackOea ler e GUI PI ayer sejam inslanciados corretamenle. A
Listagem 19.6 apresenta o mtodo setu p () de BlackjackGUI: o controle.

Aplica ndo uma alternativa ao MVC

LISTAGEM 19.6 O

467

mtodo setUp() do contro l e BlackjackGUI

public class Blackj ackGU I extends JFrame {

II CORTE !! parte do cdigo omitido por brevidade


private JPanel pl ayers

new Jpanel( new Gridlayout( O, 1 ) )i

private void setupO {


VBlackjackOealer dealer

factory.getOealer();

GUIPlayer human facto ry.getHuman():


dealer . addPlayer( human );
players.add( dealer.view() );
pl ayers.add( human.view() ) ;
getContentPane().add( players, Borderlayout.CENTER );

I
I
setUp () simplesmente recupera cada jogador, adiciona seus modos de vi sualizao em si mesmo e
conecta a banca aos jogadores. Compare isso com a Listagem 19.7, o mtodo setup() de ontem.
LISTAGEM 19.7 O

mtodo setUp() de MVC BlackjackGU I

priva te voi d setUpO {


Blackj ackOeal er dealer getOea ler () ;
PlayerView vI getPlayerView( dealer );
GUIP l ayer human getHuman();
PlayerV i ew v2 getPlayerView( human );
PlayerView [] views - { vI, v2 );
addPlayers( views ) ;
dea l er.addPlayer( human );
addOptionV i ew( human , dealer li

I
Parece que simplesmente solicitar um modo de visualizao da abstrao muito mais simples
do que criar e juntar os vrios modos de visualizao da verso MVC.

Dia 19

Resumo
Hoje, voc viu uma alternativa ao MVC. Se seu sistema re lat ivamente estvel e tem uma UI
bem defin ida, a estratgia PAC pode oferecer uma soluo mais elegante do que o MVC.
Mesmo que voc precise suportar vrias interfaces, a lio de hoje mostra como possvel usar
herana para separara camada de abstrao da funcionalidade bsica do sistema. Assim, para suportar vrias interfaces, voc precisa apenas criar uma subclasse para cada ti po de apresentao.

Perguntas e respostas
P Se o PAC oferece lim a escolha melhor, por qu e fizemos a implementaio MVC ?
R O PAC simpl esmente ofe rece uma alternativa. Uma no necessariamente melhor q ue a
outra. Trata-se apenas de uma deciso de projeto.
O rato que voc encontrara o MVC em muitas implemen taes. Voc pode encon trar o
PAC, mas mui to menos provve l. Assim , abordar o MVC pri meiro mai s prtico. Pes
soalmente, tendemos a privilegiar o PAC.
Tenha as duas opes em mente. O que voc nunca quer fazer codificar sua lgica corporativa (classes como BettlngPl ayer) diretamente como um componente da GUI. Por
exemplo, Bett i ngPl aye r nunca deve estender JComponent (ou algum outro componente
da GUI) diretamente. O MVC e o PAC fornece m um mecanismo que evita mi sturar seu
modelo e a GU I. Os padres apenas adotam estratgias diferentes. O que voc escolhe
depende de seu projeto e de sua eq ui pe de projeto.

Workshop
As perguntas e respostas do teste so fornecidas para seu melhor entendimento. Veja as respos
tas no Apndice A, " Respostas".

Teste
I. Quais so as trs camadas do padro de projeto PAC?
2. D uma breve descrio de cada uma das camadas do PAC.
3. Como voc pode usar herana para desacoplar a OUI das c lasses de sistema subjacentes?
4. Antes de usar o PA C, quais caractersticas seu projeto deve exibir?
5. Mesmo que voc usasse PAC portada esta lio, como ainda poderia fornecer uma UI de
linha de comando para o sistema?
6. Como o padro factory foi usado neste captulo?

Aplica ndo uma a lte rnativa ao MVC

Exerccios
I. Faa download do cd igofonte da iterao de hoje. Quando voc ti ver a cd igo, com pi
le-o, faa-o fu nc ionar executando 81 ackj ackGUI e, depoi s, tente entender como ele fu nci
ona. Ter um entendimento talai do cdigo ex igir algum tempo e pacincia.
2. O Exerccio 2 do Captulo 17 pediu para que voc acrescentasse aposta em dobro no jogo
vi nlecum. Voc prec isa adicionar aposta em dobro no j ogo novamentc. Desla vez, adicione-a na verso grfi ca do jogo que voc carregou pordownl oad para o Exerccio 1.

SEMANA

DIA
Divertindo-se com o jogo
vinte-e-um
Nos himos dias, voc trabalhou em um projeto de POO bastante intenso. Hoje, voc vai dar o
troco e se divertir com o jogo vinte-c-um, usando polimorfismo para adicionar vrios jogadores
no-humanos ao j ogo. Voc tambm ver como a 00 se presta para faze r simuladores.
Hoje voc aprender como pode:

Usar polimorfismo para adic ionar jogadores no j ogo vinte-e-um

Usar 00 para criar simuladores

Divertindo-se com o polimorfismo


o jogo vinte-c-um

possibi lita que at sete jogadores joguem em determinado momento. At


agora, o j ogo que voc criou inclua apenas um jogador humano e a banca. Fel izmente, Opolimorfismo permite que voc adicione jogadores no-humanos no jogo.

Criando um jogador
Para criar um novo jogador no-humano, basta criar uma nova classe que herde de Betti ngPlayer. Tudo que sua nova classe precisa faze r e implementar os dois mtodos abstratos a seguir:

I 472

Dia 20
public boo l ean hit()
pub lic void bet()

o componamento que voc fornecer para esses dois mtodos delenni nar como o jogador jogar na sua vez. Voc no presar alterar quaisquer estados ou sobrepor quaisquer outros mtodos. Os estados padro sabem corno usar os mtodos que voc im plementa.
Quando voc tiver acabado de defi nir a nova classe de jogador, pode alterar B1 ackjackGUI para
criar o jogador e ad icion-lo no jogo.

o jogador seguro
Vam os criar um novo jogador: SafePl ayer. SafePl ayer nunca recebe mai s cartas e sempre aposta a menor quantia permitida. A Listagem 20 .1 apresenta a definio de SafeP1 ayer.
LISTAGEM

20.1 SafeP1ayer . ja va

pub li c cla ss SafePlayer exte nd s BettingP1ayer {


pub l iC SafeP1ayer( String name , Hand ha nd, Bank bank ) {
supere name , ha nd, bank ) ;
}

public boolean hit() {


return false ;
}

publiC void bet() {


getBank().p l ace l OBet() ;
}
}

Voc notam que hi t () sempre retorna fal so; SafePlayer nunca receber mais canas. Do mesmo
modo, Sa fePlayer sempre chama place l OBet O.

Adicionando SafePlayer na GUI


Adicionar Sa fePl ayer no jogo relativamente si mples. Primeiro, adic ione o seguinte mtodo em
BlackjackGUI:
LISTAGEM

20.2 O mtodo getSafePlayer()

private Player getSafePlayerO {


II retorna o quanto for sol i citado
Ha nd safe_hand new Hand();
Bank sa fe_bank new Bank( 1000 ) ;

Divertindo-se com o jogo vinte-e-um

LISTAGEM 20.2

mtodo getSafePlayerO (con t inuao )

return new SafePl ayer ( MSafe", safe_hand , safe bank );

getSafePl ayer O um mtodo factory que instanci a objetos Sa fe Pl ayer. Quando voc ti ver o
mtodo, pode atualizar se tUp() para que ele adicione o novo jogador no jogo. A Listagem 20.3
apresenta o mtodo se tU pO atualizado.
LISTAGEM 20.3 O

mtodo setUp() atualizado

priva te void se tUp() {


BlackjackDealer dealer getOea ler( ) ;
PlayerVi ew vI getPlayerView( deale r ) ;
GUIPlayer human getHuman() ;
PlayerView v2 getPlayerView( human ) ;
Player sa fe getSa fePlaye r ();
Pl ayerView v3 getPlayerView( safe );
K

PlayerV i ew {J views z I vI , v2, v3 };


addPl ayers( views );
dea ler.add Playe r( human );
dealer.addPlayer( sa fe );

addOptionView( human, dea l er );

Voc tambm desejar alterar o mtodo principal da GU I, para que ele torne ajanela um pouco
maior, a fim de que o novo jogador possa caber. A Fi gura 20.1 ilustra o novo jogador, conform e
ele aparece na GUI.
Aqui, o jogador adi cionado corno um segundo jogador que joga aps o ser hum ano. Nada o impede de deixar que o jogador no-humano jogue primeiro.

Aperfeioamento
Voc pode ad icionar qualquer nmero e tipo de objeto Bett; ngPl ayer no jogo. Quando o nmcro de opes de jogador ficar maior, tal vez voc queira fornecer ao usurio uma caixa de dilogo
que permita configura r a mistura de jogadores. No mnimo, voc desejar tornar o mtodo
setUpO protegido, para que subclasses possam sobrepor o mtodo. Quando protegido, voc
pode escrever subclasses que criem jogos com diferentes misturas de jogadores.

Dia 20
FIGURA 20 .1

A CUI comeI/do Irs

jogadores.

POO e simulaes
Confonne mencionado em uma lio anterior, quando voc escreve um sislema de POO, na verdade est escrevendo um simulador vivo de algum problema real. Nesla semana, voc escreveu
um sistema que sim ula o jogo vinte-e-um .
Al aqui , o jogo lem sido centrado em um jogador humano. Voc quer uma pessoa com a qua l
possa jogar o jogo, embora o sistema no se preocupe se h um ser humano jogando ou no. Para
o sislema, todos os jogadores so objetos Plilyer. O sistema cuida apenas que existam objetos
Player.

Criando di feren tes tipos de jogadores e adicionando-os ao sistema, voc pode ter um jogo vinte-c-um que jogue sozinho, se m interao humana: um si mulador do jogo vinte-e-um.
Um simulador do jogo vinte-e-um pode ser til por vrios motivos. Ta lvez voc qui sesse criar
jogadores que util izassem diferentes estratgias para ver quais delas func ionam melhor.
Talvez voc esteja fazendo pesqui sa de IA e queira escrever uma rede neural que aprenda ajogar
perfeitamente um jogo vinte-e-um. Voc pode usar um simulador do jogo vinte-c-um para atingir todos esses objetivos.
No capt ulo e nos exerccios de hoje, voc vai criar vrios jogadores para sabcrse pode ganhar da
banca com o passar do tempo.

Os jogadores do jogo vinte-e-um


Voc j viu um objeto SafePlayer. Ser interessante ver como ele se desempenha com o passar
do tempo. Alm de SafePl ayer, vamos defi nir:

Divertindo-se co m o jogo vinte-e-um

FlipPlayer: um j ogador que alterna entre receber mais cartas e parar.

OneHaplayer: um jogador que sem pre recebe mais cartas a cada vez.

SmartPl ayer: um jogador que

NOTA

para com qualquer mo maior do que

I I.

Voc pode notar a falta de casos d e uso para esses jogadores. Como exerclcio,
talvez voc queira trabalhar nos casos de uso para os jogadores. Entretanto,
um principio deste livro t em sido realiza r apenas a quantidade de anlise que
f aa sentido e valorize seu entend imento do problema. Em nossa opinio, os
casos de uso no ajudariam no seu entendimento neste caso e pareceria mais
com a cri ao de documentao simplesmente.

Implementando FHpPlayer
A implementao de Fl i pPl ayer um pouco mais complicada do que a de SafePl ayer. A li stagem 20.4 apresenta a implementao de Fl i pPl ayer.
liSTAGEM

20.4 FlipPlaye r . ja va

publi c cl ass FlipPlayer extends BettingPlaye r (


private boolean hit false;
private boolean should_hit_once : false;
pub l ic Fl ipPlayer ( String name , Hand hand, 8ank bank ) (
super( name , hand, bank ) ;
}

public boolean h1t() (


if( should_hit_once &&l hit ) {
hit .. true;
return true;
}

return false;
}

publiC yo i d resetO (
supe r. reset() ;
hit fal se;
should hit once = lshould hit once ;
}

pub l ic yoid bet() I


getBank().pl acelOBet()i
}
}

Dia 20

F1 i pPl ayer precisa manter dois fl ags booleanos. Um flag informa ao jogador se ele deve receber
mais cartas toda vez e o outro controla se o jogador recebeu mais cartas durante essa rodada. Os
flags garantem que o jogador s receba mais cartas uma vez a cada outro jogo.

Para penniti r que toda a lgica booleana funcione, voc prec isar sobrepor O mtodo reset () ,
para alternar o estado booleano shoul d_hi t_once. Sobrepor reset O dessa maneira garante que
o jogador s receba ma is cartas a eada outro jogo.

Implementando OneHitPl ayer


OneHi tPl ayer semel hante na implementao a Fl i pPl ayer. Ao contrrio de Fl i pPl ayer, OneHi tPl ayer receber mais cartas a cada jogo, mas apenas uma cana. A Listagem 20.5 apresenta a
im plementao de OneHi tPl ayer.
LISTAGEM

20.5 OneHitPl ayer. java

pub l ic cl ass OneHitPlayer extends BettingPlayer {


pr;vate boo l ean has_hi t

false ;

pub l ic OneHitPlayer( String name , Hand hand , Sank bank ) {


supere name, hand. bank )i
}

publ ic boolean hitO (


if( !has_hit ) {
has_hit true;
return true;
}

return false j
}

public vo1d reset() {


super.reset() j
has hit false;
}

publiC vo i d bet() (
getBankO . pla celOBet();
}

Novamente, voc precisa sobrepor reset () para que ele li mpe o flag has_ hi t. Esse fl ag garante
que o jogador s receba mais uma carta na rodada.

Divertindo-se com o jogo vinte-e-um

477

Implementando SmartPl ayer


Sma r lPl ayer tcm uma implementao muito simples. A Listagem 20.6 apresenta a implementao.
LISTAGEM

20.6 SmartP l ayer . java

public cl ass SmartPlayer extends BettingPlayer (


publiC SmarlPlayer( String name , Hand hand, Bank bank ) (
supere name , hand , bank ):
J

public boo lean hit() (


if( get Hand() . total()
return false :

>

II ) (

return true :
J

pub l ic void bet() (


getBank().placeIOBet():

J
J

SmartPl aye r veri fi ca o total de seu objeto Hand. Se o total for maior que onze, o jogador pra. Se
for menor, o jogador recebe mais cartas.

Configurando o simulator
Para transformar o jogo em um simulador, voc pode simpl esmente alterar o mtodo principal
encontrado na classe Bl ackjack. Aqui , copiaremos e renomearemos a classe como Bl ackjackSim. A Listagem 20. 7 apresenta o novo si mulador.
liSTAGEM

20.7 BlackjackSim . java

pub li c class BlackjackSim {


pub l ic stat1c void main( Stri ng (] args ) ) (
Console. INSTANCLpr intMessdge( "How many t imes should the simula tor
play? " l:
String response Consol e. INSTANCE.readlnput( "invalid" ):
int loops = Integer.parselnt( response ) :
Oeckpile cards new Deckpi l e() ;

Dia 20

LISTAGEM 20.7 8lackjackSim .java (continuao)


for( int i .. O: i < 4: i ++ )
cards .shuffle() :
Oeck deck .. new Deck{};
deck.addToStack( cards );
cards.shuffle();

II

cria uma banca


Hand dealer hand .. new Hand() ;
BlackjackDealer dealer .. new BlackjackDealer( "Oealer", dealer_hand ,
cards ) ;

II

cria um OneH it Player


Ba nk one_bank .. new Bank( 1000 ) i
Hand one_hand .. new Hand(l;
Player oplayer " new OneHitPl ayer( "OneHit", one_hand , one_bank l i

II

cria um SmartPlayer
Bank smart_bank .. new Bank( 1000 ) ;
Hand smart_hand new Hand() i
Player smpl ayer .. new SmartPlayer{ "Smart" , smart_hand, smart_bank l;

II

cria um SafePlayer
Bank safe bank .. new Bank( 1000 l i
Hand safe_hand .. new Hand();
Player splayer .. new SafePl aye r ( Sa fe", safe_hand, safe_bank li

II

cria um FlipPlayer
Bank flip_bank .. new Bank( 1000 } i
Hand flip_hand .. new Hand() i
Player fplayer .. new FlipPlayer( "Flip" , flip_ha nd, f l ip_bank li

II

rene todos os jogadores


dealer.addL i stener( Console .I NSTANCE l i
oplayer.addListener( Conso l e.INSTANCE l i
dealer . addPlayer{ oplayer }i
splayer,addListener( Console . INSTANCE l i
dealer.addPlayer( splayer li
smplayer.addListener( Console . INSTANCE li
dealer.addP l ayer( smplayer li
fplayer.addlistener( Consol e. INSTANCE li
dea ler.addP l ayer( fplayer li
i nt

counter .. O;

Divertindo-se co m o jogo vinte-e-um

LISTAGEM 20.7

8lackjac kSi m. java (continuao)

whlle( counter < loops ) {


dealer . newGame();
coun ter ++;
J
J

o simulador primeiro o consu ltar quanto ao nmero de vezes a j ogar. Quando ele tiver essa informao, criar um objeto 81 ackj ac kDea 1er, um OneHitPl ayer, um Sma rtPl ayer e um FI l pPl ayer. Ento, ele conectar esses jogadores no Console e os adicionar na ba nca.
Q uando tiver terrn inado a con fi gurao, ele jogar o jogo pelo nmero de vezes que voc tiver
especifi cado.

Os resultados
Aps executar o simulador algumas vezes, com 1000 jogos por execuo, torna-se fc il ver
como os j ogadores se comportam. Aq ui esto os resultados obt idos, do maior para o menor:

SmartPl ayer

SafePlayer

FhpPlayer

OneHHPlayer

Parece que, desses quatro j ogadores, permanecer com uma mo que ma ior que II a me lhor
estratgia. Na verdade, SmartP l ayer foi o unico jogador a ficar com din hei ro aps os 1000

Jogos.
SafePl ayer vem em um segundo lugar prx imo, mas acabou perdendo di nhe iro. E, faa o que fizer, no receba mai s cartas. Esses jogadores perderam mais dinheiro do que ti nham em seu pote
inicial.

NOTA

Nenh um desses jogadores acabou com mais dinheiro do que com eo u. Os jogadore s s diferiram na velocidade com que perderam seu dinheiro.

Resumo
Voc aprendeu uma lio im portante hoje: no siga nenhuma das estratgias de hoje ao jogar
vinte-c-um . Voc perder todo seu dinheiro!

Dia 20

Voc tambm viu pela primeira vez como o polimorfismo permite escrever software prova do
futuro. Voc pode introduzi r tipos de jogador no sistema, sem ter de alterar o sistema bsico.
Esses tipos dejogador nem mesmo eram considerados, q uando vocconslruiu o sistema inicial.

Perguntas e respostas
P H um motivo pclo qual voc no tcnha usado a CU I como base deseu simulador?
R Poderamos ter usado a GU I, em vez do conso le. Poderia ter sido interessante ver osjogos ci ntilarem. Nonna lmente, um simulador no tem UI. Em vez disso, o simulador mostrar algumas estatsti cas no final.
Tambm ex istem limites prticos para uma G U!. As GU ls demoram alguJ1ltem po para
alUa li zar. Jogar 1000 jogos visuais poderia demorar um pouco ma is do que jog-los na linha de comando.
Vrias verses de Swing tambm sofrem de estouro de memria. Esses estouros poderiam
surgir e atrapalh-lo, caso voc executasse 10.000 jogos visuais.
Para propsitos de teste, entretanto, voc poderia considerar o uso da GUI como base
para o sim ulador.

Workshop
As perguntas e respostas do teste so forneci das para seu melhor entendimento. Veja as respostas no Apndice A, " Respostas".

Teste
I. Como o polimorfi smo permitiu jogar o jogo sem um jogador humano?
2. Qual estratgia de aposta voc nunca simular?

Exerccios
I. Faa download do cdigo-fonte da iterao de hoje, a partir do endereo www,samspu bllshing . com. O cd igo est dividido em quatro diretrios separados: gui o simulation,
exerci se 2 e exercise 3.

9U1 contm uma GU I que tem um jogador humano e um SafePl aye rU.

simu l ation contm o cdigo de simu lao. s imul ati on tem os seguintes jogadores: OneHi tPl ayer, Fl i pP1 ayer, Sa fePl ayer e SmartPl ayer.
exerci se 2 e exerci se 3 contm os arquivos que voc precisar para os exerccios 2 e 3,
ass im como as solues.

Dive rtindo-se co m o jo g o v inte-e- um

Estude o cd igo de gui e simula t or. Tente entender como tudo funciona. Quando voc
t iver feito isso, complete os exerccios 2 e 3.

2. O download contm todos os arquivos iniciais que voc precisar p<1ra completar este
exerccio. Os arquivos in iciais faze m alteraes no mtodo hi t declarado pela primeira
vez em PI ayer.
As alteraes adic ionam Dea ler como um parmetro. O mtodo getUpCard fo i adi cionadoem Oea l er para que voc possa obter a carta aberta de Oea I er. Em urnjogo vi nte-e-um
real , os jogadores podem ver a carta aberta da banca. Voc pode usar essa in formao
para tornar alguns movim entos mais inte ligentes.
Para este exe rc cio, escreva um ou dois j ogadores novos, que base iem s ua deciso de receber ma is cartas em seu prprio total, assim como na carta aberta da banca. Aqui esto
duas s ugestes, mas sinta-se livre para impl ementar seus prpri os j ogadores, adici on- Ias 110 simulador e ver como eles reagem :
KnowledgeablePlayer

Knowl edgeabl ePI ayer deve basear a dec iso de se vai ou no receber mais cartas de acordo com as seguintes regras:
Independentemente de tudo, se o tota l da mo for maior que 15, pra.
Se o total da mo for I I ou menor, recebe mais cartas.
Se a mo for 15 ou menos e maior que 11 , baseia a deciso de receber mais cartas na carta
da banca. Se a carta da ba nca for maior q ue 7, recebe mais cartas; caso contrrio, voc
deve parar.
OptimalPlayer
Opt ima 1PI ayer est t110 prx imo da perfei o, que voc pode no consegui r diferenciar
ent re mos fce is e difceis. (A d ifere nciao deixada como excrcc io para o leitor).
Opt i ma I PI ayer deve basear a deciso de se vai a li no receber ma is carias nas seguintes
regras:
Se o total da mo for maior ou igual a 17, pra.
Se o tota l da mo for 11 ou menos, recebe mai s cartas.
Se o total da mo for 16, baseia a deciso de receber ma is cartas ou parar na carta aberta
da banca. Se a carta aberta for 7, 8 Oll 9, recebe mais cartas; caso contrrio, pra.
Se o total da mo fo r 13, 14 ou 15, baseia a deciso de receber mais cartas ou parar na carta aberta da banca. Se a carta aberta fo r 2, 3, 4, 5 ou 6, pra; caso contrrio, recebe mais
cartas.
Se o tota l da mo for 12, baseia a deciso de receber mais cartas ou parar na carta aberta
da banca. Se a carta aberta fo r 4, 5 ou 6, pra; caso cont rrio, recebe mai s cartas.

Dia 20

3. O download contm todos os arqu ivos iniciais necessrios paravoc complelareste exercic io. Os arquivos iniciais adicionam suporte para dobrar a aposta nas classes. Alm disso, o novo mtodo doubleOown agora aceita um objeto Oealer como argumento.
As alteraes adicionam Dealer como um parmetro em doub 1eDown. O mtodo getUpCard foi adic ionado em Dealer para que voc possa obter a carta aberta de Dea 1er. Em
um jogo vinte-e-um rea l, o j ogador pode ver a carta aberta da banca. Voc pode usar essa
informao para tornar alguns movimentos mais inteligentes.
Para este exercicio, escreva um ou dois j ogadores novos que baseiem sua deciso de receber mais cartas ou dobrar em seu prprio lotai, assim como na carta aberla da banca.
Aqui esto duas sugestes, mas sinta-se I ivre para impl ementar seus prprios jogadores,
adicion-los no simul ador e ver como eles se comportam:
KnowledgeablePlayer
Para receber mai s cartas, siga as regras delineadas no Exerccio 2.
Para dobrar, siga estas regras:
Se o lotai da mo for 10 ou 11, dobra. Em todos os outros casos. no dobra.
OptimalPlayer
Para receber mais cartas, siga as regras delineadas no Exercic io 2.
Para dobrar, siga estas regras:
Se o total da mo for 1 I, sempre dobra.
Se o total da mo for 10, baseia a deciso de dobrar na carta aberta da banca. Se a carla
aberta for 10 ou um s, dobra; caso contrrio, no dobra.
Se o total da mo for 9, base ia a deciso de dobrar na carta aberta da banca. Se a carta
aberta fo r 2, 3, 4, 5 ou 6, dobra; caso contrrio, no dobra.
Em lodos os outros casos, no dobra.

SEMANA

DIA

o ltimo quilmetro
Parabns! Voc chegou ltima lio deste livro. Voc percorreu um longo caminho. Agora,
voc deve ler a base necessria para ter xito ao continuar seus estudos de POO.
l-laj e, elimi naremos algumas arestas e depois o enviaremos por seu cami nho !
Hoje voc aprender sobre:

Refazer o projeto do jogo vinle-c-um para reutilizar em outros sistemas

As vantagens que a POO trouxe para

Realidades do selor que podem impedi r sol ues totais 00

O j ogo

vinte-c-um

Amarrando as pontas
Voc abordou muitos assuntos durante as trs ltimas semanas. Voc comeou considerando a
tcoria bsica da 00 e chegou em um proj eto inteiramente baseado cm POO. Agora, voc j deve

ter uma boa idia do que POO realmente significa.


Antes de concluirmos o livro, ent retanto, restam trs problemas para abordar:

Refazer o projeto do j ogo vinte-e-um para reutil izar em outros sistemas

Um levantamento das vantagens que a

Uma palavra sobre as realidades do selar e

roo trouxe para o sistema de j ogo v inte-c-um


Poo

Dia 21

Refazendo o projeto do jogo vinte-e-um para reutilizao


em outros sistemas
Existe um pequeno problema relacionado ao projeto do jogo vinte-c-um que precisamos exami nar. Esse problema no tm impacto sobre o jogo vinte-c-um, mas poderia ter impacto negativo
em outro sistema 00, se c[c reutilizar o projeto incorretamente.
No Dia [5, voc viu duas solues altemativas. Em uma soluo, a banca fa z um lao por seus
jogadores dizendo a cada um para que jogue depoi s que o jogador anterior tcnn inar. Ento, voe
viu uma outra estratgia mais baseada em objetos para o lao do jogo.
Em vez da banca percorrer osjogadores um por um e dizer a eles o que fazer, a banca 00 iniciava cada jogador c esperava que ele dissesse quando tinha acabado de jogar.
Isso ofereceu uma soluo mais limpa, poi s voc deixava por conta do jogador dizer banca
quando tivesse terminado - somente ento que a banca continuava. Tambm se viu que esse
projeto era abso lutamente necessrio para a GUJ fun cionar; caso contrrio, um jogador humano
retornaria instantaneamente e, se a banca estivesse fa zendo o lao, diria ao prx imo jogador para
prosseguir. O jogador humano nunca teria sua vez na estratgia procedu ral!

o problema do projeto
Existe um peq ueno problema na estratgia delineada nas lies. Vamos acompanhar as chamadas de mtodo em um jogo onde ex iste um jogador e uma banca. Os dois jogadores param durante sua vez.
A Listagem 21 .1 representa um acom panhamento de Iodas as chamadas de mtodo no jogo. A
pilha termina quando um mtodo retorna.
L ISTAGEM 2 1 .1

Um acompanhamento da pilha de mtodo

BlackjackSim.main
81ackjackDealer . newGame
PI ayer. pI ay
81ackjackOealerSOealerCollecting8ets . execute
Player.play
8et tingPlayerSBetti ng.execute
8lackjackOealer. done8etting
Player . play
81ackjackDea l erSOealerCo l lec t i ng8ets.execute
81ackjackDeal erSOea l erOeal ing.execute
81 ackj ackOeale rS DealerWaiting.execute
Playe r .play
PlayerSPlaying . execute
Pl ayerSStanding.execute
Bl ackjackOealer. sta nding

o ltimo quil m etro


LISTAGEM 21 .1 Um acompa nhament o da pilha de m todo (continuao)

Player . play
Black jac kOealer$DealerWaiting.execute
PlayerSPlaying.execute
BlackjackDea ler$DealerStanding

o problema s uti!. Nen hum dos mtodos retoma at que a banca termine s ua vez! Os mtodos
chamam-se uns aos OUlros rec ursivamente. Assim, por exemplo, o mtodo noti fyChanged da
Listagem 2 1.2 no ser executado at que o jogo corrente tennine.
LISTAGEM 21 .2 Um mtodo que no ser chamado antes que o jogo corrente termine

pub l ic void execute( Dealer dealer ) {


if( hit( dealer) ) {
dealer . hit( Player.this ):
I el se (
se tCurrent State( getStandingSt ate() );
notifyStandingO:
}
cu rren t_state.execute( dealer ) ;
II transio

II

no ser chamado at que a pilha se desenrole!! !!


notifyChanged();

No jogo vinte-e-um, isso no problema, pois existe um limite de sete jogadores e a pilha de
chamada de mtodos se desenrola aps cada jogo. Voc tam bm pode codificar cu idadosamente
no caso de problemas como o demonstrado na Listagem 21.2.
Entretanto, imagine um si mu lador com centenas ou milhares de objetos que seguem o projeto do
jogo vinte-e-um . Se esses objetos chamarem um ao o utro recursivamente, mesmo que a pilha finalmente se desenrole, voc poderia acabar ficando sem memria. De qualq uer modo, cada chamada de mtodo alocar mais memria. Se voc seguir esse projeto inalterado, seu sistema no
func ionar ou exigi r muito mais memria do que o absolutamente necessrio.

Costurando uma soluo com linhas de execuo (threadsl


Felizmente, existe lima soluo : as linhas de execuo (threads). Embora uma di scusso completa sobre o uso de linhas de execuo esteja bem fora dos objctivos deste livro, voc vai ver
como pode us-Ias para resolver o problema da chamada de mtodos rapidamente.

Dia 21

NOTA

Quase todo sistema no-trivial com partilhar duas caractersticas:


Eles usaro lin has de execuo
Eles tero lgica de estado
O sistema de jogo vinte-e-u m compartilha essas duas caractersticas.

Uma linha de execuo simplesmente um caminho de execuo atravs de seu programa. At


agora, o sistema do jogo vinle-e-um tem uma (mica linha de execuo. A Figura 21. 1 ajuda a visualizar essa linha de execuo nica.

FIGURA 2 1.1
O sisfema flojogo l'illle-e-ulII
com lI/IIa llica linha de
e.recll(io.

Sistema do jogo vinte e-u m


com uma nica linha de execuAo

Uma linha deexe(:uo

Comoo jogo vinte-e-um usa apenas uma linha de execuo (ele tem somente um linha de execuo), essa linha de execuo faz tudo.
O uso de linhas de execuo penni te que voc crie vrias linhas de execuo atravs de seu programa. Criando vrias linhas de execuo, seu programa pode fazer muitas coisas diferentes, simultaneamente. A Figura 2 1.2 ajuda a visualizar duas linhas de execuo percorrendo o sistema
do jogo vi nte-c-um.
Usar linhas de execuo no sistema do jogo vinte-e- um pode perm iti r que um mtodo retorne
imed iatamente. Vamos ver um exemplo si mples de linha de exec uo da linguagem Java. A Li stagem 2 1.3 apresenta urna linha de execuo simples que imprime " Hello Worl d!".
FIGURA 2 1.2
O sisfema do jogo l'ime-e-IIIII
COIII mlfiplas linhas de
execlIlio.

Sistema do jogo vinte-eum com


mltiplas linhas de eXBCuAo

"-

"-~

"/

"-

Duas linhas de eXlCuAo

o ltimo quil m etro


lISTAGEM2 1 .3

487

"Hell o Worl d!" com mltiplas linhas de execu!o

publ i c class HelloWorld (


publ ic void sayHello() I
System.out.println( "He l lo Worl d!" };
J

public static void main( String [] args ) I


final HelloWorld hw new HelloWorldO ;
Runnable runna ble new Runna bl e() I
publ ic yoid run() {
hw. sayHe11 00 ;
J
J;

Thread t hread new Thread{ runnab 1e ) ;


thread. s tartO;
System .out. pr intln( "A11 Oone! " ) ;

J
J
He ll oWorld ela prpria uma classe simples que tem um mtodo: sayHell o. sayHel lo imprime
uma mensagem na linha de comando.
,

E no mtodo main que as coisas ficam interessantes. Pri meiro, esse mtodo instancia Hell~
Wo r1d. Ento. ele cria uma classe Runnab l e annima. Os objetos Runnab1e tm um mtodo: run.
O mtodo run diz li nha de execuo o que fazer quando fo r iniciada. Neste caso, ele di r instncia de He 11 oWor1d para que imprim a sua mensagem.
Aps cria r Runnable, O mtodo principal instancia um Thread Java . Quando voc cria um objeto
Thread, precisa passl-lo para um objeto Runnab1 e. O mtodo run de Runnabl e diz ao objeto Thread
o qu fazer quando voc disser a Thread para que comece (s tart). Aps iniciar o objelo Thread, o
mtodo ma;n imprime sua prpria mensagem.
Voc pode ficar surpreso quando ver o mtodo princi pal ser executado. A Figura 21.3 apresenta
a sada de He 11 oWor 1d.
Ao executar He11oWorld, voc ver que "Ali Done" impresso antes de "Hel io World !" a chamada de Thread .s ta r t no bloqueia como outras chamadas de melado. Como sta r t in icia uma
nova linha de execuo, ele reloma automaticamente. Aps chamar st art, voc tem duas linhas
de execuo no programa Hel loWorld. Apenas acontece que o mtodo ma i n impri me sua mensagem antes que a nova linha de execuo tenha uma chance de chamar sayHell o.

Dia 21
FIGURA 21 .3
A saida de He 11 oWor 1d.

Voc pode usar o rato de que start no bloqueia para corrigir a defi cincia do projeto no jogo
vinte-e-um. A Li stagem 21.4 apresenta um novo estado Wa i ti ng para B1 ackjackDeal er, que inicia cada jogador em sua prpria linha de execuo.
LISTAGEM 21 .4 Dea 1erWai ti n9 com 1i nha de execuo
private cla ss DealerWaiting implements PlayerState (
publ ic void handCha nged( ) {
II imposs (ve l no estado de espera
}

pub l ic void handPlayable () {


II 1mpossfvel no es t ado de espera
}

public void handBlackjac k() {


II i mposs (vel no es tado de espera
}

public voi d handBusted() 1


II impossvel no estado de espera
}

public vo i d execute( fina l Dealer dealer ) {


if( !waiting_p layers . isEmptyD ) {
final P1ayer player z (Player) waiting_players .get( O };
wa i ting_players. remove( player };
Runnable runnable : new Runnable() {
publ ic vo i d run() {
player . play( dealer );
}

};
Thread thread new Th read( runnable );
thread. s tart () ;
} el se {
setCurrent Sta te( getPlayingSta te() );
exposeHand () ;
getCurrentState().execute( dea le r };
II faz a transi ao e executa
K

o ltimo quilmetro

489

LISTAGEM 21 .4 OealerWal ting com 1inha de execuo (continuao)


}
}
}

Iniciando cada jogador em sua prpria linha de execuo, o mlodo de estado execute de Bl ackj ackOea 1er pode retornar imediatamente, desenrolando assim a pilha. Isso interpe algumas dificuldade s, se voc fi zer um lao com as chamadas de newGame, pois agora newGame retornar
antes que o jogo tenha real mente term inado. Se voc fizer o lao, iniciar outro jogo antes que o
ltimo tenha tcrminado e, ento, enrrentar todos os ti pos de problemas desagradveis. Voc
pode resolver esse problema dizendo a 81 ackjackOeal er quantas vezes deve razer o lao. No finai de cada jogo, ele pode verificar se precisa jogar novamente.

NeTA

o uso de lin has de execuo apenas uma maneira de resolver o problema da


recursividade. Apresentamos uma soluo com linhas de execuo aqui para
que voc as visse um pouco.

O problema do lao/ linha de execuo levanta algumas preocupaes. Voc


tambm pOderia criar um objeto GameTable que iniciasse e parasse as linhas de
execuo. Ento, Oea 1er poderia receber o est ado da tabela e distribuir cartas,
receber mais cartas, efetuar o jogo, etc., com base no est ado. Entretanto, tal estratgia um pouco mais complicada do que simplesmente usar linhas de execuo para os jogadores quando eles comeam.
Voc t ambm poderia se desfazer da recursividade atravs de iterao pelos
jogadores.

A boa nova que, se voc no fize r o lao, como na GUI, pode usar linha de execuo racilmen-

te, sim plesmente mudando o estado de Oea 1erWai ti n9 de Bl ackjackDea ler! O cdigo-ronte carregado por download contem verses com linhas de execuo da aul.
fci l usa r linhas de execuo no jogo vin te-e-um, pois apenas uma linha de
execuo de jogador executa da em dado momento . Voc no tem mu itas linhas de execuo de jogador sendo executadas concomitantemente.
O uso de lin has de execuo se torna complicado quando muitas linhas de execuo so executadas concom ita ntemente e compartilham os mesmos dados!

Identificando as vantagens que a POO trouxe para o


sistema do jogo vinte-e-um
A primeira semana mostrou alguns dos objetivos e vantagens da POO. Para recapitular, a POO
tenta produzir so ftwa re que :
1. Natural

2. Confivel

Dia 21

3. Reutilizvel
4. Manutenvel
5. Extensvel
6. Oportuno
A POO trouxe cada uma dessas vantagens para o sistema do jogo vinte-e-um . O sistema do jogo
vinte-e-um atinge cada um dos objetivos da POO:

Natural : o sistema do jogo vinte-e-um modela naturalmente um jogo vinte-e-um.

O sistema dojogo vinte-e-um existe nos termos de um jogo vinte-e-um real . O sistema do
jogo vinte-e-um constitudo de objetos P1 ayer, um 81 ackj ac kDea1er, objetos Ca rd, Deck
e um DeckPile. Corno voc v, o jogo vi nte-c-um uma simulao viva do domnio do
jogo vinte-e-um.
Con fi ve l: o sistema do jogo vinte-e-um confivel.

Atravs de uma combinao de testes cuidadosos e encapsulamento, voc criou um sistema do jogo vinte-c-um confivel. Como voc iso lou conheci mentos e responsabilidades e
os colocou no lugar onde pertencem, pode fa zer mel horias no sistema sem se preocupar
com um impacto negativo em partes no relacionadas do sistema.
Relll ilizvel: o sistema do jogo vinte-e-um reutilizvel.
Como esse foi o primeiro jogo de cartas que voc escreveu, no houve muita nfase na escrita de uma estrutura dejogo de cartas abstrata. Em vez disso, voc escreveu um jogo vinte-e-um. Como resultado, o jogo no completamente reutilizvel; entretanto, classes como
Card, Deck e Deckpile podem ser reuti lizadas em praticamente qualquer jogo de cartas.

Alm di sso, muitas das idias do projeto so reutilizveis em muitos problemas. medida que voc escrever mais jogos de cartas, poder abstra ir mai s e criar uma estrutura totalmente reut ili zvel.
Manuten vel : o sistema do jogo vinte-e-um manutenvel.
Encapsulando conhecimentos e responsabilidades no lugar onde eles pertencem, fi ca
simples fazer alteraes em lim a parte do sistema sem ter um impacto negativo em outras
partes no relacionadas do sistema .

Tais divises tornam possvel fazer melhorias no sistema a qualquer momento. Voc tambm viu pela primeira vez como a herana e o polimorfismo tornam possvel adicionar
novos jogadores no sistema, a qualquer momento.
Extensve l: o sistema do jogo vinte-c-um extensvel.
Voc viu pela primei ra vez como pode adicionar novos jogadores no sislema. Alm disso,
atravs de uma herana cuidadosa. voc pode inlroduzir novos tipos de cartas (como cartas visuais) e mos. O processo iterativo mostrou como um sistema de POO pode ser extensvel.

o ltimo quilmetro

491

Oportuno: o sistema do jogo vinte-e-um oportuno .


Voc produziu um jogo vinte-c-um completo em quatro iteraes mana. Veja como ele oportuno!

o tempo de uma se-

Realidades do setor e POO


As lies deste livro ti veram como pressuposto o fato de que voc estava inic iando seus projetos
de POO desde o princpio. Quando voc comea desde o principio, no precisa integrar sistemas
de backend legados, no-OO. Voc no precisa reut il izar bibliotecas proced urai s. Voc pode comear do comeo e tudo que usar pode ser 00.
Voc ver que um projeto de POO independente raro. Na maioria das vezes, voc precisar interagir com componentcs no-OO . Peg ue o caso dos bancos de dados relacionais. Os bancos de
dados relacionais no so particularmente ori entados a objetos e os bancos de dados orientados a
objctos ainda so raramente usados fora de alguns nichos do setor.
A prpria linguagem Java no totalmente orientada a objetos. A con fi ana cm primitivas
no-OO faz voc rea lizar alguma codificao no-OO, de tempos em tempos.
Ao se deparar com essas reali dades, melhor trabalhar para empacotar esses aspectos no-OO
em um empacotador orientado a objetos. Por exemplo, ao tratar com bancos de dados relacionais, ajuda escrever uma camada de persistncia de objetos. Em vez de ir diretamente a um banco
de dados e reconstitui r seus objetos atravs de vrias consultas SQL, a camada de persistncia
pode fazer esse trabal ho para voc.
Real mentc no possvel abordar aqui cada tipo de sistema no-OO que voc va i encontrar. Mas
teramos sido negligentes se no apontssemos essas realidades antes de mand-lo apli car POO.
Vai demorar muito tempo, antes que todo sistema legado seja convertido para uma arquitetura
baseada em objetos (se que isso vai acontecer). Voc deve estar preparado para essa eventualidade e pronto para tratar com e la da forma mais elegante possvel.

Resumo
Voc termi nou ! Em trs semanas curtas, este livro forn eceu a voc uma base slida em POO. O
resto fi ca por sua conta. Agora voc tem conhecimento suficiente para comear a aplicar POO
em seus projetos dirios. Boa sortc!

Perguntas e respostas
P Por que voc esperou at agora para nos dizer a respeito de linhas de execuo?
R O problema do projeto no afela o jogo vinte-e-um. Apresentar os possveis problemas
antecipadamente leria confundido a queslo.

Dia 21

importante que voc perceba as deficincias do projeto, assim como uma possvel soluo.
O uso de linhas de execuo tambm um assunto avanado. Usar linhas de execuo no
jogo vinte-e-um foi muito f cil. Mas usa-las em outros aplicativos pode no se mostrar
to simples.

P O que pode tornar o uso de linhas de execuo difci l?


R Se voc tiver mllltiplas linhas de execuo compartilhando dados, uma linha de execuo poder alterar os dados c dan ificar outra li nha de execuo. Tais problemas de concorrnc ia so ext remamente difceis de projetar, implementar e depurar.

Workshop
As perguntas e respostas do teste so forn ecidas para seu melhor entend imento. Veja as respostas no Apndice A, ;'Respostas".

Teste
I. Como as li nhas de execuo tratam do problema da chamada de mtodo recursiva?

Exerccios
I. Faa down load do cdigo-fonte da iterao de hoje. O cdigo est dividido em quatro di retrios separados: threaded _he 110_worl d, threaded _mvc _gui, threaded _pac _9ui e
threaded_simulador. Estude o cd igo e certifique-se de entender como ele funci ona.
2. Seu estudo de POO no deve terminar com este livro. Gere uma lista de assuntos sobre os
quais voc gostaria de aprender mais. Classifique esses assuntos em ordem de im portncia, pesq uise a Web para encontrar materiais e comece a estudar!

SEMANA

Em reviso
Agora, voc concluui fi terceira e ltima semana deste li vro e nos lJltimos sete dias, aprendeu a
desenvolver seu prprio jogo vinte-c-um 00.
O Dia 15 apresen tou as regras bsicas do jogo vinte-c-um. Voc desenvolveu uma li sta de casos
de LISO em potencia l e se lecionoll alguns de les para desenvolver na pri meira iterao do jogo.
Voc segu iu o processo de projeto, da anlise, de implementao e teste, e no final do d ia ti nha
uma verso funciona l do jogo vinte-c-um que distribua cartas e o deixava jogar.

No Dia 16, voc completou a segunda iterao do jogo. Voc adicio nou mai s funcionalidade,
corno a capacidade de dctcnninar os resultados do jogo. Ao fazer isso, voc aprendeu a respeito
dos estados e como us- los para melhorar seu projeto.

O Dia 17 mostrou a voc como completar uma outra iterao do jogo vinte-e-um - a aposta. Ao
fazer isso, voc viu como poderi a estender a arq uiletura de estado para suportar apostas simples
no jogo. Voc tambm viu que, s vezes, necessrio revere refazer uma hierarquia, quando novos requisitos se apresentam. Embora o fato de refazer apresente um pouco de trabal ho extra antecipado, refazer quando apropriado tende a valer a pena, quando voc prossegue.
No Dia 18, voc concl ui u ojogo vinte-e-um, adicionando uma OU I. Para isso, voc reviu o padro MVC discutido em um capitulo anterior.
O Dia 19 forneceu uma OU I alternativa, usando o padro PAC, quela desenvolvida no Dia 18.

Isso ajudou a refinar scu entendimento de quais padres so apropriados para cenrios especficos.
Durante o Dia 20, voc reviu os conceitos do polim or fismo que perm item escrever software fi
prova do futuro. Voc se divertiu um pOLlCO, quando ad icionou v rios jogadores no-humanos
ao sistema e transformou o jogo vinte-e-um em um simulador. Mexendo com est ratgias de
vrios jogadores, voc aprendeu o que no deve fazer ao participar de um jogo. Voc tambm
aprendeu que pode introd uzir tipos de jogador no sistema sem ter de alterar o sistema bsico.
Esses ti pos de jogador no foram nem mesmo considerados quando voc construiu o sistema
inicial.
Finalmente, no Dia 2 1, voc aprendeu sobre linhas de execuo. O captulo tambm abordou todas as arestas do projeto e apresentou uma discusso sobre a 00 pura, em oposio ao que voc
provavelmente ver no mundo real.

Dia 21

As lies desta semana aprofundaram seu entendimento de 00 e, alm disso, voc acabou com
um divert ido e demorado jogo vinte-e-um 00 para provar isso.
Aps concluir este livro, voc tem a base necessria em 00 para comear a desenvolver software 00. Tudo de que voc precisa agora prtica e experinc ia. Boa sorte.
Para mais recursos, o Apnd ice D. " Bibliografia selecionada", romece um ponto de partida para
mais informaes sobre 00.

Apndices
A Respostas
B Resumo do Java
C

Refernc ia da UML

O Bibliografia selecionada
E

Listagens do cdigo do jogo vinte-e-um

ApNDICE
Respostas
Dia 1 Respostas do teste
Respostas do teste
1. Como urna di sc iplina de software , a programao procedura l decompe um programa
em dados e proced imentos para manipular esses dados. A programao procedural tem
uma natureza seqencial. Li stas de chamadas procedura is que so executadas seqilncialmente or ientam O nuxo de um programa procedural. Um programa procedura l termi na
aps chamar sua ltima procedure.
2. A programao procedural fo rnece a um programa uma estrutura g loba l: dados e procedimentos. Os proced imentos tambm o ajudam a ver como deve programar uma tarefa .
Em vez de esc rever um n ico bloco de processamento grande, voc di vide os procedimentos em subprocedimentos. Os procedi mentos fornecem um nvel de reutil izao.
Voc pode criar bibliotecas de procedimentos reutilizveis.
3. A programao modu lar acopla dados e procedimentos forteme nte, para manipularesses
dados em unidades conhecidas como md ulos. Os mdulos ocultam o runcionamento e a
representao de dados internos de um programa. Entretanto, a ma ioria das linguagens
modulares ainda penn ite que voc use esses mdulos cm um ambiente procedura l.

Apndice A

4. A programao modular oculta a im plementao e, assim, protege os dados de manipulao inconsistente ou imprpria. Os mdulos tam bm fornecem uma estrutura de nvel
mais alto para um programa. Em vez de pensar em tennos de dados e proced imentos, os
mdulos pennitcm que voc pense em um nvel comportamental conceituaI.
5. A programao procedura l e a programao modu lar tm s uporte limitado para a reutil izao. Embora voc possa reutilizar procedimentos, eles so altamente dependentes de
seus dados. A natureza global dos dados no mundo procedural torna a relltil izao di fici l.
Os procedimentos podem ter dependncias dificeis de quantificar.
,

Os mdulos em si so prontamente reutilizveis. E possvel pegar um mdu lo e us-lo


em qualquer um de seus programas. Entretanto, os mdulos limitam a reutil izao. Seu
programa s pode usar os mdulos diretamente. Voc no pode usar um mdulo existente como base para um novo mdulo.
6.

roo uma di sciplina de so ftware que modela o programa em termos de objetos do mundo real. A POO divideo programa em vrios objetos inter-reJac ionados. Ela complementa a programao modu lar, s uportando encaps ulamento, assim como eliminando
defici ncias da reut ilizao atravs da herana e deficincias de tipos atravs do polimorfi smo.

7. As se is vantagens da

roo so programas que so:

Natura is
Confive is
Reutili zve is
Manutenveis
Extensveis
Oportunos
8. A POO natural. Em vez de modelar os problemas em termos de dados ou proced im entos, a
permite que voc modele seus programas nos termos do problema. Tal estratgia o li bera para pensar nos termos do problema e focalizar o que est tentando faze r.
Isso reti ra o foco dos detalhes da implementao.

roo

9. A classe define todos os atributos e comportamentos comuns de um grupo de objetos.


Voc usa essa definio de classe para criar instncias desses objetos.
Um objelo uma instncia de lima classe. Seus programas manipul am esses objetos.
Um objeto executa componamentos. Voc tambem pode chamar os comporta mentos de
um objeto de interface pblica dele. O utros objetos podem exercer q ualq uer comportamento na interface de um objelo.

Respostas

10. Os objetos se comunicam atravs do envio de mensagens de uns para os o utros. Chamar
um mtodo si nnimo de fazer uma chamada de mtodo Oll procedim ento.
11. Um const rutor um mtodo que defi ne como se cria uma instncia de objeto. O uso do
construtor instanciar um objelo e o to rnar disponvel para seu programa.
12. Um acessor um comportamento que d acesso aos dados internos de um objeto.
13. Um mutante um comportamen to que pode alterar o estado interno de um objelo.
14. thi s uma reCerncia que cada instncia tem para si mesma. A referncia thi s d instncia acesso s suas varive is e comportamentos internos.

Dia 2 Respostas do teste e dos exerccios


Respostas do teste
I.

o encapsulamento natural. O encapsulamento pennite que voc mode le o software em


termos do problema e no nos tennos da implementao.
O encapsulamento leva a um software confivel. O encapsulamento oculta o funci onamento interno de um componente de softw are e garante q ue ele seja acessado corretamente. O encapsulamento permite que voc isole e va lide a res ponsabilidade. Quando
voc ver um componente agir corretamente, pode reutiliz-lo com confi ana.
O encapsulamento proporciona a voc um software reutilizve l. Como cada componente
de software independente, voc pode reutil izarocomponente em muitas si tuaes diferentes.
O encapsulamento leva a um cdigo manutenvel, pois cada componente independente.
Uma alterao em um componente no danificar outro componente. Assim , a manuteno e os aprimoramentos so simplificados.
O encapsu lamento torna se u software modular. As alteraes em uma parte de um programa no danificaro O cdigo em outra parte. A modularidade permite que voc faa
correes de erro e melhorias de func ional idade sem danifi ca r o restante de seu cdigo.
O encapsulamento leva a um desenvolvimento de cd igo oportuno, pois remove acoplamento de cdigo des necessrio. Freqentemente, dependncias ocultas levam a erros
que so dificeis de encont rar e corrigir.

2. Abstrao o processo de simplificar um problema dificil. Quando voc comea a resolver um problema, no se sobrecarrega com cada detalhe que envolve o domnio. Em vez
disso, voc o simplifica, tratando dos detalhes pertinentes formulao de uma soluo.
A rea de trabalho grfica de seu computador um exem plo de abstrao. A rea de trabalho oculta completamente os detalhes do sistema de arquivo.

Apndice A

3. Uma implementao defi ne como um componente fornece um servio. A implementao defin e os detalhes internos do componente.
4. Uma interface defi ne o qu voc pode fazer com um componente. A interface oculta
completamente a implementao subjacente.
5. Uma interface descreve o que um componente de software faz; a implementao diz
como o componente faz isso.
6. Sem uma diviso clara, as responsabi lidades se misturam. Responsab iIidades misturadas
levam a dois problemas relacionados.
Pri meiro, o cdigo que poderia ser centra lizado se torna descentraI izado. A responsabi Iidade descentralizada deve ser repetida ou reimplementada em cada lugar onde ela necessria. Lembre- se do exem pl o BadItem apresentado anteriormente.

fci l ver que cada usurio precisaria reimplementar o cdigo para ca lcul ar o tota l ajustado de um item. Sempre que voc reescreve a lgica, abre a possibi lidade de erros. Voc
tambm abre seu cdigo para um liSO incorreto, pois a responsabilidade de manter o estado interno no est mais den tro do componente. Em vez disso, voc coloca essa responsabi lidade nas milos de o utros.
7. Um tipo um elemento da linguagem q ue representa alguma unidade de clculo ou com portamento. Se as linhas de cd igo so frases, os tipos so as palavras. Normalmente, os
tipos so tratados como unidades independentes e atmicas.
8. Um TAO um conj unto de dados e um conj unto de operaes sobre esses dados. Os
TAOs nos pennitem defini r novos tipos de linguagem, ocultando dados internos e o estado por trs de uma interface bem definida. Essa interface apresenta o TAO como uma
ni ca unidade atm ica.
9. Ex istem vrias maneiras de obter ocu ltamento de impl ementao e cd igo fracamente
acoplado. A resposta fci I usar encaps ulamento. Entretanto, um encapsulamento eficaz
no acidente. Aqui esto algumas d icas para o encapsulamento e fi caz:

Acesse seu TAO apenas at ravs de uma interface de mtodos; nunca perm ita que estruturas internas se tomem parte da interface pblica.

No fornea acesso s estruturas de dados internas; abst raia todo o acesso.

No fornea acesso inadvertido s estruturas de dados internas, retornando acidentalmente ponteiros ou re ferncias.

Nunca faa suposies a respeito dos outros tipos que voc usa. A no ser que um
comportamento aparea na interface ou na documentao, no conte com ele.

C uidado ao escrever dois tipos intimamente relacionados. No se permita programar


acidentalmente com base em s uposies e dependncias.

10. Voc preci sa conhecer algumas annadilhas da abslrao.

Respostas

No caia na parali sia da abstrao. Resolva os problemas que voc encontrar primeiro.
Resolver problemas s ua pri ncipal tarefa. Veja a abstrao como um bnus e no como o
objetivo final. Caso contrrio, voc vai se deparar com a possibi lidade de prazos fi nais
perdidos e abstrao incorreta. Existem momentos para abstrair e momentos em que a
abstrao no apropriada .
A abstrao pode ser perigosa. Mes mo que voc tenha abstrado algum elemento, isso
pode no fun cionar em todos os casos. muito dificil escrever uma classe que sati sfaa
as necessidades de todos os us urios.
No coloque em uma classe mais detalhes do que so necessrios para resolvero prob lema.
No queira resolver todos os prob lemas. Resolva o problema que est a sua fren te e depois
procure maneiras de abstrair o que voc fez.

Respostas dos exerccios


I. Um possvel TAD de pil ha:

pub lie interface Stack {


publlc void push( Obj ect obj ) ;
pu bli c Obj ec t pop ();
pub l i c boolean isEmpty() ;
pu bl i c Objec t peek();
}
2. A pil ha mel hor implementada como uma lista encadeada isoladamente, com um ponteiro
de frente. Quando coloca ou ret ira um elemento, voc usa o ponte iro de fren te para encontrar o primeiro elemento.
3. Examinando a resposta do Exerccio I e a implementao do Exerccio 2, voc v que a
interface era adequada. A interface nos proporciona as vantagens que qua lquer interface
bem definida o ferece. Aqui est uma lista breve das vantagens:

A interface de fine a pi lha como um ti po. Estudando a interface, voc sabe exatamente
o que a pilha fur.

A interface oculta completamente a representao interna da pilha.

A interface defin e c laramente as responsabilidades da pilha.

Dia 3 Respostas do teste e dos exerccios


Respostas do teste
I. Aeeount tem dois mutantes: depositFunds() e wi thdrawFund s( ).
Aceount tem um aeessor: getBa laneeO.

Apndice A

2. Existem dois tipos de construtores: aqueles que tm argumentos e aqueles que no tm


(noargs).
Accou nt. do Laboratrio 2, tem os dois tipos de construtores.
3. (Opcional) Publ i c ace itve l no caso de Boolean, pois as variveis so constantes. Ter
acesso pbl ico s constantes no estraga o encapsulamen to, pois isso no est expondo a
implementao para liSO externo.
Alm disso, O uso de valores Bool ea n constantes para verdadeiro e fa lso economi za memria. No h necess idade de instanciar suas prprias cpias de Boo l ean. Voc pode simplesmente compartilhar essas constantes de instncias gl obai s.
4. As instnc ias de Card so imutveis. Seria mais eficiente definir 52 constantes Card uma para cada carta. No h necess idade de instanciar vrias representaes da mesma
,
carta, mesmo quando existem vrias instnc ias de Deck. E perfe itamente seguro compartilhar as mesmas instnc ias de Card entre os maos de carta.
5. Ao projetar suas classes, voc deve perguntar-se o que torna ' isso' uma classe? Espec ificamen te, lembre-se da di scusso sobre como as classes classificam obj etos relacionados.
Como as cartas so rel acionadas? Todas as cartas contm um nmero, um naipe e como
exibi -Ias.

o nmero ou o naipe no torna uma carta um tipo di fere nte de carta . Ela ai nda uma carta de pquer. As cartas de pquer simplesmente poderiam ter va lores diferentes. Assim
como um mamfero marrom ainda um mamfero, um l O de copas ai nda apenas uma
carta.
,

As vezes, pode ser extremamente dificil decidiroque devec o que no deve ser uma classe. Contudo, existe uma regra geral que voc pode seguir.
Se voc ver que o comportamento de um objeto muda fundam entalmente quando o va lor
de um atributo muda, as chances so de que voc deva criar c lasses separadas: uma para
cada va lor possvel desse atributo. Claramente, o valor da carta no muda seu comportamento de nenhuma manei ra fundamental.
6. A diviso correta de responsabilidades toma o projeto de Deck, Dea l er e Card mais modular. Em vez de urna nica classe grande, as cartas de pquer se dividem perfeitamente em
trs classes. Cada classe responsvel por fazer seu lraba lho e ocu ltar essa implementao das outras classes. Como resultado, essas classes podem mudar sua implementao
fac ilmente, a qual quer momento, sem prejud icar qualq uer um de seus usurios.
Com classes separadas, voc tambm tem a vantagem de q ue pode reutilizar a classe
Car d separada das classes Deck e Dea l er.

Respostas

Respostas dos exerccios


I.

Aqui est uma possvel soluo para o Exerccio I:


public class DoubleKey {
private Object keyl. key2;

II

um construtor noargs
public DoubleKeyO {
keyl z "keyl ";
key2 '" "key2";
}

II
II

um construtor com argumentos


deve procurar e ma nipular caso nulo
public DoubleKey( Object keyl. Object key2 ) {
th is .keyl .. keyl;
th1s.key2 = key2;
}

II

acessor
publi c Object getKeyl() {
return keyl ;
}

II
II

mutante
deve proc urar e manipular caso nulo
publi c void se tKeyl( Object keyl ) {
th1s.keyl = keyl;
}

II

acessor
publ ic Object getKey2() {
return key2;
}

II
II

mutante
deve procurar e manipular caso nulo
public void setKey2( Object key2 ) {
thi s . key2 = key2;
}

II

os doi s mtodos a seguir so exigidos para


. . .. 11 trabalhar cor retamente como um keyif passado para HashMap ou
Hashtable
pub li c boolean equals( Object obj ) {

Apndice A

il( Ih is obj ) (
return true;
}

if( thi s .getC l ass O "" obj. getC l ass () ) {


DoubleKey dk " ( Doub l eKey )obj;
if( dk . getKey l().equa ls ( getKeyl() ) &&
dk . gelKey2 () . equa 1s ( gelKey2 () ) ) {
return true;
}
}
return false;
}
public int hashCode () {
return keyl.hashCode{) + key2.hashCode();
}
}

2. Aqui est lima possvel soluo para o Exerccio 2:


pub li c class Deck (
private java.util.Li nkedlist deck ;
publi c Deck() {
bui l dCardsO ;
}
public String dis play() (
int num_cards " deck . size() ;
String display .. "";
i nt cou nter '" O;
for( int i ,. O; i < num_cards; i ++ ) {
Card card " (Card ) deck.get( i );
display " display + card . display()+ " ";
counter++ ;
if( counter "" 13 ) {
counter .. O;
display " display + "\ n";
}
}
return display;
}
publi c Card get( int index) (
if( index < deck . size() ) {
return (Card) deck.ge t( index };
}

Respostas
return nul1;
}

pub l i c void replace( int index. Card card ) {


deck.set( index. card )i
}

public int sizeO {


return deck.size() i
}

publ ic Card removeFromFront() {


if( deck.sizeO > O } (
Card card (Card) deck .removeFirst()i
return ca rdi
}

return nul1;
}

public void returnToBack( Card card ) {


deck. add( card l ;
}

pr ivate void bu i l dCards() {


deck "'new j ava.util.linkedlist();
deck.add( new Card( Card . CLUBS. Ca rd.TWO ) ) i
deck.add( new Card( Card . CLUBS . Ca r d.THREE ) l;
deck.add( new Card( Ca rd. CLUBS . Card .FOUR ) ) i
deck.add( new Card( Card . CLUBS. Card . FIVE ) );
II definio comp l eta cortada por brevidade
II veja a listagem comp l eta no cdigo - fonte
}

Dia 4 Respostas do teste e dos exerccios


Respostas do teste
I. A reutilizao simples no fornece nenhum mecanismo para reut il izao alm da instanciao. Para reutil izar cd igo diretamente, voc precisa reconar e co lar o cdigo que deseja reuti lizar. Tal prtica resulta em vrias bases de cd igo que diferem apenas em um
pequeno nmero de maneiras. Um cdigo q ue no possu i herana esttico. Ele no
pode serestend ido. Alm disso. um cd igo esttico limi tado quanto ao ti po. Um cd igo

Apndice A

esttico no pode compart ilhar tipo. Assim, voc perde as vantagens da capacidade de
conexo de tipo.
2. A herana um mecanismo interno para a reutil izao segura e a extenso de defin ies
de classes preex istentes. A herana penn ite que voc estabelea relacionamentos ' um '
entre as classes.
3. As trs formas de herana so:
Herana para reutili zao de implementao
Herana por d ifere na
Herana pa ra s ubstituio de tipo
4 . A impl ementao da herana pode cegar um desenvolvedor. A reuti lizao da implementao nunca devc ser o n ico objeti vo da herana. A substituio de tipo sempre deve
ser s ua primeira prioridade. A herana para reutili zao cega leva a hi erarquias de classes que simplesmente no fazem sentido .
5. A programao por diferena uma das fo rm as de herana. Isso signi fica que, quando
voc herda, programa apenas os recursos que diferenciam a nova classe da antiga. Tal
prti ca leva a classes menores e incrementais. As classes menores so mais fce is de ge
renc.ar.
6. Os trs tipos de mtodos e atri butos so:
Sobrepostos
Novos
Recursivos
Um atributo ou mtodo sobreposto um atri buto o u mtodo declarado na progeni tora (ou
ancestral) e reimplementado na filha. A filha altera o comportamento do mtodo ou a defin io do atributo.
Um mtodo ou atributo novo um mtodo ou atributo que aparece na filh a, mas no na
progenitora ou ancestral.
Um atributo ou mtodo recursivo de fin ido na progenitora o u na ancestra l, mas no redefinido pe la filha. A filha sim plesmente herda o mtodo o u atributo. Quando feita uma
chamada para esse mtodo ou atribulo na filha , a chamada sobe na hierarquia at que seja
encontrado algum que saiba como manipul-la.
7. A programao pela diferena fornece as menores classes que definem um nmero menor de comportamemos. Classes menores devem conter menos erros, ser mais fceis de
depurar, mais fceis de manter e mais fceis de entender.

Resposta s

A programao pela diferena permite que voc programe de fo rma incrementa l. Como
resu ltado, um projeto pode evoluir com o passar do tempo.
8. A11 Permi ss ion, Bas i cPermi ss i on e Un reso 1vedPermi ss i on so todas fi lhas de Penni ss i on. SecurityPenniss i on descendente de Permission.
Penn ission a classe-raiz. Al I Permi 5S i on, Unreso 1vedPenni ss; on e Securi tyPermi ss i on
so todas classes folhas, pois elas no tm fi lhas.
Sim, Penni ss10n ancestral de SecurityPennission.
9. Herana por substituio de tipo o processo de defin ir relacionamentos com capacidade
de substituio. A capacidade de substituio permite que voc subst itua uma descendente por uma ancestral , desde que no precise lIsar quaisquer novos mtodos defi nidos
pela descendente.
10. A herana pode destruir o encapsulamento, dando a uma subc lasse acesso inadvert ido

representao interna de uma superc lasse.


A destruio inadvertida do encapsulamento uma anlladi lha que pode apanh-lo sorrateiramente. A herana fo rnece silenciosamente a uma classe filh a acesso mais liberal
progenitora. Como resul tado, se os passos corretos no forem dados, uma fi lha poderia
ter acesso direto im plementao da progenitora. O acesso direto implementao to
perigoso entre progenitora e fil ha quanto entre dois objetos. Muitas das mesmas armadilhas ainda se aplicam.
Evite a destruio do encapsu lamento tomando a implementao interna privada. Faa
implementao interna privada apenas dos mtodos absolutamente necessrios para
uma subclasse.
Na maioria das vezes, as filhas devem exercitar apenas a interface pblica da progeni tora.

Respostas dos exerccios


I. Toda subclasse ler acesso direto representao interna de Point. Ta l acesso irrestrito
destri o encapsulamento c abre a classe para os prob lemas tratados na pergunta 10.
Remediar a si tuao to fci l quanto tornar x e y privados. Note que essa classe Pai nt
mode lada de acordo com java.awt.Point.

Apndice A

Dia 5 Respostas do teste


Respostas do teste
lo Em CheekingAeeount, publie double withdrawFunds( double amount ) um exemplo

de mtodo redefin ido. CheckingAeeount sobrepe withdrawFunds() para que ele possa
cont"rOlar O nmero de transaes.
Em BankAeeount, publ i e double getBal anee() um exemplo de mtodo recursivo. O
mtodo aparece na progenitora, mas nenhuma das subclasses o redefine.
Entretanto, as subclasses o chamam.
Finalmente, o mtodo publ ie double getlnterestRate() de SavingsAeeount um exemplo de mtodo novo. O mtodo aparece apenas na classe Savi ngsAeeount e no na progenitora.
2. Voc usa ria uma classe abstrata para herana planejada. Uma classe abstraIa fornece s
suas subclasses um indcio do que ela prec isar redefinir. As classes abstratas garantem
que suas subclasses usem a classe base corretamente.
3. O Laboratrio 3 mostra 'tem um'. Deck tem objelos Cardo DoubleKey, do Laboratrio 2,
tambm tcm duas St rings.
4. Os laboratrios preservaram o encapsulamento ocultando lodos os membros de dados.
Se voc exami naras solues, ver que todos os dados so pri vados. Por exemplo, a classe BankAeeount declara o saldo (balance) como privado. Em vez disso, cada classe d
acesso representao dos dados atravs de uma interface bem defin ida.
5. SavingsAeeount um exemplo de especializao. Ela se especializa em relao sua
progenitora, BankAeeount, ad icionando mtodos para configurar, consultar e aplicar juros na conta.
6. O Laboratrio 3 usa herana para reut ilizar o comportamento bsico defi nido pela classe
BankAccount. BankAccount de fi ne uma implementao comum para sacar fundos, depositar fundos e consultar o sa ldo. Atravs da hera na, as subc lasses de conta obtm essa implementao.
O Laboratrio 4 comea apresentando um caso de herana para reuti liz.1o da implementao, mas tennina usando composio, para obter uma forma dc reutilizao mais limpa.

Dia 6 Respostas do teste e dos exerccios


Respostas do teste
I. Inc luso

Respostas

Paramtrico
Sobreposio
Sobrecarga
2. O polimorfismo de incluso permite que voc trate um objelo como se fosse um tipo di fere nte de objeto. Como resultado, um objeto pode demonstrar muitos tipos diferentes de
comportamento.
3. Os polim orfi smos de sobrecarga c paramtrico perm item que voc modele algo em nvel
conceituaI. Em vez de se preocupar com os tipos de parmetros que algo processa, voc
pode escrever seu cdigo de forma mais genrica. Em vez di sso, voc modela seus mtodos e tipos em nvel conceitua i do que e les fazem e no para que fazem .
4. Uma interface pode ter qualquer nmero de implementaes. Programando para uma interface, voc no fica vinculado a nenhuma im plementao espectica. Como resultado,
seu programa pode usar automaticamente qualquer implementao que aparea. Essa Iiberdade de implementao permite que voc troque entre diferentes implementaes
para mudar o comportamento de seu programa.
5. Quando voc sobrepe um mtodo, o polimorfismo garante que a verso correta do mtodo seja chamada.
6. Polimorfi smo ad-Iroc outro nome para sobrecarga.
7. A sobrecarga permite a voc de fin ir um nome de mtodo vrias vezes. Cada definio difere simplesme nte no nmero e nos tipos de argumentos. A sobrecarga expressa um
comportamento diferente porque voc sim plesmente c hama o mtodo. Voc no precisa
fazer nada para garantir que a verso correta do mtodo sej a cha mada.
A sobrecarga permite a voc modelar um mtodo em nvel conce ituai do que ele faz. A
natureza polim rfica da sobrecarga cuida dos argumentos especfi cos.
8. O po limorfi smo paramtrico pcnnite a voc escrever tipos e mtodos verdadeiramente
genricos, adiando as de fini es de tipo at o momento da execuo . Esse tipo de po limorfi smo permi te que voc escreva cd igo rea lmente natural, pois pode programar tipos
e mtodos muito genricos e conceituais. Voc escreve esses tipos e mtodos a partir da
viso conceituai do que eles fa zem e no do que especificamente fa zem com ela. Por
exempl o, se voc programar um mtodo compare ( [T] a, [T] b) . pensar em lermos do
conceito mai s alto da comparao de do is objetos de tipo [T] . Os argumentos de tipo [TJ
simplesmente precisari am compart ilhar uma estrutura comum, como < ou um mlodo
compare( ). O ponto impo rtante que voc escreve si mplesmente um mtodo e ele pode
comparar mu itos tipos diferentes de objetos.
9. O po limorfi smo nomlal mente incorrer em um custo na efic incia. Algumas fonnas e
implementaes de polimorfi smo ex igem verificaes e pesquisas em tempo de execuo. Essas verificaes so dispendiosas, quando comparadas com as linguagens estaticamente tipadas.

Apndice A

o polimorfis mo tenta fazer o desenvolvedor quebrar a hierarquia de herana. Voc nunca deve mover funciona lidade para cima na hierarquia, si mplesmente para aumentar as
oport unidades para comportamento polimrfico.
Quando trata um subtipo como se ele fosse o tipo base, voc perde o acesso a todos os
comportamentos adicionados pelo subtipo. Assim, quando voc criar um novo subtipo,
prec isar garantir que a interface do tipo base seja adequada para a interao com seu
novo subtipo, em mtodos que trabalham com o tipo base.
10. A herana efi cnz tem um impacto direto no polimorfismo de incluso. Pnra nproveilar a
capacidade de conexo oferec ida pelo poli morfismo de subtipo, voc deve ter lima hierarquia de objetos correta.
O encapsulamento evita que um objeto fique vincu lado a um a implementao especifica.
Sem encapsulam ento, um obj eto poderia se tornar facilmente dependente da im plementao interna de outro objeto. Tal acoplamento fone toma a substi tuio difc il, se no
impossvel.

Respostas dos exerccos


1. Imagine um programa que escreva seu status na linha de comando ao ser executado. Na
linguagem Java, voc poderia si mplesmente usar Sys tem .write. pr i nt l n D. para escrever essas mensagens na tela . E se voc quisesse que essas mensagens fosse m gravadas
cm um arquivo? E se voc quisesse que essas mensagens fossem enviadas para uma GU I
de alarme em outro computador? Obviamente, voc precisaria alterar seu cdigo, conforme os req uis itos mudassem.
E se seus requisitos exigissem que voc oferecesse suporte para ambos ao mesmo tem po? Em vez de um ou outro, voc quer permit ir que o usurio escol hn onde va i escrever,
atravs de um argumento de linha de comando. Sem pol imorfismo, voc precisaria programar casos para cada tipo de escrita. Com o polimorfi smo, entretanto, voc pode simplesmente declarar uma clnsse chamada 1og, que ten ha um mtodo de escrita. Subclasses
podem especificar onde as mensagens so gravadas. Voc pode ad icionar novos subtipos
em seu progra ma a qualq uer momento. O programa sabera automati camente como usar
os novos subtipos, desde que voc programe para a interface 109. Assim, voc pode trocar para o novo comportamento de log a qualquer momento.
2. int i

2 + 3. 0

Dependendo da defin io de +, essa instruo pode ser coerciva. Aqui , a instruo tenta
somar um nmero inteiro e um nmero real. Ela pega o resultado e o coloca em um a varivel 1nt. Dependendo da linguagem, o compilador pode converter o inteiro 2 em um
nmlero rea l, efetuar a operao aritmtica e. em seguida. convener o resultado novamente para um inte iro.

Respostas

Essa instruo interessante, pois e la tambm pode demonstrar uma instncia de sobrecarga. + pode sobrecarregar as seguintes operaes:
+(real ,real)
+(integer . integer)
+(integer . real)
Em qualquer caso, voc tem pol imorfi smo ad-floc, pois, em vez de um mtodo pol imrfic o, voc tem vrios mtodos polimrfi cos ou converso.
3. Sobrecarga:
Considere java . util . SimpleTimeZone. SimpleTimeZone define os doi s mtodos sobrecarregados a seguir: setEndRu 1e e setS ta rtRu 1e. Como resultado, esses mtodos respondem diferentemente, dependendo do nmero e dos tipos de entrada.
Polimorfi smo de incluso:
Cons idere java. iO.Writer. A classe abstrata Wri ter define vrios mtodos para gravar
dados. Correntemente, a linguagem Java define vrias subclasses de Wri ter: BufferedWri ter, CharArrayWriter, Fi 1terWriter, OutputStreamWriter, PipedWriter, PrintWriter
e StringWrite r . Cada subclasse define o comportamenlo dos mtodos el ose, f lush e
write (um mtodo sobrecarregado, a propsito).
Ao programar, voc deve escrever seus objetos e mtodos para agirem em instncias de
Wri te. Desse modo, voc pode trocar para diferentes subc lasses, dependendo de como
deseja que os dados sej am gravados. Se voc programar dessa maneira, Wri ter expressar vrios comportamentos di fe rentes, dependendo da im plementao subjacente que esteja sendo usada.

Dia 7 Respostas do teste


Respostas do teste
I. o mtodo observeO de

PsychiatristObject um exemplo de sobrecarga de mtodo.

2. O mtodo observe () i Iustra muito bem o problema da sobreca rga . Sempre que voc adicionar um novo subtipo, precisar ad icionar outro mtodo sobrecarregado. med ida que
o nmero de mlodos aumentar, voc desejar encont rar uma manei ra de ad icionar uma
funo com um em seus objelos, para que possa trat-los genericamente e remover os mtodos sobrepostos.
3. So dois passos para adicionar novo comportamento em uma hierarquia poli mrfica.
Pri meiro, crie o novo ti po. Segundo, al tere seu programa de modo que ele possa eriar instncias do novo tipo. Voc no deve ter de mudar nada ma is, a no ser que precise tirar
proveito de algum recurso especial da nova classe.

Apndice A

4. O mtodo exami ne() de Psychi at ri stObjec t um exempl o de polimorfismo de incluso. Ele pode trabalhar com qualquer subtipo de MoodyObject.
5. Voc pode eliminar as condicionais atacando os dados que fazem parte das condicionais. Se os dados no so um objeto, transforme-os em um objeto. Se os dados so um objeto, adicione um mtodo que fornea o comportamento necessrio. Uma vez feito isso,
pea ao objeto para que faa a lgo, no faa algo nos dados.
6. O polimorfismo de incluso permitir que um mtodo funcione para o tipo de argum ento
e qua lquer s ubtipo. Voc no precisa de um metodo d iferente para cada s ubtipo. Ter apenas um mtodo dim inui o nmero de mtodos que, de outra forma, voc precisaria. Isso
tambm simplilica a adio de novos recursos.
7. Na 00, voc no deve pedir os dados de um objelo. Em vez disso, voc deve pedir a um
objeto para quc faa algo com scus dados.
8. As condicionais o obrigam a quebrar o relacionamento deli neado no Exerccio 7. Quebrar o relacionamento o obriga a misturar responsabilidades, pois todo usurio precisar
saber o qu os dados representam e como manipul-los.
9. Se voc se encontraratua li zando vrias condi cionais, semprc que adiciona um novo t ipo,
ento a condiciona l um problema. Se voc se encontrar escrevendo a mesma cond icionaI em vrios lugares (ou chamando um mtodo que tenha a cond icional), ento a condicional um problema.

10. O polimorfismo permite que voc trate um s ubtipo como se ele fosse o supertipo. Entretanto, o poli morfismo permite que voc use o comportamento do tipo subjacente real. O
pol imorfis mo faz parecer que osupertipo manifesta muitos comportamentos diferentes.

Dia 8 Respostas do teste e dos exerccios


Respostas do teste
I. A UML a Unified Model ing Language. A UML uma linguagcm de modelagem padro do setor.

2. Uma metodologia descreve como projetar software. Uma linguagem de modelagem ajuda a capturar esse projeto graficamente. Uma metodologia freqentcmente conter sua
prpria linguagem de modelagem.
3. O laboratrio demonstra um relacionamento de dependncia.
4. Voc pode fazer duas afirm ativas sobre MoodyObject. MoodyObject tem um mtodo chamado queryMood (). MoodyObject tambm uma classe abstrata. O nome em it lico ind ica
que a classe abstrata .

Respostas

5. O relacionamento Employee, do Laboratrio I, um exemplo de dependncia. O mtodo


payEmployeesO de Payroll depende da interface pbl ica de Employee.
6. Cada um desses smbolos transmite informaes de visibi lidade. + pbl ico, # prote
gido, e - pri vado.
7. Um objcto Queue e seus elementos so um exemplo de agregao.
8. O obj eto Deck tem muitas cartas. Entretanto, se voc destruir O baralho, dever destrui r as
cartas. O objeto Deck um exemplo de relacionamento de composio.
9. Basta deixar um nome de classe ou mtodo em itlico para mostrar que ele abst rato.
10. O objet ivo tinal da modelagem transmitir seu projeto. Conseqentemente, voc no
deve se preoc upar com o uso de toda notao de modelagem disponvel. Em vez disso,
voc deve usar a notao mnima que ainda transm ita sua mc nsagem com xi to.
I I. Uma associao modela relacionamentos estruturais entre objetos. A agregao e a composio so subt ipos da assoc iao que modela relac ionamentos ' todo/ parte'. Uma agregao um relacionamento estrutural entre pares. A composio um relacionamento
estrutural onde a parte no independente do todo. A parte no pode existi r separadamente do todo.
12. Mode le uma associao quando o objetivo de seu modelo for modelar os papis entre os
objetos. Use agregao ou composio quando voc estiver tentando transmitir o projeto
est rutural.

Respostas dos exerccos


I.
Fir.

FIGURA A .1

Uma fila.

+ enqullulI (obj' ObjOClI: yold


+ dequllua ( I' ObjllCt
+ ,sEmpty (I' boolean
+ pook (I: ObjOCl

2.
FIGURA A .2

Um relaciollamemo de
composit1o
A belllalCol",ia.

COJrT\6i.

Aba lha

Apndice A

3.
..~

FIGURA A .3

VIII ndaciollalllelllo de
agrega(io
Banco/Collfa Bal/cria.

ConuEru:n.

4.
FIGURA A .4
A associa(io
COlllpradorlCOIllel""iol1re.

compra dor

compra de

Comprador

vendedor

Comercianle

vende para

vendedor

comprador

Comercianle

Comp-rador

5.
FIGURA A .5

Emplo YH

A hieml"qllia Employee.

- tifSl...na me : Slring
-Iasename: Slrlng
- wage : double
+ getWage ( ) : double
+ gelFirslName ( ) : String
+ getLastName ( ) : String
+ calculatePay (): double
+ printPaychllCk ( ) : String
+ calculate80nuli ( ): double

7
Comml"lonedEmployee
- oommission : double
- unidades: inl
+ addSalfl'S (unilli inl) : void
+ resetSales ( ) : void
+ calculatePav () : double
+ calculateBonu$ (I: double

I
haure : inl
+ addHo ur. (hou,..: inl) : void
+ resetHours ( ): void
+ calculataPay ( ) : double
+ calculateBonus ( ) : double

Resposta s
P'fson. lityObject

FIGURA A .6

A hierarquia
spelk ( I : String

Persona l ; tyObject.

OptimlsticObJec:t

Introv.rtedObJec:t

PeulmllllcOb}ed

+ speak ( I: String

spellk ( I :

Strin~

spellk ( I : String

Dia 9 Respostas do teste e dos exerccios


Respostas do teste
I. Um processo de software d ispe os vrios estgios do desenvolvimento do software.
2. Um processo iterativo um processo que permite a voc voltar e refazer o u melhorar
continuamente o produto de iteraes anteriores. Um processo iterativo adota uma estratgia iterativa e incrementa l para o desenvolvimento de software .
Incremental significa que cada iterao acrescenta um pequeno aumento na funcionalidade. No to pequena para passar desapercebida, mas no to grande para ser deixada
de lado por ser demasiadamente d is pendiosa.
3. No fina l da AOO voc deve ter um bom entendi mento dos requisitos do sistema, assim
como do vocabulrio do domnio do sistema.
4 . Os requi si tos informam o que os usurios querem fazer com o sistema e quais tipos de
respostas eles esperam receber.
Os requ isitos so aqueles recursos que o sistema deve ter para resolver deterrn inado problema .
5. Um caso de LI SO descreve a interao entre o usuri o do sistema e o sistema. O caso de
uso descreve como o usurio uti lizar o sistema a partir de seu ponto de vista.
6. Voc deve dar os seguintes passos para defi nir seus casos de uso:
I. Identi fi car os alores
2. Criar uma lista pre liminar de casos de uso
3. Re fin ar e nomear os casos de uso
4. Defin ir a seq ncia de eventos de cada caso de uso
5. Mode lar seus casos de uso
7. Um ator algo que interage com o sistema.

Apndi ce A

8. Voc pode fazer as segui ntes perguntas para ajudar a encontrar atares:
Quem principal mente vai usar o sistema?
Exi stem outros sistemas que usaro o sistema? Por exemplo. existem usurios
no-humanos?
O sistema vai se comunicar com qualquer outro sistema? Por exem plo, j existe um
banco de dados que voc precisa integrar?
O sistema responde a estmu los no gerados pelo usurio? Por exemp lo, o sistema precisa fazer algo em dctcnninado diade cada ms? Um estmulo pode serprovenicnte dc
fontes norma lmente no consideradas ao se pensar do ponto de vista puramente do
usurio.
9. Um caso de uso pode conter e utilizar outro caso de LI SO, ou estender outro caso de uso.
Um caso de uso tambm pode ser uma variante de outro caso de li SO.
10. Uma variante de caso de uso um caso especial de um caso de uso mais gera l.
I I. Um cenrio uma seq Uncia ou flu xo de eventos entre o usu rio e o sistema.
12. Voc pode modelar seus casos de uso atravs de diagramas de intcrao e diagramas de
atividade. Ex istem dois tipos de diagramas de interao: diagramas de seqUncia e de colaborao.
13. Os diagramas de seq i.inc ia modelam a seqncia de eventos com o passar do tempo. Um
diagrama de colaborao modela as interaes entre os atares de um caso de uso. Os dois
tipos de diagramas so diagramas de interao. Entretanto, cada um adota um ponto de
vi sta diferente em relao ao sistema. Use diagramas de seqncia quando quiser controlar eve ntos e diagramas de colaborao, quando quiser destacar relacionamentos.
Os diagramas de at ividade o ajudam a modelar processos paralelos. Use diagramas dc
at ividade quando qui ser transmiti r o fato de que um processo pode ser executado em parale lo com outros processos, durante um cenrio de caso de uso.
14. Um modelo de dom nio apresenta vrias vantagens. O mode lo de domn io pode servir
como base ou esqueleto de seu mode lo de objetos. Voc pode usar essa base como um
incio e construir a part ir de la.
Os mode los de domnio tambm fornecem um vocabulrio com um e um entendimento
do problema.
15. Os casos de uso o ajudam a entender o sistema, seus requi sitos e seus usos.
Os casos de uso podem aj ud-lo a planejar as iteraes de seu projeto.
Final mente, os casos de uso o ajudam a definir seu mode lo de domnio.

Respostas

5 17

Respostas dos exerccios


1. Alguns outros casos de uso:

Remover lIem: um usurio pode remover um item do carrinho.

Exclui r Usurio: um admin istrador pode remover contas inativas.

Premiar Usurio: o sistema pode recompensar cl ientes freqentes, oferecendo descontos dinamicamente.

2. O usuriose leciona um item do carrinho de com pras. O usuri o remove O item selecionado do carrinho de compras.

Remover Item .

I. O usuri o convidado se lec iona um item do carrin ho de compras.


2. O usuri o conv idado pede ao carrinho para que remova o item:

Condies prvias.
O carrinho contm um item para remover.

Condies posteriores.

O item no aparece mais no carrinho.

Alternati va: Operao Cancelada.

O usurio pode optar por cancelar a transao aps o passo I.


3. Os dois casos de LISO a seguir so variantes do caso de uso Pesq uisar o Cat logo de Produtos:

Os usurios convidados podem pesquisar o catlogo de produtos.

Os usurios convidados podem procurar um item especfico.

Os doi s casos de

LISO

a seguir so variantes do caso de uso Assinar Not ilicaes:

Os usurios reg istrados podem assinar notifi caes.

Os usurios regi strados podem assi nar vrias listas de mensagens.

4. Existem muitos outros obj etos de domnio. Aqu i esto alguns: Administrador, Li sta de
Produtos Destacados e Lista de Pedidos.

Dia 10 Respostas do teste e dos exerccios


Respostas do teste
I. Existem trs vantagens em um projeto fonnal. Um proj eto fo rmal o aj uda a descobri r
quais objetos aparecero em seu programa e como e les vo interagir ou se enca ixar.

Apndice A

Um proj eto o ajuda a prever muitos dos problemas de projeto que apareceriam durante a
implementao. mu ito mais fcil corrigir um projeto antes que seja codificado.
Finalmente, um projeto ajuda a garantir que todos os desenvolvedores estejam na mesma
pgina; caso contrrio, voc corre o risco de que cada desenvolvedor desenvolva partes
incompatveis.
2. POO o processo de construir o modelo de objetos de uma sol uo. Di lo de outra manei ra, POO o processo de decompor uma soluo em vrios objelos constitui ntes.
3. O modelo de objetos o projeto dos objetos que aparecem na soluo de um problema. O
modelo de objelos final pode conter muitos objelos no encont rados no domn io. O //1 0dela de objelos descrever as responsabil idades, relacionamentos e estrutura dos vrios
objetos.
4. Si mpl esmente no possive l prever cada deciso de projeto, antes que voc a tome, e
isso nem sempre vale a pena. Algum projeto pode ser deixado at a construo. Alm
disso, voc no quer ser pego tentando criar o projeto perfeito. Voc precisa comear a
cod ificar, algum dia.
5. As partes signi ficativa s so aqueles aspectos do sistema que alteram completamente sua
estrutura ou seu com portamento. Essas so as partes que realmente importam, quando
voc cod ifica a soluo. Uma mudana em uma parte arquitetnica importante mudar a
estrutura da soluo.
6. Os cinco passos bsicos do POO so:
I. Gerar a lista inicial de objetos.

2. Refinar as responsabilidades de seus objetos atravs de ca rtes CRC.


3. Desenvolver os pontos de interao.
4. Detalhar os relacionamentos entre os objetos.
5. Construir seu mode lo.
7. Comear com o domnio para gerar sua lista inicial de objetos. Cada objeto e cada atar do
domnio deve se tornar uma classe em seu model o de objetos.
Sistemas de tercei ros, interfaces de hardware, relatrios, telas e dispos itivos tambm devem se tornar classes.
8. Um projeto completo capturar as responsabilidades de cada objeto, assim como a estrutura e os relacionamentos do objeto. Um projeto mostrar como tudo se encaixa.
9. Os cartes CRC oaj udam a identi ficar responsabil idades e colaboracsde cada classe.
10. Colaborao o relac ionamento de delegao entre dois objetos. Voc pode considerar
uma colaborao como um relacionamento cliente/servidor enlre dois obj ctos.

Respostas

I I. Praticamente, as responsabilidades se trad uz iro em mtodos. Os relacionamentos se traduziro em uma estrutura; entretanto, um entendimento g lobal das responsabi lidades o
aj udar a dividir as responsabil idades eficientemente entre os objetos. Voc precisa evitar ter um conjun to pcqueno de objetos muito grandes. Atravs do projeto, voc garanti r
a disperso das responsabilidades.
12. Um carto C RC uma fi cha de arquivo 4x6 que o ajuda a descobri r as responsabi lidades
e colaboraes de um objeto, explorando casos de uso.
13. Voc est intencionalmente lim itado pelo tamanho de um carto CRC. Se voc verificar
que est ficando se m espao, so boas as chances de que sua classe esteja faze ndo coisas
demai s.
14. Voc deve usar cartes C RC durante os estgios iniciais do desenvolvi mento, especialmente quando voc ainda for in ic iante no desenvolvimento 00. Os cartes CRC sc prestam para pequenos projetas ou para uma pequena seo de um projeto maior.
Voc s deve usar cartes CRC para descobrir res ponsabilidades e colaboraes. No
tente descrevcr relacionamentos complexos atravs de cartes CRe .
15. Os cartcs C RC no funcionam bem para projetos grandes ou para grupos de desenvolvimento. Um grande nmero de classes pode atrapalhar uma sesso de cartes CRC. Desenvolvedores demais tambm podem dan ificar uma sesso de cartes CRC.
16. Um ponto de interao qualquer lugar onde um objeto use outro.
17. Em um ponto de interao, voc deve considerar transformao de dados, alterao fut ura, interfaces c o uso de agentes.
18. Um agente um objeto que faz a intenned iao entre dois ou mai s objetos para cumprir
algum objetivo.
19. Voc vai definir as dependncias, associaes e general izaes. Detalhar esses relacionamentos um passo importante, pois isso define como os objetos se encaixam. Isso
tam bm dcfine a est rutura interna dos vrios objetos.
20. Voc poderia criar diagramas dc classe, diagramas de atividade e diagramas de interao
para mode lar seu projeto. A UML tambm define diagramas de objeto e d iagramas de estado.

Respostas dos exerccios


I. As instncias de Shopp i ngCart tero a responsabil idade g lobal de conter itens. Especificamente, um objeto Shoppi ngCart pode adicionar um item em si mesmo, remover um
item de si mesmo e permitir que um obj eto externo selec ione um item, sem remov-lo.

Apndice A

Dia 11 Respostas do teste e dos exerccios


Respostas do teste
I. Uma classe adaptadora transforma a interface de um objeto naquela esperada por seu
programa. Um adaptador contm um objeto e delega mensagens da nova interface para a
interface do objeto contido.
2. O padro Iterator descreve um mecanismo para fazer lao pelos elementos de uma colco.
3. Voc usaria o padro Ite r ator para conter lgica de navegao em um local, fornecer
um modo padro de percorrer colees e ocultar do usuri o a implementao da co lco.
4. O padro Adapter descreve um mecan ismo que permi te transformar uma interfa ce de objetos.
5. Voc usaria o padro Adapter quando precisasse utilizar um objeto que tivesse uma interface incompatvel. Voc tambm pode usar empacotadores preventivamente, para
isolar seu cdigo das mudanas de APL
6. O padro Proxy intennedia de fonna transparente o acesso a um objelo. Os proxies adicionam um procedimento indireto no uso do objeto.
7. Voc usaria o padro Proxy sem pre que quisesse intenned iar o acesso a um objeto de maneira que uma si mples referncia no pennite. Exemplos comuns inc luem recursos remotos, otimi zaes e limpeza gera l de objeto, como contagem de referncia ou reunio
de estatsticas de util izao.
8. Nessa situao, voc pode usar o padro Adapter para criar uma interface independente
daquela fornec ida pe la Sun, IBM ou Apache. Criando sua prpria interface, voc pode
permanecer independente da APl ligeiramente diferente de cada forneced or. Empacotando a bibl ioteca, voc est li vre para trocarde bibl ioteca a qualquer momento, seja para
migrar para uma nova verso ou para trocar de fornecedo r, pois voc controla a interface
do adaptador.
9. Nessa situao, voc pode usar o padro Proxy para ocultar a identidade do objeto que armazena os dados dos objetos que o chamam. Dependendo da localizao do cliente,
voc pode instanciar um proxy interligado em rede ou um proxy local. De qualquer
modo, O restante do programa no notar a diferena; portanto, todos os seus objetos podem usar uma interface proxy sem ter de se preocupar com a implementao subjacente.
10. O padro Proxy no muda uma interface, no sentido de que ele no retira nada dela.
Entretanto, um proxy est livre para adicionar mais mtodos e atributos na interface.

Respostas

Respostas dos exerccios


I.

LISTAGEM 11 .13 ShoppingCart .java


public class ShoppingCart 1
java.util.linkedlist items : new java.uti l .lin kedlist() ;

r* ad iciona um item no carrinho


* @param item o item a ser ad i cionado

./

pu bl ic void add ltem( Item item ) {


items . add ( item);

r* remove o item dado do carrinho


* @param item o item a ser removido

./

pub l ic void removeItem( Item item) (


items. remove( item )i

r* @return int o nmero de it ens no carrinho


./

public int getNumberltems() (


return items.size()i

r* recupera o item indexado


* @param i ndex o lndice do item
* @ret urn Item o item no lndi ce

./

public Item get ltem( int index) {


return (Item) items.get( index )i

pub l ic I te rator iterator() (


II Arraylist tem um mtodo iterator() que retorna um ite rator
/1 ent retanto, pa ra propS itos de demonstrao , ajuda ver um iterato r
/1 simples
return new Cart l terator( items )i

I
I

521

Apndice A

LISTAGEM 11 .14

CartIterator.java.

public class Cartlterator implements lterator {


private Object [] items;
private int index;
public Cartlterator( java . util.linkedlist items ) (
this.items items.toArray() ;
}

public boo l ean isOone() {


if( index >z items.length ) {
return true ;
}

ret urn false;


}

publ iC Object curre ntItemO (


if( lisOone() ) I
return items [index];
}

return null;
}

publiC void next() {


index++ ;
}

publiC void f irst() {


index O;
}

2. Tornando o adaptador mutante, voc pode usar o mesmo empacotador para empacotar
muitos objetos diferentes e no precisa instanciar um em pacotador para cada objeto que
precise ser empacotado. A reutilizao de empacotadores faz melhor uso da memria e
Iibera se u programa de ter de pagar o preo da instanciao de muitos empacotadores.
LISTAGEM 11 .15

MutableAdapter.java

publ ic cla ss MutableAdapter extends MoodyOb ject I


private Pet pet;
publi C Mu tableAdapter( Pet pet ) {

Respostas

LISTAGEM 11 .15

Mutab leAdapte r.java (continuao)

setPet( pet );
}

protec ted St ri ng getMood () I


II imp lementando apenas porque ex i gido
II por MoodyObject, pOis tambm sobrepe queryMood
II no precisamos disso
return pet.speak();
}

publi C yoid queryMoodO I


System . out.println( getMoodO );
}

public yold se tPet( Pet pet ) I


this.pet pet;
}
}

Dia 12 Respostas do teste e dos exerccios


Respostas do teste
1. Uma classe empacotadora transfonna a interface de um objeto naquela esperada por seu
programa. Um empacotador contm um objeto e delega mensagens da nova interface
para a interface do objeto contido.

2. O padro Abstract Factory fornece um mecanismo que instancia instncias de classe descendentes especficas, sem reve lar qual descendente real men te criada. Isso permite conectar, de forma transparente, diferentes descendentes em seu sistema.
3. Voc lisa o padro Abstract Factory para ocultar os detalhes da instanciao, para ocultar

a classe de objetos que instanciada e quando quer que um conjunto de objetos seja usado junto.
4. O padro Singleton garante que um objeto seja instanciado apenas uma vez.
5. Voc usa o padro Singleton quando quer que um objeto seja instaneiado apenas uma

vez.
6. Usar consta ntes primitivas no uma estratgia de 00 para programao, pois voc tem
de aplicar um significado externo constante. Voc viu quantos problemas o desdobramento da responsabilidade poderia causar!

Apndice A

o padro Typesafe Enum resolve esse problema, transformando a constante em um objeto de nivel mais alto. Usando um objeto de nvel mais alto, voc pode encapsular me lhor a responsabil idade dentro do objeto constante.
7. Voc deve usar o padro Typesafe Enum quando se encont rar declarando constantes pblicas q ue devem ser objetos propriamente di tos.
8. No, os pad res no garantem um projeto perfeito, pois voc poderia acabar usando um
padro incorretamente. Alm disso, usar um padro corretamente no significa que o restante de se u projeto seja vl ido. Muitos projetos vlidos nem mesmo contm um padro.

Respostas dos exerccios


I.

LISTAGEM 12.19 Bank.java


publi c class Bank {
private java.util.Ha shta ble accounts

new java.uti l . HashtableO;

private statlc Bank ins tance;


protected Ba nkO {)
publi c stati c Ba nk getlnstance(){
i f( ins t ance nu l l ) I
in stance new Bank();
}

re t urn in stan ce;


}

public vo i d addAccoun t( String name , BankAccount ac count ) {


aceounts .put( name , aeeo unt ) ;
}

pu bl ic double tota l Ho l ding s( ) {


doubl e total = 0.0 ;
java.ut il .Enurnerati on enum" ac counts.elemen t sO ;
wh il e ( enum.hasMoreElernents() ) I
BankAceount aeeount
(BankAccount) enum. nextE l ement();
tota l +- aecount.getBalance();
E

return tota l;
}

Respostas

LISTAGEM 12.19 Bank.java (continuao)


publiC int totalAccounts() (
return accounts .size():
J

publi C void deposite Str i ng name , double ammount ) (


BankAeeount aeeount retrieveAeeount( name ):
if( aeeount ! - null ) (
aeeount .deposi tFunds( ammount ):
J
J

publie double balanee( String name ) {


BankAeeount aeeount ret r ieveAeeount( name ):
if( aeeount ! - null ) (
return aceount.getBalance{):
J

return 0.0:
J

private BankAecount retrieveAccount( String name ) (


return (BankAecount) accounts .get{ name );

J
2.

LISTAGEM12.20 Level .java


publie fina l elass Level {
public
public
publie
public

fi nal
fi nal
fi na 1
fi na 1

statie
stat1e
slatie
statie

Level
Level
Level
Level

NO ISE
INFO
WARNING
ERROR

new
new
new
new

Level (
Level (
Leve 1 (
Level (

private int level:


private St ring name ;
private level( int level, String name ) {
this.level leve l :
thiS.name name :
J

publlc int getlevelO {

O, "NOISE" ):
1 , "INFO" ):
2, "WARNING" ):
3, "ERROR" ):

Apndice A

LISTAGEM 12.20 level. j ava (continuao)


return level;
}

public String getName() I


return name ;
}
}

LISTAGEM 12.21 Error .java


pub l ic class Error 1
pr;vate Level level ;
public Error( Level level ) {
this.level level ;
}

pub l iC Level getLevel() 1


return level;
}

publiC String toString() {


return level.getName ();
}
}

3. A soluo consiste em uma factory abst rata de conta bancria (escrita como uma interface; entretanto, ela tambm pode ser uma classe abstrata) e em uma Factory concreta de
conta bancria. A factory tem um mtodo para criar cada tipo de conta bancria.
Essa factory oculta os deta lhes da instanciao e no necessariamente o subtipo do objeto.

LISTAGEM 12.22 AbstractAccountFactory.java


pub li c inte rface AbstractAccountFactory {
publ iC CheckingAccount createCheckingAccount( double i nitDeposit . int trans.
doubl e fee ) ;
pub l ic OverdraftAccount createOverdraftAccou nt( double in i tOeposit. double
rate );
public RewardsAccount createRewardsAccount( double i nitDepos;t. double
interest . double min };

Respostas
LISTAGEM

527

12.22 AbstractAccountFactory .java (continuao)

publiC SavingsAccount createSavingsAccount( double initBalance. double


interestRate );
public TimedMaturityAccount createTimedMaturityAccount( double initBalance.
double interestRate. double feeRate );

LISTAGEM

12.23 ConcreteAccountFactory,java

public class ConcreteAccountFactory implements AbstractAccountFactory (


publiC CheckingAccount createCheckingAccount( double initOeposit . int tra ns .
double fee ) {
return new Check i ngAccount ( i ni tDepos i t . tra ns . fee ) ;
I
publ i c OverdraftAccount createOverdraftAccount( double initDeposi t . double
rate) (
return new OverdraftAccount( initOeposit . rate );

I
public RewardsAccount createRewardsAccount( double initOeposit. doub le
interest. double min } I
return new RewardsAccount( initOeposit. interest. min };

I
publi c SavlngsAccount createSavingsAccount( double initBalance. double
interestRate ) I
return new SavingsAccount{ i nitBalance . intere st Rate );

I
publi C TimedMaturityAccount createTimedMaturi tyAccount( double i nit8alance.
double interestRate . double feeRate ) 1
return new TimedMatu r ityAccount( ini t Balance. interestRate. feeRate ) ;

I
I

Apndice A

Dia 13 Respostas do teste e dos exerccios


Respostas do teste
I. A anlise, projeto e implementao de uma UI no so diferentes do restante do sistema.
A UI deve ter considerao igual durante todas as fases do desenvolvimento. Antes de
tudo, voc deve certificar-se de no ignorar as consideraes sobre a UI.
2. Voc deve desacoplar as Uls para que o sistema e a UI no se tomem entrelaados. dificil fazer alteraes na UI, quando entre laada com a funci onal idade bsica do sistema.
Tambm imposs vel com partil haro sistema com outras Uls ou tipos de UI, quando a UI
e o sistema esto entrelaados.

3. Os trs componentes so o mode lo, o modo de visuali zao e O controlador.


4. O padro PA C e o Document/V iew Model so duas alternativas para o padro MVC.

5. O modelo a camada da trade MVC que gerencia o comportamento bsico e o estado do


sistema. O controlador usa o modelo para instigar o comportamento do sistema. O modo
de visualizao usa o modelo para recuperar informaes de estado para exi bio.
O modelo tambm fomece um mecanismo de notificao de alterao. O modo de visualizao e o controlador podem usar esse mecanismo para estar a par das mudanas de estado no modelo.
6. O modo de visua lizao o membro da trade MVC responsvel por apresentar o modelo
para o usurio.
7. O controlador responsve l por interpretar os eventos gerados pelo usuri o. O controlador instiga o comportamento no modelo ou no modo de visual izao, em resposta a esses
eventos.

8. Um sistema pode ter muitos mode los. Um modelo pode ter muitos modos de vi sualizao diferentes. Um modo de vi suali zao pode ter um controlador e um controlador pode
controlar apenas um modo de visua lizao.

9. Ineficcias podem ser encontradas no modelo do modo de visua li7.ao c do controlador.


Um modelo deve ev itar notificaes de alterao de estado desnecessrias. Os modos de
visualizai'lo e controladores devem colocar os dados cm cac he, quando possvel.
10. O padro MVC supe um modelo estvel e uma apresentai'lo varivel.
11 . Um resumo muito detal hado da histria e da moti vao por trs do padnl0 MVC est em
"A ppl ical ions Programming in Smal ltalk-80(TM): I-Iow to use Model- View-Conlroller
(MVC)", de Steve Burbeck, Ph .D. Voc pode encontrar uma cpia no endereo
http: //st-www.cs. ui uc.edu/users/sma rch/ st-docs/ mvc.html

Respostas

Ento, qual o objetivo dessa pergunta? Bem, a resposta proporciona a voc uma perspectiva importante da moti vao por trs do pad ro MVC. Lendo a histria, voc tambm notar que o padro MVC fo i desenvolvido inicialmente como parte da Smalltalk.
Agora seu uso encontrado em quase qualquer li nguagem. Isso traz um ponto importante: os padres no so ut ilizaes de linguagem - eles so padres que funcionam em
qualq uer linguagem com os recursos requisitados.
A MVC no est relacionada com Java ou Smalltalk. Est relacionada a um projeto que
transcende a linguagem de implementao.

Respostas dos exerccios


I. A listagem 13.1 1 apresenta a nova classe Employee.
LISTAGEM 13.11 Employee. j ava
import java.util . ArrayLi st :
1mport java. ut 11 . Itera tor :
publi C abstract c1ass Emp10yee {
private
private
private
private

String firs t_name :


Str ing l ast_name ;
double wage:
ArrayList 11steners new Arrayli st() :

publi C Employee(Str ing first_name,S t ring las t _name,doub l e wage) {


thi s . first_name first_name :
this.last_name a las t_name :
t hi s .wage wage;
}

pu bl iC double getWageO {
re turn wage:
}

publ ic vo i d setWage( double wage ) {


this.wage wage ;
updateObservers() ;
}

pub l ic String getFirstName() {


r eturn fir s t_name ;
}

publi c St ring getLastName() I

Apndi ce A

LISTAGEM 13.11

Empl oyee.java (continuao)

return last_name ;
}

publiC abstract double calculatePay() ;


public abstract doub l e calcul ateBonus() ;
publ i c vold prlntPaycheck(l (
Stri ng full_name last_name + ", " + first_name;
System.out.printl n( "Pay: " + fu ll name + " $ " + calculatePay() );
}

public vold reglster( Observe r o ) {


listeners . add( o l ;
o.update() ;
}

pub l ic void deregister( Observer o ) (


listeners.remove( o ) ;
}

private void updateObservers() (


Iterator i l isteners . iterator() ;
while( i.hasNext() ) (
Observer o (Observer) i.nex t ();
o.update();
}

}
}

2.
A Listagem 13. 12 apresenta a nova implementao de BankAccountController.
LISTAGEM 13.12

BankAccountControl 1er .java

pub l ic class BankAccountController implements Ba nkActivity l istene r {


private BankAccountView view ;
private BankAccountMode l mode' ;
public BankAccountCont roller( BankAccountView view , BankAccountModel model )

I
this.view view;
this .modelo '" mode];
}

Respostas

531

LISTAGEM 13.12 BankAccou nt Controll er. java} (c ontinuao)


publiC vold wlthdrawPerformed( BankAct l vityEvent e ) (
double amount e.getAmount();
model.withdrawFunds( amount );
}

public void deposltPerfonmed( Ban kAc ti vityEvent e ) (


doubl e amoun t a e.getAmount() ;
model .depositFunds( amount );
}
}

ESIa verso de BankAccountControl l er muito mai s fcil de ler do que a origi nal; entretanto, o
modo de vis ualizao agora muito mai s complexo.

Dia 14 Respostas do teste e dos exerccios


Respostas do teste
I. Erros de digitao, erros na lgica ou enganos bobos cometidos durante a codificao
podem surgir. Os erros tambm podem res ultar da interao incorreta entre objetos ou de
falhas no projeto ou na anl ise.
2. Um caso de teste o bloco de construo dos testes. Cada forma de teste constituda de
casos de teste e cada caso de teste testa um aspecto do sistema .
3. Voc pode basea r seus casos de teste em teste de caixa preta ou caixa branca.
4. Os testes de caixa branca so baseados na estrutura do cdigo- fonte s ubjacente. Os testes
de ca ixa branca so projetados para atingir 100% de cobertura do cdigo testado.
Os testes de caixa preta so baseados na especifi cao. Os lestes de ca ixa preta veri fi cam
se o sistema se comporta conforme o esperado.
5. As quatro formas de teste so: teste de unidade, leste de inlegrao, {este de ~istellla e
teste de regresso.
6. Um teste de uni dade o dispositivo de teste de nvel mais baixo. Um teste de unidade envia uma mensagem para um objeto e verifica se recebe o resultado esperado. Um teste de
unidade s deve verificar um recurso por vez.
7. O leste de integrao confirm a se os objetos interagem corretamente. O teste de sistema
verifica se o sistema se comporta conforme definido nos casos de uso e se e le pode manipular uso imprevisto nonnal mente.

Apndice A

8. Voc no deve deixar as testes para o fim. Testarenq uanto voc desenvolve o aj uda a encontrar erros imediatamente. Se voc deixar os testes para o final , haver mais erros e
eles sero mais difceis de rastrear e corrigir.
Testar enquanto voc desenvolve tambm toma mais faci l alterar seu cd igo e pode melhorar seu projeto.
9. A validao manual ou visual propensa a erros. Voc deve evit-Ia o mximo possvel.
Em vez disso, voc deve contar com um mecanismo automtico para validao dos testes
de unidade.
10. Uma estrutura define um modelo de domnio reut ilizvel. Voc pode usar as classes des-

se modelo corno base para seu apli cativo espec fi co.


I I . Um objeto falsificado um substituto simplista de um objelo real , que o ajuda a fazer o

teste de unidade de seus objetos.


12. Os objctos fal sificados permitem que voc faa o teste de unidade de suas classes iso la-

damente. Eles tambm abrem possibilidades de teste que, de outra forma, seriam di ficei s
ou impossveis de fazer.
13. Um erro surge de uma fa lha ou de um defeito no sistema. Uma condio de erro, por outro lado, no um erro, mas sim uma condio para a qual seu sistema deve estar preparado e deve manipular normalmente.
14. Ao escrever seu cdigo, voc pode garantir a qualidade atravs dos testes de unidade, do

tratamento correto de excees e atravs de documentao correta.

Respostas dos exerccos


I. Cookstour dar idias sobre o projeto e as noes por trs de JUnil.

2. A Li stagem 14.12 apresenta um poss vel teste de unidade.


LISTAGEM 14.12 HourlyEmp l oyeeTesLja va

import juni t. framework .TestCase :


i mport junit.framework.Assert ;
public cl ass HourlyEmployeeTest extends TestCase {
private Hou rlyEmp loyee emp:
private static f i na l St r ing FI RST NAME
private static fi nal String LAST NAME
private statlc fi nal double WAGE
protected void setUp() {

=
=
=

-FNAME"
-LNAME"

500 . 00 ;

Respostas

LISTAGEM 14.12

HourlyEmpl oyeeTest . java (con t inuao)

emp new Hou rl yEmp loyee( FIRS T_NAME. l AST NAME . WAGE );
}

publiC yoid test_calculatePay() (


emp .addHours( 10 );
doubl e expected WAGE * 10;
assertTrue( "incorrect pay calculation" . emp.calculatePay() expected );
}

publi C HourlyEmployeeTest( String name ) (


supe re name );
}
}

Dia 15 Respostas do teste e dos exerccios


Respostas do teste
I. PlayerListener um exemplo do padro observvel.

Consol e singlcton. Ele implementa o padro si ngleton.


Rank e Sui t implementam o padro Typesa fe Enum.
2. 81 ackjackDea 1er trata de HumanPlayer de forma polimrfica como um P1 ayer. Voc p0deri a criar jogadores no humanos e B1 ackjackDea1 er saberia como jogar viruee um
com eles.
3. Pl aye r!B1ackjackDealer/HumanP1ayer um exemplo de hierarquia de herana.
4. Deck encapsul a comp letamente os objelos Card que contm. Ele no fornece quai sq uer
mtodos de obteno ou configurao. Em vez disso, Deck adiciona seus objetos Card em
objetos Deckpile.
5. B1 ackjackDea 1er e HumanP1 ayer atuam de fonna polimrfi ca., fornecendo suas prprias ver
5eS personal izadas do mtodo hi t(). Quando o mtodo p1 ay() chamar hi t() , o comporta
mento do mtodo p1ay() variar de acordo com a implementao subjacente de hi te).

Respostas dos exerccios


I. Sem resposta.
2. Sem resposta.

Apndice A

Dia 16 Respostas do teste e dos exerccios


Respostas do teste
I. As estruturas cond icionais so perigosas quando retiram responsabilidade de um objeto e
a colocam em outro lugar. O comportamento pertence ao objeto e no distribudo por
todo o programa . Uma lgica distri buda o obriga a repetir lgica por todo o seu programa, em vez de t- la em apenas um lugar.
As est ruturas condicionais tambm so perigosas porque tornam mais difc il testar um
objeto e cobrir todas as comb inaes de caminhos atravs do objeto.
2. Antcrionncnte, voc viu que podia usar polimorfismo para remover estruturas condicionais.
Hoje, voc vi u que pode usar uma combinao de polimorfi smo e estado para remover
estruturas cond icionai s. O estado um modo excelente de im plementar regras.
3. A verso anterior de Hand exig ia que voc mesmo comparasse os objetos Card de Hand
para veri ficar se dois objetos Hand so iguais ou se um o bjeto Hand maior do que out ro.
Agora, Hand faz essa verificao para voc, sem comprometer seu estado interno.
Hand fa z out ra coisa para se encapsular. Agora, Hand infonna aos receptores de mudanas
de estado. Como Hand coloca prontamente suas infornlaes de estado nos receptores,
no h moti vo para que um objeto interessado faa uma consulta em Hand para conhecer
seu estado.
4. Hand e Handlistene r implementam pad ro observador.
5.

Sem resposta.

Respostas dos exerccios


I. Sem resposta.
2. O segredo desse problema perceber que todos os mtodos levam as mes mas aes para
cima, at o ponto onde uma chamada feita em Pl ayerl i s t encr. A soluo empacotar
essa chamada em um objeto.
Considere o mtodo noti fyl i stener() a seguir:
protected void notifylisteners( Not"ifyHelper helper ) {
I terator i = listeners. i terator() ;
while( LhasNext() ) {
Playe rl istener pl = ( Playe r listener )i.next() ;
helper.notifylistener( pl l;
}
}

Respostas

Note que esse mtodo exalamenle igua l ao ant igo not i fyChangedO ou not i fyBusted() ,
exceto quanto a uma diferena. Em vez de chamar um mtodo diretamente em PI ayerl i stener, o mtodo noti fyl i steners() delega a chamada para um objeto fiot i fyHel per.
A Listagem 16.17 apresenta NotifyHe l per.
LISTAGEM

16.17

estado de espera da banca personalizado

protected i nterface Not i fyHelper I


publ ic void not ifylistener( Playerlistener pI )i
J

A interface NotifyHelper define um mtodo: notifylistenerO. Os implementadores


decidiro qual mtodo vo chamar em Playerlistener.
Ao todo, voc precisar defini r sete implementadores de Not 1fyHe I per, uma im plementao para cada mtodo na interface PI ayerl i stener. A Listagem 16.18 apresenta essas
sete implementaes.
LISTAGEM

16.18 As impl ement ae s de Not HyHe lper .

protected cl ass NotifyBusted imp leme nts Not ifyHe l pe r {


public void notifyl i stener( Pl ayerl istener pI ) {
pl . playerBusted( Pl ayer. th is l i )

J
protected cla ss NotifyBlackj ack imp l ements NotifyHe lper I
publi c void notifyl i stener( Playerlistener pI ) {
pl .playerBla ckj ack( Player . this )i }
J

protected cl ass Noti fyWon implements Not i fyHelper (


publ ic vo i d notifylistener( Playerl istener pI ) (
pl.playerWon( Pl ayer. thi s ) i )
J

protected cl ass Not1fylost implements NotifyHelper (


publi c vo i d notify l i stener( PlayerListener pI ) I
pl.playerlost( Player.thi s )i )
J

protected cla ss NotifyCh anged imp lements NotifyHelper I


publ ic vo i d notifylistener( Playerlistener pI ) I
pl . playerChanged( Player.this ) ; )
J

protected cla ss NotifyStanding imp lements NotifyHelper I


public void not ifyli stener( Player lis tener pI ) (
pl.playerStand i ng( Playe r. th i s ); )

J
protec ted cl ass NotifyStandoff implemen ts Noti fyHe l per I

Apndice A

LISTAGEM 16 .18 As implementaes de NotifyHe 1pe r .

(continuoo)

pub1iC vold notifyListener( PlayerListener pI ) (


p1.playerStandoff( P1ayer . this ); I

Agora, em vez de chamar not i fyCh anged () ou not i fyB1 ac kj ac k(), voc chamaria not i fylisteners( new NotifyChanged() ) ou notifyListeners( new NotifyBlack jack() ).
Se voc acha que essa uma boa soluo ou no, uma questo de gosto pessoal. Emretan to, e la remove os mtodos notifyXXX redundantes.

Dia 17 Respostas do teste e dos exerccios


Respostas do teste
1. Tomar abstrato um mtodo protegido uma boa maneira de estabelecer um protocolo de
herana.
2. Aps a anlise e o projeto de hoje, uma nova hierarquia PI ayer foi descoberta. Como os
requisitos se apresentaram atravs dos casos de uso, a necessidade de uma nova hierarquia de herana se apresentou.
3. A programao por especulao raramente funciona. As hierarquias que voc precisar
para mode lar corretamente um domn ioabslralo se apresentaro aps voc ter traba lhado
com um domnio por algum tempo. Se voc lentar abstrair um domnio sem trabalhar
com esse dom n io, es tar supondo uma soluo.
4. Refazendo a hierarquia, voc ficou com um modelo que representa mais detalhadamente
o j ogo vi nte-e-um . O cdigo tambm mais fc il de entender. Colocar responsabi lidade
ext ra na classe base Player teria resultado em um cdigo difici l de entender.

Respostas dos exerccios


I. Sem resposta.
2. Dobro apenas outro estado de Betti ngPI ayer. Voc sabe q ue ele precisa ser um estado
separado, porque Pl ayer deve reagir de uma fonna d ifere nte ao evento handPlayable.
Em vez de permanecer no estado Jogo, PI ayer deve fazer a transio para o estado Para-

do.
A Figura A. 7 ilustra o novo diagrama de estado para um objeto Bett ingPl aye r que pode dobrar.

Respostas

537

FIGURA A.7
O diagrama
de estadQ de

BettiogPlayer
(lluali: lIdo.
mio 6 ,,1!>!&+Um
(mio In ld.1
dobto(

/ ' d' ~r. )011"


I ~r.l<>g.r

CClm' 11'110

com.m'"
( m'CI~2 1 (

(m6C1~2 1 (

mio .1t01lroU
(11'160>21)

mto Iourou
(mio>21(

Voc tambm precisa alterar o estado Jogo para que ele possa faze r a transio para o estado Dobro. A Listagem 17.6 apresenta os novos estados de Bett i ngPl ayer.

LISTAGEM 17.6

Ooub 1i ngDown e Jogo

pri vate clas s OoublingOown implements PlayerState {


publlc void handChanged() {
notifyChanged() ;

I
public vo i d handPlayable() {
setCurrentState( getStandingS t at e() ) ;
notifyStand1 ng() ;

I
public vo i d handBlackjack( ) {
II imposs ivel no estado de dobro

I
pub l i c vo i d handBusted() {
setCurrentState( getBustedState() ) ;
not ifyBus ted () ;

I
pub l ic void execute( Deale r dea l er ) {
bank .doub l eOown();
dea l er.hit( BettingPlayer . t hi s ) ;
getCurrentState().execute( dea l er );

I 538

Apndice A

LISTAGEM 17.6

Doub llngDown e Jogo (continuao)

I
private class Be tterPl ayi ng i mplements PlayerState (
public voi d handChanged{) (
not ifyC hanged();

I
public void handPlayable(} (
II pode ignorar no estado de jogo

I
public v01d handBlackjack() (
II imposs fvel no estado de jogo

I
publi C void handBusted() {
setCu rrent State ( getBus tedS ta te () ) ;
not ifyBusted () ;

I
publ ic void execute( De aler dealer ) (
if{ getHand().canDoubleDown() &&doub leDown() ) (
se tCurrent State( getDoublingDownState() );
getCurrentState().execute( deale r );
return;

I
if( hit()

I (

dealer.hit{ Bett i ngPlayer.this ) ;


I else (
setCurrentS tate ( getStandingState() );
notifyStanding() ;
I
getCurrentState().execute( dealer );
II transio
I

I
Voc tambm prec isar atualizar HumanPl ayer para que oferea a opo de dobrar. A Listagem 17.7 apresenta a classe HumanPlayer atualizada.
LISTAGEM 17.7

Huma nPlayer .java

publiC cla ss HumanPlayer extends BettingPlayer {


private
private
private
pri vate
private

f inal
fi na 1
fi na1
fi nal
fi nal

static
static
static
stat ic
stat i c

String
St r ing
St r i ng
St r i ng
String

= MH"
HIT

STAND - S"
PlAY_HSG '" "[H]it or (S]tay" ;
BET_MSG = MPlace Bet: [10] [50] or [100]" ;
OD_MSG = MDouble Down? [V] es [N]o";

Respostas

LISTAGEM 17.7

private
priva te
private
private
pri vate
pr ivate

HumanPlayer.java (continuao)

fi na 1
final
f i nal
fi na I
fi na I
fi nal

static
static
stati c
statlc
static
stati c

String
String
String
String
Str i ng
Str ; ng

BEl_lO = MIO";
BEl_50 = MSO";
BEI_I00 = MIOO M;
NO " "NN;
YES = "Y";
OEFAULI = "invalid";

publ ic HumanPlayer( String name , Hand hand. Bank bank ) {


supere name , hand. bank };

I
protected boolean hit() (
while( true ) (
Console.INSIANCE . printMessage( PLAY_MSG ) :
String response Conso l e.INSTANCE.readInput( DEFAUlI );
if( response . equals IgnoreCase( HII ) ) {
return true:
lelse if( response.equalsIgnoreCase( SIAND ) ) I
return fal se ;

II se chegarmos at aqui .
II sign ifica tiva

faz

um lao at obtermos entrada

I
I
protected boolean doubleOown() I
while( true ) I
Conso le.lNSIANCE.printMessage( OO_MSG ) ;
String response Console.INSIANCE.readInput( OEFAULI ,;
if( re sponse .equal sI gnoreCase( NO) ) {
return fal se;
} el se if( response.equalsIgnoreCase( YES ) ) I
return true ;
I
II se chegarmos at aqui, faz um lao at obtermos entrada
II significativa
I

I
protected void betO (
while( true ) (
Conso le . INSTANCE.printMessage( BET_MSG ):
Str i ng response " Conso le. INSTANCE . read Input( DEFAULT l:
if( response.equals( BEl_lO) ) I
getBank().placelOBet():

I 540

Apndice A

LISTAGEM 17.7

HumanPlayer.java (continuao)
return ;

I
if( response.equal s ( BEl_50) ) (
getBank().place50Bet() ;
return;

I
if( respon se,equa ls( 8EI_IOO) ) {
getBank ( ).place l OOSet() :
return ;

/1
/1

se chegarmos at aqui, faz um l ao at ob te rmos entrada


s i gnificativa

I
I
I

Dia 18 Respostas do teste e dos exerccios


Respostas do teste
1. Para introduzir um Vcard, voc pode si mplesmente faze r lima subclasse de Card oPara coloc- Ia no jogo, voc pode faze r uma subclasse de Oeck e, em segu ida, sobrepor bui 1dCards para que a s ubclasse crie objetos VCa rd, em vez de objetos Cardo
2. Originalmente, o mtodo bu i 1dCa rds de Deck era privado. Quando veri ficamos que uma
subclasse prec isava sobrepor o comportamento de bui 1dCards, o tornamos protegido.

Respostas dos exerccios


I. Sem resposta.
2. O projeto e im plementao inici ais que fizemos para o Exerccio 2 do Captulo 17 ainda
so vl idos. Dobrar ape nas outro estado em Sett i ngPl ayer. Voc deve comear escrevendo o cdigo para este exerccio, adicionando o novo estado Ooubl i ngOown em Bet tlngPlayer. Voc tambm precisar fazer as mesmas alteraes fe itas no Captu lo 17,
nas classes Bank e Hand. Quando fi zer essas alteraes, voc precisar atualizar GUI Pl ayer, assim corno Opt i onView e Opt ionViewCont roll er .
Antes de fazer as alteraes exigidas nas classes de modo de visualizao e de con trolador, examinaremoS as alteraes ex igidas em SettingP layer, Hand e Bank.
A Listagem 18.13 destaca as alteraes que foram feitas na classe Hand.

Respostas

LISTAGEM

541

18.13 Destaques das alteraes feitas em Hand

publ i c boolean canDoubleOown() {


return ( ca rds. slze() 2 );

o novo mtodo canOoubleDown penn ite que Be tt i ngPl ayer veri fi que o objeto Hand para
ver se o jogador pode dobrar.
Voc tambm prec isa adicionar um novo mtodo doubl eDown na classc Bank. A Listagem
18. 14 apresenta esse novo mtodo.
LISTAGEM

18.14 O novo mtodo doubleDown

pub l ic void doubl eDownO (


placeBet( bet ) ;
bet bet .. 2;

o mtodo doubleOown dobra a aposta corrente.


Para poder adicionar a fu no de dobrar, voc precisa adici onar um novo estado em Bet tingPl ayer. Voc sabe que precisa de um novo estado porque Bett 1ngPl ayer tem de tratar do evento handPlayable, especial mente ao se dobrar. Normalmente, um evento
handPl ayable sign ifica que o jogador pode receber mai s canas novam ente, se quiser. Ao
dobrar, Ojogador deve parar imediatamente, aps a operao (caso ele no estoure). A
Listagem 18.15 apresenta o novo estado de DoubleDown.
LISTAGEM

18.15 The New Doub l eDown Stat e

private class DoubllngDown implements PlayerState (


public void handChanged() {
noti fyChanged( );

publ ic vo i d handPlayable () {
setCurrentState( getStandingSta t e() ) ;
notify Standi ng();

pub l ic void handB lac kjack() {


II impossfve l no estado de dobro

pub l ic void handBus t ed() {


setCurrentState( get Bust edSta t e() };
not i fyBusted();

publi c void execute( Dea l er dea l er ) {

Apndice A

LISTAGEM 18.15 lhe New OoubleOown State (continuao)


bank.doubleOown();
dealer.hit( BettingPlayer.this );
getCurrentState().execute( dealer ) i
J

J
Quando executado, esse novo estado dir ao objelo Bank para que duplique a aposta, pedi r banca para que distribua mais cartas para o jogador e, ento, far a tran sio para o
prximo estado. O estado seguinte ser parado ou estouro, dependendo do evento enviado para o estado por Hand.
Para obter o estado Doubl i ngDown (Dobro), voc precisar fazer algumas alteraes no
estado Jogo. A Li stage m 18.16 apresenta o novo estado BetterPlaying.
LISTAGEM 18.16 O novo estado BetterPl ayi ng
private class BetterPlaylng implements PlayerState (
public void handChanged() I
notifyChanged();

pub li C vo ld handPlayable() I
II pode ignorar no estado de jogo

publi c vold handBlack jack() (


II impossfvel no es tado de jogo
J

public voi d hand8usted() I


setCurrentState( getBustedS tate() ) ;
notHyBustedO;
J

public void execute( Dealer dealer ) (


if( getHand() . canDoubleDown() &&doub l eDown() ) (
setCurrentS tate( getDoublingDownState() );
getCurrentState().execute( dealer );
returni
J
if( hit()

J (

dealer.hit( BettlngPlayer.this ,;
) else I
setCurrentState( getStandingState() ) i
notifyStanding();

getCurrenlState().execute( dealer ) ;
II transio
J

Respostas

Quando executado, o estado BetterPl aying primeiro verifica se o jogador pode dobrar.
Se assim for, o estado chamar o mtodo doub l eOown de Betti ngPl ayer (voc precisar
adicionar um mtodo abstrato doub leOown em Betti ngPl ayer). Seo mtodo indicar que o
jogador gostaria de dobrar, o estado BetterPl ayi ng configurar o estado corrente como
Ooub 1i ngDown e far a transio para ele.
Se o jogador no quiser dobrar, Oestado continuar ejogar nonnalmente. Veja todas as
alteracs no cdigo-fonte. Existem algumas outras pequenas alteraes, como a adio
de um mtodo getOoubl eDownState em BettingPl ayer. Esse mtodo efetivamente adiciona a possibilidade de dobro no sistema.
Agora, voc precisa al ualizar GU I PI ayer, Opt i onView e Opti onVi ewControll er.
A boa nova que voc no precisa fazer quaisquer alteraes nos estados de GU I PI ayer.
Esses estados no devem fazer nada, pois eles prec isam esperar at que o jogador humano cl iq ue em um boto. Voc precisa implementar o mtod o doubleOown. A Li stagem
18.17 apresenta o mtodo.
LISTAGEM

18.17 O mtodo doubleDown

protected boolean doubleOown() I


setCurrentState( getOoubl i ngOownState() ):
getCurrentState().execute( dealer ):
return true;
}

o boio da GUI pode chamar esse mtodo, caso o usurio decida dobrar. O mtodo configura o estado corrente como o dobro e, em seguida, fa z a transio para ele. O estado
manipula o restante.
Todas as alteraes restantes prec isam entrar em Opt i onVi ew c Opt i onVi ewControll er.
Voc precisa principa lmente adicionar um boto de dobro no modo de visualizao e garantir que ele seja ativado pe lo controlador imediatamente aps a aposta e desativado assim que o jogador pressionar esse boto, o balo de parada ou o de receber mai s cartas.
No se preocupe mui to, se voc no entender totalmente o cdigo da GU !. O importante
que voc entenda como a operao de dobro adicionada no sistema e as id ias bsicas
por trs do modo de visualizao e do controlador.

Dia 19 Respostas do teste e dos exerccios


Respostas do teste
1. As trs camadas so: aprese,,/ao, abstrao e eDil/role.

Apndice A

2. A apresentao responsvel por exibir a abstrao, assim como por responder interao do usurio.
A abslraoeseme lhante ao modelo na MVC. A abstrao representa o sistema bsico.

O controle responsve l por pegar as diversas apresentaes ecombin-Ias em um modo


de visualizao.
3. Voc pode usar herana para faze r uma subclasse de cada uma das classes de sistema que
exigiro uma apresentao. Desse modo, voc no enxerta uma classe de apresentao
diretamente na c lasse de sistema. Em vez disso, voc pode adicionar a classe de apresentao na s ubc lasse.
Usa ndo herana dessa maneira, voc pode fornecer vrios modos de visuali zao do
mesmo sistema. Sempre que voc precisar de um modo de visuali zao diferente, bastar
fazer uma s ubclasse das classes que preci sa ex ibir e faz- Ias criar uma nova apresentao. Quando voc precisar reun ir todas as classes como um ap licat ivo, bastar garant ir a
instanciao das subclasses corretas.
,

4. E, melhor usaro PAC em um sistema estvel com requisitos de interface bem defin idos.
As vezes, a estratgia da herana pode fa lhar para projetas mai s complicados. Q uando a
herana fa lhar, voc ter de enxertar a apresentaodiretamente na classe de sistema. Tal
eventualidade lorna d incil servir muitos modos de visualizao diferentes.
5. Voc consegu iu manter duas Uls porque de ixou a estrutura de observador intacta. Nada
o obriga a remover a estrutura, apenas porque voc utiliza PAC. Na verdade, Sett ingView e Oea l erView usam o mecanismo Pl ayerl i stener para fi car a par das alteraes no jogador e na banca.
6. O padro factory foi usado para garant ir que as instnc ias de classe corretas fosse m usadas juntas. Em particular, voc deve tomar ocuidado de usar um objeto VOeck quando utilizar as classes que criam uma apresentao.

Respostas dos exerccios


I. Sem resposta.
2. O projeto e a implementao ini ciais que voc realizou para o Exerccio 2 do Capitulo 17
ainda so v lidos. Dobro apenas outro estado em Sett i ngPl ayer. Voc deve comear a
escrever o cd igo deste exerc ici o, adicionando o novo estado Ooubl i ngOown em Bett ingPl ayer. Voc tambm precisar fazer as mesmas alteracs que fez no Capitulo 17, nas
classes Bank e Hand. Quando voc fize r essas alteraes, precisar alualizar GUIPlayer e
sua classe de apresentao.
Antes de faze r as alteraes exigidas nas classes da GU I, vamos examinar as alteraes
exigidas em BettingPl ayer, Hand e Bank.

Respostas

A Listagem 19.8 destaca as alteraes que foram feitas na classe Hand.


LISTAGEM 19.8

Destaques das alteraes feitas em Hand

publlc boolean canDoubleDownO {


2 };
return ( cards.size()
ZE

o novo mtodo canDoubleDown permite que Bett; ngPl ayer verifique o objeto Hand para ver se o
jogador pode dobrar.
Voc tambm precisa adicionar um novo mtodo doubleDown na classe Bank. A Listagem 19.9
apresenta esse novo mtodo.
LISTAGEM 19.9

O novo mtodo doubl eOown

pub l ic void doubl eDown() (


placeBet( bet );
bet bet ... 2;

o mtodo doubleDown dobra a aposta corrente.


Para adicionar a aposta em dobro, voc precisa adicionar um novo estado em Bett; ngPI ayer. Voc sabe que precisa de um novo estado, porque Bett; ngPlayer tem de tratar do
evento handPI ayabl e de uma maneira especial quando se dobra. Nonnalmente, um even
to handPlayable significa que o jogador pode receber mais cartas novamente, se qu iser.
Ao dobrar, Ojogador deve parar imediatamente aps t-lo fei to (caso ele no estoure). A
Listagem 19.10 apresenta o novo estado Doub 1eOown.
LISTAGEM 19.10 O novo estado DoubleDown
private class DoubllngDown 1mplements PlayerState {
public void handChanged() {
notifyChanged();

I
public void handPlayable() {
setCurrentState( getStandingS tate() ) ;
notlfyStanding();

I
public void handBlack jac k() {
II 1mpossfvel no estado de dobro

I
publ ic void handBustedO {
setCurrentState( getBustedState() l ;

Apndice A

LISTAGEM 19.10 O novo estado OoubleOown (continuao )


not1 fyBustedO i
}

public voi d execute ( Dea l er dea ler ) {


bank .doubleDown()i
dealer.hit( BettingPlayer.this ) i
getCurrentState() . exec ute( dea ler )i
}

Quando executado, esse novo estado diz a Bank para que duplique a aposta, pede banca
para que di stribua mai s cartas para o jogador e, em seguida , faz a transio para o prximo estado. O estado seguinte ser parado ou vai estourar, dependendo do evento que for
envi ado para o estado por Hand.
Para obter o estado Doub 1i ngDown, voc precisar fazer algumas alteraes no estado
Jogo. A Li stagem 19. 11 apresenta o novo estado BetterPlayi ng.
LISTAGEM 19.11 O novo estado Jogo
private cla ss BetterPlaying implements PlayerState (
publi c vo id handChanged{) {
noti fyC hanged()i
}

public voi d handP layab le( ) {


II pode ignora r no estado de jogo
}

public voi d handBl ackjack() I


II impossfvel no estado de j ogo
}

publi c vo i d handBu sted() {


setCurrent State( ge tBustedStateO };
not ifyBu sted () i
}

publi c yo i d executeI De aler dealer ) {


if( getHand (), canDoubleDown() && doubleDown() ) (
setCurrentState( ge tDoubl i ngDownState() )i
getCurrentState().execute( dealer l i
returni
}
if( hitO } I

dealer .h it( Betti ngPl aye r . th i s li


) else (
se t Curren tSta te( getS tandingState () ) i
notifyStanding() ;

Respostas

LISTAGEM

547

19.11 O novo estado Jogo (continuao)


}

getCurrentState().execute( dealer );
II trans io
}

Quando executado, o estado BetterPl aying primeiro verifica se o jogador pode dobrar.
Se assim for, o estado chamar o mtodo doub 1eDown de Betti ngPlayer (voc precisar
adicionar um mtodo abst rato doubl eDown em Bett i ngPl ayer). Se o mtodo indicar que o
jogador gostaria de dobrar, o estado BetterPl ayi n9 configurar o estado corrente como
Doub 1i ngDown e depoi s far a transio para ele.
Se o jogador no quiser dobrar, o estado continuar e jogar normalmente . Veja todas as
alteraes no cd igo- fontc; cx istem algumas outras pequenas alteraes, como a adio
de um mtodo getooubleOownState em BettingPl ayer.
Voc efeti vamente adicionou a capaci dade de dobrar no sistema. Agora, voc precisa
atuali zarGU IPl ayer e sua classe de apresentao, para que possa suportar a aposta em dobro.

A boa nova que voc no precisa fazer quaisquer alteraes nos estados de GU IP l ayer.
Esses estados no faze m nada, pois eles precisam esperar at que o jogador humano clique em um boto. Voc precisa implementar o mtodo doub 1eOown. A Listagem 19.12
apresenta o metodo.
LISTAGEM

19.12 O mtodo doub 1eOown

protected boolean doubleDown() f


setCurrentState( getOoublingOownState() ) ;
getCurrentState() .execute( dealer ) ;
return true;
}

o boto da GUI pode chamar esse mtodo, caso o usurio decida dobrar. O mtodo confi gura o estado corrente como dobro e, em seguid a, faz a transio para ele. O estado trata
do resto.
Todas as alteraes restantes precisam entrar na classe de apresentao: GUIView. Voc
precisa adicionar um boto de dobro, cert ificar-se de que ele seja ativado aps a aposta e
desalivado assim que o jogador pressionar esse boto, o boto de parar ou de receber
mais cartas.

Apndice A

No se preocupe mu ito, caso voc no entenda 100almente o cdigo da GUI. O importante que voc entenda como a capacidade de dobrar ad icionada no sistema.

Dia 20 Respostas do teste e dos exerccios


Respostas do teste
I. Atravs dos relacionamentos com capacidade de substituio e do pol imorfismo, voc
pode criar qualquer subclasse de Bett i ngPl ayer que queira e adicion-la ao jogo.

O jogo no sabe a d iferena entre um jogador humano e um jogador automtico


no-humano. Como res ultado, voc pode configurar o jogo sem nenhum jogador humano.lmp lementando o mtodo hi t nas subclasses de Pl ayer, e las podero j ogar sem interveno humana.
2. Voc nunca deve seguir a estratgia de OneHHPlayer.

Respostas dos exerccios


I. Sem resposta.

2. Suas solues podem variar. As listagens 20.8 e 20.9 apresentam a implementao de


Knowl edgeablePlayer e OptimalPlayer, res pecti vamente.
LISTAGEM

20.8

Knowl edgea b 1ePl ayer .java

publ i c class KnowledgeablePlayer extends BettingPl ayer

publiC KnowledgeablePlayer(Stri ng name,Hand ha nd ,Bank bank}


super( name , hand , ba nk };

I
publi c boolean hit ( Dealer deale r ) {
i nt total get Hand O . tota 1 () ;

Card card dealer.getUpCard();

II

nunca recebe mais cartas , no importa qua l, se total> 15


if( total> 15 ) {
return fal se ;

II

sempre recebe mais ca rta s para 11 e menos


if( tolal < z 11 ) I
return l r ue ;

Respostas

LISTAGEM 20.8

Knowl edgeab 1ePl ayer .java (continuao)

II 1sso deixa ll. 12. 13. 14


II baseia a decis~o na banca
i f( card.getRank().getRank()
return true;

>

7 ) (

return false;
J

publi C yo i d bet() 1
getBankO .place l OBet();
J
J

LISTAGEM 20.9

OptimalPlayer.java

publiC cla ss Op timalPlayer extends BettingPlayer (


publ ic Opt imalPlaye r( Stri ng name, Hand hand , Bank bank ) (
supere name , hand, bank );
J

publi c boolean hit ( Oeal er dealer ) {


i nt total getHandO.totalO;
Card card dealer.getUpCard(};
i f( total >- 17 ) {
return fal se;
J

;t( total 16 ) {

if( card.getRank(} Rank.SEVEN I I


card.getRankO == Rank.EIGHT II
card . getRank() Rank.NINE ) {
return true;
I else (
return fa 1se;
J

; f( total 13 II total == 14 II total


if( card. ge tRank( ) Rank.TWO II
card.getRank() Rank.THREE I I

==

15 ) (

I 550

Apndice A

LISTAGEM

20.9

Opt imal Player . java (continuao)

card.ge tRank () == Rank.FOUR II


card .getRank() Rank.FIVE I I
card .getRank{) Rank.S IX ) {
return false;
} else {
return true;
}
}
if( total 12 ) (
if( card. getRank()

'ao'.
'OU, II
Rank . FIVE I I

card.get Rank(} ==
card.getRank{) Rank . SIX ) {
return false ;
} el se {
return truei
}
}

return true;
}

publiC void bet() I


getBank().placel0Bet{);
}

Ento, corno esses jogadores se companam?


Em nossos lestes, Knowl edgeablePlayer e OptimalPlayer executam melhor do que
SmartPl ayer, apresentado no captulo. Comparando um com outro, Opt lmal PI ayer executa me lhor.
Contudo, com o passar do tempo, ambos ainda perdem dinheiro, apenas que mu ito lentamente.
3. Suas solues podem variar. As listagens 20.10 e 20 .1 1 apresentam a implementao de
Knowl edgeabl ePl ayer e Optima 1PI ayer, respectivamente.
LISTAGEM

20.10 Knowl edgeab 1ePl ayer .java

public cla ss KnowledgeablePlayer extends BettingPlayer I


public KnowledgeablePlayer(String name , Hand hand, Bank bank) (
super( name . hand. bank );
}

Respostas

LISTAGEM 20 .10

Knowl edgeab 1ePl ayer .java (continuao)

publiC boolean doubl eDown( Oealer d ) {


i nt total getHand (). to ta 1():
if( total 10 Il total .... 11 ) (
return t rue:
J

return false :
J

public boolean hit( Oealer d ) (


int total " getHand() . total () ;
Card c " d.getUpCard():

II nunca recebe mais cartas , no importa qual , se total> 15


if( tota l> 15 ) {
return fal se :
J

II sempre recebe mais ca rt as para 11 e menos


if( total <" II ) {

return t rue:

II isso deixa 11, 12. 13. 14


II baseia a decisao na banca
if( c.getRankO .getRank() > 7 ) (

return true;
J

return fal se :
J

publi C yo id bet() {
getBank() . place10Bet():
J

LISTAGEM 20.11

OptimalPlayer. java

publ i C class Opt imalPlayer extends BettingPl aye r (


public OptimalPlaye r ( String name , Hand hand. Bank bank ) {
super ( name, hand, bank ) ;

551

Apndi ce A

LISTAGEM 20.11 OptimalPlayer . java (continuao)


}

publ i c boolean doubleOown( Oealer d ) I


int total = getHandO.tota l O;
Card c d.getUpCard();
if( total 11 ) I
return true:
}

if( total 10 ) {
if( c.getRankO.getRankO != Ra nk.TEN.getRankO &&
c.getRank() ! = Rank.ACE ) I
return true;
}

retu r n fa I se:
}
if( total --9 ) I
if ( c. getRank O ,... Rank. TWO
c.getRankO Rank . THREE
c.getRankO Rank.FOUR

II
II
II
II

c. getRank O Rank . FIVE


c. getRank O Rank . SIX ) {
return true:
}

retu rn fa l se;
}

return false :
}

public boolean hit( Dealer d ) {


i nt to ta 1 .. getHand () . tota I O ;

Card c .. d.getUpCard() :
if( tota l >= 17 ) {

return ta I se :
}

if( total .. 16 ) {
if( c.getRank() .... Rank.SEVEN J J

c.getRank() == Rank.EIGHT II
c .getRank() == Rank.NINE ) {
return t rue :
} e l se {
retu rn fa l se;
}

Respostas
LISTAGEM 20.11 Opt imal Player . java (continuao)
}

if( total 13 Il total " 14 II total


if( c .ge t Rank () Rank.TWO I I
c.getRankO == Rank. THREE I I
c.getRank() == Rank.FOUR I I
c .getRank O Rank.FIVE I I
c .getRank O Rank.SIX ) {
return false;
} else {
return true;

==

15 ) {

}
if( tota l" 12 ) {
if ( c. getRank O

Rank . FOUR II
c.ge tRankO Rank.FIVE II
c.ge tRank() Rank.SIX ) {
return false;
} else I
return true;
u

}
}

return true;
}

public voi d betO I


get8ank().placeI08et();
}

Em nossos testes, Knowl edgeabl ePI ayer e Opt imal PI ayer executam melhor do que as
verses do Exerccio 2.
Contudo, com o passar do tempo, ambos ainda perdem dinheiro - apenas muito lentamente.

Dia 21 Respostas do teste e dos exerccios


Respostas do teste
I. Voc pode cu idar do problema da chamada de mtodo recursiva colocando cada jogador
em lima linha de execuo. Quando voc chamar Thread.s t art, a chamada retornar
imediatamente, ao contrrio de um mtodo normal. Como o mtodo reloma imed iatamente, a pilha de chamada de mtodos pode desenrolar e retomar.

Apndi ce A

Respostas dos exerccios


1. Sem resposta .

2. As respostas dependero dos interesses pessoais. O Apndice D, "B ibliografia se lecionada", apresenta unta lista de recursos excelente, na q ual voc pode basear a cont in uao
de seus estudos.

ApNDICE

Resumo do Java

o Java Developer's Kit: J2SE 1.3 SDK


o JDK (Java Developcr's Kit) da Sun Microsystems fornece o ambiente para todo o desenvolvi-

mento Java. Com o passar dos anos, a Sun mudou o nome do kit de desenvolvimento de JDK
para Java 2 Standard Edition (J2SE) Software Developmenl Kil (SDK; entretanto, os objetivosdas
ferramentas e das bibliotecas permanecem os mesmos - aj udar os desenvolvedores em seus esforos para escrever soRware de qual idade, independente da plataforma, c orientado a objetos).

Muitos ambientes de desenvolvimento integrados (IDEs) populares incorporam o SDK , alm de


um editor e depurador poderoso. O Forte da Sun e o J Builder da Borland fornecem gratuitamente
verses mais simples do IDE; entretanto, para o objetivo desta discuss~o, a abrangncia ser limitada ao uso do SDK com um editor de textos como o TextPad, NOlepad ou vi.
A Sun fornece o J2SE SDK para vrias plataformas:
Windows NT, 2000, 95, 98, ME
Sun Solaris
Linux
Voc pode obter o SDK para outras platafonnas, como HP ou AIX, com o forneced or da plataforma apropriada. O J2SE SDK para Windows ser utilizado como exemplo. A instalao e confi gurao em outras platafonnas vai variar pouco em relao aos procedimentos di scut idos a

segUIr.

Apndice B

Os desenvolvedores podem fazer download do J2SE SDK no si te Web J2SE da Java50ft, no endereo javI . sun.comj j2sej 1.3. Siga os links apropriados para fazer download do J2SE 1.3
SDK. Alm do J2SE SDK, voc deve faze r download da documentao da APl J2SE. Embora
no seja exigida. a documentao da APl tremendamente til. A documentao da APl J2$E
fornece documentao detal hada de atributo, mtodo e classe que at os desenvolvedores de
Java altamente experientes consideraro teis.

Configurao do ambiente de desenvolvimento


A JavaSoft empacota o Windows J25E 1.3 SDK em um pacote InstallShie ld . Quando voc fizer
download do arquivo, execute-o e percorra as caixas de dilogo para instalar o SDK no diretrio
de destino apropriado. (O diretrio de destino padro C: \jdkl. 3.) Instale todos os componentes, quando so licitado. Isso exigir cerca de 54MB de espao no disco rgido. Quando term inar,
voc dever ver a seguinte estrutura de di retrio em seu diretrio de destino de instalao:
C,\jdk1.3

\bi n
\demo
\include
\include-old
\j re
\ll b

o pacote de instalao apenas distribui OSDK nos diretrios apropriados. Para in iciar o desenvolvi mento, voc deve confi gurar as seguintes variveis de ambiente.

JAVA HOME

PATH

CLASSPATH

Primeiro, con fi gure JAVA HOME com o diretrio instalado apropriado. Por exemplo, voc executaria o segu inte na linha de comando:
set JAVA_HOME z c:\jdk l .3
Em seguida, configure o PATH:
set PATH=%PATH%;%JAVA_HOM E%\bin
Finalmente, configure o CLASSPATH. O ClASSPATH infornlar o compilador e a mquina vi rtual
onde deve procurar os arquivos de classe compilados.
Em geral, esse caminho o mesmo da raiz da rvore-fonte. Escolha c : \projects\src\java\
cla sses. Assim, voc configurar o CLASSPATH:
set ClASSPATH -c: \ projects \s rc \java\c lasses
A Figura B. I demonstra as configuraes de ambiente que acabamos de descrever.

Aesumo do Java

557

FIGURA B.1

COI/figural/do
o ambiellfe.

A maior parte dos out ros fornecedores empacotar suas bibliotecas na forma de arqu ivos jar ou
zip. Para usar essas bi bliotecas, voc deve anexar a localizao do arquivo jar no CLASSPATH. Por
exemplo, para usar c : \projects\ 1i b\mycl asses . jar, voc deve executar o seguinte:
set

CLASSPATH ~%CLASSPAT H% ; c :\projects\lib\myclasses.jar

Voc deve anexar cada arquivo jar em CLASSPATH, antes de usar.

Panorama das ferramentas do SDK


Alm de forne<:er as bibliote<:as Java, o Java SDK fornece vrias ferramentas necessrias para o
desenvolvimento. As ferrame ntas mais usadas so:

javac
j ava

Jar

javadoc

Voc precisar das outras ferram entas para recursos adicionais, como cham adas de mtodos remotos e interface Java nativa.

Compilador Java: javac


j avac , o compi lador Java, compila cdigo-fonte Java em byte code. Quando voc digitar j avac
FirstProgram.java, o compilador gerar um arquivo FirstProgram.class no diretri o corrente
- supondo que o compilador no detecte nenhum erro dentro de seu cd igo Java.
Se um program a Java utilizar bibl iotecas de terceiros, o compilador tentar local izar essas bibliotecas a part ir do CLASSPATHespecificado; entretanto, voc pode optar por modi fi car a CLASSPATH ao
com pilar. A opo -C 1asspath <cominho> permite aos desenvolvedores substituir o
ClASSPATH.
Voc tambm pode especi fi car diferentes diretrios de origem e destino. atravs de -sourcepath
<cominho> e -d <cominho>, respectivamente. A opo -sourcepath especi fi ca uma nova localizao para arquivos-fonte de entrada. Assim, voc pode optar por compilar arq uivos-fonte loca-

Apndice B

lizados em um lugar diferente do d iretrio corrente. A opo -d infonna o com pi lador para que
deposite os arquivos .c1ass no caminho especificado, em vezde faz-lo no di retrio corrente.
Voc no precisar das opes -c1asspath, -sou rcepath ou-d para os exerccios deste li vro.

Interpretador Java : java


j ava, o interpretador Java, fornece o ambiente de tempo de execuo. Ele interpretar e executar os arquivos de classe compi lados. Para executar um programa Java, digite:
Java FirstProgram
Note que o comando omite a extenso .c1ass oO interpretador anexa, c1 ass automaticamente
no nome da classe.
Assim como no compi lador, voc pode espec ificar opes de linha de comando para o interpretador. Algumas das opes usadas mais freq entemente so:

- classpath, para especificar um cam inho de classe diferente daquele defini do no


ClASSPATH

-OpropName"'propValue . para especifica r propriedades de sistema

Essas e outras opes do interpretador, entretanto, esto fora dos objet ivos desta di scusso.

Utilitrio de compactao de arquivos Java: j ar


o ut ilitrio jar gera arquivos compactados java (jar). Os arq uivos jar s."Io equivalentes aos arquivos zip, compactando arquivos para um tamanho menor e fornecendo uma mane ira conveni ente de distribuir classes java compiladas.
Para criar um arq ui vo compactado, basta chamar:
jar cvf <nomedoorquivojar> <arqui vos_o_compactar>
Voc tambm pode especi ficar todos os arqui vos jar e s ubdiretrios de determinado diretrio,
atravs de:
jar cv f <nomedoarquivojar> <diret6rio>
Note que todos os arquivos jar devem ler

su fixo ,j ar.

Se voc quiser ver o contedo de um arquivo jar, chame:


jar tvf <arquivojar>
O comando jar tvf ex ibir o tamanho, adala de inseroe o nome de arq uivo que est no arquivo com pactado.
Mais opes esto descritas na documentao do SDK Java.

Aesumo do Java

Documentao Java e o gerador de documentao:

javadoc
Todos os desenvolvedores j ouviram o mantra da documentao de cdigo. A JavaSoft fac ilita
o processo de documentao, fornecendo uma ferrame nta para gerar documentao HTML amigvel para o usurio. O desenvolvedor precisa uti lizar apenas tags padro, ao escrever comentrios de atributos, mtodos e classes, e depois chamar a ferramenta javadoc com as opes
apropriadas para gerar documentao de APl . A documentao do SDK Java forn ece infonnaes elaboradas sobre a fe rramenta e o processo j avadoc ; entretanto, vamos abordar alguns recursos bsicos para comear.
Os desenvolvcdorcs devem primeiro documentar seu cdigo com os comentrios e tags apropriados. Seria t imo se a fe rramenta de documentao pudesse adentrar nosso cdigo e decifrar exatamente o que estvamos pensando quando escrevemos aquele mtodo cm part icular; ent retanto,
a ferramenta javadoc no suficienlemenle avanada para ler a mente.
Em Java, ex istem trs nveis principa is de documentao: classe, mtodo e atribulo. A ferramenta javadoc reconhecer comentrios que comeam com j ** como um comentrio javadoc.
Os comentrios terminam com * j .
Para comentrios de classe, normalmente voc ver:

~author

<nome autor> especifica o autor da classe. Voc pode ter mais de um autor; en-

tretanto, cada autor deve comear com a tag @author.

~version <nmero

verso> especifica a verso da classe. Alguns soft wares de controle

de verso fornecem tags que geraro o nmero automaticamente.


~see <nomedaclasse> fornece links para outras classes, para mai s informaes. Voc
pode ter mais de uma refernc ia; entretanto, cada refernc ia deve comear com a tag@see.
Uma doc umentao de classe seria semelhante a:

r'

* <Comentrios e descrio da clas se>

*
*
*
*

@author Mi chael C. Han


@author Tony Sln t es
@version 1. 0
@see SecondJa vaCla ss

./
Os comenlrios de mtodo usam as tags anteriores, alm de:
@param <lIomeyarmelro> <comentrios > descreve os parmetros do metodo.
~retu rn <comen t rios> descreve o valor de retorno do metodo.

~excep t 1on

<NomeExceo> <comen tr ios> descreve todas asexcecs lanadas pelo m-

todo corrente.

Apndice B

Uma documentao de mtodo seria semelhante a:

/H
* <descrio e

coment~rios

do m t odo>

* @param valuel parSmetro obtido pe l o mtodo de teste


* @param value2 segundo parmetro obtido pelo m todo de tes t e
* @return ve rdadei ro se valuel :: va l ue2
* @except i on NumberFormatException lanado se valuel ou val ue2
i nte i ros

n~ o

forem

./
Os comentrios javadoc de atri buto tendem a no ter tags espec iais. Em vez d isso, voc deve denotara bloco de comentrio corno um comentrio javadoc. A seguirest um exempl o de comentrio de atributo javadoc:

/H
* Atributo de classe para conter o estado da operao de comparao anterior

./

Cercadinho Java: seu primeiro programa


Java
Para ajudar a confi rmar sua instalao do SDK e praticar com as ferramenta s descritas at aq ui,
voc vai escrever o infame exemplo He ll oWorld. Pri mei ro, crie um arquivo chamado Hello Wor 1d . java, na raiz da origem. Se estiver usando a raiz da origem sugerida (\projects \s rc \java
\classes), crie o arquivo sob c:\projects\src\ java \classes.
Aps criar o arquivo, voc pode comear a escrever seu pri mei ro programa Java. A Li stagem
8.1 contm o exemplo HelloWorld em Java.
LISTAGEM

B.l

HelloWorld.java

/H
* Um programa hell o world pa ra confirmar que o SDK foi con f igurado corretamente.
* Tambm utilizado para ajudar a demonstrar as ferramentas bsicas do SDK

*@
*@

author Michael C. Han


version 1.0

./
publi c cla ss HelloWorld {

/H
* Mtodo principa l do programa. Todas as classes Java execut ve i s devem
* conter esse mtodo .

* @param argument os passados da linha de comando

Aesumo do Java

LISTAGEM 8 .1

561

HelloWorld.java (continuao)

'1

public static void main(String [] args) I


HelloWorld helloTest : new HelloWorld();
System.out.pri ntln(hel loTest .sayHel l o(;
System.out.pri ntln(M");
System. out . pri nt ln(helloTest.sayHi( ;
}

;-

... Construtor da classe padro

'1

public HelloWorld() {
}

I"

... Mtodo para dizer hel Io para o chamador


... @return String dizendo "Helio"

'1

publ ic String sayHell o() {


return "HelIo";
}

I"

... Mtodo para dizer hi para o chamador


... @return String dizendo "Hi! "

'1

public String sayHi() I


return "H1!";
}

Compilando e executando
Para compilar a classe, execute:
javac HelloWorld
no diretrio-raiz da origem. Se tiver xi to, voc ver um arq uivo HelloWorld .class gerado 110
mesmo di retrio.
Em seguida, execute o programa, digitando:
java HelloWorld

Apndice B

Se o programa Hell oWorl d executar com sucesso e impri mir "Hello" e "Hi! ", como mostrado na
Figura 8.2, voc configurou seu SDK corrctamentc; enlretanlO, se voc ver o segui nte ao exeular java Hel l oWorld,
Excep t ion in thread "main" java. lang.NoClassOefFoundError:Hell oWorld
ou no configurou o CLASSPATH correlamente ou colocou oarq uivo Hel loWorld.java em um lugar
que no a raiz da origem. Em qualquer caso, confinne pri meirose o CLASSPATH contm a raiz da
origem (\projec ts\ sr c\ja va\cl asses) e, em seguida, confi rme se o arquivo He ll oWorld.java
est na raiz da origem .
FIGURA 8 .2

Compilando e
exeC"II/(lI1do

HelloWorld.

Criando um arquivo . Jar

Em seguida, lente executar o ulil itrio jar nos arquivos do diretrio. Na ra iz da origem , execute:
jar cvf hel l o.jar *.java *.class
Voc ver um arq ui vo hello.jar gerado.
Para con finn ar o contedo de hello.jar, execute:
jar tvf hello.jar
Voc ver dois arquivos-Hel loWorld .java e HelloWorld. class- na listagem, como na Figura 8.3.
Em seguida, exclua HelloWorld.java e HelloWorld. class da raiz da origem (\projects\s rc \java\classes). Final mente, voc precisa executar:
jar xv f hel lo.jar
Isso extra ir os arquivos Hel loWorl d.java e He ll oWorld .class na ra iz da origem (veja a Figura
B.3).

Resumo do Java

FIGURA 8 .3

Criando, /is/ando e
ex/rail/do hello.jar.

Gerando javadoc
Se voc examinar o cdigofonte de HelloWorld, notar comentrios no estilo javadoc para a
classe e para os mtodos da c lasse.
Para gerar a docum enlao, crie o diretrio de documentao. Sob c : \projects, crie um direl
rio docs e depois execute:
javadoc - public - d c:\projects\docs HelloWorld

o comando depositar a documentao HTML no diretrio c : \projects\docs para todos os m


todos pblicos da classe Hel l oWorl d, como se v na Figura B.4. Para ver a docum entao, abra
c : \p ro jects\docs\ index, html em um navegador da Web. Observe a semel hana de estil os en
tre a documentao gerada e a documentao da APl J2SE da Sun.

FIGURA 8 .4

Tela do gerao de jamdoc

de He 11 oWorl d.

Ap nd ice B

Mecnica da linguagem Java


Aps segui r os passos anteriores, voc deve ter um ambiente de desenvolvimento Java totalmente configurado, assim como um entendimento das ferramentas bsicas do SDK. De posse do ambiente de desenvolv imento, agora hora de escrever algumas classes Java.

Classe Java simples


A segui rest a verso simplificada do programa He11 olior1 d apresentado na seo anterior. Agora que voc sabe como faz para com pilar e executar programas Java, pode exami nar o cdigo-fonte com ma is detalhes:
pub l ic class Simp1eHe11oWorld {
public stat i c void main ( String ar gs E] ) {
String hi new String(" Hello All lO)
System.out.print1n(hi)

I
I
A primeira pa lavra-chave utilizada publ ic. A palavra pub1 ic denominada modificador de
acesso. Semelhanlemente linguagem C++ ou SmallTalk, a li nguagem Java fomece mod ificadores de acesso para especi ficar quem pode acessar um mtodo, atributo ou classe em particular.
O acesso pblico garante o acesso a todos aqueles que qui serem usar uma classe. mtodo ou atributo em particular. Os outros mod ificad ores de acesso so protected, private e nivel de pacote.
Nvel de pacote algo especial na linguagem Java. Basicamente, um modi fi cador de nvel de pacote garante o acesso a todas as classes dentro do mesmo pacote ou di retrio.
A prx ima palavra-chave do exemplo de classe c1 asso Em Java, uma classe o fundamento bsico e os blocos de construo de programas. Ela o encapsu lamento de varivci s de dados ou
atributos e operaes, fune s, ou mtodos. Tudo em Java deve residir dentro de uma classe.
O nome do exemplo de classe Simp1eHe11oWor 1d. Em Java, o cd igo-fo nte dessa classe deve
residir em um arqu ivo chamado Si mp 1eHe 11 oWor 1d. j ava. Se a classe residir em qua lquer outro
arqu ivo, o comp ilador rec lamar que "c 1ass Simp 1eHe 11 oWor 1d is pub 1i c, deveria ser dec larado em um arquivo com nome Simp1eHelloWorl d.java". O arquivo de classe compilado reside
em SimpleHel1oWo r ld.c1ass.
A classe Si mp 1eHe 11oWo r1d tambm contm pub 1i c s ta t i c voi d ma i n (Stri ng args []). Ignore
os mod ificadore s static e vo i d. A linguagem Java exige um mtodo principal, se voc quiser
executar uma classe Java atravs do comando java. Voc pode optar por adicionar mais mtodos
e operaes na classe; entretanto, sem um mtodo com essa assi natura, voc no pode executar a
classe.
Observe as chaves ({}) e pontos-e-vrgu las ( ) no cdigo-fonte. Em Java, as chaves designam
blocos de programa. Um mtodo e uma classe devem comear e tenni nar com uma chave.

Aesumo do Java

Assi m, voc deve tomara cuidado especial de terminar chaves de abertura com chaves de fechamento. Os pontos-e-vrgulas designam o fina l de uma instruo. Se voc programador de
C/C++, ento j est fam iliarizado com eles e sabe que deve fecha r todas as instrues com ponlos-c-vrgulas.
As palavras-chave static e void descrevem um mtodo. A palavra-chave void o valor de retorno. Seme lhantemente s outras linguagens, os mtodos Java tm um valor de reto rno. Neste
caso, o mtodo princ ipal no retorna nenhum valor. A palavra-chave statlc designa o mtodo
como acessvel atravs da classe. Em outras palavras, voc pode chamar um mtodo esttico de
uma c lasse, sem criar uma instncia da classe.
As duas linhas de cdigo a seg uir, encapsuladas pelas chaves do mtodo principa l, representam
o m ;010 do programa.
String hi new String(" Hello All
System .out.print ln( hi);

U
)

Aqui, uma referncia chamada hi aponta para uma instncia construda da classe Stri ng. Como
em SmallTa lk ou Ctt, o operador new cria a instncia. A instncia de St ring contm o valor
"Hello All". Ela recebe o valor como parmetro do construtor. Na linha seguinte, o objeto
System imprime o valor de hi no console do sistema.
Note tambm os pontos-e-vrgulas no fina l de cada li nha de cd igo. A fa lha em tenllinar instrues
de programa ou declaraes de varivel com um ponto-e-virgula resultar em erros de compilao.

Tipo de Dados
A li nguagem Java, assim como C++ e Smal ltalk, fortemente tipada. Assim , ao declarar variveis e valores de retomo, voc deve especificar a varive l ou tipo de retomo. A linguagem Java
contm oito tipos primit ivos. A Tabela R I lista os ti pos primitivos vl idos em um programa
Java e o numero de bits assoc iados ao tipo:
TABELA B . 1

Tipos primitivos J ava e tamanhos de armazenamento

Tipo

Nm ero de bits

byte

8 bits

short

16 bits

char

16 bits

i nt

32 bits

fl oat

32 bits

doub 1e

64 bits

10ng

64 bits

boo lean

1 bi t

Apndice B

Na maioria dos cenrios, voc pode usar i nt para representar inteiros e float para representar
valores de ponto fl utuante; ent retanto, certos tipos de dados podem exigir espao de armazenamento maior. Por exemplo, talvez voc queira expressar o nmero de mi lissegundos desde 1970.
Esse nmero sufi cientemente grande para ex igir um valor l ong, em vez de um inteiro.
Voc pode representar um valor 1ong como IOOOOOOOOOL. A letra L pos-fixada denota o nmero
como long. Analogamente, voc pode representar valores f loat como 4.3405F.
Se voc for programador de C++, sabe que nessa linguagem os caracteres so ASCI I. A linguagem Java, entretanto, usa Unicode para representar caracteres. O padro Unicode usa 2 bytes
para representar caracteres, em oposio a I byte usado pelo padro ASC II. Isso pennite a representao de um conjunto de caracteres maior para propsitos de internaciona lizao. Por exemplo, a ma ioria das li nguagens As ian exige armazenamento maior do que o padro ASC II . A
linguagem Java no o impede completamente de usar ASC II. Em vez disso, voc tem a escolha
de usar um dos dois. Por exemplo, voc pode usar seq Uncias ASC II com uns, como \n para
nova linha ou \ t para tabulao.
Em certas ocasies, talvez voc queira converter um tipo numrico cm outro, como de i nt para
1ong. A Iinguagem Java fornece converso automtica entre tipos numricos, se a converso no
levar a nenhuma perda de preciso. Ela converter um valor int de 32 bi ts automaticamente para
um valor long de 64 bits; entretanto, voc deve especifica r explicitamente a converso de ti po,
para converter de um va lor 10ng para um valor i nt ou de um valor doub 1e para um valor i nt. A
li nguagem Java ehama essa operao de converso. Se voc no converter ao rea lizar uma converso de reduo de preciso, o compilador rejeitar.
As linhas a seguir demonstram uma converso explcita:
lon9 valuel 40000L
in t va I ue (int)valuel
float value2 z 4.003F;
double value3 value2;
Observe que a converso de fI oat para double no ex ige converso explcita, poi s um valor flo at tem 32 bits e um valor double tem 64 bits. Assim , a operao aumenta a preciso.

Variveis
A lm de ser forteme nte tipada, a linguagem Java tambm leva em considerao letras maiSCUlas e minscu las. ConseqUentemente, a linguagem Java considera duas variveis com posicionamento de letras maisculas e minscu las di fere nte corno duas varive is separadas. Por exemplo,
variableOne e variab l eone so duas declaraes de varivel diferentes. Um nome de varivel
Java deve comear com uma letra e conter quaisquer caracteres alfanumricos. Os caracteres alfanu mricos podem ser qualquer caractere Unicode que denote uma letra em qualquer idioma;
entretanto, o nome no pode conter quaisquer smbolos, como $, %. & etc.
As seguintes palavras reservadas no podem ser utilizadas:

Aesumo do Java
abs t rac t
case
canst
daub1e
f ina l1 y
generic
import
inte rface
null
private
return
swi tch
throws
void

boolean
ca tch
cont inue
else
f1 oat
goto
inner
10ng
operator
protected
sho rt
synchroni zed
transient
volatile

break
char
defaul t
extends
for
if

567

byte
c1ass
do

f i na 1
fut ure
implements
int

instanceof
native
outer
public
static
this

package
rest
super
throw

try

,ar

new

while

A seguir esto alguns exemplos de declaraes de varivel:


int valuel;
doubl e Value2;
float _va l ue3 ;
cha r VALUE4 , Value5 ;
Observe a ltima declarao de varivel. A linguagem Java permite vrias declaraes de tipo de
varivel por linha. Nesse cenrio, VAlUE4 e Va 1ue5 so valores char. Para declarar mltiplas variveis, use uma vrgula para separar cada nome de varivel e ternline com um ponto-e-vrgu la.
Tambm existem modificadores de atributo que voc pode adicionar em uma declarao de varivel. Por exemplo, as variveis podem ser declaradas pub 1i c, pri va te ou protec ted, para controle de acesso. Uma varive l tam bm pode ser declarada sttic ou final, ou ambos. Uma
varivel sta t i c acessvel atravs da classe, enquanto uma varivel fi na 1 no pode ser med ificada.
Embora voc tenha poucas restries quanto aos nomes de varivel , altamente aconselhvel
segu ir alguma fo rma de conveno de atri buio de nomes ou padres de codifi cao. Os padres de codi fi cao levam a um cd igo unifonne e, assim , melhoram a legibi lidade do cd igo.
Uma conveno de atribuio de nomes de varivel comum colocar a primeira letra de toda palavra em maiscul a. exceto a primeira pal avra. Os nomes seriam como:
int anlntegerValue;
cha r aCharValue;
Outra conveni'lo prefixar todas as variveis privadas e protegidas com um sublinhado. Assim,
as variveis seriam como:
private in t _value;
pr;vate char _aCharValue:
Voc deve seguir os pad res de codificao de sua empresa ou seguir um padro de codi fi cao

comum.

Apndice B

Constantes
As constantes podem ser consideradas como um tipo especial de varivel. Assim como em outras linguagens. as constantes Java so variveis com valores que no mudam. Voc pode declarar uma constante anexando as palavras-chave stati c final no inicio da declarao de varivel .
Exemplos de declaraes de constante incluem:
pri vate s tati e final String _NAME_VALUE
pr; vate stati e final i nt _AN_INTEGER_CONSTANT
publi c stati e fina l String PARAMETER_NAME
proteeted static f i nal ehar _TYPE_CHAR_VALUE

"MyName";
1;
"MyParam";

'c';

Observe que os nomes de constante esto em letras maiscu las. Embora no seja um req ui sito,
uma prtica normalmente seguida entre os desenvolvedores de Java nomear as constantes com
todas as let ras maiscul as.
Voc pode acessar essas constantes atravs de <el assname>.<cons tant_name>. Por exemplo, se
as constantes anteriores forem declaradas em MyC l ass, voc poder acessar a constante
PARAMETER- NAME atravs de MyCl ass. PARAMETER- NAME. Essa a nica constante pbl ica declarada
e, assim, essa a nica constante di sponvel fora de MyCl ass ; entretanto, voc pode usar qualquer
uma das outras constantes dentro de MyCl asso Voc tambm pode usar a conSlante
_TYPE _CHAR_ VALUEem todas as subclasses de HyC1ass. Ao usar constantes dentro da mesma classe, voc pode omilir o prefixo <c1assname>. Por exemplo, para acessar _NAME_VALUE dentro de
HyCla ss, voc pode fazer referncia constante como MyCl asso _HAME_ VAlUE ou simplesmente
NAME VALUE.

Operadores
A linguagem Java fornece vrios operadores para operaes aritmticas e booleanas. Aqueles
que esto fam ili arizados com a sintaxe da linguagem C/C++, devem conhecer a sitHaxe desses
operadores. Conforme mencionamos anteriormente, Iodas as instrues Java devem terminar
com um ponlo-e-vrgula.
A linguagem Java tem os operadores +, I, -,. normais para operaes aritmticas. O operador =
usado para atribu io. Alm disso, a linguagem Java suporta o operador de mdul o ou resto, %.
Por exempl o, 15 / 3 igua l a 5, enquanto 15 % 3 igual a O. Voc tambm pode usar operadores
aritmticos ao ini cializar varivei s. Por exemplo, inicializar x como n + 2 semelhante a:
int x n + 2;
Voc tambm pode opiar por usar uma sinlaxe abreviada ao efetuar operaes na mesma varivel. Por exemplo, para incrementar x por n, voc pode optar por escrever:

x .. n

x;

Voc tam bm pode adotar uma estratgia abreviada e escrever:

Aesumo do Java

569

A linguagem Java tambm oferece s uporte para exponenciao. A linguagem Java no fornece
um operador. Em vez di sso, voc usa o mtodo pow, fornecido na classe java. lang. Hath. assim,
para elevar x potncia n, a expresso seria semelhante a:
int y Hath.pow(x, n}:
A linguagem Java tambm fornece operadores de incremento e decremento, como em C/C++.
Para incrementar x por 1, voc pode escrever o seguinte :

x z X + I;
x +" I;
A me lhor maneira, ent retanto, escrever:
x++',

o mesmo se aplica ao opemdor de decremento:


x_O;
Para os dois operadores, ex istem duas fonnas. Voc pode colocar o operador antes ou depois da
varive l. Por exemplo, para decrementar x, voc pode se expressar como segue:

x_O:
-- x;
A localizao do operador diz quando ele efetuado. Em uma expresso aritmtica, colocar o
operador antes da varivel incrementar (ou decrementar) a varivel primeiro, antes da avaliao da expresso. Se voc colocar o operador depois da varivel, a expresso ser avaliada pri meiro. Pegue como exemplo o seguinte trecho de cdigo:
i nt x
i nt y
i nt k
i nt j

" 5:
.. 6;
"++x;
"Y++:

I I' ps
I I'ps

esta expresso , k 6 e x 6
esta expresso , J 6 e y 7

Como voc pode ver, o posicionamento do operador de incremento ou decremento fundamenta l. Tome o cuidado especial de usar os operadores apropriadamente.
Os operadores booleanos da linguagem Java so mu ito parecidos com os operadores booleanos
de outras li nguagens de programao. Ao comparar maior que ou menor que, a linguagem Java
fornece> e <, respecti vamente. Alm disso, <= e >= denotam menor ou igual a e ma ior ou igual a,
respectivamente. Isso se aplica comparao de tipos primitivos, como valores inteiros (integers), long, double, caracteres, etc:
intx"S:
inty "6 :
boolean z .. x < Yi

/1

Z .. verdadeiro

Apndice B

Para fazer comparao de igualdade, a li nguagem Java fornece dois operadores d iferentes. Voc
pode usar o operador para com parar tipos primitivos; entretanto, ao com parar dois obj etos
(como String, MyObject), voc deve usar o mtodo equalsO,de fi nido para o objelo. Se voc
usar = por engano, para comparar dois obj eros, isso na verdade com parar a referncia dos dois
objetos e no os objelos reai s. A no ser que voc esteja comparando as mesmas refernc ias de
obj eto, esta operao retornar fa lsa:
String X "
String y.
boolean z "
boolean w "

new S tring(~My Stri ng ") ;


new String(UMy St r i ng");
(x y); II z falso
(x.equals(y)) ; II w ~ verd adeiro

Para fazer comparao de desigualdade, a linguagem Java usa o operador!. A desigualdade enIrc lipos primitivos usar! = e entre dois objetos ser !objl.equals(obj2).
Voc tam bm pode optar por usar && e
(ou), respectivamente).

II

para verificar cond icionais (operaes and (e) e or

Estruturas condicionais
As estrut uras cond icionais so uma parte importante de qualquer linguagem de programao.
Assim como ClC++, a linguagem Java fornece o operador i t l el se. A sintaxe. assim como em
C/C ++, como segue:
if (condio) {
.. . llc omportamento para quando a condio for verdadeira
}
el se {
.. .11 comportamento para quando a condio for fal sa
}

Voc pode optar por ter um nico; f , i f je1se ou ; f com vrias instrucs e 1se.
A seguir est um exemplo de instruo i f j e 1se com vrios el se:
if (, y)

x -- :
}
e l se if (x > y)
x '" 2;
}
el se (
, I 2;
)

Observe as chaves que denotam o inc io e o final de um bloco i f. Embora as chaves no sejam
exigidas, se voc tiver apenas uma instruo no bloco i t , us- Ias nessa situao recomendado.
Fazendo isso, voc pode evitar dores de cabea em potencial posteriormente, quando decidi r

Aesumo do Java

571

adicionar mai s instrues no bloco i f. Se voc se esquecer de adicionar chaves nesse momento,
ter que depurar para encontrar as chaves ausentes.
A linguagem Java, assim como C/C++, fornece um operador ternrio para reduzi r a expresso
lf/else. Uma expresso temria como segue:
z =( x>y)? 3:1 ;
(x > y) o teste condicional. O pri mei ro valor aps? representa o valor de z se a condicional for
verdadeira. O segundo valor representa o valor de z se a condicional for falsa.
Seguindo o exemplo anterior, se x 5 e y " 7, ento z .. 1. A condicional falsa (5
z recebe O segundo valor na expresso, I.

>

7) e, ass im,

laos ou estruturas de repetio


Os laos ou estruturas de repet io so um componente importante para qualquer linguagem de
programao. A li nguagem Java, ass im como muitas outras, fornece urna variedade de mecanismos de lao.
Um lao usado com umente, o lao for, tem a seguinte si ntaxe:
for (i nt x O; x < 8; x++ ) {
l/_al guma ope ra o em la o

I
A restrio do lao, x, definida dentro dos parnteses e iniciali zada como zero. A instruo seguinte testa a restrio para garanti r que ela esteja dentro dos Iimites necessrios. Neste caso, x
deve ser menor que 8. A ltima instruo incrementa a restrio do lao.
Outro lao comumente usado, o lao whi 1e, tem a seguinte si ntaxe:
while (condio for verdadeira) {
/ l . exec uta alguma operao

o lao continuar a executar, dcsdc que a condio dentro do teste entre parnteses seja verdadeira.

Classes e interfaces da linguagem Java

blocos de construo

Em Java, voc no pode fazer nada sem classes e, at certo ponto, interfaces. As classes compreendem os blocos de construo bsicos da linguagem. Assim, quando escrever seu prprio programa, voc ter que criar classes e tambm usar classes de bibliotecas j existentes. Talvez voc
tambm precise construir interfaces para melhor expressar seu projeto atravs do programa.

Apndice B

Usando classes j existentes


Para usar classes j existentes no S DK Java, voc precisar criar uma instncia da classe, inicializ- Ia e depois trabalhar com as instncias. Para uti lizar a classe existente j ava. uti 1. StringBuffer, voc criaria uma instncia ou objeto dessa classe:
St ri ngBuffer sbTest new St r i ngBuffer();
Ago ra que voc j criou um novo Stri ng Buffer para usar, pode operar no objeto. Por exemplo,
talvez voc quisesse anexar outra String no buffer.
sbTest.append(" Th is is a te st St r ing") ;
Talvez seja preciso criar vrias instncias da mesma classe, para executar as o peraes necessrias. Assim, voc pode criar quantos objetos Str i ng Buffer forem necessrios:
StringBu ff er sbTest2 new Stri ngBuffer();
Agora, voc criou uma nova instncia de um objeto StringBuffer, identificado pe la referncia
sb Tes t2. Voc tambm pode atribu ir uma varivel a outra, atravs do sina l ::::. 1sso configurar as
duas variveis para que apontem para o mesmoobjelo. Assim, as operaes exe<:utadas nas duas
varive is afetaro o mesmo objeto. Tome como exemplo as instrues a seguir:
StringBuf fer sbTest new St r i ngBuffer();
StringBuffer s bTe st2 new Stri ngBuffer();
sbTest '" sbTes t 2
sbTes t. append( NTest String 1. " );
sbTest2.append( aTes t St r i ng 2 .- )
System.out. prin tl n("Output f or s bTes t = " +sbTest.toSt ringO)
System.out.println("Output f or sbTest2 '" " +sbTest2. t oSt r ing(} )j
Como voc configura sbTest s bTest2, as operaes de anexao em sbTest e sbTes t 2 modificaro o mesmo objeto s ubjacente. A sada do trecho de cdigo anterior ser:
Output for s bTe st = Test Stri ng I. Tes t String 2 .
Output for s bTest2 " Te s t String I.Test String 2.

Criando suas prprias classes


A sintaxe Java para um a classe :
public cla ss Cl assName {
l/mtodos e atri butos da c lasse

I
Todos os mtodos e atribulas da classe residiro dentro das chaves. Todas as classes tambm devem residir em um arq uivo chamado ClassName.java.
Exami ne o trecho de cd igo do arquivo Product.Java, apresentado na Listagem 8 .2.

Aesumo do Java

8.2 Trecho de Product.java

LISTAGEM

lO>

* @author Michael C.Han


... @vers i on 1. 0

'1

public class Product (

lO>

... @param argumentos passados da l i nha de comando

'1

pub l ic stat i c void main (Stri ng [] arg s) (


Product prod
new Product("wi dgetl" , "Acme Inc" , "Mas ter Widge t".
"This is the master widget product to so l ve all
problems!",
90 . 10f);

System .out.println(prod.getProductId())j
System.out.printl n(prod. getManufa ct urer () );
System. out .p r i nt ln (prod.getProduct Desc()) ;

I
pri vate St ring prodName , productld. manufacturer , desc i
f loat pri ce i

lO>

... @param argumentos passados da linha de comando

'1

pu bl ic Product(String product ld . String manufact urer ,


Stri ng prodName. String desc, float pr i ce ) (
this.prodName ~ prodName ;
this.productld = productld j
th1s.manufacturer ~ manufacturer;
t his.desc a desc i
this.price = price ;

lO>

... @re turn i d do produ t o

'1

publ ic St ring getProductld() I


retur n productIdj

I 574

Apndice B

LISTAGEM

8 .2

Trecho de Product.java (continuao)

~return

nome do produ to

'1
pub l ic St ring getProduc tName() {
return prodName;
J

I"

* @ret urn nome do fabricante

'1
public String getManufacturer() (
return man ufact urer;
J

I"

~retu r n descri~o

do produt o

'1
publ ic St r ing getProductDesc() {
return desci

I"

* @return preo do produto

'1
public fl oa t ge tPri ce() (
return price ;
J

I"

* @param price - novo preo desse produto

'1
publ ic void setP ri ce(float price) {
this.price price ;
J
J

A classe Product tem um mtodo construtor com cinco parmetros: product name, manufa cturer, product id, descri ption e price. O construtor efetua as operaes necessrias para iniciali zar O objeto. Neste caso, voc inicializa as infonnaes do produto designadas. Um construtor
deve seguir as regras que c itaremos:

Aesumo do Java
O construtor deve ter o mesmo nome da classe.
Um const rutor pode receber qualquer nmero de parmetros. Um construtor sem parmetros chamado de construtor padro.
Um construtor no retorna valores.
Um construtor s pode ser chamado atravs da palavra-chave new (por exemplo, Product
prod = new Produc t ( . .. ).

Uma classe pode ter mais de um construtor (ou, mais comumente conhecidos como consfrufores sobrecarregados).

Note o uso da palavra-chave thi s dentro do construtor. A pa lavra-chave thi s opera sobre a instncia corrente da classe. No construtor, voc usa a palavra-chave t hi 5 para ev itar confund ir os
atributos privados com os parmetros do construtor.
Alm dos construtores, a classe Produ ct tambm tem quatro (Icessore~' OUlltfodos de obfel1o.
Os acessores fornecem acesso de leitura aos atri butos da classe Product. Para mod ificar atri butos
da classe, voc deve usar mtodos chamados modificadores ou de cOI/f igurao. A classe Product tem um modificador, setPri ce, para mod ificar o preo de um produto.
Observe que todos os atributos da classe Product so privados e apenas um, pr i ce, pode ser modificado aps um objeto Product ser cri ado. importante lembrar que as classes no devem expor seus atri butos internos, a menos que o usurio da classe tenha motivos legt imos para ler e/oll
modi fi car o atributo. ConseqUentemente, voc fornece acesso aos atri butos atravs de mod ificadores e acessores.
A classe Product tem apenas mtodos de acesso pblico. Voc pode optar por implemcntar mlodos com outros niveis de acesso; voc pode optar por im plementar mtodos pri vados ou prote
gidos, alm dos mtodos pblicos. E importante lembrar que os mtodos privados so acessveis
dentro da classe que est implementando e que os mtodos protegidos so acessveis tanto dentro da classe que est im plementando quandto de todas as suas subclasses. Ao decidir-se sobre os
nve is de acesso para um mtodo, lem bre-se das seguintes diretrizcs para mtodos privados:
Um mtodo pri vado no traz preocupaes para os usurios da classe.
O mtodo mudar se a implementao da classe mudar.
Lem bre-se tambm do seguinte em relao aos mtodos protegidos:

Um mtodo protegido no traz preocupaes para os usurios dessa classe; entretanto, as


classes que estendem fun cionalidade da classe que est implementando exigiro acesso
ao mtodo.

O mtodo atende aos requisitos fu ncionais de todas as subclasses.

Interfaces
Assi m como as classes, as interraces so recursos bsicos da linguagem Java. Ao contrrio das
cl asses, entretanto, as interfaces no defi nem atri butos e mtodos para uma classe. Em vez disso,

Apndice B

as interfaces fornecem definies de mtodo que podem ser implementados pelas classes. I)ara
aqueles que esto familiarizados com e++, as interfaces sero semelhantes s defin ies de classe dentro de arquivos de cabealho.
D uma olhada em uma interface para objetos que podem ser ordenados ou comparados:

I"

* Interface para comparar a i gua l dade de dois objetos

'I
public interface Comparable {

I"
*
*
*
*

Compara esse objeto com um objeto desejado. Se o corrente


for maior , ento retorna I, o objeto toCompare maior .
ento retorna - 1. Se os dois objetos forem ig ua is . retorna O
@param toCompare - objeto para comparao
* @retu rn - 1 se toCompare > this. O se toCompare this .
* 1 se thi s > toCompare

'I
public int compare(Object toCompare);

I
Essa interface reside dentro do SDK Java. Ela defi ne os mtodos que todos os objelos de tipo
Comparable devem implementar. Neste caso, todos os objetos Comparabl e devem implementar o
mtodo de comparao. De forma simples, uma interface um contrato que uma classe que esteja implementando deve cum prir. Se uma classe implementa uma inter fa ce em particular, ela pro-mete imp lementar todos os mtodos designados pela interface.
Atualmentc, a linguagem Java fornece suporte apenas para herana simples. Em outras palavras,
uma classe Java s6 pode estender uma classe Java. Conseqentemente, se voc optar por class ificar um objcto de Cl assA c C1 assB (herana mlti pla), ento s podcr fazer isso atravs de interfaces. Usando interfaces para sim ular herana mltipla, a linguagem Java recupera grande parte
da fu ncional idade fornecida pela herana mltipla. Parte da outra func iona lidade perdida poderia scr recuperada parcialmente, atravs de mtodos de projeto, como composio de objeto.
As interfaces tambm tm vrias outras propriedades. Voc no pode instanciar uma interface
atravs de new. Sua classe pode implementar vrias interfaces. Por exemplo, a classe Product
pode implementar as interfaces Sortable e Clonable:
publi c cla ss Product imp1ements So rtab le . Clonable
As interfaces tambm podem estender outras interfaces. A interfa ce Sortable tambm pode estender uma interface Collectible. Uma classe implementando a interface Sortabl e tambm
deve cumprir o contrato da interface Collec t i bl e:
public interface Sortable extends Cl onable

Aesumo do Java

577

Classes internas e classes internas annimas


Os arquitetos da linguagem Java acrescentaram o concei to de classes internas com a Java 1. 1.
Uma classe interna uma classe declarada dentro do escopo de uma classe pblica. Porque voc
deve usar uma? As classes internas tm as seguintes vantagens imponantes:

Um objeto de uma classe interna pode acessar quaisquer atributos, privados ou no, da
classe que est encapsulando.
As classes internas annimas simplifi cam tarefas, comocallbacks e tratamento de eventos.
As classes internas so extremamente teis para a criao de objctos que armazenam dados, que no tm nenhum significado fo ra do contexto da classe que os empacota, corno
uma chave de hashing especializada para uma cache. Fora da cache, a chave de hashing
no tcm nenhum significado. Assim , voc cria uma classe interna Ha shKey dentro doescopo da classe ObjectCache.
Aqui est como a cl asse Ob j ectCache com a cl asse interna HashKey seri a:
i mport java.util . Map ;
i mport java.util.Has hMap ;
publi C cla ss Obj ectCache (
private Map cache ;
publ iC Object Cache() (
cache new Ha shMap();
}

pub11C void add(String oid , St r ing objName, Object obj) (


Ha shKey key new HashKey(oid , objName);
cac he. put(key , obj) ;
}

publ ic Object get( String oi d, St ring objName ) {


Has hKey key = new Hash Key( oid. objName);
Object ob j cache.get( key);
return obj ;
}

// .... Mais mtodos ...


pri vate cla ss HashKey {
private Stri ng oi d, objName ;
publiC Ha shKey(St r ing oid , St ring objName) I
th i s.o id
oid;
th i s .objName = objName ;
}

Apndice B

pub l iC String getOi d() {


r eturn oi d ;
}

public String getObjName() {


return objName;
}

public boolean equals(Object obj) {


if (obj instanceof HashKey) {
HashKey key = {Ha shKey)obj;
return (key.g etOidO.equals(getOidO ) &&
key.getObjName{).equa ls{ getOb j Name{) ) ) ;
}

return fal se ;
}

public int has hCode() {


return 17;
}
}
}

Nas classes internas, assi m como nas classes normais, voc pode acessar os atributos da classe
interna com a palavra-chave t his; entretanto, voc tambm pode acessar os atributos da classe
que est encapsulando. Voc prec isar usar a palavra-chave ou ter para acessar esses atributos.
As classes anni mas so uma forma es pecial de classes internas. As classes annimas so mais
predominantes na escrita de cdigo de tratamento de eventos. Tome como exemplo o trecho de
cd igo a seguir, para tratar de eventos de ao em um boto OK:
publi c class FooF rame {

II
JButton ok .. new Jbutton("ok");
ok.addActionLis t ene r(n ew ActionListener{) {
public vo i d actionPerformed(Action Event evt) {
II real iz a al gum tratamento de evento para o bota o ok
}
}} ;
}

11-

Embora a sintaxe seja um pouco com plicada, as classes internas annimas permitem q ue voc
reduza o numero de classes em seu projeto. Em vez de uma classe ou classe interna para cada
manipulador de evento, voc colocaria as dedaracs de d asse em linha. Isso economiza muito
tempo; entretanto, dev ido natureza complexa do cd igo, classes internas annimas em dema

Aesumo do Java

sia reduziro a legibilidade do cdigo. Conseqentemente, se voc tiver de real izar muito tratamento de evento, talvez queira usar alguns padres de proj eto (como o padro Command) para
melhorar seu projeto e, assim, esclarecer sua implementao.

Resumo
De modo algum este resumo uma introduo completa linguagem Java. Entretanto, ele fornece informaes suficientes, dentro do contexto deste texto. Se voc quiser obter mais infonnaes, ex istem vrios sites na Web que fornecem exerccios dirigidos aprofundados sobre os
fundamentos da linguagem Java. Um recurso excelente para desenvolvedores in iciantes e experientes o JDC (Java Developer's Connection), local izado no endereo developer.java . sun.
com. Esse site fornece muitos exerc cios d irig idos e software de acesso adiantado para desenvolvedores de Java.

ApNDICE
Referncia da UML
Referncia da UML
Este apndice fornece lima referncia rpida para a nOlao UML usada por todo O livro.

Classes
A UML representa uma classe atravs de uma caixa dividida em trs sees. A seo superior
contm O nOme, a seo do meio contm os atributos e a seo inferior contm os mtodos.

A Figura C. I ilustra como a UML representa uma classe.

Objeto
A UML representa objeto igual a uma classe. A nica diferena que o nome do objeto sublinhado e os mtodos so omitidos. Os atri butos tambm podem exib ir um valor.

Visibilidade
A Figura C.2 ilustra como a UML representa visibil idade de atri buto e mtodo:

+ representa visi bi lidade pbl ica

# representa visibil idade protegida


- representa visibilidade privada

Apndice C

FIGURA C.1
UII/a c/asse UMI..

Nome r::
da classe

--

---~~~,,<Nome de Cl_
<<AtribulOD>

_____ . Atribulol

,,
Opera6es

FIGURA C.2

Visibilidade d(! mtodo


e atributo.

Vislbllldade
+pl.lblic_anr
'protecte-(Canr
-private-_attr
+pl.lblic_op,( )
'p-rotecte-(Copr( )
-private_op,( I

Classes e mtodos abstratos


As classes e mtodos abstraias so simbolizados pelo nome abstrato em itl ico. A Figura C.3 d
um exem plo de classe abstrata.

FIGURA C.3

Uma cltlSse (/bsll(l/a.

Voc tam bm pode adicionar a restrio {abs tract} aps o nome. Usar o rtul o de restrio aj lida ao se desenhar um d iagrama mo.

Notas

As vezes, um a nota tornam um modelo mais inleligvel. Na UML, uma nota semelhante a uma
nota adesiva e ligada ao elemento que a eSl recebendo com uma linha tracejada.
A Figura C.4 ilustra a nota UML. Voc pode anexar uma nota em qualquer parte de seu modelo
UML.

583

Refe rncia da UML

FIGURA C .4

1I01a

U:\IL
+addAccount I )
+totalHold ings f)
+totalAccounts ( )
+deposil ( )
+balanc::e I )

----_ .

B!!nk cont6m vllri!lS conl!!S'


fo rnece opera6es pa ra
manipular essas c::onlas.

Esteretipos
Um estereripo um elemento da UML que permite a voc estender o vocabu lrio da prpria
li nguagem UML ou class ificar uma marcao. Um esteret ipo consiste em uma palavra ou frase
inclu da entre e> >. Voc coloca um esteretipo acima o u ao lado de um elemento existente .
A Fi gura C.5 ilustra um esteret ipo que defin e um tipo de mtodo.

FIGURA C.5

O esteretipo UML
acc::essoO' +getBalanc::el)
+depositfundsll
+withdrawFund'()

Relacionamentos
Um relacionamelllo descreve como as classes interagem umas com as outras. Na UM L. um relacionamento uma conexo entre dois ou mai s elementos de notao. Na UML, um relacionamento normalmente ilustrado atravs de uma linha ou de uma seta entre as classes.

Dependncia
Em um relacionamento de dependllcia, um obj eto dependente da espec ificao de outro obj eto. Se a especificao mudar, voc prec isar atualizar o objelo dependente.
Na UML, voc representa uma dependncia como uma seta tracejada entre as classes dependentes. A Figura C.6 ilustra a notao de dependncia da UM L. O relacionamento infonna que
Cl assA depende de Cl as sB.

FIGURA C.S

Um relaciol/amel/to de
depel/del/da simples.

c....

Claq B

Apndice C

Associao
Uma associao indica q ue um obj etocontm outro. Nos termos da UML, quando se est em um
relacionameOlo de associao, um objeto est conectado a outro.
Na UML, voc representa uma assoc iao como uma li nha que conecta as duas classes. Diz-se
que uma associao que no tem seta bidirecional. Uma seta sign ifica que o relacionamento
funciona apenas em uma di rco.
A Figura C.7 ilustra a notao de associao da UML. O relacionamento d iz que Cl assA est associada a Cla ssB.

FIGURA C .7

Um re/(/c ;OI/(//IIeIlfO
de associa(;o.

ClusA

CI ..sB

Papis
A UML pennite que voc denote o papel de cada classe na associao. O papel da associao a

parte que um objelo desempenha em um relacionamento.


A Figura C.8 ilustra a notao UML para o papel.

FIGURA

C.8

O pape/lia UML.

j)II~1 B

Multiplicidade
A UML permi te que voc denote a multiplicidade da associao. A multiplicidade indica quantos objctos podem tomar parte na instncia de uma associao.

O intervalo dos valores de mult"iplicidade est listado na Tabela C. I.


TABELA C.1

Valores de multiplicidade

NOfao

Valor

Um

Qualquer nmero

1.. *

Pelo menos um

X .. y

Qualquer nmero de valores no interva lo x a y

A Figura C.9 il ustra a notao UML para multiplicidade.

Ref erncia da UML

FIGURA C.9

AJlllliplicidade.

Cln sA

,I

Agregao
A UML fornece notao para agregao. Uma agregao um tipo especial de associao que
modela relacionamentos 'tem um ' de todo/parte entre pares.
Voc modela uma agregao como uma linha com um losango aberto na extremidade relat iva a
' todo/parte '. A Figura C. lO ilustra a notao UML para agregao.
ClusA

FIGURA C.10

Agregaeio.

Composio
A UML fornece notao para composio. Uma composio um tipo especial de associao
que modela relacionamentos 'tem um' de todo/parte entre classes que no so pares. A parte no
independente do todo em um relacionamento de composio.
Voc mooela a composio como uma linha com um losango fechad o na extremidade relativa ao
'todo/parte' . A Figura C I I ilustra a notao UML para composio.
FIGURA C.1 1

Composifio.

a ....

Generalizao
,

Um relacionamento de generalizao existe entre o geral e o espec fico. E a herana.


A generalizao sim bolizada atravs de uma li nha cheia com uma seta fec hada e vazada. A Figura C, 12 il ust ra a notao UML para generalizao,

FIGURA C.12

Generali:aeio.

a ....

CI. asA

a.""

Apndice C

Diagramas de interao
Os diagramas de interao modelam as interaes entre os objelos.

Diagramas de colaborao
Os diagramas de colaborao representam as mensagens que os objetos enviam uns para os outros.

Cada objeto simbolizado como uma caixa no diagrama. Uma li nha conecta cada objeto que in
terage. Sobre essa linha, voc escreve as mensagens que os objetos enviam e a direo dessas
mensagens.
Os diagramas de colaborao destacam os relacionamentos ent re os atores. A Figura C. 13 ilustra
o diagrama de colaborao UML.
FIGURA C.13

Objelol

Um diagrama de
colabo/"ar7o.
Ob!e!03

Objelo2

Diagramas de seqncia
Os diagramas de seqUncia modelam a seqUncia de eventos em um cenrio, com o passar do
tempo.
Cada objeto no diagrama si mbol izado na parte superior do diagrama como uma caixa. As linhas que saem das caixas representam a linha da vida do objeto. As mensagens so passadas entre os objctos. A Fi gura c' 14 ilustra o diagrama de seqUncia UML .
FIGURA C.14

Vm diagrama
l/e seqiiimcia.

Objeto1

ApNDICE
Bibliografia selecionada
o domnio dos objetos s pode vir com o tempo, a prtica e o estudo. Nenh um livro pode ensi
n-Io tudo que h a respeito da programao orienlada a objetos.
Este Apnd ice apresenta lima lista de recursos de 00 classificados. Use esta lista como guia
para seus prx imos passos no estudo e na aplicao de POO. Embora no seja importante que
voc investigue cada recurso, esta li sta pode conduzi-l o para mais informaes sobre os assuntos
que voc achar interessan tes.

Anlise, projeto e metodologias


Beck, Kent. Ex/reme Prograllllllillg ETplailled: Embrace Change. Boston: Addison-Weslcy, 2000.
Baoch, Grady. Objecl Oriellled Ana/ysis And Design: Wilh Applicaliolls. Reading: Addi
son- W esley, 1994.

Baoch, Grady, James Rumbaugh e IYar Jacobson. The Unified Modeling Langl/age Use,. Guidc.
Reading: Add ison-Wesley, 1999.
Fowler, Martin e Kendall Scott. UML Dislilled: A BriefG/lide to fhe Standard Ohjecl Modeling
Language. 2'" ed . Readi ng: Addi son-Wcsley, 2000.
Johnson, Ralph E. e Brian Foote. "Designing Reusable Classes:' JOIl1"l1a/ of Objecl Orienled
Programming 1.2 (Junho/Julho 1988): 22-35.
Liberty, Jessc. Beginnillg Objecl Orienled Ana/ysis and Design. Ollon, UK: Wrox, 1998.

Apndice D

Programao com C++


Stroustrup, Bjame. TI/e C+ + Programmillg Lallguage. Special ed . Readi ng: Addison-Wcsley,
2000.

Padres de projeto
Buschman, Frank, Regi ne Meunier, Hans Rohnen, Peler Sommerlad e Michael Slal. Paltern-Oriellted Software Architecture: A System of Patterns. C hi chesler: Wiley, 1996.
Garnma, Erich, Richard I-Ielrn , Ralph Johnson e John Vlissides. Design Pallel'llS: E/emenls of
Rel/sab/e Object-Oriel/fed Software. Read ing : Addison- Wesley, 1995.

Princpios e teoria geral da 00


Booch, Grady. Object Oriel1led Analysis AI/d Design. With Applicatiolls. Reading: Addison-Wesley, 1994.
BlId, Ti molhy. Ali /ll/rodllctiOIl lo Object Oriel1led Programming. 2'" ed . Read ing: Addison-Wesley, 1997.
Fowler, Martin. Refa ctoring: /mprovillg lhe Design of Edsling Code. BOSlon: Addison-Wcsley,
2000.
Rum baugh, James. " Disinhcrited! Examples of Misuse of Inherilance." Joumal ofObjecl Orienled Programming 5.9 (Feverei ro 1993): 22-24.
Se idewitz, Ed. "Controll ing Inherilance". Joul'I1al ofObject Oriellled Programming 8.8 (Janeiro
1996): 36-42.
Taenzer, David, Murthy Ganti e Sunil Podar. "Objecl-Orienled Software Reuse: The Voyo Probl em." ./OII1'11al ofObjecl Oriented Programming 2.3 (setembr%utubro de 1989): 30-35.

Teoria "Hard Core" (mas no deixe isso


assust-lo! )
Cardelli, Luca e Peter Wegner. "On Understandi ng Types, Dala Abstraclions and Polymorphism". Compllting SlIr\leys 17.4 ( 1985): 471-523.
Danfonh, Scott e Chris Tomlinson. 'Type Theories and Objecl Oriented Programming" . ACM
Computing SlIrveys 20. 1 ( 1988): 29-72.

Bibliografia selecionada

Snyder, Alan. "Encapsulation and lnheri lance in Objecl Orienled Prograrnrn ing Languages" .
Proceedings ofthc 1986 OO PSLA Conference on Object Oricnted Programming Syslems, Languages and App1icalions. Sigp/all Nolices 21.11 ( 1986): 38-45.
Wegner, Peler e Stanley B. Zdonik. " Inheritance as an Incremental Modificat ion Mechanis m or
What Likc is and isn' l Likc". ECOOP 1988: 55-77.

Programao com Java


Bloch, Joshua. Efleclive .Java Programming Langl/age Guidc. Boslon: Add ison- Wes ley. 200 1.
Eckel, Bruce. Thinking i/1 Java . 20d cd. Upper Saddle River: Prenlice Hall , 2000.
Warren, Nige l e Philip Bi shop. Java in Praclice: Design S/y/es alld Idiolllsfor Eflec/ive Java.
Harlow, UK : Addi son- Wesley, 1999.

Miscelnea
Brooks, Frederick P., Jr. Tlle Mylhica/ Man-Mo1l1h. Anniversary ed. Rcading: Addison- Wesley,
1995.
Scame, Joh n. Scarne' s Encyclopedia ofCard Games: Ali lhe Rules for Ali thc Games You' lI
Want to Play . Nova York: Harper, 1983.

Smalltalk
Budd, Timot hy. A Liule SII/(III/alk. Reading: Addison-Wesley, 1987.
Goldberg, Adele c David Robson. Small/aik-80: Tlle Language. Reading: Addison-Weslcy,
1989.

Teste
Beck, Kent. Ex/reme Progralllllling Exp/ained: Embrace Change. Boston: Addi son- Wesley,

2000.
Mackinnon, Tim, Stcvc Frceman e Philip Craig. "Endo-Testing: Unit Tcst ing \\Ii th Mock
Objects". Artigo apresentado na confe rencia eXtreme Programming and Flexiblc Processes in
Software Engineeri ng - XP2000, Cagl iari, Sardinia, Itl ia, junho de 2000.

ApNDICE
Listagens do cdigo do jogo
vinte-e-um
Nos dias 15 a 21 , voc construiu um jogo vinte-c- um completo. Muitos dos exerccios tambm
pedi ram para que voc adicionasse mais fu ncionalidade ao sistema. Esta listagem de cdi go-fonte apresenta a verso final do jogo vinte-c-um. A verso fina l combina cada recurso que
foi adicionado nos dias 15 a 2 1.

Este apndice contm a listagem completa de todo o cdigo. O cdigo foi empacotado para evitar arq uivos-fon te duplicados. O que pode ser comparti lhado compm1 il hado. O que no pode
ser com partilhado no compmt il hado.

O cd igo-fon te contm uma OU I MVC, urna OUI PAC, urna UI C U e um si mulador. O cdigo-fonte fo i d ividido nos segu intes pacotes:

blackjack.core

blackjack.core.threaded

blackjack.exe

blackjack.players
bl ackjack. ui
bl ackjack .ui.mvc
bl ackjack .ui .pac

Ap ndi ce E

blackjack.core
blackjack .core contm todas as classes comuns encontradas nas listagens E.I a E.14. Essas
classes constroem o sistema do jogo vi nte-e-um bsico.
liSTAGEM

E.1

Bank.java

package blackj ack. corej


public class Bank (
private int total ;
private int bet ;
publiC Bank( int amount )
tota I amount ;

I
pub l ic vo i d doubleOown()
placeBet( bet ) ;
bet - bet * 2-,

I
publ ic void placelOOBet()
placeBe t( 100 );

I
public void place50Bet() (
placeBet( 50 ) ;

I
publi C vo i d pl acel0Bet()
placeBet( 10 ) ;

I
publiC vo i d win() I
total +- ( 2 * bet ) ;
bet - O;

I
pub l ic void l ose () I
/1 j ext rado de tota l
bet O;

I
publi C void blackjack() I

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E .1

593

Bank.java (continuao)

total +- ( ( ( 3 bel ) / 2 )+ bel );


bel - O
J

publiC void standoff() I


total +- bet;
bel - O;
J

public String toString() {


return ( "$" + total + " . 00" l;
J

private void placeBet( inl amount ) {


bet - amount;
tota 1 _ a amount ;

J
J

LISTAGEM E .2

BettingPlayer.java

package blackjack . co re;


public abstraet elass Bett i ngPlayer extends Player {
private Bank bank;
publiC BettingPlayer( St r ing name, Hand hand. Bank bank 1 {
super( name , hand li
this.bank a banki
J

11******************************************* ****** *************


Ilcomportamento sobreposto
publ ic Stri ng toString(l {
return ( super . getName() + lO: " + getHandO.toString() + "\n" +
bank.toStr ing() )i

J
publie Stri ng getName() {
return ( supe r.getName() + " " + bank.toString() l i
J

publ ie vo id wi nO {

I 594

Ap ndi ce E

LISTAGEM E.2

BettingPlayer .java (continuao)

bank .winO:
super.winO:
J

publi C void l ose() {


bank.loseO:
super .lose() ;
J

public vo i d standoff() {
bank. s tandoff () :
super . standoff():
J

publ ic vo i d blackjack() {
bank.blackjack O:
s uper.bla ckjack() :
J

protected PlayerState geUnitia l StateO {


return get8ettingState();

J
protected Playe rSta te getPlayingState() {
return new 8etterPlaying():
J

11**************************************************** **********************

Iladicionado recentemente para BettingPlayer


protected final 8ank get8ank() {
return bank:
J

protected PlayerStale getBettingState() {


return new Betting():

J
protected PlayerState getDoublingDownState() {
return new DoublingOown():

J
protected abstract void bet():
pro tected abst ra ct boolean doubleDown( Dealer dea l er );
private class Betting implements PlayerState {

Listagen s do cdigo do jogo vinte-e-um

LISTAGEM

E.2

BettingPlayer.java (continuao)

publiC void hand Changed() I


II impossfve l no estado de estouro
J

publiC void handPlayab le() I


II impossfve l no estado de estouro

J
public void handBlackjack() {
II impossfvel no estado de estouro
J

pub li c void handBusted() {


I I impossfvel no estado de estou ro
J

public void execute( Dea l er dealer ) {


bet () ;

setCurrentState( getWaitingState() );
dealer.doneBetting( BettingPlayer.this );
II tenni na
J

private class DoublingDown implements PlayerState I


public void handChanged( ) {
notifyChanged():
J

publiC void handPlayable() {


setCurrentState ( getStandingState() ):
notifyStanding():
J

pub l iC void handBlackjack() {


I I impossfvel no estado de dobro
J

pub li C void handBusted() {


setCu rrentState( getBustedState() ):
notifyBustedO ;
J

publi c void execute( Dea le r dealer ) {


bank .doubleDown();
dealer.hit( BettingPlayer.this };
getCurre ntState{).execute( dealer ):
J

private class BetterPlaying implements PlayerState I

595

I 596

Apndice E

E.2

LI STAGEM

Bett ingPlayer .java (continuao)


publiC "oid handChangedO {
not i fyChanged () ;

I
public "oid handPlayable(} {
Ilpode ignorar no es tado de jogo

I
publ i c void handBlackjack(} {
Ilimpossf"el no estado de jogo

I
public void handBusted() {
setCurrentS tate( getBustedSta te() };
notifyBu sted O j

I
pub li c "oid execute( Dealer deale r ) {
i f( getHand().canDoubleDown( ) && doubl eDown( dealer ) ) {
setCurrentS tate( getDoubl ingDownState(l );
getCurrentState().execute( dea1er l ;
return;

I
i r( hit( dealer ) ) {

dealer.hit( BettingPlayer.this };
) else {
setCurrentState( getStandingState() );
notifyStanding();

I
getCurrentState().execute( dealer ) ;
II transio

I
I
I

LI STAGEM

E.3

B1 ackjackDea 1er . java

package bl ackjack.core;
import java.util . ArrayList ;
import java.uti 1. Iterator ;
pub l ic cl ass BlackjackDealer extends Player implements Oea l er {
private Oeckpi l e cards ;
priva te ArrayLi st pl ayers

new ArrayList() ;

Listagen s do cdigo do jogo vinte-e-um

LISTAGEM E.3

597

8lackjackDeal er.java (continuao)

protected ArrayList waiting_players;


protected Arraylist betting_players;
private ArrayList standing_players;
private Arraylist busted_players ;
private Arraylist bla ckjack_players;
public 81ackjackOeal er( String name. Hand hand, Oeckpile cards ) {
super( name, hand ) ;
thls.cards cards;
J

//**********************************************************************

//Mtodos Que os jogadores podem chamar


public void blackjack( Player player ) {
blackjack_playe rs.add( player );
play( thls );
J

publiC vold busted( Player playe r ) {


busted_players.add( player );
play( this )i

J
publiC void standing( Pl ayer player ) {
standing_pl ayers.add( player );
play( this );
J

public void doneBetting{ Player player ) {


waiting_players . add{ player );
play( this ) i
J

public void hit( Player player ) {


player.addCard( cards.dealUp() );
J

public Card getupCard{) {


Iterator 1 getHandO.getCards{)i
while( i.hasNext() ) {
Card ca rd = (Ca rd) i.next();
if( card.lsFaceUpO ) {
return card;
J
J

I 598

Apndice E

8lackjac kDea 1 er. java (continuao)

LISTAGEM E.3

II

no deve chegar aqui


return nu11;

II ..................
II Mtodos de conf igurao do jogo
pub1ic void addPlayer( Player pl ayer ) {
players . add( pl ayer );
}

public void reset() (


super,reset();
Ilconfigura os baldes do jogador
waiting_p l ayers new Array List() ;
standing_players new ArrayList() ;
busted_p1ayers new ArrayList();
b1ackjack_players a new ArrayL is t();
betting_players new ArrayList() ;
betting_players .addA1l(p1ayers ):
3

cards . reset O;
lterator i players.iterato r ():
while{ i.hasNext() ) (
Player p1ayer : (Player) i .next {) ;
player,reset{);
}
}

pu bli c void newGameO (


reset O;
I I vai!
play( this );
}

11********************* **** ******.*****


public void dea l () (
cards.shuffle();
II reconfigura cada jogador e distribui uma carta abert a para cada um e
II para si mesma
P1ayer [] player : new Player (waiting players.size{)]:
waiting-p1ayers.toArray{ player };
for{ int ; O; i < player.length; i ++ ) {
player (1] . addCard( cards .dealUp() ):
}

this.addCard( cards.dealUp() ) :

Listagen s do cdigo do jogo vinte-e-um

599

LISTAGEM E.3 8lackjackDea 1er. java (continuao)

II distribui mais uma carta aberta para cada jogador e uma fechada para
II s1 mesma
for( in t i O; i < player.length: i ) {
player[i] .addCard( cards.dea lUpO ):
J

this.addCard( cards .dealDown(l l:


J

protected boolean hit( Dealer dealer ) {


if( standing_players .size() > O && getHand().total()
return true:

<

return false
J

protected voi d exposeHand () (


getHand().turnOver();
notifyChanged():

J
protected PlayerState getBlackjackState() (
return new OealerBlackjack();
J

protected PlayerState getDealingState() (


return new OealerDealing(l;
J

protected Pl ayerState getCollectingBetsState() I


return new OealerCo ll ectingBets() ;
J

protected PlayerState getBustedState() {


return new DealerBusted():
J

protected PlayerState getStandingState() {


return new DealerStanding() :
J

protected PlayerState getWaitingStateO {


return new DealerWaiting() :
J

protected PlayerState getInitialState() {


return new Oea lerCollect i ngBets():

J
private class DealerCollectingBets implements Pl ayerState (
public void handChanged() {

17 ) {

I 600

Ap ndi ce E

LISTAGEM E.3

8la ckj ackDea 1er. java (continuao)

II

impossivel no estado de aposta

I
public void handPlayable() {
II imposslvel no estado de aposta

I
pu bli c void handBlac kjackO (
II impossfvel no estado de aposta

I
publ ic void handBu sted() (
II impossfvel no estado de aposta

I
public void executeI Oealer dealer ) (
1f( !betting_players. isEmptyO ) (
Player pl ayer s( Player )betting_players.get(O) ;
bett l ng_players.remove( player );
player.play( dealer ) ;
I else (
setCurrentState( getOealingState() ) ;
getCurrentState() . execute( dealer );
II faz a trans i o e executa

I
I
private cl ass OealerBusted implements Pl ayerSt ate (
publ i c void hand Changed() (
II imposshe l no estado de est ouro

I
public vold handPlayab l e() (
II impossfvel no estado de estouro

I
pub l ic void handB l ackjack() (
II impos sf vel no estado de estouro

I
pub l i c vol d handBu st ed() (
II impossfvel no estado de estouro

I
publl c vo id executeI Oea l er dealer ) (
I terator 1 standi ng_pl ayers. i terator() ;
while( i.ha sNext() ) {
Pl ayer pl ayer =( Pl ayer ) i .next() ;
player.wlnO;

I
i s blackjack_players. i terator( ) ;
wh l1 e( i .hasNext() ) {

Listagen s do cdigo do jogo vinte-e-um

LISTAGEM E.3

8lackjackDea 1er. java (continuao)


Player player = (Player) 1. next();
player.blackjack();
J

i = busted_players.iterator() ;
while( i.hasNext() ) {
Player player z (Player) i.next();
player.lose() ;
J
J
J

private class DealerBlackjack implements PlayerState {


publie void handChanged() {
not i fyChanged () ;
J

publie void handPlayable() {


II impossfve l no estado de vinte-e-um
J

publie void handBlackjaek() (


II impossfve l no estado de vinte -e- um

J
publie void handBusted() (
II impossfvel no estado de vinte-e-um

J
publie void execute( Dealer dealer ) (
exposeHand();
Iterator 1 pl ayers.iterator();
while( i.hasNext() ) (
Player player =(Player) Lnext();
;t( player .getHandO .blackjackO ) {
player.standoff() ;
) else {
player.loseO ;
J

J
J
J

private class DealerStanding implements PlayerState {


publie void handChangedO (
II impossfve l no estado de parada

J
publ ie void handPlayable() {
II impossfvel no estado de parada

J
publiC void handBlackjack() {
II impossfvel no estado de parada

601

I 602

Ap ndi ce E

LISTAGEM

E.3 8la ckj ackDea l er.java (continuao)


}

public void handBu sted () {


II impossfve l no estado de parada
}

publiC void execute( Oealer dealer ) I


Iterator i stand i ng_players. iterator();
while( i.hasNext() ) I
Pl ayer player (Player) i .next();
if( player .getHandO. i sEqual( getHand() ) ) I
player .standoff() ;
) else if( player .getHand() . isGreate rThan(getHand() ) ) I
player.w;n{) j
) el se I
player . lose() ;
}
}

i blackjack_players.iterator() ;
wh ile( i.hasNext( ) ) I
Pl ayer player (Pl aye r) LnextO;
player.b l ackjack()i
}

i bu sted_players . iterator();
whi le( i.hasNext() ) (
Player pl ayer : (Player) i .next () i
pl ayer.lose ();
}
}

private class OealerWaiting i mplements Pl aye rState I


public void handChanged () {
II imposs vel no estado de espera
}

public vo i d handPlayable( ) {
II impossve l no es t ado de espera
}

publ ic voi d handBl ackjack() {


II i mpossfvel no estado de espera
}

publiC voi d handBu sted() I


II impossve l no estado de espera
}

publi c vo i d executeI Oealer deale r ) (


i f(!wait i ng_pl ayers .i sEmpty() ) I
Player pl aye r (Pl ayer) wa i t i ng_players .get(O),
waiting_players.remove( player li

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.3 8lackjac kDea l er.java (continuao)


player.pl ay( deale r ) i
) else {
setCurrent State( getPlayingState() );
exposeHand () i
getCurrentState() . exec ute( dealer ) ;
Il faz a transio e executa
}
}
}

private class DealerDeal ing implements Playe rState {


pub l ic void handChanged() {
noti fyChanged() i
}

public void handPlayable() {


setCurrentState( ge tWa i tingState() li
II tran si o
}

publiC void ha ndBlackjack() {


setCurrent Sta te ( ge t Bl ackj ackS ta te () ) i
notifyBlackjack() ;
II transio
}

publ ic vo i d handBustedO {
II impossfvel no estado de di stribui o
}

public void execute( Deal er dea l er ) {


dealO ;
ge tCurrentS tate( ) .execu te( dealer ) i
II faz a transio e executa
}

}
}

LISTAGEM E.4

Ca rd.java

package blackjack.core;
pub l iC class Card {
pri vate Rank ran k:
private Suit suit;
pri vate boolean face_uPi
public Card( Suit suit . Rank rank ) {

603

I 604

Apndice E

LISTAGEM E.4

Ca rd. java (continuao)

th'is.sult sult:
thls . rank rank :
J

publ'ic Sult getSuit() {


return SUl t:
J

public Rank getRank () {


return rank;
J

public void setFaceUp( boo l ean up ) {


fa ce_up up;
J

publ iC boolean isFaceUpO {


return face_up:

J
public String toStr'ing() {
i f( ! isFaceUpO ) {
return -Hidden" :

J
return rank.toString() + suit .toSt ring() ;
J

LISTAGEM E.5

Dea l er.java

package blackjack.core;
publi c interfa ce Oealer {
II usado pelo jogado r para 'i nteragir com a banca
publ ic void hl t( Player player l:

II usado pelo jogador para comun i car estado


public
publ ic
public
publ ic

vold
vo i d
vo i d
void

blackjack( Playe r player l:


busted( Player playe r l ;
stand'i ng( Pl ayer player l;
doneBetting( Player playe r ):

pub l ic Card getUpCard();

banca

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.6

Oeck.java

package blackjack . core i


import java. ut il .Iteratori
impo rt java. ut il.Random i
public class Oeck 1
private Ca rd [] deck ;
pr i vate int index ;
pu bliC Deck() (
buildCardsOi

I
publ ic vo i d addToStack( Deckpil e stack) (
stack .addCards( deck )i

I
pro tected voi d setOeck( Card [] deck ) (
t hi s. deck deck;

I
protected voi d buildCardS( ) 1
deck new Card[52] i
Ite ra tor suit s Suit.SUITS.i terator() i
int coun ter Di
while( su its . hasNext() ) {
Sui t sui t (Suit) suits .next()i
Iterator ranks Rank.RANKS.iterator() ;
whi l e( ranks.hasNext() ) {
Rank rank (Rank) ranks.next()i
deck(counter] " new Ca rd( suit. ra nk ) i
counter++ i

I
I

I
I

605

I 606

Ap ndi ce E

LISTAGEM E.7

Oeckpi l e.java

package bl ackjack . core ;


import java.util.Arraylist;
import java.util.lterator;
import java . util.Random;
publi c class Oeckpile (
private Arrayllst stack new Arraylist()j
private int i ndex;
private Random rand z new Random();
public void addCards( Card [] ca rds ) (
for( int i O; i < cards.length ; i ++ ) {
stack . add( cards [i) ) ;

pub l ic void shuffle() {


reset();
randomize() ;
randomizeO;
randomi ze () :
randomizeO;

publ ic Card dealUp() {


Card card z dea l ();
i f( ca rd !z nul l ) {
card.setFaceUp( true );

return card;

publiC Card deal0ownO {


Card ca rd z deal();
if( ca rd ! - null ) {
card . set FaceUp( false );

return ca rd;

public void reset() {


index z O;
Iterator 1 stack.iterator();

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.7 Oeckpi l e.java (continuao)


while( 1. hasNext( ) ) I
Card card (Card) i. next O:
card.setFaceUp( fa l se ) :
J
J

private Card deal() I


if( in dex ! - stack.size() ) I
Card card (Card) stack.get( i ndex ):
index++;
return card:
J

return null;
J

private void randomlze() {


int num_cards stack.size();
for( int i O: i < num_cards: i ++ ) I
int index - rand.nextlnt( num_cards ) ;
Card card_i (Card) stack .get( i ):
Ca rd card_index (Card) stack . get( index ):
stack .se t ( i, ca rd_index ):
stack.set( i ndex, card i ):

J
J

J
LISTAGEM E.a

Hand.java

package blackjack.core:
import java . utl1 . ArrayList :
import java.uti l. lterator:
pub li C cl ass Hand {
private
private
private
private

ArrayList cards - new ArrayList() :


sta t ic final int BLACKJACK : 21;
HandListener hOl der:
i nt number_a ces :

public HandO I
setHolder(
new HandUstenerO {

607

I 608

Apndice E

Hand.java (continuao)

LISTAGEM E.a

publiC
pub l ic
public
publ ic

void
vo id
voi d
void

handPlayable() {}
handBlackjackO {}
handBustedO {I
handChangedO {I

}
};
}

public vo1d setHolde r( HandListener holder ) {


this.ho l der holder i
}

public Iterator getCardsO (


return cards.iterato r();
}

publ iC void addCard( Card card ) (


cards.add( card )i
holder.handChanged();
if( ca rd. getRank () Rank .ACE ) {
number_aces++:
}

if(

b,stO ) I
ho l der.handBusted();
return;

if( blackjack() ) (
holder.handBlackjack();
return ;
J

if ( ca rd s.size () >= 2 ) {
holder.handPl ayable() ;
return ;
J
J

pub li c boolean canOoubleOown() {


return ( cards.size() == 2 );

J
publ iC boolean isEqua l ( Hand hand ) {
if( hand . totalO this.total{) ) {

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.a

Hand.java (continuao)

return true ;
}

return false;
}

public boolean i sGreaterThan{ Hand hand ) I


return thi s.total() > hand.total();
}

public boolean bla ck jack() (


if( cards. sizeO ,,= 2 && total ()
return true;

BLACKJACK )

return fal se ;
}

publ iC void resetO {


cards. clearO ;
number aces " O;
}

public void turnOver() I


Iterator i " cards.ite rator ();
while( i.hasNext() ) I
Card card " (Card) i.next();
card.setFaceUp( true );
}

public String toString() (


Iterator i " ca rds.iterator();
String string " '''';
while( i.hasNext() ) (
Card card = (Card) i.next ();
string " string + " " + cardo toString() ;
}

return string ;
}

public int total0 (


int total = O;
Iterator i " cards.ite rator();
while( i.hasNext() ) (
Card card " (Card) LnextO i
total +. card.getRank().getRank();

609

I 610

Apndice E

LISTAGEM E.a

Hand.java (continuao)

in t temp_aces number_aces ;
while( total> BLACKJACK && temp_aces > O ) I
total = total - 10;
temp_aces-- ;
}

return total;
}

private boolean bustO {


if( total() > BLACKJACK ) {
return true ;
}

return false;
}
}

LISTAGEM E.9

Hand Liste ner .java

package blackjack.core;
public interface HandLlstener I
publi C void handPlayab le( );
public void handBlackjack() ;
publiC void handBusted();
public void handChanged();
}

LISTAGEM E.10

Pl ayer.java

package blackjack.core ;
import java.ut ll.ArrayList;
import java.utll.Iterator;
publ i c abstract class Player I
private Hand hand;

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.10

Player.java (continuao)

private Stri ng name :


private ArrayList l isteners new ArrayList();
private PlayerState current_state :
publi C Pl ayer( String name, Hand hand ) (
this.name name:
this.hand hand;
setCurrentState{ getlnitialState{) );

I
publi C void addCard{ Card card ) 1
hand.addCard( card ):

I
publ ic void play( Oeale r dealer ) {
current_state . execute( dealer }:

I
public void reset() {
hand. reset O;
setCurrentState( getlnitialState() );
notifyChanged():

I
publi C vo1d addlistener( Playerlistener 1 ) (
listeners.add( 1 );

I
public String getName() 1
return name:

I
publi c Stri ng toString() 1
return (name + ": " + hand.toStringO ):

I
publ ic void win() 1
notifyWinO :

I
publiC void lose() (
not ifyLoseO :

I
public vo1d standoff() I

611

I 612

Apndice E

LISTAGEM E.10

Player.java (continuao)

no t 1fyStandoff() :
}

publl C void blac kjac k()


not 1 fySl ackj ack () :
}

public Hand getHand() {


return hand:
}
protected void notifyChanged() I
Iterato r i l i s t ene rs.iterator():
while( i.hasNext() ) 1
PlayerListener pl .. (PlayerListe ner) i.next();
pl.playerChanged( this ) :
}
}
protected voi d notifyBusted() (
Iterator i .. li steners.iterator();
while( i.hasNext() ) (
Pl ayerli s tener pl .. (PlayerListener) i .nextO :
pl . playerSusted( th is );
}
}

protected yoid notifyBlackjack() {


Iterator i hsteners .iterator():
while( i.ha sNext() ) {
PlayerListener pl : ( Playerlistener) i . next();
pl.playerBlackjack( this ):
}
}
protected void notifyStanding() (
Iterator i l i s teners . i t erator() :
while( i .hasNextO ) (
Pl ayerListener pl .. (PlayerListener) i .next() ;
pl.playerStand i ng( th is ) :
}
}
protected yoid notifyStandoff() (
Iterator i l i steners.iterator() :

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.10

Player.java (continuao)

while( 1. hasNext( ) ) I
Playerlistener pl (PlayerListener) i .next();
pl . playerStandoff{ this );
J
J

protected void notifyWin(} I


Iterator i listeners.iterator{);
while( 1. hasNext() ) I
PlayerListener pl (Player l istener) i .next{);
pl.playerWon{ this ) ;
J
J

protected vo l d not1fyLose() {
Iterator i listeners.iterator();
while( i .hasNext() ) I
Playerlistener pl z (PlayerListener) i .next();
pl .pl ayerlost( this };

J
J
protected fina l void setCurrentState( Pl ayerState state ) I
current_sta te state;
hand . setHolder( state ) ;
J

protected final PlayerState getCurrentStateO I


return current_statei
J

protected PlayerState getBustedState() {


return new Busted();
J

protected PlayerState getStandingState() I


return new Standing() ;
J

protected PlayerState getPlayingState() {


return new Playing(} ;

J
protected Playe rState getWaitingState() (
return new Waiting();

613

I 614

Apndice E

LISTAGEM E.10

Pl ayer.java (continuao)

protected PlayerState getBlackjackState{) I


return new Blackjack{);
}

protected abstract PlayerState getInitia IState():


protected abstract boolean hit( Dealer deale r );
private class Waiting implements PlayerState I
public void handC hanged() {
not i fyChanged () :
}

publi c void handPlayable{) {


setCurrent Sta te{ ge tPlayingState() l:
II transio
}

public void handBlackjack{) {


setCurrentS ta te ( getBl ackj ackS ta te () );
notifyBlackjack();
II trans i o
}

pub l ic void handBusted{) {


II impossvel no estado de espera
}

public void execute{ Dealer dea ler ) {


II no faz nada enquanto espera
}
}

private class Busted implements PlayerState {


public void handC hanged {l {
II impossve l no es tado de estouro
}

public void handPl ayable() {


II imposs fve l no estado de estouro
}

pUblic voi d handBlackjack{) I


II impossve l no estado de estou ro
}

publi c vo i d handBusted{) I
II impossvel no estado de estou ro
}

publ ic void exec ute( Dealer deal er ) I

Listagen s do cdigo do jogo vinte-e-um

LISTAGEM E.10

Player.java (continuao)

dealer.busted( Player.this );
II tennina
}
}

private class Blackjack implements PlayerState (


public void hand Changed{) I
II impossfvel no estado de vinte -e-um
}

public void handPlayable() I


II impossfvel no estado de vinte-e-um
}

public void handBlackjack() {


II impossfvel no estado de vinte-e - um
}

public void handBu sted() {


II impossfve l no estado de vinte-e-um
}

public void execute( Dea ler dealer ) (


dealer . blackjack{ Player.this );
II tennina
}
}

private class Standing imp lements Pl ayerState I


public void handChanged() {
II lmpossfvel no estado de parada
}

public void handPlayable() {


II lmpossfvel no estado de parada
}

public void handBlackjack{) {


II lmpossfvel no estado de parada
}

public void handBusted{) {


II impossfve l no estado de parada
}

public void execute( Dea l er dealer ) (


dealer.standing{ Player . this ) ;
II tenni na
}
}

private class Playing implements Playe rState I


public void handChanged() (
notifyChanged() ;
}

public vold handPlayable() I

615

I 616

Apndice E

LISTAGEM E.10

Pl ayer.java (continuao)

II pode ignorar no estado de jogo


}

public void handBlackjack() I


II impossivel no estado de jogo
}

publ ic void handBustedO I


setCurrentS tate( ge tBustedState() ) ;
notifyBusted(}i
}

public void execute( Deale r dealer ) {


if( hit( dealer ) } {
dea l er.hit( Pl ayer.this }i
} else (
setCurrentState( getStandingS t ateO );
notifyStanding{) i
}

current_state.execute( dealer ) i
II transiao
}
}

LISTAGEM E.l1

PlayerUstene r. java

package blackjack .co rei


public interface PlayerListener {
public void playerChanged( Player player };
publi c void playerBusted( Player player l i
publi c vofd playerBlackjack ( Player pl ayer };
publ ic yoid playerStanding( Player player } ;
pub l ic yoid playerWon( Player player li
public void playerLost( Playe r player )i
public void playerStandoff( Player player li
}

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.12

PlayerState.java

package bl ackjack . core :


public interface PlayerState extends Handlistener I
publiC void execute( Oealer dealer ):

LISTAGEM E.13

Rank.java

package blackjack. core :


import java.util . Collections:
import java.util . list :
import java.util.Arrays;
public final class Rank {
publiC
public
public
public
public
public
pubh c
public
publ ic
public
public
public
public

static
stati c
static
stati c
static
stati c
stati c
static
static
static
static
static
stat i c

final
final
final
f ina l
fi nal
fi na 1
f ina l
final
final
final
fina l
final
fi na l

Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank
Rank

lWO
THREE
FOUR
FIVE

new
" oew
" oew
"ew
51'
" oew
SEVEN "ew
EIGHT "e,
NINE ne,
TE' " ne'
JACK "e,
QUEEN - "e,
KING " new
ACE " "ew

Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(
Rank(

2 , "2" };

3,
4,
5,
6,

I;
I;
I;
I;
I;
"S" I ;
"9" I ;

"3 "
"4 "
" 5"
"6"
7, "7"

S,
9,

lO, "10" ):

l O, "J" I ;
lO, "Q" I ;
10, " K" I ;
11, "A" I ;

private static final Rank [] VALUES "


I TWO, THREE, FOUR , FIVE , SIX , SEVE N,
EIGHT, NINE, TEN , JACK , QUEEN , KING , ACE J:

II fornece uma lista no modif ic ve l para fazer l ao


publ ic static final List RANKS ~
Co 'l ec t ions .unmodifiablelist( Arrays.asList( VALUES ) }:
private fina l int
rank:
private fi na 1 String disp lay ;
private Rank( int rank , String disp l ay ) {
this.rank z rank;

617

I 618

Apndice E

LISTAGEM E.13

Rank.java (continuoo)

thiS.display displaYi
}

publlC int getRankO {


return rank i
}

publ ic String toString() {


return displaYi
}
}

LISTAGEM E.14

$u;t.java

package blackjack.corei
i mport java . util. Co ll ections;
i mport java.utll.listi
import java.ut il.Arraysi
publiC final class Suit {

Ildefine
publl c
publl c
public
public

estaticamente todos os valores


static final Suit OIAMONOS - new
st atic final Suit HEARTS new
static final Suit SPAOES new
static final Suit (LUBS
new

private sta tic final Suit [] VALUES

vlidos de Su it
Suit ( (c har)4 ) i
Suit ( (char)3 )i
Suite (char)6 ) ;
Suite (char)5 )i
{OIAMONDS. HEARTS . SPAOES . CLUBS }i

II fornece uma lista n1l0 modificve l para fazer l ao


public st atic fi nal List SUI TS
Collect i ons.unmodifiable Li st( Arrays.asList( VALUES ) )i

II varivel de instncia para conter o valor de exibi o


private final char displaYi

II

no permite inst ancia o por objetos ex ternos


private Suit e char disp lay ) {
lh i s. display displ ay;
}

II retorna o valor de Suit


publ ic String toStringO {

Listagens do cdigo do jogo vi nte-e-um

LISTAGEM E,14

6 19

$ult.java (continuao)

return String.valueOf( display };


}
}

blackjack.core.threaded
bl ack j ack. core. threaded contm um objeto Bl ackjackOeal er que coloca osjogadores em suas
prprias lin has de execuo (Listagem E. IS).
LISTAGEM E.15

ThreadedBl ackjac kDea 1er.j ava

package blackjack . core.threaded;


import blackja ck. co re.*;
i mport java.utll .ArrayLi st;
import java.uti 1. Iterator ;
public cl as s Threaded BlackjackDealer extends BlackjackOealer (
publiC ThreadedBlackjackOealer( String name , Hand hand, Oeckpile cards ) (
supere name , hand, cards );
}

protected PlayerSta te getWaitingState() (


return new OealerWaiting();
}

protected PlayerState getCollectingBetsState() (


return new DealerCol l ectingBets() ;
}

private class DealerCollectingBets implements PlayerState (


publi c void handChanged{) {
II impos s ve l no estado de aposta
}

public void handPl ayable() {


II impossve l no estado de aposta
}

public void handBl ackjack() {


II impossve l no estado de aposta
}

publ ic void handBusted() {


II impossvel no estado de aposta

I 620

Apndice E

LISTAGEM E.15

ThreadedBl ackjackDea 1er .java (cont inuoo)

public void execute( fina l Oea ler dealer } {


H( !betting_p1ayers. isEmptyO } {
final Player player ~ (Player) betting_players.get( O }i
betting players.remove( player };
Runnable runnable = new Runnable(} (
publi c void run() I
player.play( dealer };
}

};
Thread threaded = new Thread( runnable }i
threaded.start(}i
} else I
setCurrentState( getDealingState() )i
getCurrentState().execute( dealer )i
II faz a transio e executa
}

}
}

private class DealerWaiting implements PlayerState (


publi c void handChanged() {
II impossfvel no estado de espera
}

publ i C void handPlayable() {


II impossfvel no estado de espera
}

publiC void handBlackjack() {


II impossfvel no estado de espera
}

publiC void handBusted() I


II impossfvel no estado de espera
}

public void execute ( final Dealer d ) I


H( !waiting_players.isEmptyO ) {
final Player p (Player) waiting_players.get( O )i
waiting_players . remove( p );
Runnable r z new Runnable() I
public void runO {
p.play( d )i
K

};
Thread t new Thread( r )i
t.startO i
} else {

Listagen s do cdigo do jogo vinte-e-um

LISTAGEM E.15

621

ThreadedBl ackjackDea 1er .java (cont inuoo)


setCurrentState( getPlayingState()
exposeHand () ;
getCurrentState().execu te( d );
II faz a transio e executa

l;

}
}
}

blackjack.exe
blackjack.exe contm os executveis para GU I MVC, GU I PAC, UI CU e si mu lador
(I iSlagens E. 16 a E. 19).

LISTAGEM E.16

Bl ackjackCLI.java

package bl ackjack.exe;
i mpo rt blackjack.core .*:
impo rt blackjack.players.*;
import blackjack.ui.*;
public class Bl ackjackClI 1
publ1c static vo1d maln( String [] args ) 1
Oeckpile ca rds new Oeckpile() :
for( int i .. O; i < 4; i ++ ) {
cards.shuffl eO:
Deck deck new Deck():
deck.addToStack( cards l ;
cards. shuf fle{):
}

Hand dealer_hand new Hand();


BlackjackDealer dealer .. new BlackjackDealer{ "Oealer" , dealer_hand. cards
" );Bank human_bank .. new Bank{ 1000 );
Hand human_hand new Hand(l:
Player player .. new Coomandl inePlayer( "Human", human_hand. human_bankl;
dealer . addllstener{ Consol e.INSTANCE ) ;
player.a ddl istener{ Consol e.INSTANCE l;
dea l er.addP layer( pl ayer );
do

I 622

Apndice E

LISTAGEM E.16

BlackjackCLI.java (continuao)

dealer.newGame( );
} while ( playAga i n() );
Console .INSTANCLprintMessage( "Thank you for playing !" );
J

private sta t ic boolean playAgain() (


Console. INSTMCLprintMessage( "Wou ld you like to play again? [Y] es [Nlo" ) ;
String response -Co nsole. IN STANCLreadlnput( "invalid" );
if( response.equalsIgnoreCase( "y" ) ) {
return true;
J

return fa 1se;
J

LISTAGEM E.17

BlackjackMVC .java

package blackjack.exe ;
impo rt
import
impo rt
import
import
import

blackjack.core .*;
blackjack.core . th readed .*;
blackjack.u i.mvc .*;
javax.swing.* :
java . awt .*;
java.awt.event.*;

public class 8lackjackMVC extends JFrame (


public static void main( St r ing [] args ) (
JFrame frame = new 81ackjackMVC() ;
frame.ge t ContentPa ne(). set8ackg round( FOREST GREEN )i
frame.setSize( 580 , 480 );
frame.show():
J

private BlackjackDealer dealer;


priv ate GUIPl ayer
human:
private JPanel players - new Jpanel( new Gridlayout( O, 1 ) };
private static fina l Color FOREST GREEN = new Color( 35 , 142, 35 ,;
public Bl ackjackMVC() {

Listagen s do cdigo do jogo vinte-e-um

LISTAGEM E.17

BlackjackMVC .java (continuao)

setUpO ;

WindowAdapter wa new WindowAdapter() (


public void windowClosing( WindowEvent e ) I
System.exit ( O );
}
};

addWindowListener( wa };
}

II precisa ser protegid o se houve r subclasse


private PlayerView getPlayerView( Player player } {
PlayerView view new PlayerView( player };
view.setBackground( FOREST_GREEN };
return view;
}

II precisa ser protegido se houver subclasse


private void setUp{) {
BlackjackOealer dealer getOealer(};
PlayerView vI getPlayerView( dea l er };
GUIPlayer human getHuman(};
PlayerView v2 getPlayerView( human ):
PlayerView (] views I vI, v2 }:
addPlayers{ views }:
dealer.addPl ayer( human };
addOptionView( human, dealer }:
}

II precisa ser protegido se houver subclasse


private void addPlayers( PlayerV iew [] pview ) {
players.setBackground( FOREST_GREEN }:
for( int i O: i < pview . length: i ++ } {
players.add( pview [i] };
}

getContentPane().add( players, Borderlayout.CENTER }:


}

private void addOpt ionView( GUIPlayer human , BlackjackOealer dealer ) I


OptionView ov new OptionView( human, dealer ):
ov.setBackground( FOREST_GREEN }:
getContentPane().add( ov, BorderLayout.SOUTH };

623

I 624

Apndi ce E

LISTAGEM E.17

Bl ackjackMVC .java (continuao)

private 81ackjackDealer getDea1er() (


if( dea1er == null ) (
Hand dea1er_hand = new Hand();
Deckpi 1e cards ,. getCards() ;
dea1er" new ThreadedBlackjackOea1er( "Deale r ", dea1er_hand, cards) ;
}

return dea1er;
}

private GUIP1ayer getHuman( ) (


if( human a. nu11 ) (
Hand human_hand new Hand() ;
8ank bank ,. new Bank( 1000 ) ;
human" new GUIPl ayer( "Huma n", human_hand , bank );
3

return human;
}

pr;vate Oeckpi1e getCards() {


Oeckpi1e cards ,. new Oeckpile(} ;
for( int i ,. O; i < 4; i ++ ) {
cards.shuff1e{} ;
Deck deck new VOeck();
deck.addToStack( cards );
cards.shuffleO;
}

return cards ;
}

LISTAGEM E.18

BlackjackPAC.java

package b1ackjack.exe ;
i mport bl ackjack.core.*;
i mport bl ackjack. ui. pac. *;
;
import Javax . swlng.
.
t . ;
i mpo rt Java.aw
l. mpor t jdva.awt.even t . ;

pub1ic cl ass B1ackjackPAC extends J Frame {

Listagen s do cdigo do jogo vi nte-e-um

LISTAGEM E.18 8lackjackPAC .java (continuao)


publ iC static void main( String [] args ) {
JFrame frame new Bl ackj ackPAC().
frame .getContentPane(}.setBackgraund{ FOREST_GREEN )i
frame.setSize{ 580. 480 ).
frame.shaw();
J

private VPlayerFactory factary = new VPlayerFactorY()i


private JPanel players new Jpanel( new GridLayout( O. I ) ) i
private static final Colar FOREST GREEN

new Co l or( 35 . 142 . 35 );

public Bl ackjackPAC() {
se tup() ;
WindowAdapter wa new WindowAdapter() {
pub l i c voi d windowC l os i ng( WindowEvent e ) {
System.exit( O )i
J
J;

addWindowListener( wa ,;

II preci sa ser proteg ido se houver subc l asse


private void se tup() {
VBlackjackDealer dealer factory.getOealer()i
GUIPlayer huma n

factory.getHuman() ;

dealer.ad dPl ayer( human };


players.add( dealer.view() );
players.add( human.view() ) ;
getContentPane().add( pl ayers . 8orderLayout.CENTER )j
J
J

LISTAGEM E.19 Bla ckjackSim .java


pa ckage bl ackja ck . exe;
import blackjack.co re.*;
import blackjack.ui.* ;
impo rt blackjack.players.*;

625

Apndi ce E

LISTAGEM E.19

8lackj ackSim .java

publ i c class BlackjackSim {


public static void main( String [] args } I
Console , INSTANCE.printMessage( "How many t imes should the simula tor
pl ay?" ):
St ring response Conso l e.INSTANCE . read Input( "invalid" ):
1nt loops Integer.parselnt( response ) :
Oeckpile cards new Deckpile() :
for( int i O: i < 4: i ++ ) {
ca rd s . shuffl e () :
Deck deck new Deck():
deck.addToStack( cards ) :
cards.shuffl eO:

II

cri a uma banca


Hand dea le r hand new Hand() :
BlackjackOealer dealer" new Bl ackjackDealer( -Oeal er". dealer_hand . cards ) :

II

cria um OneHitPl aye r


Bank one_bank new Bank( 1000 }:
Hand one_hand new Hand( ) ;
Pl ayer oplayer new OneHHPlayer( "OneHH ", one_hand , one bank );

II

cr ia um SmartPlayer
Bank smart_bank " new Bank( 1000 ) :
Hand smart_hand new Hand():
Pl ayer smplayer new SmartPlayer( "Smart" , smart_ha nd. smart_bank ):

II

cria um SafePlayer
Bank safe_ban k new Bank( 1000 }:
Hand safe_hand = new Hand() ;
Pl ayer spl ayer new SafeP l ayer( "Safe" , safe_hand , safe bank ) i
t

II

cria um FlipPlaye r
Bank flip_bank new Bank( 1000 ) :
Hand flip_hand new Hand() ;
Playe r fplayer = new FlipPlayer( MFlip". flip_hand. fl i p_bank )i

II

cria um jogador intel igente


Bank kn_bank new Bank( 1000 );
Hand kn_hand " new Hand();

Listagens do cdigo do jogo vi nte-e-um

627

LISTAGEM E.19 8lackjackSim .java (continuao)


Pl ayer knpl ayer ,. new Know ledgeablePlayer( "Knowledgeable", kn_hand.
kn_bank );

/1 cri a um jogador "tlmo"


Bank opt_bank ,. new Bank( 1000 ) ;
Hand opt_hand new Hand();
Player optp l ayer ,. new OptlmalPl ayer( "Opti mal " , opt_hand. opt_bank );

1/ rene todos os jogadores


dealer.addlistener( Console.INSTANCE ) ;
oplayer.addlistener( Console . INSTANCE ) ;
dealer . addPlayer( opTayer )i
splayer.addlistener ( Conso l e. INSTANCE )
dealer.addPlayer( splayer ) i
smplayer . addllstener( Console.INSTANCE )
dealer . addPlayer( smplayer )i
fplayer .add listener( Console.INSTANCE )
dealer.addPl ayer( fplayer ) ;
knplayer.addlistener( Console.INSTANCE );
deal er.addPl ayer ( knplayer );
op tplayer.addli stener( Console . INS TANCE );
dealer.addPlayer( optplayer li
int counter O;
while( counter < loops ) {
dealer . newGame( )
cou nter ++;
J
J

blackjack.players
bl ackjack. pI ayers contm os vrios jogadores que fo ram criados no texto e cm alguns dos
exerccios (listagens E.20 a E.26).
LISTAGEM E.20 COrmland Li neP l aye r . j ava
pa ckage bl ackj ack.pl ayers
import blackjack.core.*
import blackjack .ui.*

Apndi ce E

LISTAGEM E.20

COl11TlandL i nePl aye r . java

publ i c class Command LinePlayer extends BettingPlayer (


private
private
pri vate
private
private
private
private
private
private
private
private

final
fi na 1
fi na 1
fi nal
fi nal
fi na 1
fi na 1
fi na 1
final
final
fina 1

static
statlc
static
static
static
static
static
static
static
static
static

String
String
String
Str; ng
Str; ng
String
Stri ng
String
String
String
String

HIT " "H" :


STANO ~ "S" :
PLAY _MSG = "[H] H ou [5] tay " ;
BET_MSG = Pl ace Bet:(l O] [50] or [100]";
00- MSG "Oouble Oown? [i] es [N]o " .,
BEl_lO = "10" :
BEl_50" "50":
BEl_IOO = "100" :
NO = "N":
YES = "Y" :
OEFAULT" "i nva li d":

publ ic CommandLinePlayer( String name , Hand hand , Bank bank ) (


supere name , hand, bank ):

I
protected boolean hit( Oealer dealer ) (
while( true ) (
Console. INSTANCE.printMessage( PLAY_MSG ) :
String response Console.INSTANCE. readlnput( OEFAULT );
if( response.equa l sIgnoreCase( HI T ) ) I
return true:
I el se if( response.equalsIgnoreCase( STANO ) ) I
return false:
I
II se chegarmos at aqui . faz lao at obtermos uma entrada
II significativa
I

I
protected boolean doubleOown ( Oealer dea l er ) (
while( true ) (
Console. INSTANCE.printMessage( OO_MSG ) ;
Stri ng response Conso l e.INSTANCE.readlnput( OEFAUlT ):
if( response.equals IgnoreCase( NO ) ) (
return false;
lelse if( response.equalsIgnoreCase( YES ) ) {
return true;

II se chegarmos at aqui , faz l ao at obtermos uma entrada significativa


I
I

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.20

Colt1t1andLi nePl ayer. j ava (cont inuoo)

protected void betO (


whl1e( true ) {
Co nso le . INSTANCE.pri ntMessage( BET_MSG )j
String response = Console . INSTANCE . readIn put( DEFAULT )j
if( re sponse.equa l s( BET_I0 } ) I
getBank() . place lOBet()j
return j
J

if( response . equals( BET_50 ) ) I


getBank() . place50Bet() :
returnj
J

if( response .equal s ( BET_I00 ) } (


getBank().placelOOBet();
returnj
J

II se cheganmos at aqui. faz lao at obtenmos uma entrada


II s ignif ica t iva
J
J

LISTAGEM E.21

Fl ipPlayer. java

package blackjack.players :
import blackjack.core.*;
pub l ic class FlipPlayer extends BettingPlayer {
private boolean hit false;
private boolean should_hit_once

false ;

publ ic Fl i pPlayer( Stri ng name. Hand hand. Bank bank ) {


supere name, hand , bank };

J
public boolean hit( Dea ler dealer ) {
if( should_hit_once && !hit ) {
hit .. true;
return true j
J

629

Apndice E

LISTAGEM E.21 Fll pPl ayer .java (continuao)


return false :
}

publlC voi d resetO I


super. reset O;
hit false ;
should hit once

- -

public void bet() I


getBank{) .place l OBetO ;
}

publi c boolean doubleDown( Deale r dealer ) {


ret urn false:
}
}

LISTAGEM E.22 KnowledgeablePlayer.java


package bl ackja ck.players:
import blackjack. core .*:
publ i c cl ass Knowl edgeablePlayer extends BettingPl ayer I
public KnowledgeablePlayer( String name, Hand hand , Bank bank) I
supere name, hand, bank ) ;
}

pub l ic boolean doubleDown( Deale r dealer ) {


int total getHandO . total O ;
1f( total 10 I I total ,.'"' 11 ) {
return true:
}

ret urn false:


}

pub l iC boolean hit( Dealer dealer ) I


int total. getHandO.total0:
Ca rd ca rd = dealer. getUpCard( ) :
l/nunca di stribu i mais cartas , independente de qual, se total> 15
1f( total> 15 ) I

Listagens do cdigo do jogo vi nte-e-um

LISTAGEM E.22

Knowl edgeab 1ePl ayer .java (continuao)

return false;

I
l/sempre distribui mais cartas para 11 e menos
1f( total c- 11 ) {
return true;
I
l/ isso deixa 11, 12, 13 , 14
l/baseia a deciso na banca
1f(

card .getRank() .getRankO


return true;

>

7 ) {

I
return false:

I
pub l ic voi d bet() {
getBank().place lOBet();

I
I

LISTAGEM E.23

OneHitPlayer.java

package blackjack.players;
import blackjack . core.*:
pub l i c class OneHit Player extends Bett1ngPlayer {
pr1vate boolean has_hit false :
publ iC OneHitPlayer( String name , Hand hand, Bank bank ) {
supere name , hand, bank ):
I
pub l ic boole an hit ( Dea ler dea ler ) {
1f( !has_hit ) {
has_h it - true;
return t rue ;

I
return fa lse ;

63 1

I 632

Ap ndi ce E

LISTAGEM E.23

OneHitP1ayer .java (continuao)

public void reset() I


super.reset():
has hit .. false:
}

public void bet() {


getBank() .placelOBet():
}

publiC boolean doubleOown( Oeale r dealer ) {


return false;
}
}

LISTAGEM E.24

Opt ima lPlayer.java

package bl ackjack . players :


import blackjack .co re.*:
public class Opt imalPlayer extends BettingPlayer I
publi C OptimalPlayer( St ring name, Hand hand , Bank bank ) I
super( name , hand, bank ):
}

public boo lean doubleOown( Oealer dealer ) {


i nt total .. getHand() . tota 1 () :
Card ca rd = dealer.getUpCard() :
if( total 11 ) {
return true:
}
H( total .... 10 ) {

if( card . getRank().getRank() != Rank.TEN.getRank() &&


card .getRankO )" Rank .ACE ) {
return true:
}

return fa l se:
}

if l tot.1 9 } I
H( card.getRankO .... Rank. TWO

II

card.getRank() .... Rank.THREE

II

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.24

Opt imal Player . java (conmt inuoo)


card.getRankO == Rank.FOUR II
card .getRank() Rank.FIVE I I
card .getRank{) Rank.SIX ) {
return true;

return fal se ;
}

return false;
}

publi C boolean hit( Oealer dealer ) {


; nt total .. getHand O . tota 1 () ;
Card ca rd dealer.getUpCard() ;
H( total

>.

17 ) {

return false;
}
H{ total " 16 ) {
H{ card.getRankO == Rank..SEVEN

II
II

card .getRank() Rank.EIGHT


card .getRa nk {) Rank..N INE ) I
return true;
} else I
return false;
}

}
H{ total 13

II

total 14 II total ... 15 ) {


if( card.getRank{) Rank.TWO I I
card.getRankO == Rank . THREE II
card.getRank.{) .... Rank .FOUR II
card.getRank{) ,,~ Rank . FIVE I I
card.getRank.{) == Rank . SIX ) {
return false;
} else {
return true;
}

if( total .~ 12 ) {
H( card.getRankO == Rank..FOUR II
card .getRank() Rank.FI VE II
card.getRank{) Rank.S IX ) {
return false;
} else {

633

I 634

Apndice E

LISTAGEM E.24

Opt imal Player .java (conmt inuoo)


return true:

I
I
return truei

I
publ ic voi d betO {
getBank().p l ace l OBet() :

I
I

LISTAGEM E.25

SafePlaye r.java

package blackjack.p l ayers i


i mport bl ackja ck. co re.*:
publiC cla ss SafePlayer extends BettingPlayer {
publ ic Sa feP layer( String name , Hand hand, Bank bank ) (
super( name , hand. bank )i

I
publi C boolean hit ( Oealer dealer ) (
return falsei

I
publiC boolean doubleOown( Dealer dealer ) {
return fa lse i

I
public void bet() {
getBank() . placelOBetO i

I
I

LISTAGEM E.26

SmartP l ayer.java

pa ckage bl ackjack.players;
import blackjack. core.*i
public cla ss Sma rtPlayer extends Bett i ngPlayer {

Listagen s do cdigo do jogo vinte-e-um

LISTAGEM E.26

SmartPlayer.java (continuao)

publiC SmartPlayer( St ring name, Hand hand , Bank bank ) (


super( name , hand, bank );
J

publiC boolean hit( Oealer dealer ) (


if( getHand().total() > 11) I
return fal se ;
J

return true ;
J

publiC void bet() I


getBank() .placelOBet();
J

publ ic boolean doubleOown( Dealer dealer ) {


return false;
J
J

blackjack.ui
blackjack.ui contm cd igo da UI comum (Listagem E.27).
LISTAGEM E.27

Co nso l e.java

package blackjack.ul ;
import
import
import
import

blackjack.core.*j
java . io.BufferedReader;
java.io. lnputStreamReader j
java.io.IOException:

pub li C cl ass Console imp lements PlayerListener {

II console singleton
public final static Console IN STANCE

new Console() :

private BufferedReader in =
new BufferedReader( new InputS treamReader( System.in ) );
publiC void printMessage( String message ) (
Sys tem.out.print ln( message );

635

I 636
LISTAGEM

Ap ndi ce E

E.27

Console .java (continuao)

publiC String readlnput( St r ing default_input ) (


String response;
try (
return i n.read Line();
I cat ch (IOException ioe) I
return default_input;
}
}

public void pl ayerChanged( Playe r pl ayer ) {


printMess age( player.toString() , ;
}

public vo i d playerBusted( Player player ) I


printMessage( player.toStringO + "BUSTEOl" , ;
}

pub l ic void playerBlackjack( Pl ayer player ) I


pr i ntMessage ( player.toStringO + "BLACKJACK!" );
}

publiC void playerStanding( Pl ayer player )1


printHessage( pl ayer . toStringO + "STANOING };
}

publi C void playerWon( Pl ayer pl ayer ) I


printMessage( pl ayer . toStringO + "WINNER!" );
}

publi C void playerLost( Pl ayer pl ayer ) I


printMessage( player.toStringO + "LOSER!" ,;
}

publiC void playerStandoff( Player player ) I


pr; ntMessage ( pl ayer. toS t ri ng () + "STANDOFF" );
}

l/privado para ev i tar instanciao


private ConsoleO {}
}

blackjack.ui.mvc
blackja ck. ui .mvc contm o cdigo mvc (listagens E.28 a E.34).

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.28

Ca rdVi ew.java

pa ckage bl ackja ck . ui .mvc ;


import blackj ack .core .*;
import javax.swing.*;
import java . awt.*;
publi c cla ss CardView extends Jlabel (
pr i vate Imagelcon icon ;
publiC CardView( VCard card ) (
ge t Image( ca rd.get lmage() )j
set Icon( i con );
setBackg round( Co lor.white );
setOpaque( true )i

I
pri vate void getlmage ( St ri ng name ) (
java.net.URl url this.getC l ass() . ge tResource( name l i
icon new Imagel con( url ) i

I
I

LISTAGEM E.29

GUIPlayer. j ava

package blackj ack . ui.mvc ;


import blackjack.core.*;
publ ic cla ss GU IPlayer extends Bett ingPlayer {
private Dealer dealer;
pu bl iC GU IPlayer ( String name , Hand hand , Bank bank) (
s upere name, hand , bank );

I
pub l ic boolean hit ( Dea ler dealer ) {
return truei

I
public voi d betO I
I I no faz nada , is t o no ser chamado
II em vez disso . o jogador humano press iona um bo t o da GUI

637

I 638

A pndi ce E

LISTAGEM E.29

GUIP1ayer.java (continuao)

II
II
II

esses mtodos de aposta sero chamados pelo controlador da GUI


para cada um: faz a aposta correta, muda o estado, penmite que a
banca saiba que o j ogador tenminou de apostar
publ ic void placelOBetO I
getBank().placelOBet();
setCurrentState( getWaitingState() );
dealer.doneBetting( th is );

publiC void place50Bet() (


getBank() .place50Bet();
setCurrentState( getWaitingState() );
dealer . doneBetting( this );
}

pub l iC void placelOOBet() (


getBank() . pl ace l OOBet() ;
setCurrentState( getWaitingState() ) ;
dealer.doneBetting( this );
}

II
II
II

a aposta em dobro um pouco diferente , pois o jogador precisa


responder aos eventos de Hand quando uma carta adicionada na mo
de modo que configura o estado como Ooubli ngOown e depois o executa
protected boolean doubleDown( Dealer d ) I
setCurrentState( getDoublingDownState() );
getCurrentState().execute( dealer ) ;
return true;

II
II

takeCard ser chamado pe l o contro l ador da GUI quando o jogador


decidir receber mais cartas
public void takeCard() {
dealer.hit( th is ) ;
}

II
II
II

stand se r chamado pel o controlador da GUl quando o jogador optar


por parar. quando a parada mudar de estado. deixa o mundo saber. e depois
diz banca
public void standO {
setCurrentSta te ( getS tandi ngS tate () );
not ifyStanding() ;
getCurrentState().execute( dealer );

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.29

GUIP1ayer.java (continuao)

II
II

voc precisa sObrepor play para que ele armazene a banca para
uso posterior
public void play( Dealer dealer ) I
this.dealer dealerj
super.p l ay( dea l er );
}

II

o seguinte trata dos estados


protected PlayerState getPlayingState() I
return new Playing();
}

protected PlayerState getBettingState() I


return new Betting();
}

private class Playing implements PlayerState I


publiC void handPlayable() {
II no faz nada
}

publiC void handBlackjack() I


setCurrentState( getBl ackjackState() );
notifyBlackjack();
getCurrentState().execute( dealer ) ;
}

publiC void handBusted() I


setCurrentState( getBustedState() );
not ifyBus ted () ;
getCurrentState().execute( dealer );
}

public void handCh anged() I


notifyChanged();
}

publiC void exec ute( Dealer dealer ) I


II no faz nada aqui, as aes viro da GUI, Que
II externa ao estado, mas quando eventos vie rem, certifica- se de
II fora r a transio de estado imediatamente
}

639

I 640

Apndice E

LISTAGEM E.29

GUIP1ayer.java (continuao)

private class Betting implement s Pl ayerState I


public void handChanged{) {
II impossfvel no estado de estou ro
}

public void handPlayable() {


II impos sfvel no estado de estouro
}

public void handBlackjack() {


II impossfvel no estado de estouro
}

public void handBusted() I


II impossfvel no estado de estouro
}

publ1c vold execute( Oea l er dealer ) I


II no faz nada aqui, as aes viro da GUI, que
II exte r na ao estado, pois nenhum evento aparece como parte da
II aposta, o estado precisar ser mudado externamente para este estado
}
}

LISTAGEM E.30

OptionView.java

package blackjack . ui.mvc:


import blackjack . core.*;
:
import Javax.swlng.
.
import Java
. aw t . :

pub li c class Op tionVi ew extends JPanel {


pub 1i c
publi c
publ ic
publi c
publi c
pub l ic
pub l ic
publi c

static
static
static
static
static
static
statlc
static

fi nal
fi na l
final
final
fi nal
fi na l
final
final

String
String
String
String
String
St r ing
String
String

NEW GAME
QUIT
HIT
STAND
BEl- 10
BEl 50
BEl 100
OOUBlE OOWN

"new":
"quit" :
- "hit";
"stand ":
"BETlO" :

~BET50":

-BETlOO M;
Mdd'"

private JButton bet 10 new Jbutton( " $10" );


pr; vate JButton bet 50 new Jbutton( "$50" ):
private JButton bet 100 new Jbutton( "$1 00" l:
-

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.30
private
priva te
private
private
private
pr ivate
private

Opt i onVi ew .java (continuao)

JButton deal new Jbutton( NNew Game- );


JButton quit new Jbutton( "Quit- );
JButton hit new Jbutton( "Hit" ) ;
JButton stand = new Jbutton( Stand N ) :
JButton ddown z new Jbutton( -Double Down );
BlackjackDealer dealer:
GUIPlayer player:

private stat1c final Color FOREST_GREEN

new Co lor( 35 , 142, 35 ) :

publi C OptionView( GUIPlayer player , BlackjackDealer dea l er ) I


super( new BorderLayout() ):
this.player player:
this.dea l er dealer;
attachController( makeContro l ler() );
buildGUI ();

I
publiC void attachController( OptionViewControl ler controller )1
deal.addAction l istener( control le r ) :
quit.addActionlistener( controller ) ;
hit . addActionListener( contro ll er ) ;
stand.addActionlistener( controller ):
bet_lO.addActionListener( controller ):
bet_50.addActionlistener( controller ) ;
bet_lOO . addActionListener( controller ):
ddown.addActionlistener( controller }:

I
public void enableDoubleDown( boolean enable ) I
ddown . setEnabled( enable };

I
publi C vo id enableBettingContro l s( boolean enable ) I
bet_l O. se tEnabled( enable );
bet_50 . setEnabled( enable ) :
bet_lOO.setEnabled( enab l e );

I
public void enablePlayerControls( boolean enabl e ) (
hit . setEnab l ed( enable );
sta nd. setEnabled( enable l ;

I
public vo1d enableGameControls( boo l ean enabl e ) I

641

Apndice E

LISTAGEM E.30

OptionView. j ava (con tinuao)

dea l. setEnab led( enable};


quit .se tEnab led( enable );
J

protected Op t ionV iewCont roller makeController(} {


return new Opt i onV i ewControl ler( player, dealer, this };
J

priva te vo1d buildGUI() I


JPanel betting_con trols new JPane l () ;
JPa nel game_control s = new Jpanel() ;
add ( betting_controls. Border layout.NORTH );
add( game_controls. Borderlayout . SOUTH );
betting_contro l s .se tBackground{ FOREST_GREEN };
game control s .setBackground( FOREST GREEN );
ddown. setAc ti onCommand( DOUBlE_DOWN ) ;
dea l .setActi onComma nd( NEW_GAME ) i
quit. setActionComma nd( QUIT } i
hit .se tActionComma nd( HIT ) ;
sta nd .setAct i onCommand( STAND ) ;
bet_lO.setAct i onCommand ( BET_lO l ;
bet_50.setActionCommand( BET_50 l;
bet_lOO .se tAct ionCommand( BET_100 };
betting_control s.add ( bet_lO l ;
bett i ng_control s.add ( bet_50 l ;
betti ng_controls . add ( bet_IOO l ;
game_contro l s . add( ddown };
game_control s.add( hit l ;
game_contro l s . add( st and };
game_contro l s .add( deal ) ;
game_controls.add( quit };
enableBettingContro l s( fal se );
enablePlayerControls( false };
enableDoubleDown( false };
J

LISTAGEM E.31

Opt i onVi ewContro l l er . j ava

package blackjack.ui.mvc;
import blackjack. core. ;
impo rt java. awt.e ven t . ;

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.31

643

Dpt 1onVi ewContro 11 er .java (cont inuoo)

publiC class OptionViewController implements Actionllstener , Pl aye rlistener {


prlvate GUIPlayer mode1i
private QptionView view:
private BlackjackDealer dealer;
public OptionViewContro l 1er( GU IPlayer model , BlackjackOealer dealer ,
OptionView view ) (
thls.model model i
model.addlistener{ this ) i
this.dealer dealer ;
thls.view view;
view.enablePlayerControls( false ) i
J

public void actionPe rformed( ActionEvent event ) {


if( event.getActionCommand() . equals( OptionView .QUIT ) ) (
System.exit( O )i
) else if( event.getActionCommand().equals( OptionView . HIT ) ) (
view.enableDoubleOown( false ) i
model.takeCa rd( );
} else if( event . getActionCommand().equals( OptionView.STAND ) ) {
view.enableOoubleOown( false };
mode l. standOi
} else if ( event.getActionCommand().equal s( OptionView . NEW_GAME ) ) {
view.enableOoubleDown( false )i
view.enableGameControls( false };
view.enablePlayerControls( false )i
view.enableBettingControls( true )i
dealer.newGame();
I else i f{ event.getActionCommand().equals( OptionView.BET_lO ) ) {
vlew . enableBettingControls( false };
view.enablePlayerControls( t rue )i
view.enableDoubleDown( true ) ;
model.placelOBet()i
) else if( event.getActionCommand().equals( OptionVi ew.BET_50 l ) {
view.enableBettingControl s( false li
vlew . enab lePlayerContro ls( true );
view .enableDoubleOown( true )i
model.place50Bet() ;
} else if( event.getActionCommand() . equals( OptionView.BET_lOO ) ) {
view.enabl eBettingContro l s( false )i
view.enab l ePlayerControls( t rue );
view.enableOoubleOown( true ):
model.placelOOBetO i

I 644
LISTAGEM E.31

Apndice E

OptionV i ewController.java (continuao)

} else if( event.getActionCommand().equals( OptionView .OOUBLE_OOWN ) ) {


view.enableBettingControls( false };
view .enablePlayerControl s( false );
view.enableOoubleOown( false );
view .enableGameControls( true );
model.doubleOown( dealer );
I

I
public vo i d pl ayerChanged( Player player } {}
publiC void playerBusted( Player player ) {
view.enablePl ayerControls( false ) ;
view.enableOoubleOown( false ) ;
view.enableGameControls( true ) ;

I
pub l iC void playerBlackjack( Player player ) {
view.enablePlayerCont rols( false };
view.enableOoubleOown( fal se ) ;
view.enableGameControls( true ) ;

I
publiC void playerStanding( Player player ) (
view .enablePlayerControl s( false ) ;
view.enableGameControls( true );
I
public void playerWon( Playe r player ) (
view.enablePlayerControls( false );
view.enableGameControls( true );

I
publiC void playerLost( Player player } (
view.enablePlaye rControls( false );
view.enableOoubleOown( false };
view.enableGameControls( true );

I
public void playerStandoff( Player player ) (
view.enablePlayerContro ls( fal se );
view.enableGameControls( true };
I

Listagen s do cdigo do jogo vinte-e-um

LISTAGEM E.32

PlayerView.java

package bl ackjack . ui .mvc:


import
import
import
import
import

blackjack.core .*:
.
. :
Javax.swlng.
javax.swing.border.*:
.
t. j
Java.aw
java.util.lterator:
~

public class PlayerView extends JPanel implements PlayerL1stener {]


private JPanel cards new JPanel (new FlowLayout( FlowLayout.LEFT ) ):
private T;tledBorder border:
publi c Pl ayerView( Player player ) (
super( new Borde r LayoutO ):
bUildUI( player )i
player.addListener( this );

I
public void playerChanged( Player pl ayer ) (
border.setTille( player . getName() ) :
ca rds.removeAl 1():
Hand hand player.gelHand() :
Iteralor i hand.getCards();
while( 1.hasNext() ) (
VCard vcard (Vcard) i.next() :
JLabel card : new CardView( vcard ) ;
cards.add( card ):

I
reval idateO;
repa;ntO i

I
publi c vo i d playerBusted( Player player ) (
border.setTitle( player.getNameO + " BUSTED!" l;
cards . repaint();

I
pub l ic void playerBlackjack( Player pl ayer )(
border.setTille( player.getName() + ~ BLACkJACk!~ };
ca rds. repaint( ) i

I
public void playerSlanding( Player player ) (
border.setTitle( player.getNameO + STANOING " ) ;
card s. repaint():

645

I 646
LISTAGEM E.32

Ap ndice E

Pl ayerVi ew .java (c on tinuao)

public voi d playerWon( Player playe r ) I


bo rder.se tT itle( playe r.getNameO + " WINNER!" )i
ca rd s.repa int( )i
}

publ ic vold pl ayerLost( Player playe r ) (


border.setTitle( player.getName() + " LOSER!" li
cards .repain t() ;
}

pu bli c vo i d pl ayerStandoff( Player player ) I


border.setTitle( player.getNameO + " STANDOFF!" ) i
cards .repaint():
}

pri vate vo id buildU I( Player pl aye r ) (


add ( cards . Borderlayou t.NORTH l i
bo rde r new TitledBo rder ( player .getName () l:
ca rds.set6order( borde r );
ca rds.setBackground( new Color( 35. 142 . 35 ) li
border.setTit leCo lor ( Color.black li
}
}

LISTAGEM E.33

VCard.java

pack age blackjack.ul.mvc :


import blackjack . core. *j
public cl ass VCard extends Ca rd I
private String imagei
publi c Yca rd( Suit suit , Rank rank,
super( suit. rank ) i
th i s. image image i
}

publiC St ring getlmage() {


if( is Fa ceUp() ) (
return image i

St ring lIl1dge ) I

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.33

VCard.java (continuao)

} else {
return "/ b1ackj ack/ ui / bi tmaps/ empty _pi 1e. xbm" ;
}
}

LISTAGEM E.34

VDeck .java

package blackjack.ui .mvc ;


import blackjack.core.*j
import java.util . lterator;
pub li C class VDeck extends Deck {
protected void bu ildCardsO {
// Isso horrvel, mas melhor do que os laos e estruturas
cond i cionais alternativas
Ca rd () deck new Card [52];
setOeck( deck );
deck [O] new Vcard( Suit.HEARTS, Rank.TWO,
"/ blackjack/ ui / bitmaps/ h2" l;
deck [1] new Vcard( Suit. HEARTS , Rank.THREE,
/ blackjack/ ul / bitmaps/ h3" ,;
deck [2] new Vcard( Suit.HEARTS, Rank.FOUR ,
"/b1ackj aCk/u i /bi tmaps/h4" ,;
deck [3] new Vcard( Suit.HEARTS , Rank.FIVE,
"/ b1ackj ac k/u i /b i tmaps/h5" ) :
deck [4 ) = new Vcard( Suit.HEARTS , Rank .SIX .
"/b 1ac kj ac k/u 1/bi tmaps/h6" ):
deck [5] new Vca rd( Suit.HEARTS, Rank.SEVEN,
"/bl ackjack/ui/bitmaps/h7" );
de ck [6] ~ new Vcard( Suit.HEARTS . Rank.EIGHT ,
~ /black jack/ ui /bi tmaps/h8" ):
deck [7] new Vcard( Su it.H EARTS. Rank.NINE,
"/ blackjack/ ui / bitmaps/ h9" };
deck [8 ] new Vcard( Suit .HEARTS , Rank.TEN,
"/ blackjack/ ui/ bitmaps/ hIO" ):
deck (9] new Vcard( Su it . HEARTS, Rank . JACK ,
"/ blackjack/ ui / bitmaps/ hll );
deck [10] new Vcard( Suit . HEARTS, Rank.QUEEN ,
/ blackjack/ ui / bitmaps/ hI2" );

647

I 648
LISTAGEM E.34

Apndice E

VOeck.java (continuao)

deck (11 ] new Vcard(


"j blackjackj u1 j b1tmapsj h13" );
deck [1 2] new Vca rd(
"j blackjackj ui j bitmapsj hl " );
deck (13] " new Vcard(
"j bl ackjack j ui j bi tmaps j d2" );
deck [14] " new Vcard(
"/ bl ackjack j ui /Mtmaps j d3" ) ;
deck [1 5] new Vcard(
"/b1ackj ackju i /bi tmaps/d4" ) ;
deck [16) new Vcard (
"/b 1ac kj ac k/u i /bi tmaps/d5" ) ;
deck (1 7) " new Vca rd(
"/ b1ackj ackju i /b i tmaps/d6" ) ;
deck [1 8J new Vcard(
"/bla ckjack/ui/bitmaps/d7" );
deck [19] " new Vcard(
"j blackjack/ ui / bitmaps/ d8" );
deck [20] new Vcard(
-j blackjack/ ui j bitmaps / d9" );
deck [21J " new Vcard(
"j blackjackj ui j bitmapsj dlO" );
deck [22] " new Vcard(
"/ blackjackj ui j bitmapsj dl1" );
deck [23] new Vcard(
"j bl ackjack j ui j bi tmaps j dl 2" ) ;
deck [24] new Vcard(
"/ blackjackj ui / bi tmaps j d13" ) ;
deck [2 5] new Vca rd(
"/blackjackjui/bltmaps/dl" ) ;
de ck [26) " new Vca rd(
"/bl ackjack/ui/bitmaps/s2" );
deck (27) " new Vcard(
"/bl ackja ckjui / bitmaps/s3" );
deck [2 8] new Vcard(
"/blackjack/ui/bltmaps/ s4" );
deck [29] " new Vcard(
"j blackjackj ui / bltmaps/ s5" );
deck [30] new Vcard(
-j blackjack/ ui j bitmapsj s6" );
deck [31] = new Vcard(
"j blackjackj ui j bitmapsj s7 " );
deck [32] " new Vcard(
"j blackjackj ui j bitmapsj s8" );
deck (3 3] new Vcard(

Suit.HEARTS . Rank.KING .
Su it.H EARTS . Rank.ACE .
Sult.DIAMONDS . Rank . TWO .
Suit . DIAMONDS . Rank.THREE.
Suit.OIAMONDS. Rank.FOUR .
Suit.OIAMONDS , Ra nk. FIVE ,
Sui t.OIAMONDS. Ra nk. SIX.
Suit. OI AMONDS . Rank.SEVEN.
Suit.DIAMONDS , Rank.E IGHT,
Suit .O IAMONOS . Rank.N INE .
Suit.OIAMONOS. Rank . TEN.
Suit.DI AMONOS. Rank.JACK.
Su it.DIAMONOS. Rank .QU EEN.
Su it.OIAMONDS . Rank.KING,
Suit.OIAMONDS. Rank.ACE .
Suit.SPADES . Rank.TWO .
Suit.SPADES . Rank.THREE.
Suit.SPAOES . Rank.FOUR.
Suit.SPADES . Rank.FIVE.
Suit.SPAOES. Rank.SIX .
Suit.SPADES. Rank.SEVEN .
Suit.SPAOES. Rank.EIGHT,
Suit.SPAOES. Rank.NINE ,

Listagens do cdigo do jogo vi nte-e-um

LISTAGEM E.34

VOeck.java

-j blackjackj ul j bitmapsjs9" );
deck [34] new Vcard(
Mjblackjackj ui j bitmapsj slO" );
deck [35] = new Vcard(
-j blackjackj ui j bitmapsjs ll" );
deck [36] new Veard(
"/ blackjackj ui j bitmapsj sI2" );
deek [37J new Veard(
"/ b1ackj ackju1/ bl tmap sjs 13" );
deek [38J new Veard(
"/ b1aekj aekj ui / bi tmap s/s 1" );
deek [39J new Veard(
"/bl aekjaekjui/bitmaps/c2" ) ;
deek [40) new Veard(
"/bl aekjaek/ ul / bitmaps/c3" );
deek [4 1] new Vcard(
"/ blaekjaek/ ui / bitmaps/c4" ,;
deck [42] new Vcard(
Mjblaekja ek/ui j bi t ma ps/c 5" )i
dec k [43] new Vcard(
-j blackjackj ui j bitmapsjc6" ,;
deck [44] new Vcard(
-j blackjackj ui j bitmapsjc7"
deck [45] new Vcard(
-/ b1ackjack j ui / bi t maps/c8" );
deck [46J new Veard(
j blackjackjui j bi tmaps je9" );
dee k [47] new Veard(
"/ b1ackj aek j ui / bi tmaps je 10" ) ;
deek [48J new Veard(
"/b 1aekj ae kj ui / bi tmap s/ c 11" );
deek [49] new Vcard(
"/bl aekjaek j ui/bitm apsje12"
deek [50) = new Veard(
"/b 1ackj ae k/ ui / bitmaps/ c 13" ) ;
de ek [51} new Veard(
~/blaekjaek/ui/bitmaps/cl" };

'i

$uit.SPADES. Rank.TEN.
Suit .SPAOES , Rank.JACK.
Suit .SPAOES. Rank.QUEEN.
Suit.SPAOES . Rank.KING.
Suit.SPAOES . Rank.ACE.
Suit.CLUBS . Rank . TWO ,
Suit.CLUBS . Rank . THREE .
Suit.ClU8S. Rank.FOUR.
Suit.ClUBS . Rank.FIVE ,
Suit.ClUBS . Rank.S IX.
$uit.ClUBS. Rank.SEVEN.
Suit . ClUBS. Rank . EIGHT.
Suit.CLUBS. Rank . NINE.

Suit.CLUBS . Rank . TEN ,


Suit.CLUBS . Rank.JACK.

'i

Suit .CLUBS . Rank.QUEEN .


Suit .CLUBS . Rank . KING .
Suit.ClU8S. Rank.ACE.

I
I

blackjack.ui.pac
b1ack j ae k. ui . pac contm o cdigo pac (listagens E.35 a E,42).

649

Apndice E

Disp layable.java
package blackjack . ui . pac:
import javax.swing .JComponent:
publiC interface Oisplayable I
public JComponent view() :
}

Listagem E.36

GUIPlayer.java

package blackjack.ui.pac:
import
i mport
import
i mport

blackjack.core.*;
javax.swing.*:
java.awt.*:
java.awt.event.*:

publiC cla ss GUIPlayer extends VBettingPlayer impl ements Displayable (


private BlackjackDealer deale r;
private JPanel view:
pUblic GUIP layer( Str ing name , VHand hand, Bank bank . VblackjackDealer
_ dea le r ) I
super( name. hand, bank ):
this .dealer dealer ;
}

public boo lean h1t( Dealer dealer ) I


return true;
}

public void bet() I


II no faz nada, isto no ser chamado
II em vez disso, o jogador humano pressiona um boto da GUI
}

II esses mtodos de aposta se ro chamados pelo contro lado r da GUI


II para cada um: faz a aposta correta, muda o estado. permite que a
II banca sa iba que o jogador terminou de apostar
public void placelOBet() {
getBank().pl acelOBet():
setCurrentState( ge tWai tingState() ) :
dealer.done8etting( th i s ) :

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.36

651

GUIP1ayer.java (continuao)

public void place50Bet () {


getBank().place50Bet();
setCurrentState( getWaitingState() );
dealer.doneBetting( this ):
}

public vo1d placelOOBet() {


getBank().place IOOBet() :
setCurrent State( getWaitingState() ) ;
dealer . doneBetting( this ):
}

II
II
II

a aposta em dobro um pouco diferente, pois o jogador pre cisa


responder aos eventos de Hand quando uma carta adicionada na mo
de modo que configura o estado como DoublingDown e depois o executa
protected boolean doubleOown( Dealer d ) {
se tCurrentState( getOoublingOownState() ) ;
getCurrentState().execute( dealer ) :
return true :
}

II
II

takeCard ser chamado pelo controlador da GU I quando o jogador


decidir receber mais cartas
public void takeCard() {
dealer.hit( th is );
}

II
II
II

stand ser chamado pelo controlador da GU I quando o jogador optar


por parar, quando a parada mudar de estado, deixa o mu ndo saber, e depois
diz ba nca
publi c void standO {
setCurrentState( getStandingSta te() );
notifyStand i ng():
getCurrentState() . execute( dealer l :
}

pub l ic JComponent view() {


if( view ,,= null ) {
view = new Jpanel( new Borderlayout() ):
JComponent pv " super.view():
GU IView cv new GUIView();
addListener( cv l;
view.add( pv, BorderLayout. CENTER ):

I 652

Ap ndi ce E

LISTAGEM E.36

GUIP1ayer.java (continuao)

view.add( cv, Bo rderlayout.SOUTH );

I
return view;

II

o seguinte trata dos estados


protected PlayerState getPlayingState() (
return new Playing()j

I
protected PlayerState getBettingState() I
return new Betting() ;

I
private class Playing implements PlayerState {
publiC void handPlayableO I
II nlio faz nada

I
publiC void handBl ackjack() (
setCurrentState( getBlackjackStateO );
notifyBlackjack():
getCurrentState().execute( dealer )j

I
public void handBusted() (
setCurrentState( getBustedState() ) ;
notifyBustedO:
getCurrentState().execute( dealer l i

I
public vo i d handChanged{) {
not i fyChanged () ;

I
publ i c void executeI Oea l er dealer ) (
II nlio faz nada aqui, as aes viro da GUI , que
II externa ao estado, mas quando eventos vierem, certifica-se de
II forar a transio de estado imediatamente

I
I
private class Betting implements Pl ayerState I
public void handChanged() {
II impossfvel no estado de estouro

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.36

653

GUI P1aye r.java (con t inuao)

publ ic vo l d handPlayable() {
II impossfvel no estado de estouro
}

pub l ic void handBlackjack() {


II impossfvel no estado de es t ouro
}

pu bl lc void handBusted{) {
II impossfvel no estado de estouro
}

pub l ic void exec ut e( Dealer dealer ) {


II n~o faz nada aqui, as aes viro da GU I. que
II externa ao estado , pois nenhum evento aparece como parte da
II aposta, o estado preci sa r ser mudado externamente para este estado
}
}

private class GU IView extends JPanel implement s Playe rl is t ener , Act io nl is tener

I
private
pri vate
prlvate
pri vate
pri vate
pr i vate
pr i vate
private

JButlon
JButton
JButton
JBut ton
JButt on
JButt on
JButton
JBu t ton

pr ivate
pr ivate
pr ivat e
private
private
private
private
private

fi nal
fi na l
final
f inal
final
final
final
fi na 1

bet 10
bet 50
bet- 100
dea l
quit
hit
stand
ddown

String
String
String
Str ing
St ring
St ring
String
St ring

new Jbutton ( "$10 }:


new Jbu tton( "$50 ) ;
new Jbutton( "$1 00 };
new Jbutton { NNew Game" };
new Jbutton{ Quit" }:
new Jbutt on( "Hit" }:
new Jbutton ( Stand" ) :
new Jbutton ( "Doub le Down" ) :

NEW- GAME "new" :


QUIT
"quit" ;
HIT
"hit";
STAND
"stand":
BET- 10 - "BETlO"
BET 50 "BET50" ;
BET 100 "BETlOO" ;
O DOWN "ODown " .

private final Color FORES T GREEN = new Color( 35 . 142 . 35 );


publ iC GUIView() (
supe r e new Borde rLayoutO );
GU IPlaye r.thi s.add l is tener ( th is ) ;
bui 1dGUI ();
}

I 654

A pndi ce E

LISTAGEM E.36

GUIP1ayer.java (continuao)

private void buildGUI() I


JPane l bett i ng_controls new Jpanel():
JPane l game_control s
new JPanel():
add( betting_controls . Borderl ayout.NORTH ):
add( game_controls. Borderlayout.SOUTH ):
betting_controls.setBackground( FOREST_GREEN ) ;
game_control s.setBackground( FOREST_GREEN ):
deal.setActionCommand( NEW_GAME ) :
deal.addActionliste ner( this );
qu i t.se t ActionCommand( QUIT ) :
qu i t.addActionliste ner( this ) :
hit.setActionCommand( HI T ) ;
hit . addActionlistener( this ) :
stand.setActionCommand( STAND ):
stand.addActionlistener( this ):
bet_lO.setActionCommand( BET_IO ) :
bet_IO . addActionlistener( this );
bet_SO. setActionCommand( BET_50 ):
bet_50 .addActionlistener( this );
bet_ IOO.setActionCommand( BET_IOO ):
bet_IOO.addActionlistener( this ):
ddown. setActionCommand( D_OOWN ):
ddown.addActi onli stener( this ) :
betting_control s.add( bet_IO );
betting_contro l s.add( bet_50 );
betting_controls.add( bet_IOO ) ;
game_control s.add{ ddown ):
game_control s.add{ hit ) :
game_contro l s.add{ stand );
game_contro l s.add{ deal ) :
game_contro l s.add( quit ) :
enableBettingControls( false ) ;
enablePlayerControls( fa l se ) :
enabl eDoubleOown( false }:

I
private void enableBettingControls( boolean enable ) I
bet_lO. setEnabled( enable };
bet_50 .setEnabled( enable );
bet_lOO.setEnabled( enab l e ):
I
private void enablePlayerControls( boo l ean enable ) {

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.36

GUIP1ayer.java (continuao)

hit.setEnabled( enabl e li
stand .setEnabl ed( enable )i
}

private void enableGameControls( boolean enab l e ) (


deal.setEnabled( enabl e )i
quit.setEnabled( enable );
}

private void enableDoubleDown( boolean enable ) {


ddown,setEnabled( enable );
}

public void actionPerformed( ActionEvent eve nt ) {


if( event.getActionCommand(),equal s( QUIT ) l {
System .exit( O ,;
lelse if( event.getActionCommand().equals( HIT ) ) {
enabl eDoubleDown( false );
takeCard O i
)else if( event.getActionCommand().equals( STANO ) ) {
enableOoubleOown( false l i
standO i
)e lse i f ( event.getActionCommand().equals( NEW_GAME ) ) {
enabl eOoubleOown( false );
enab l eGameControls( fa lse );
enablePlayerControls( false )i
enableBettingControls( true )i
dealer,newGame();
lelse if( event .getActionCommand(),equals( BET_IO ) ) {
enableOoubleDown( true )i
enableBetti ngControls( false )i
enablePlayerCont rols( true );
pl acelOBet () i
lelse if( event.getActionCommand() .equals( BET 50 } ) {
enableOoubleDown( true ) i
enableBettingControls( false }i
enablePl ayerControls( true ) i
placeSOBet() i
)else if( event.getActionCommand().equals( BET 100 ) ) {
enableOoubleOown( true );
enableBettingControl s( false l i
enabl ePlayerControls( true );
placelOOBetO;
}else if( event.getActionCommand().equals( O OOWN ) ) I
enab l ePlayerControls( false lj

655

I 656

Apndi ce E

LISTAGEM E.36

GUIP1ayer.java (continuao)
enabl eDoubleDown( false ) ;
doubl eDown( dealer );

I
I
public void playerChanged( Player pl ayer ) {}
publiC void playerBusted( Pl ayer player ) (
enablePlayerControls( false ) ;
enableGameControls( true ) ;

I
public void playerB l ackjack( Pl ayer player ) {
enabl eDoubleDown( false ) ;
enablePl ayerControls( fa l se ) ;
enableGameContrOl S( true };

I
publiC void playerStanding( Player player ) (
enabl ePlayerCont rols( fa l se l ;
enableGameControls( true l ;

I
publiC void playerWon( Player player ) (
enablePlayerControl s( false );
enableGameControls( true ,;
I
public void playerLost( Player player ) {
enableDoubleDown( false ) ;
enablePl ayerControls( false ) ;
enableGameControls( true , ;

I
publiC void playerStandoff{ Player pl ayer ) {
enabl ePlaye rControls( false };
enabl eGameContro l s{ true };

I
I
I

Listagen s do cdigo do jogo vi nte-e-um

657

LISTAGEM E.37 VBettlngPlayer.java


package bl ackjack . ui . pac;
import
lmport
import
import

blackjack.core .*;
java.awt.*;
javax.swlng.*;
javax.swing . border.*;

public abstract class VBettingPlayer extends BettingPlayer implements


- Oisplayable {
private BettingView view;
public VBettingPlayer( String name , VHand hand, Bank bank ) {
supere name, hand. bank ) ;

I
publ iC JComponent view() {
H( view ... null ) {
vlew new BettingView( (VHand)getHandO );
addListener( view );

I
return view;

II Note que tudo que essa classe faz

recuperar o modo de vlsualiza!o de

Hand. ad i ciona esse modo


II em si mesmo e atualiza a borda , conforme for necessrio. Note o que essa
classe no faz:
II atualiza as cartas quando elas mudam. 00 ponto de vista deste modo de
visualizao. a
Ilatuallzaao da carta acontece automaticamente, pois VHand atualiza sua
exibio nos
Ilbastidores
private class BettingView extends JPanel implements Pl ayerListener {
private TitledBorder border;
publiC BettingVlew( VHand hand ) (
supere new FlowLayout( Fl owLayout.LEFT ) );
buildGUI( hand.view() );

I
publiC void playerChanged( Player pl ayer ) {
String name VBettingPlayer.this.getName();

Apndice E

LISTAGEM E.37 VBett 1ngPl ayer .java (continuao)


border.setTit l e( name ):
repalntO:
}

pub l iC void player6usted( Player player ) (


String name VBettingPlayer.this.getHame():
border.setTitle( name + " BUSTEO!" )i
repaint()i
}

pub l iC void playerBlackjack( Playe r player ) {


String name VBettingPlayer.this.getName()i
border.setTitle( name + " BLACKJACK!" )i
repa i ntO:
}

publiC void pl ayerStanding( Player player ) (


String name V6ettingPlayer . this.getName() ;
border. setTitle( name + " STANDING ~ ):
repa in tO ;
}

publ ic void playerWon( Pl ayer pl ayer ) (


String name VBettingPlayer. t his .ge tHame() i
border.setTit l e( name + " WINNER! " ):
repaintO;
}

pub l ic void playerLost( Player player ) (


String name VBettingPlaye r.this.getName() :
border.setTitle( name + " LOSER !" );
repaintO i
}

publiC void playerStando ff( Player player ) (


St ring name VBettingPlayer.this.getName()i
border.setTitle( name + " STANDQFF !" ) i
repaint() ;
}

pri vate void buildGUI( JComponent hand )(


border new TitledBorder( V6ettingPlayer.thi s.getNameO );
setBorder ( border ) ;
setBackg round ( new Col or( 35 , 142 , 35 i
border . se tT lt l eCo l or( Co l or.bl ack ) ;

Listagen s do cdigo do jogo vinte-e-um

LISTAGEM E.37

659

VBettlngPlayer.java (continuao)

add( hand );
}
}
}

LISTAGEM E.3S

VBlackjackDealer.java

package blackjack.ui.pac ;
import
import
import
import
import

blackjack.core.*;
blackjack.core.threaded.*;
javax .swing.*;
javax.swing.border.*;
java.awt.*;

public class VBlackjackDealer extends ThreadedBlackjackDealer implements


Displayable {
private OealerView view;
public VBlackjackDealer( String name, VHand hand, Deckpile cards ) {
supere name . hand, cards ) ;
}

publi c JComponent view() {


if(v1ew null ) (
v1ew new OealerView( (VHand)getHand() );
addlistener( view );
}

return view;
}

II

Note que tudo que essa classe faz recuperar o modo de v1sualizaao de
Hand, adiciona esse modo
II em si mesmo e atualiza a borda conforme for necessrio .Note o que essa
classe no faz:
II atua l iza as cart as quando elas mudam. 00 ponto de vista desse modo de
visualizao.
II a atualizao da ca rta acontece automaticamente, pois VHand atualiza sua
exibio
II nos ba st idores
private class OealerView extends JPane l impl ements Playerlistener {
private TitledBorder border ;

I 660

Apndice E

LISTAGEM E.3S

VBlackjackOea l er .java (continua o)

publiC Oea l erView( VHand hand ) I


supe r e new Fl owlayout( Fl owlayout.lEFT ) );
Stri ng name VBlackjackOealer.this.getName() ;
border = new Ti tledBorder( name );
setBo rder ( bo rder ) ;
se tBackgrou nd ( new Col or( 35 . 142. 35 ) ) i
border.setTit leColor( Co l or . black ) ;
add( hand.view() ) i
repaintOi
J

publiC voi d playerChanged( Player player ) {


St ring name VBlackjackDealer . this.getName()i
border.setTitle( name );
repalntO i
J

publ iC void pl ayerBust ed( Playe r player ) {


String name VBla ckjackOea l er.th is .getName() ;
border.setT itle( name +" BUSTED! ") i
repa intO i

J
pub l iC vo i d playerB l ackjack( Player player ) I
Stri ng name VBlackjackDealer . this.getName() ;
border.setTitle( name + " BlACKJACK !" )i
repa intO;
J

pu bl ic void playerStand i ng( Player pl ayer ) (


String name VBlackjac kDeale r. this . getName ()i
border.setTit le ( name + " STANDING " );
repaintOi
J

publ ic void pl ayerWon( Playe r playe r ) {


String name VBla ckjackOea ler.this .getName() i
border. setT itle( name + " WINNER !" ) ;
repaintO i

J
publ ic vo i d pl aye rLost( Playe r player ) (
String name VBlackjackDealer . this.getName():
border.setTit le( name + " LOSER!- )i
repaintOi

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.3S

VBlackjackOea l er .java (continuao)

I
publ i c void playerStandoff( Player player } I
Stri ng name z VBlackjackOealer . this.getName();
border . setTit l e( name + MSTANOOFF!M };
repa intO;

I
I
I

LISTAGEM E.39

VCa rd. java

package blackjack.ui.pac;
i mport bla ckj ack . core.* ;

;
i mpor t Ja
vax.swlng.
l. mpor t Java.aw t . ;
publ i c cla ss VCa rd extends Card implements Displayab l e {
private Stri ng image ;
private CardView view ;
publ ic IJcard( Suit suit, Ran k rank . String image ) (
supere sui t, rank l ;
th i s. image image ;
view = new CardlJiew( getImageO );

I
publ iC void set Fa ceUp( boolean up ) I
super. se tFaceUp( up );
view. changed();

I
public JComponent view() I
return view;

I
pri vate String get Image( ) (
i f( i sFaceUp() ) (
return image ;
) else {
return "/ blackj ack/ ui / bi tmaps/ empty pile.xbm M ;

661

I 662

Apndice E

LISTAGEM E.39

VCard.java (continuao)

}
}

private class CardV iew extends JLabel {


pub li c CardView( St ring image ) {
setImage( image ) ;
setBackground( Color.white );
setOpaque( true );
}

publie void changed(){


set Image( getlmage() );
}

private void se tImage( String image ) {


java . net.URL url .. th is .getC la ss().getResouree( image );
Image l eon ieon .. new ImageIeon ( url ) ;
set lcon( ieon );
}

}
}

LISTAGEM E.40

VDeck .java

package blackjack . ui.pae ;


import blaekjaek.eore.*;
import java . uti l .Iterator;
pub li c class VOeck extends Oeck {
protected void bu ildCards () {

II Isso

ho rrvel. mas me lhor do que os l aos e as estrut uras

condicionai s alternativas
Card [] deck" new Card[52] ;
setDeck( deck ) ;
deck (O] .. new Vcard( Su it.HEARTS. Rank. TWO .
-/ blackjac k/ ui / bitmaps/ h2" ):
deck (1] z new VCard(Suit.HEARTS. Rank. THREE .
-/ blackjack/ ui / bitmaps/ h3" );
deck [2] .. new Vcard( Suit. HEARTS. Rank . FOUR.

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.40

VOeck.java (continuao)

- j b1ackjackj u; j bi tmaps j h4" );


deck (3) new Vcard( Suit.HEARTS, Rank.FIVE,
- j blackjack j ui j bitmaps j h5" );
deck [4) = new Vcard( Sult.HEARTS. Rank . SIX,
- j blackjackj ui j bitmaps j h6" );
deek [5] new Veard( Suit.HEARTS . Rank.SEVEN,
/ bl aekjaek j ui / bi tmaps j h7" ) ;
deek [6] new Vcard( Suit.HEARTS, Rank.EIGHT.
"/b 1aekj aekju 1/bl tmaps/h8" ) ;
deck [7] new Veard( Sult . HEARTS. Rank.NINE,
"/ b1aekj aekju i /bi tmaps/h9" );
deek [8) new Vcard( Suit.HEARTS . Rank.TEN.
"/b 1ae kj ae kju i /bltmaps/hIO" ) i
deek [9] new Vea rd( Suit.HEARTS , Ran k.JACK ,
"/b 1ae kjae k/u i /bitmaps/h 11" ) i
deck [10] - new Veard( Suit.HEARTS. Rank.QUEEN,
/blaek jaekjui/bi tmaps/hI2" );
deek [11) .. new Veard( Sult .HEARTS . Rank.KING.
"j bl aekja ek/ui j bitmaps/ h13" ) i
deek (12 ) .. new Veard( Suit . HEARTS, Rank.ACE,
- j blackjackj ui j bitmaps j hI " );
deek (13) new Veard( Suit.OIAMONDS, Rank. TWO,
"j blackjaekj ui j bitmaps j d2" )i
deek [14) .. new Veard( Suit.OIAMONOS . Rank.THREE .
- / b 1aekjaek j ui / bi tmaps j d3 " );
deek [15) .. new Veard( Suit.OIAMONDS, Rank.FOUR,
j blaekjack j ui j bi tmaps j d4" ) i
deek [16) .. new Veard( Suit.OIAMONDS . Rank .FI VE ,
"/b 1aekjaekjui /bitma ps jd5" ) i
deek [17) new Veard( Suit . DIAMONDS , Rank.SIX,
"/b 1aekj ae kju i /bi tmapsjd6" );
deek [18) .. new Vca rd( Suit.DIAMONDS , Rank . SEVEN .
"/b 1ae kj ae kj ui /b i tmaps/d7" );
deck [19] = new Veard( Suit.DIAMONDS , Rank . EIGHT,
"/b la ckjaek/ui/bitmaps/d8" ) i
deck [20] new Veard( Suit.DIAMONDS . Rank . NINE.
"/blaekjaekjui/bi tmaps/d9" );
deek [21) - new Vcard( Sult.D IAMONDS. Rank. TEN,
"j blaekjaek/ ui j bitmaps / dl0" ) i
deck (22] .. new Veard( Suit . OIAMONOS . Rank . JACK .
- j blackjackj ui j bitmaps j dll" );
deek (23) .. new Veard( Suit.OIAMONOS. Rank.QUEEN.
"j blackjack j ui j bitmaps j d1 2" );
deek (24) .. new Veard( Suit.OIAMONDS.Rank . KING,
.. / bl aekjaek j ui / bi tmaps j d13 " );
H

663

I 664
LISTAGEM E.40

Apndice E

VOeck.java (con tinuao)

deck [25] new Vcard( Suit.OIAMONOS . Rank.ACE.


-j blackjackj ul j bltmapsj dl " l;
deck [26] new Vcard( Suit.SPAOES. Rank.TWO .
"j blackjackj ui j bilmapsj s2" l;
deck (27) ~ new Vcard( Suit.SPAOES . Rank . THREE.
"j blackjackjui j bitmapsjs3 " );
deck (28) new Vcard( Suit .SPADES. Rank .FOUR ,
/ blackjackjui/bi tmapsjs4" ) ;
deck [29] new VCard(S ui t.SPADES. Rank. FIVE.
"/b1ackj ack ju i /bi tmaps/sS" l ;
deck [30] = new Vca rd( Suit .SPADES. Rank .SIX .
"/b 1ac kj ac k/ ui /bi tmaps/s 6" );
deck [31] new Vca rd( Suit.SPADES . Rank.SEVEN.
"/bl ackjackjui/bitmaps/s7" );
deck [32] new Vcard( Suit.SPADES . Rank.EIGHT.
"/b 1ac kjac k/u i /b i tmaps/s8" );
deck [33] new Vcard( Suit.SPADES , Rank . NINE.
"jblackjack/ui/bitmaps/s9" );
deck [34] new Vcard( Suit.SPADES, Rank.TEN.
"j blackjack/ ui j bi tmaps/s IO" l;
deck (35] new Vcard( Suit.SPAOES , Rank .JACK,
-j blackjackj ul j bHmapsjs ll" l;
deck [36] new Vca rd ( Suit.SPAOES . Rank.QUEEN.
"/ blackjackj ui j bitmapsj sI2" l;
deck [37] z new Vcard( Suit.SPADES . Rank . KING.
"j blackjackj ui j bitmapsj s 13" ) ;
deck (38) new Vcard( Suit.SPADES . Rank .ACE .
"/blackjackjuijbi tmapsjsl" l;
deck [39) new Vcard( Suit.CLUBS. Rank. TWO.
"/b1ackj ac kju i / bi tmaps/c2" l ;
deck [40] new Vca rd( Suit.CLUBS . Rank.THREE .
"/b 1ac kj ac k/u i /b i tmaps/ c3" l;
deck [41] new Vcard( Suit.CLUBS , Rank.FOUR .
"/bl ackjack j ui / bitmaps/c4" l;
deck [42] new Vcard( Suit.CLUBS , Ran k.FI VE .
"/b 1ac kjack/u i / bi tmaps/cS" ) ;
deck [43J new Vcard( Suit.CLUBS , Rank .SIX .
"j blackjackjui / bitmaps/c6" l;
deck [44] new Vcard( Suit . CLUBS , Rank.SEVEN .
"j blackjack/ui / bitmaps /c 7" );
deck (45] = new Vcard( Suit.CLUBS . Rank . EIGHT.
-j blackjack/ ui / bi tmaps/ c8" ,;
deck [46) new Vcard( Suit.CLUBS . Rank.NINE,
"j blackjack/ ui j bitmaps/c9" l;
deck [47) new Vcard( Suit.CLUBS. Rank. TEN.

Listagen s do cdigo do jogo vinte-e-um

665

VOeck.java (continuao)
-j blackjack/ ul j bitmapsj clO N );
deck (48] new Vcard( Suit.CLUBS, Rank.JACK,
Mjblackjackj ui j bitmapsj cll N );
deck [49] = new Vcard( Suit.CLUBS. Rank . QUEEN,
Nj blackjackj ui j bitmapsj cl2" ) ;
deck [50] new Vcard( Sult.CLUBS . Rank.KING,
"/blackjackjui j bitmapsj c13" );
deck [51J new Vcard( Suit.CLUBS, Rank.ACE .
"/blackjackjul/bitmaps/cl" );

LISTAGEM E.40

I
I

LISTAGEM E.41

VHand.java

package blackjack.ui.pac;
import
import
import
i mpo rt

bla ckjack.core.* ;
java.awt.*;
javax . swi ng.*;
java.uti 1. Iterator;

public cl ass VHand extends Hand implements Oisplayabl e I


private HandV iew view

new HandView();

public JComponent view() I


return view;

II voc precisa sobrepor addCard e reconfigurar para que quando a mo mudar. a


II altera!o se propague no modo de visualizao
public vold addCard( Card card ) {
super.add Ca rd( card ) ;
view.changed() ;

I
pub l ic void reset() {
super. reset O i
view . changedO i

I
private class HandView extends JPanel I
pub l ic HandView() I
super e new Flowlayout( Fl owlayout . lEFT ) };

I 666

Apndi ce E

LISTAGEM E.41

VHand.java (continuao)

setBackground( new Color( 35 . 142 , 35 ) );

I
pub1i c void changed() I
relllOveA 11 () ;
Iterator i getCards() ;
whi1e( i.hasNext() ) I
VCard card ( Vcard) i. next();
add( card.viewO ) ;

I
revalidate();

I
I
I

LISTAGEM E.42

VPl ayerFactory .java

package bl ackjack.ui.pac;
impo rt b1ackjack.core.*;
public class VPlayerFactory I
private VBlackjackDea l er dea1er ;
private GUIP l ayer human;
private Deckpile pile;
publiC VBlackjackOealer getDealer() I
II cria e retorna apenas um
if( dealer nu l l ) {
VHand dea l er_hand = getHand() ;
Oeckpile cards getCards ()j
dea1er new VBlackjackOealer( "Deale r ". dea l er_hand . cards )i

I
ret urn deale r ;

I
pub l iC GUIP1ayer getHuman() {
II cria e retorna apenas um
if( human null ) I
VHand human_ha nd getHand();
Bank bank new Bank( 1000 ) ;
human new GUI Player( -Human". human_hand. bank. getOea l er() );

Listagens do cdigo do jogo vinte-e-um

LISTAGEM E.42

VPlayerFactory.java (continuao)

return human :
}

publlC Oeckpile getCardsO I


II cria e retorna apenas um
if( pile nul1 ) I
pi le new Oeckpile();
for( in t i O: i < 4 : i ++ ) {
pile.shuffleO:
Oeck deck new VOeck(lj
deck.addToStack( pile l;
pile.shuffleO j
}
}

return pile:
}

private VHand getHand() I


return new VHand():
}

667

ndice Remissivo
Smbolos
(asterisco), agr egnes de o bjeto, 186

A
Abstrao,26-27
exem plo de jogo de cartas, 56

exemplo de, 26-29


imp lementao eficie nte de, 41 -47
regras para, 28-29
situaes apropriadas para, 29
Abst rao, a ltern ativas, 93
Abstracl Datll Ty pc. Veja ADT

Acesso
privado, 25

protegido, 25
pb lico, 25

nveis de, 25
Assesso res, 11
classes, 575
ACM S peciallntc rcst G ro up 0 0 Computer- Hum a " lnleraction (S IGC HI), 290
Ada ptado r es, 242
de classe, 244-245
de objeto, 244-245
Agentes, o bjetos. 23 1
Agregaes, UM L, 585
Ambiente

configurao, SDK, 555-556


variveis, PATH , 556
Ana lisadores
documentos XML, padro de projeto
Abslracl Faclol)' e, 266

exemplo de cdigo, 266-267


An lise

recursos, 587
Veja tambm AOO

Anlise de caso de uso, 199


casos de uso resultantes, 204-205
combinando casos de uso, ?03-204
definindo a seqUncia de eventos,
205-207
diagramas, 207
de atividade, 2 12
de colaboraO. 2 11
de interao, 209
de seqUncia, 2 10-211
dicas para escrever, 207
divid indo casos de uso, 203-204
entrada do usurio e, 200
identificando atores, 200-201
jogo de cartas vinte-c-um
aposta, 414-417
GU I, 433-435
regras, 384-388
listando casos de uso, 201-203
lgica booleana da, 476
Ancestrais, 88
Aninhando in strues ir/cise, 337
AOO (A n lise O rientada a O bj eto)
modelo de caso de uso, 199
casos de uso resultantes, 204
combinando casos, 203-204
definindo seqUncia de eventos,
205-207
diagramas de atividade, 2 12
diagramas de caso de uso, 207-208
diagramas de colaborao, 211
diagramas de interao, 209-210
diagramas de seqUncia, 210-2 11
dividindo a lista de casos, 203
dividindo casos, 203
gerando lista preliminar, 20 1-203
identificando atores, 200-201

670

Aprenda Programao Orientada a Objetos em 21 Dias

modelo de domnio, diagramas de 3t ividade,


2 12
objelivo, 352
panorama, 197-198
protlipos,2 14
sistema, 198

APls (interraces de programa aplicativo), 24


Argum entos
converso, 137
ferramentas de terceiros, adaptadores,
244-245
Veja wmbm parmetros, 133- 134

Arquivo

Product.java, 573-574
SimpleHelloWorldjava,564

Arquivos, criando arquivos .jar, 562-563


Associaes (obj elos), UML, 584
Asteriscos (.), associaes d e objeto, 185
Atividades, diagrama de estados. 390-391
Atores, 200
anlise de caso de uso, 352-353
jogo de canas viOle-c-um, 353
modelando, 207

Atributos, 8
especializao, 87-89
herana, 77-78
recursivos, 84-85
sobrepostos, 79-83
controle de acesso, 83
visibi lidade, UML, 58 1-582
Atuali .....ando
doc umen tao, 339
interfaces, 35
projeto de UI desacoplada e, 290-291
bibliotecas de terceiros, padro de projeto
Abstracl FaCial)', 264
Autotransies, dia gr a ma s de estado,
390-391

B
Bibliotecas
ferram entas de terceiros

adaptadores, 244-245
arualizando, 264
Swillg, 293
Blackjack.cxc, intcrraces com O us urio,
621-627
Blackjack.java, 376-377
BlackjackDealer.j ava, 374-375

c
C++, recursos, 588
Cabealhos (m todos e cla sses), dOCulllcntllo, 338-339
Camada controladora (MVC), 301
combinando com camada de modelo,
302-303
implementando, 301-302
Camada de modelo (MVC), 294
implementando, 295-296
reunindo com camada de controle,
302-303
Camada de modo d e vis ua lizai\o (MVC),
297
Ca pacidade de conexi\o, 9 1-92
im plementando, 297-300
Cartes C RC (Class Rcs pons ibility Co llaboratio n),224-225
aplicando, 225-226
exemplo, 226-229
GU ls, jogo de cartas vinte-e-um , 437
limitaes, 230-23 1
Casos de teste, 316
nomeando, 322
teste de caixa branca, 316
teste de caixa preta, 3 16
Casos de uso
aposta, 414-416
atares, 352
jogo de cartas vinle-e-um, 353,
356-360
Banca efellla jogo, 387-388
Deal Cards, 384-387

Indice Remissivo

Cen rios (a nlise de easo de uso), 205


Cha madas de mtodo, 8
Chaves ({ }) no cdigo-fonte, 564
Chaves, especifica ndo, 51
C lasse Bank Gogo de cartas vinte-e-um)
exemplo de cd igo, 159
implementao, 421 4 22
projetando, 417
C lasse
BettingPlayer, implementao, 423-424
Blackjack Oealer. implementao, 426-427
BlackjackG UI, mtodo setUpO, 448-449
CardV iew, implementando, 443
CountedObjecl, exemplo de cdigo, 65
Oealer
DoubleKey
construtores, 52
exemplo de cdigo, 50-5 1
exemplo de cdigo, 61
FlipPlayer, implementando, 475-476
GUIPlayer, implementando, 445-448, 465
Hand, receptor para, 395-399
HumanPlayer, im plementao, 424-426
OneHit l)layer. implementando. 476
Option View, implementando, 445
Opt ionViewController, implementando, 445
Player
herana, refazendo a hierarquia, 419-420
interface PlayerListener, 403-404
interface Pl ayerState, 399-403
PlayerView, implementando, 444-445
progenitora, 77-79
exem plo de cd igo de herana, 99-100
palavra-chave super, 84
SafePlayer
adicionando na GU I, 472-473
criando, 471-472
Smart Player, implementando, 477
Stack, herana
exemplo de cdigo da soluo, 118- 119
exemplo de problenta, 11 7- 118
exposio do problema, 118
State, jogo de cartas vinte-e-um, 393

671

VBettingPlayer, implementando, 462-463


VB lackjackDealer, implementando,
464-465
VCard, implementando, 44 1-442, 460-46 1
VDeck, implementando, 442
VHand, implementando, 46 1-462
Classes abstratas
exemplo de cdigo, 102-103, 126-128
mtodos, definindo, 104
requisitos do exemplo, 105
UML,582
notao, 182
C la sses a nllimas, criando, 324
C lasses filh as, 77-78
especiali zao, 87-88
exemp lo de cdigo de herana, 100-10 I
novos mtodos, 84
palavra-chave super, 84
polimorfismo, exemplo de cdigo, 147-148
requisitos do exemplo, 99-10 1
Classes fo lha, 89
Classes intern as, 577-579
ann imas, 577-579
Classes-raiz, 89
annimas, 577-579
Classes, 8
abstratas
exemplo de cdigo, 102- 103
notao UML, 181 - 182
requisitos do exemplo, 105- 106
AOT (Abstract Data Type), TAO, implementao eficiente de, 47
agregaes, UM L, 585
ancestral , 88
annimas, 577-579
criando, 324-325
assessores, 575
associaes de objelo, UML, 584
atributos, 8
Bank, 416-4 17
implementao, 42 1
BaseLog, exemplo de cd igo, 127-128
BettingPlayer, implementao, 423-424

672

Aprenda Programao Orientada a Objetos em 21 Dias

Blackjack
diagrama de atualiz.1llo, 420-42 1
mtodo setUp( ), 448-449
BlackjackDealer, im plementao, 426-427
cabealhos, documentao e, 338-339
CardV iew, implcmcnlando, 443
cartes CRC (C lass Responsibility Collaboration), 224-225

aplicando, 225-226
exemplo, 226-227
limitaes, 230-23 [
compilando, 56 1-562
composii'lo, 76

UML,585
com uns
pacote blackjack.core, 592-619, 618-619
consideraes de projeto, lestes de unidade
e,321 -322
convenes de atribuio de nomes, 338
CountedObject, exemplo de cdigo, 65
criando, estado de jogo e, 393, 395
Dealer, implementao, 424-425
diagramas
de colaborao, UML, 586
de seqUncia, UML, 586
DoubleKey, construtores, 52
exemp lo de cdigo, 9- 10
Bank, 159-1 60
BankAccount, 111-1 12
CheckingAccount, 114- 11 5
OverdraftAccount, 116
Savi ngsAccount, 112-113
TimeMaturityAccount, I 13-114
exem plo de cOnla
cdigo para, 55
requi sitos, 5343
exemplo de jogo de cartas, cdigo para,
57-62
exemplos de cdigo, DoubleKey.java, 50
filhas, 77
especializao, 87
exemplo de cdigo de herana, 100-101
novos mtodos, 84

palavra-chave super, 84
polimorfismo (exemplo de cdigo),
147- 148

requisitos do exemplo, 100


FlipPlayer, implementando, 475
fo lha, 89

GUIPlayer, implementando, 445-448, 465


Hand, receptor para, 395 -398
Hashtablc, canvcrsllo c, 157
herana, principias bsicos, 77-78
hierarquia de herana, 77

Hum anP layer, implementao, 424-425


instanciao, evitando m lt ipla, 268
internas, 577-579
Java, 564-565, 57 1-572
criando, 572-573
jogo de cartas vinte-c-um , 360-364
criando jogadores no-humanos,
471-472
implementao, 365-380
modelo, 365
mtodos
construtores, 574-575
de con figurao, 575
de obteno, 575
modelando, 188
documentando cdigo, 179
notao de seleo UM L, 181
notao UML avanada, 181
notao UML, 179-1 80
re lacionamentos de agregao, 186-187
relacionamentos de associao, 184-1 85
relacionamentos de composio, 187-188
relacionamentos de dependncia, 183- 184
relacionamentos de generalizao, 188-189
relacionamentos, 183
modificadores, 575
mult iplicidade, UML, 584-585
numero de responsabilidades (problemas
de projeto), 229-230
objctos, 7-8
OneHitPlayer, implementando, 476
OptionV iew, implemen tando, 445

Vous aimerez peut-être aussi