¿Cuál es la forma correcta de documentar archivos, clases y constructores?


¿Cuál es la forma más útil/más estándar/menos sorprendente de escribir bloques de comentarios consistentemente para constructores y clases y archivos que contienen una sola clase?

  • Bloques de comentarios para clases, no constructores
  • Bloques de comentarios para constructores, no clases
  • Bloques de comentarios para constructores y clases -> En ese caso, ¿qué tipo de detalles deben ir en cada uno?

Y luego el archivo en sí? ¿Esto necesita un bloque de comentarios si solo contiene una sola clase? ¿Qué detalles deben ir allí?

Quiero intentar evitar, en la medida de lo posible, la repetición entre bloques de clase, constructor y comentario de archivo.

 23
Author: Rupert, 2011-04-21

4 answers

Esto depende en gran medida de su contexto y el nivel de habilidad asumido de las personas con las que trabaja o las personas que vienen después de usted.

Si publicas un framework, una biblioteca o algo por el estilo, normalmente asumes que tu usuario tiene todos los niveles de habilidad, por lo que podría querer documentar tanta basura trivial como sea posible para reducir la carga de preguntas que tu comunidad tiene que manejar.

Permítanme comenzar con un ejemplo donde creo que la documentación puede ser un gran dolor.

¿Qué necesitas absolutamente

Si desea usar PHPDoc, necesita un bloque doc de archivo y otro bloque doc después de eso (generalmente el bloque doc de clase).

Esos **necesitan* tener una etiqueta @package. Todo lo demás es opcional.

Diría que incluso la etiqueta @package es opcional, ya que es posible que pueda generarla automáticamente para project. Y si no recuerdo mal PHPDoc te permite incluso establecer un valor predeterminado paquete para todo lo que no tiene una etiqueta.

Para la documentación en general permítanme comenzar con un ejemplo ( un ejemplo más largo está al final):

¿Cuántas veces puedes explicar lo que significa "uri": {[34]]}

Massive docsTenga en cuenta que para getUri se explica lo que significa URI (solo para tener algo de qué hablar en el comentario que asumiría) mientras que no está en isAbsUri porque allí puede al menos decir "abs significa absoluto" dos veces.


Si usted no es un proyecto de código abierto (o necesita enviar COMPLETO!!!11eleven documentación de api):

Me gustaría fuertemente sugerir el uso de clase apropiada, larga y descriptiva, nombres de variables y métodos en lugar de documentación.

No hay ganancia en escribir algo de nuevo en los bloques de documentos y como es 2011 y tenemos terminales de 120 caracteres de ancho y autocompletado, ya no hay necesidad de abreviar todo por el bien de guardar algunos chars.

Incluso argumentaría que documentar cosas triviales te lastima a ti y a tu equipo al forzarte a perder el tiempo en cosas que nadie obtiene valor de ti, te pones en el hábito de siempre escribir documentos triviales y no volver a leerlos.

Un buen comentario debe explicar POR qué se hizo algo, mientras que el código debe explicar cómo sin necesidad de más comentarios.

Mi ejemplo favorito para documentos redundantes es este:

class myClass {
/**
 * Constructor
 */
public function __construct() {
}

Algunos las directrices dicen que TIENESpara documentar TODO y terminas con personas que afirman lo obvio una y otra vez.

Esto no añade ningún valor, pero pierde tiempo al leer el código.

Un ejemplo para nombrar correctamente:

class Person { 
/** 
 * Set a persons weight in Kilogram
 *
 * @param float $kg Weight in Kilogram
 */
public function setWeight($kg) {}

Este código es fácil de documentar porque necesitas explicar lo que significa "kg" porque algunas personas podrían usar un sistema diferente y no puedes buscar en Google "kg".

Estoy a favor de escribir{[24]]}

class Person { 
/** 
 * @param float $kilogram
 */
public function setWeight($kilogram) {}

El bloque doc es superfluo porque llamar setWeight en Person realmente se puede esperar que fije el Peso en una Persona. No hay necesidad de escribir eso de nuevo.

Usar $kilogramm como parámetro también le ahorra la molestia de explicarlo en los documentos y yo diría que, dependiendo de su entorno, se puede esperar que todos busquen "kilogramo" en google si realmente no conocen la unidad de medición.


@PHPDoc documentation

