Fico me perguntando se é legítimo usar verbos baseados em substantivos em OOP.
Me deparei com este artigo brilhante , embora ainda discorde do que afirma.
Para explicar um pouco mais o problema, o artigo afirma que não deveria haver, por exemplo, uma FileWriter
classe, mas como escrever é uma ação , deve ser um método da classe File
. Você perceberá que muitas vezes depende da linguagem, já que um programador Ruby provavelmente seria contra o uso de uma FileWriter
classe (o Ruby usa o método File.open
para acessar um arquivo), enquanto um programador Java não.
Meu ponto de vista pessoal (e sim, muito humilde) é que isso violaria o princípio da responsabilidade única. Quando programava em PHP (porque o PHP é obviamente a melhor linguagem para OOP, certo?), Usava frequentemente esse tipo de estrutura:
<?php
// This is just an example that I just made on the fly, may contain errors
class User extends Record {
protected $name;
public function __construct($name) {
$this->name = $name;
}
}
class UserDataHandler extends DataHandler /* knows the pdo object */ {
public function find($id) {
$query = $this->db->prepare('SELECT ' . $this->getFields . ' FROM users WHERE id = :id');
$query->bindParam(':id', $id, PDO::PARAM_INT);
$query->setFetchMode( PDO::FETCH_CLASS, 'user');
$query->execute();
return $query->fetch( PDO::FETCH_CLASS );
}
}
?>
Entendo que o sufixo DataHandler não adiciona nada relevante ; mas o ponto é que o princípio de responsabilidade única nos determina que um objeto usado como modelo contendo dados (que pode ser chamado de Registro) também não deve ter a responsabilidade de fazer consultas SQL e acesso ao DataBase. De alguma forma, isso invalida o padrão ActionRecord usado, por exemplo, pelo Ruby on Rails.
Me deparei com esse código C # (sim, a quarta linguagem de objetos usada neste post) outro dia:
byte[] bytes = Encoding.Default.GetBytes(myString);
myString = Encoding.UTF8.GetString(bytes);
E eu tenho que dizer que não faz muito sentido para mim que uma classe Encoding
ou Charset
realmente codifique strings. Deve ser apenas uma representação do que realmente é uma codificação.
Assim, eu tenderia a pensar que:
- Não é
File
responsabilidade da classe abrir, ler ou salvar arquivos. - Não é
Xml
responsabilidade da classe serializar-se. - Não é
User
responsabilidade da classe consultar um banco de dados. - etc.
No entanto, se extrapolarmos essas idéias, por que Object
uma toString
aula? Não é responsabilidade de um carro ou de um cachorro se converter em uma corda, agora é?
Entendo que, de um ponto de vista pragmático, livrar-se do toString
método pela beleza de seguir uma forma rígida do SOLID, que torna o código mais sustentável, tornando-o inútil, não é uma opção aceitável.
Entendo também que pode não haver uma resposta exata (que seria mais um ensaio do que uma resposta séria) a isso, ou que pode ser baseada em opiniões. Ainda assim, eu ainda gostaria de saber se minha abordagem realmente segue o que realmente é o princípio de responsabilidade única.
Qual é a responsabilidade de uma classe?