Skip to content

Commit 65f99d9

Browse files
elissonmichaeldavidgf
authored andcommitted
Brazilian Portuguese Translation (#23)
* Add README Brazilian Portuguese Translation * Add Singleton Brazilian Portuguese Translation * Add Adapter Brazilian Portuguese Translation * Add Builder Brazilian Portuguese Translation * Add Strategy Brazilian Portuguese Translation * Add Template Brazilian Portuguese Translation * Add Proxy Brazilian Portuguese Translation * Add Command Brazilian Portuguese Translation * Add Composite Brazilian Portuguese Translation * Add Decorator Brazilian Portuguese Translation * Add Convention Over Configuration Brazilian Portuguese Translation * Add Factory Brazilian Portuguese Translation * Add Interpreter Brazilian Portuguese Translation * Add DSL Brazilian Portuguese Translation * Add Iterator Brazilian Portuguese Translation * Add Meta Programming Brazilian Portuguese Translation * Add Observer Brazilian Portuguese Translation
1 parent 5da4f35 commit 65f99d9

17 files changed

+1860
-0
lines changed

translations/pt-BR/README.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Padrões de Design em Ruby
2+
3+
Sumário dos padrões de design explicados no livro [Design Patterns in Ruby](http://designpatternsinruby.com/), onde [Russ Olsen](http://russolsen.com/)
4+
explica e adapta para Ruby 14 dos 23 padrões de design da Gangue dos Quatro
5+
(GoF - Gang of Four).
6+
7+
## Padrões de Design
8+
9+
### Padrões dos GoF
10+
11+
* [Adapter](adapter.md): ajuda duas interfaces incompatíveis a trabalharem em conjunto
12+
* [Builder](builder.md): cria objetos complexos que são difíceis de serem configurados
13+
* [Command](command.md): executa uma tarefa específica sem ter informação alguma sobre o receptor da requisição
14+
* [Composite](composite.md): constrói uma hierarquia de objetos árvore e interage com todos eles da mesma forma
15+
* [Decorator](decorator.md): modifica as responsabilidades de um objeto adicionando algumas funcionalidades
16+
* [Factory](factory.md): cria objetos sem ter que especificar a classe exata do objeto que será criado
17+
* [Interpreter](interpreter.md): fornece uma linguagem especializada para resolver um problema bem definido em um domínio conhecido
18+
* [Iterator](iterator.md): fornece um jeito de acessar uma coleção de sub-objetos sem expor a representação por baixo
19+
* [Observer](observer.md): ajuda na construção de uma sistema altamente integrado, sustentável e evita acoplamento entre classes
20+
* [Proxy](proxy.md): permite que tenhamos mais controle sobre como e quando nós acessamos um determinado objeto
21+
* [Singleton](singleton.md): tenha uma única instância de uma certa classe em toda sua aplicação
22+
* [Strategy](strategy.md): modifica parte de um algoritmo em tempo de execução
23+
* [Template Method](template_method.md): redefine certos passos de um algoritmo sem mudar a estrutura do algoritmo
24+
25+
### Padrões que não são dos GoF: Padrões para Ruby
26+
27+
* [Convention Over Configuration](convention_over_configuration.md): constrói um sistema extensível sem ter que carregar o peso da configuração
28+
* [Domain-Specific Language](dsl.md): constrói uma sintaxe conveniente para resolver problemas de um domínio específico
29+
* [Meta-Programming](meta_programming.md): ganhe mais flexibilidade quando estiver definindo novas classes e criando objetos customizado em tempo de execução
30+
31+
## Contribuições
32+
33+
Contribuições são bem-vindas! O que você poderia fazer?:
34+
35+
* Encontrar erros de digitação e gramática
36+
* Propor um jeito melhor de explicar algum dos padrões
37+
* Adicionar um exemplo melhor de utilização de um padrões
38+
* Adicionar algum outro padrão da GoF que não foi coberto no livro
39+
40+
Pull Requests de **refatoração de exemplos de código não serão consideradas**.
41+
Os exemplos fornecidos por Russ Olsen no livro foram feito para serem simples
42+
e auto explicativo, não o mais elegante ou com melhor desempenho, o propósito
43+
deles é apenas educacional.

translations/pt-BR/adapter.md

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# O Padrão *Adapter*
2+
3+
## Problema
4+
Nós queremos conversar que um objeto converse com outro objeto, mas as interfaces
5+
deles não combinam.
6+
7+
## Solução
8+
Nós simplesmente envolvemos o **adaptado** com a nossa nova classe **adaptadora**.
9+
Essa classe implementa uma interface que o invocador compreenda, embora todo o
10+
trabalho seja realizado pelo objeto adaptado.
11+
12+
## Exemplo
13+
Vamos pensar em uma classe que receba dois arquivos (um leitor e um escritor) e
14+
criptografe um arquivo.
15+
16+
```ruby
17+
class Encrypter
18+
def initialize(key)
19+
@key = key
20+
end
21+
22+
def encrypt(reader, writer)
23+
key_index = 0
24+
while not reader.eof?
25+
clear_char = reader.getc
26+
encrypted_char = clear_char ^ @key[key_index]
27+
writer.putc(encrypted_char)
28+
key_index = (key_index + 1) % @key.size
29+
end
30+
end
31+
end
32+
```
33+
Mas o que acontece se a informação que queremos deixar segura estiver em uma
34+
string, ao invés de em um arquivo? Nós precisamos de um objeto que se parece
35+
com um arquivo, ou seja, suporte a mesma interface que um objeto de `IO` do
36+
Ruby. Podemos criar uma classe adaptadora `StringIOAdapter` para alcançar isso:
37+
38+
```ruby
39+
class StringIOAdapter
40+
def initialize(string)
41+
@string = string
42+
@position = 0
43+
end
44+
45+
def getc
46+
if @position >= @string.length
47+
raise EOFError
48+
end
49+
ch = @string[@position]
50+
@position += 1
51+
return ch
52+
end
53+
54+
def eof?
55+
return @position >= @string.length
56+
end
57+
end
58+
```
59+
60+
Agora podemos usar uma `String` como se fosse um arquivo, apenas uma pequena
61+
parte da interface `IO` é implementada, basicamente o que precisamos.
62+
63+
```ruby
64+
encrypter = Encrypter.new('XYZZY')
65+
reader= StringIOAdapter.new('We attack at dawn')
66+
writer=File.open('out.txt', 'w')
67+
encrypter.encrypt(reader, writer)
68+
```

translations/pt-BR/builder.md

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# O Padrão *Builder*
2+
3+
## Problema
4+
Precisamos criar um objeto complexo que é difícil de configurar.
5+
6+
## Solução
7+
O Padrão *Builder* encapsula a lógica de construção de objetos complexos em sua
8+
própria classe. Ele define uma interface para configurar o objeto passo a passo,
9+
escondendo os detalhes de implementação.
10+
11+
## Exemplo
12+
Vamos imaginar que nós temos que construir um sistema que mantém o controle dos
13+
componentes de um computador.
14+
15+
```ruby
16+
class Computer
17+
attr_accessor :display
18+
attr_accessor :motherboard
19+
attr_reader :drives
20+
21+
def initialize(display=:crt, motherboard=Motherboard.new, drives=[])
22+
@motherboard = motherboard
23+
@drives = drives
24+
@display = display
25+
end
26+
end
27+
```
28+
29+
A criação de um objeto `Computer` (Computador) pode se tornar muito complexa,
30+
assim como `Motherboard` (Placa Mãe), por exemplo, é um objeto completo:
31+
32+
```ruby
33+
class CPU
34+
# Common CPU stuff...
35+
end
36+
37+
class BasicCPU < CPU
38+
# Lots of not very fast CPU-related stuff...
39+
end
40+
41+
class TurboCPU < CPU
42+
# Lots of very fast CPU stuff...
43+
end
44+
45+
class Motherboard
46+
attr_accessor :cpu
47+
attr_accessor :memory_size
48+
49+
def initialize(cpu=BasicCPU.new, memory_size=1000)
50+
@cpu = cpu
51+
@memory_size = memory_size
52+
end
53+
end
54+
```
55+
Então, o processo de construir um `Computer` pode ser realmente tedioso.
56+
57+
```ruby
58+
# Build a fast computer with lots of memory...
59+
motherboard = Motherboard.new(TurboCPU.new, 4000)
60+
61+
# ...and a hard drive, a CD writer, and a DVD
62+
drives = []
63+
drives << Drive.new(:hard_drive, 200000, true)
64+
drives << Drive.new(:cd, 760, true)
65+
drives << Drive.new(:dvd, 4700, false)
66+
computer = Computer.new(:lcd, motherboard, drives)
67+
```
68+
Podemos tornar esse processo muito mais simples ao encapsular a lógica de
69+
construção em uma classe.
70+
71+
```ruby
72+
class ComputerBuilder
73+
attr_reader :computer
74+
75+
def initialize
76+
@computer = Computer.new
77+
end
78+
79+
def turbo(has_turbo_cpu=true)
80+
@computer.motherboard.cpu = TurboCPU.new
81+
end
82+
83+
def display=(display)
84+
@computer.display=display
85+
end
86+
87+
def memory_size=(size_in_mb)
88+
@computer.motherboard.memory_size = size_in_mb
89+
end
90+
91+
def add_cd(writer=false)
92+
@computer.drives << Drive.new(:cd, 760, writer)
93+
end
94+
95+
def add_dvd(writer=false)
96+
@computer.drives << Drive.new(:dvd, 4000, writer)
97+
end
98+
99+
def add_hard_disk(size_in_mb)
100+
@computer.drives << Drive.new(:hard_disk, size_in_mb, true)
101+
end
102+
end
103+
104+
builder = ComputerBuilder.new
105+
builder.turbo
106+
builder.add_cd(true)
107+
builder.add_dvd
108+
builder.add_hard_disk(100000)
109+
```

translations/pt-BR/command.md

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# O Padrão *Command*
2+
3+
## Problema
4+
Nós queremos realizar alguma tarefa específica sem saber como todo o processo
5+
funciona ou ter qualquer informação sobre o destinatário da requisição.
6+
7+
## Solução
8+
O Padrão *Command* (Comando) desacopla o objeto que precisa realizar uma tarefa
9+
específica daquele que sabe como fazer. Ele encapsula toda a informação necessária
10+
para fazer o trabalho em seu próprio objeto incluindo: quem são os destinatários,
11+
os métodos que serão chamados e seus parâmetros. Dessa forma, qualquer objeto
12+
que quiser realizar a tarefa apenas precisa conhecer a interface do objeto comando.
13+
14+
## Exemplo
15+
Vamos considerar uma implementação de um botão de algum framework GUI, o qual tem
16+
um método chamado durante um clique de um botão.
17+
18+
```ruby
19+
class SlickButton
20+
21+
# Lots of button drawing and management
22+
# code omitted...
23+
24+
def on_button_push
25+
# Do something when the button is pushed
26+
end
27+
end
28+
```
29+
30+
Nós podemos estender a classe botão que sobrescreve o método `on_button_push`
31+
para realizar certas ações sempre que o usuário clique no botão. Por exemplo,
32+
se o objetivo do botão é salvar um documento, poderíamos fazer algo assim:
33+
34+
```ruby
35+
class SaveButton < SlickButton
36+
def on_button_push
37+
# Save the current document...
38+
end
39+
end
40+
```
41+
42+
No entanto, uma GUI complexa poderia ter centenas de botões, o que significa que
43+
nós poderíamos acabar tendo centenas de subclasses para nossos botões. Existe
44+
uma maneira mais fácil. Nós podemos refatorar o código que executa a ação em seu
45+
próprio objeto, o qual implementa uma interface simples. Então, nós podemos
46+
refatorar a implementação de nosso botão para receber um objeto comando como
47+
parâmetro e chama-lo quando clicado.
48+
49+
```ruby
50+
class SaveCommand
51+
def execute
52+
# Save the current document...
53+
end
54+
end
55+
56+
class SlickButton
57+
attr_accessor :command
58+
59+
def initialize(command)
60+
@command = command
61+
end
62+
63+
def on_button_push
64+
@command.execute if @command
65+
end
66+
end
67+
68+
save_button = SlickButton.new(SaveCommand.new)
69+
```
70+
71+
O padrão *Command* é muito útil se nós precisarmos implementar uma funcionalidade
72+
do tipo **desfazer/voltar**. Tudo que precisamos fazer é implementar o método
73+
`unexecute` em nosso objeto comando. Por exemplo, assim é como nós iríamos
74+
implementar a criação de um arquivo:
75+
76+
```ruby
77+
class CreateFile < Command
78+
def initialize(path, contents)
79+
super "Create file: #{path}"
80+
@path = path
81+
@contents = contents
82+
end
83+
84+
def execute
85+
f = File.open(@path, "w")
86+
f.write(@contents)
87+
f.close
88+
end
89+
90+
def unexecute
91+
File.delete(@path)
92+
end
93+
end
94+
```
95+
Outra situação útil onde o padrão **Command** é muito conveniente é em programas
96+
de instalação. Ao combinar ele com o padrão **Composite** (Composto), nós podemos
97+
guardar uma lista de tarefas que precisem ser realizadas.
98+
99+
```ruby
100+
class CompositeCommand < Command
101+
def initialize
102+
@commands = []
103+
end
104+
105+
def add_command(cmd)
106+
@commands << cmd
107+
end
108+
109+
def execute
110+
@commands.each {|cmd| cmd.execute}
111+
end
112+
end
113+
114+
cmds = CompositeCommand.new
115+
cmds.add_command(CreateFile.new('file1.txt', "hello world\n"))
116+
cmds.add_command(CopyFile.new('file1.txt', 'file2.txt'))
117+
cmds.add_command(DeleteFile.new('file1.txt'))
118+
```

0 commit comments

Comments
 (0)