raonibs 64 Denunciar post Postado Novembro 27, 2013 Atualizei meu Netbeans recentemente e notei que ele esta mostrando um aviso para métodos com mais de 10 linhas, ex.: O tamanho do método é 15 linhas. (10 Permitido) Sei que quanto menos linhas mais claro o código é. Ja descobri também onde alterar isso no netbeans, mas essa não é questão. Me surgiu alguns questionamentos a respeito dessa característica: - Existe uma um numero adequado de linhas em um método? - Métodos grandes "fedem"? - Existe algum tipo de norma como as "PSR's" para tamanhos dos métodos ou classes? - O que é melhor: 1)um método grande com com todo código de que ele precisa. 2)Dividir esse código de um método public grande em métodos menores mesmo que esses novos métodos sejam apenas privates ou protecteds. Neste caso, multiplicar o numero de métodos de uma classe não é ainda pior que um método grande? Compartilhar este post Link para o post Compartilhar em outros sites
William Bruno 1501 Denunciar post Postado Novembro 27, 2013 - Existe uma um numero adequado de linhas em um método?tecnicamente não. Não medimos isso em "linhas", mas sim em responsabilidades - Métodos grandes "fedem"?sim, e muito. God Class fede. - Existe algum tipo de norma como as "PSR's" para tamanhos dos métodos ou classes?Sim, e pense também em coesão. Para métodos, oque geralmente se usa é: "descreva oque esse método faz, em uma frase simples, sem usar "E" 2)Dividir esse código de um método public grande em métodos menores mesmo que esses novos métodos sejam apenas privates ou protecteds. Neste caso, multiplicar o numero de métodos de uma classe não é ainda pior que um método grande? Não, e talvez seja até melhor separar outras Classes apartir dessa, e dividir a responsabilidade ainda mais, o quanto menor possível que ainda fizer sentido. Existem muitos outros princípios e boas práticas. Dá uma olhada: http://wbruno.com.br/php/boas-praticas-de-programacao-filosofias-de-desenvolvimento/ Compartilhar este post Link para o post Compartilhar em outros sites
raonibs 64 Denunciar post Postado Novembro 28, 2013 Já conhecia esses conceitos, mas é bom relembrar e seu artigo esta excelente. Quando me refiro a classes e métodos grandes não digo os que violem o principio de responsabilidade única. Podemos, por exemplo, ter uma classe cuidadosa que faz muitas validações e que com isso fica inchada, vou dar um exemplo em código para ilustrar o problema. Para validar os dados vamos usar objetos do tipo "ValidatorInterface" que implementa os métodos isValid() que retorna um booleano e getMessages() que retorna um array com as mensagens de erro. Abaixo uma classe que representa uma simples entidade user. <?php class User { protected $id; protected $username; protected $password; protected $email; protected $secondEmail; public function __construct( $id, //O id é o unico que não possui um validador pois ja o fizemos no construtor $username, $password, $email, $secondEmail, $validatorUsername, $validatorPassword, $validatorEmail //Mesmo Validador para o email e o email secundario. ) { if (is_int($id)) { $this->id = $id; } else { throw new \Exception('O id deve ser do tipo inteiro'); } $this->setUsername($username, $validatorUsername); $this->setPassword($password, $validatorPassword); $this->setEmail($email, $validatorEmail); $this->setSecondEmail($secondEmail, $validatorEmail); } //Criamos este metodo para evitar que um programador desatento passe um validador inválido private function checkValidator($validator) { $message = ''; if (!method_exists($validator, 'isValid')) { $message .= "O método isValid não existe no validator passado. \n"; } if (!method_exists($validator, 'getMessages')) { $message .= "O método getMessages não existe no validator passado. \n"; } return $message; } //Este metodo chama Exception se ouver algum erro private function checkError($validator, $data) { $message = $this->checkValidator($validator); if (!empty($message)) { throw new \Exception($message); } if (!$validator->isValid($data)) { foreach ($validator->getMessages() as $value) { $message .= "Validation failure: ' $value\n"; } throw new \Exception($message); } return true; } public function setUsername($username, $validator) { $this->checkError($validator, $username); $this->username = $username; } public function setPassword($password, $validator) { $this->checkError($validator, $password); $this->password = $password; } public function setEmail($email, $validator) { $this->checkError($validator, $email); $this->email = $email; } public function setsecondEmail($secondEmail, $validator) { $this->checkError($validator, $secondEmail); $this->secondEmail = $secondEmail; } public function getId() { return $this->id; } public function getUsername() { return $this->username; } public function getPassword() { return $this->password; } public function getEmail() { return $this->email; } public function getSecondEmail() { return $this->secondEmail; } } Note que a classe já tem suas 115 linhas, e ainda pode inchar mais pois não foi adicionado os comentários phpDoc, poderíamos também pegar os dados do construtor e recebe-los através de um array para simplificar a instanciação e com isso teríamos que validar também a estrutura deste array aumentando o construtor (talvez em vez de colocar o código direto no construtor usemos mais um método privado) porém do jeito que ela esta já posso atentar ao meu ponto. Observe que os dois métodos privados checkError e checkValidator, eles poderiam ser (e eram originalmente) um só método. Esse tipo de coisa não afeta em nada o lado do cliente que instancia e lida com objetos desta classe mas me pergunto até que ponto é saudável essa divisão do código privado só para evitar que um método qualquer cressa demais ou ultrapasse um valor arbitrário como "10 linhas" já temos algo do tipo nas regras PSR que dizem que uma linha não deve ter mais que 80 caráteres. Compartilhar este post Link para o post Compartilhar em outros sites