  • Toda mi humilde opinión, por supuesto {[98]]}
  • Si no usa las sugerencias de tipo siempre usan etiquetas @param.
  • Utilice siempre las etiquetas @ return
  • No uses etiquetas @author en absoluto. La propiedad del código de la colección es más valiosa y la información está en el repositorio de control de código fuente de todos modos.
  • Solo use las etiquetas @copyright si es necesario. Me gusta solo tener un archivo de LICENCIA, pero no soy abogado, por lo que podría ser necesario.

Comentarios en línea:

public function generateReport() {
  // get the db connection
  $reg = WhateverGlobalStorage::get(“db“);
  // auth
  if(!$reg->getOne("SELECT view_report FROM USER ...")) {}
  // template
  $id = $reg->getOne("select ... "); 
  // render
  new ReportTemplate($id); // ...
}

Si esos son "bloques" separados, simplemente muévalos a descriptive named funciones

public function generateReport() {
  $this->checkAuthentication();
  $template = this->createReportTemplate();
  $this->renderReport($template);
}
// Not perfect but at least you can grasp what the method does much quicker

Recursos adicionales:

Diapositivas de una presentación que di sobre el tema en algunas conferencias: Slideshare: clean-code-stop-wasting-my-time

Y adicional pequeño, un poco mayor, despotricar: they-told-you-to-document-everything-they-lied

Referencias de libros:

Código Limpio-CubiertaClean Code: A Handbook of Agile Software Craftsmanship

Refactorización: Mejora del Diseño del Código Existente

Un ejemplo más largo

abstract class xyzRequest {
 /**
   * Initializes this xyzRequest.
   *
   * Available options:
   *
   *  * logging: Whether to enable logging or not (false by default)
   *
   * @param  xyzEventDispatcher $dispatcher  An xyzEventDispatcher instance
   * @param  array  $parameters  An associative array of initialization parameters
   * @param  array  $attributes  An associative array of initialization attributes
   * @param  array  $options     An associative array of options
   *
   * @return bool true, if initialization completes successfully, otherwise false
   *
   * @throws <b>xyzInitializationException</b> If an error occurs while initializing this xyzRequest
   */
  public function initialize(xyzEventDispatcher $dispatcher, $parameters = array(), $attributes = array(), $options = array()) {

Veamos, línea por línea, lo que dice esa documentación usted. (Estoy bromeando por aquí un poco para conseguir mi punto a través)

* Initializes this xyzRequest.

Entonces, ¿llamando a ->initialize en un xyzRequest inicializa esa solicitud? ¿En serio? Ok entonces, si tú lo dices!

   * Available options:
   *
   *  * logging: Whether to enable logging or not (false by default)

Se nos dicen las opciones para el tercer parámetro, no para el segundo o tercer parámetro, pero tal vez las conocemos si conocemos el marco? (Dado que no somos capaces de averiguar lo que ->initialize hace sin que alguien le diga el uso, es posible que no seamos tan inteligentes...)

   * @param  xyzEventDispatcher $dispatcher  An xyzEventDispatcher instance

Sí, el la pista de tipo está ahí. Así que si el método espera una "instancia xyzEventDispatcher" necesitamos pasar una "instancia xyzEventDispatcher". Es bueno saberlo.

   * @param  array  $parameters  An associative array of initialization parameters
   * @param  array  $attributes  An associative array of initialization attributes
   * @param  array  $options     An associative array of options

Ok. Así que no es una matriz lineal. Pero que necesito pasar " parámetros de inicialización "a un método" inicializar " que podría haber averiguado.

Todavía no hay idea de lo que realmente necesito pasar allí, pero siempre y cuando esté documentado, ¡tiene que estar bien!

   * @return bool true, if initialization completes successfully, otherwise false

Así que un valor de retorno booleano es "verdadero" para "bueno" y "falso" para malo".

   * @throws <b>xyzInitializationException</b> If an error occurs while initializing this xyzRequest
   */

Así que se lanza una excepción si se produce un error mientras estamos haciendo lo que la función se llama?

Así que las excepciones se utilizan para casos de error. Ok. Es bueno saberlo.

  • No me dice la diferencia entre return false y una excepción.
  • El @ arroja su auto está bien porque agrega información
  • Por cierto: ¿Por qué es esto en NEGRITA y no un @link
 58
Author: edorian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-17 16:22:48

Personalmente, solo comento en los constructores si hay algo especial que comentar al respecto (como una inicialización especial).

No diría que esa es la forma "más útil" de hacerlo, pero mantiene el código limpio, y repetir dos veces lo mismo no es realmente necesario (si eso es lo que te preocupa).

 1
Author: Sword22,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-21 09:20:45

Comenta todo: archivos (autoría, derechos de autor, descripción, etc.), clases (descripción, ejemplos de código), métodos y propiedades. Aquí es un buen ejemplo de phpDoc comentarios.

 0
Author: biakaveron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-21 09:19:08

Personalmente creo que la documentación de clase y método es la documentación más importante. Cuando escribo código quiero la ayuda de mi IDE cuando la finalización del código me muestra la documentación perteneciente a un método. De esta manera puedo encontrar fácilmente el método que necesito.

Dado que trato de mantener la inicialización explícita de las clases al mínimo, no hago comentarios del constructor de usuarios. Por lo tanto, trato de evitar el uso de constructores en sí.

El código en un método o función debe ser lo más claro posible mediante el uso de nombres de variables declarativas y manteniéndolos tan pequeños como sea posible. Solo cuando hago algo inesperado, por ejemplo para cuestiones de integración los comento.

 0
Author: pderaaij,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-21 09:38:11