Segundo o livro Use a Cabeça: Desenvolvimento de Softwares, a definição de PRE é: Cada objeto de seu sistema deve ter uma responsabilidade exclusiva e todos os serviços do objeto devem estar orientados à execução dessa responsabilidade. Em outras palavras, uma classe deve ser responsável por uma determinada função, e só ela pode exercê-la.
Uma classe Carro, por exemplo, deve ser unica e exclusivamente responsável por realizar funções de um carro (como medir óleo, acender farol, etc). A classe Carro não deve ser responsável por saber se lavar (essa é uma responsabilidade que poderia ser entregue a uma classe LavaRapido, por exemplo).
Conversando hoje com o Murilo Amêndola, discutimos sobre como saber quais as responsabilidades de uma classe. Concordamos que não é uma tarefa trivial e que depende de muita experiência para que todas suas classes tenham um alto nível de coesão. Lendo hoje um trecho do livro citado acima, encontrei um algoritmo muito interessante para saber se determinada responsabilidade deve ou não pertencer a determinada classe. Vou reproduzí-lo aqui:
- Escreva, em uma folha de papel, várias linhascomo essa: O [espaço] [espaço] sozinho. Escreva 1 linha dessa para cada método da classe que você está testando quanto ao PRE.
- No primeiro espaço em branco de cada linha, preencha o nome da classe. No segundo espaço em branco, anote um dos métodos da classe. Faça isso para todos os métodos.
- Leia cada linha em voz alta. Você pode até adicionar uma letra ou palavra para que a leitura fique adequada. Se a frase que você disse fez algum sentido, então esse método realmente pertence a essa classe. Se não fizer nenhum sentido, então provavalmente esse método não pertence a essa classe.
Voltando ao exemplo da classe Carro:
- O carro se liga sozinho. (CERTO)
- O carro se desliga sozinho. (CERTO)
- O carro trocaPneus sozinho. (ERRADO)
- O carro dirige sozinho. (ERRADO)
- O carro se lava sozinho. (ERRADO)
- O carro medeOleo sozinho. (CERTO)
Repare que faz todo sentido o carro medir óleo sozinho, enquanto não faz sentido nenhum o carro se dirigir sozinho (esse método deveria estar em uma classe Motorista), ou se lavar sozinho (deveria ser responsabilidade da classe LavaRapido)!
O método liga e desliga não fazem taaanto sentido (afinal, um carro não se liga sozinho), mas nesse caso, não vejo outra alternativa (é o carro que sabe como se ligar!). Isso mostra que a regra acima é apenas uma diretriz, e por isso você deve usar de bom senso e de sua experiência.
O interessante é que você pode adaptar essa regra até para métodos que recebem parâmetros. Se você tiver um método troca(peça), você escreve a seguinte sentença: O carro troca [uma] peça sozinho. No caso, também não faz muito sentido, você poderia ter uma classe Mecânico, com o método troca(peça, carro).
Enfim, é uma análise interesse, não acham?
(Exemplo retirado do livro Use a Cabeça: Desenvolvimento de Softwares, capítulo 5.)
Siga-me no twitter!
Muito bacana
Bastante interesssante. Acho que descondiderando-se as decisões e complexidades de nível mais alto, este tipo de prática por si só já ajuda muito.
[]‘s
Hmm… se formos aplicar ao pé da letra a regra um carro não verifica seu oléo sozinho (o frentista ou o dono fazem isso) e também não liga nem desliga sozinho. Ele permite que alguém o faça.
No caso do método Dirigir o ideal seria colocar este método em um motorista e este receberia como parametro o carro que deveria dirigir.
FelipeMassa.Dirigir(carroQueDeveDirigir)
Pra complementar vou usar uma referência do Phillip (http://fragmental.com.br e http://fragmental.com.br) que acho excelente: http://fragmental.com.br/wiki/index.php/Fantoches
Tucaz,
Sobre o método Dirigir, eu citei no post que ele deveria estar na classe Motorista.
Sobre o método verificaOleo, a idéia não seria verificar o óleo, e sim *MEDIR* o óleo. Ou medir a qtde de gasolina. Isso é responsabilidade do carro. Eu havia alterado isso antes de publicar o post, mas esse BlogEngine não vai muito com a minha cara…
Sobre o método ligar e desligar, talvez a frase não faça sentido (o carro se liga sozinho), mas não vejo outra classe responsável por isso.
Como citei no post, a regra é uma simples diretriz, o que vale é o bom senso.
Olá,
Robert Martin (Uncle Bob) descreve este principio em um paper chamado principles of OOd (http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod). Lá o PRE é na verdade o SRP Single Responsibility Principle. Esta coisa das editoras nacionais em traduzir todos os termos técnicos ao pé da letra, provoca confusões e muitas ambiguidades.
Mas o importante é ter o conceito bem definido na cabeça e aplica-lo bem.
Precisamos ter em mente que Classes e Objetos nao sao copias fieis da realidade. Mas sim apenas abstrações utilizadas para resolver problemas do dominio.