Guía de codificación
Nota
Aunque el framework es muy reciente, tenga en cuenta que algunas de las primeras clases de Ubiquity no siguen completamente esta guía y no han sido modificadas por razones de compatibilidad con versiones anteriores.
Sin embargo, todos los códigos nuevos deben seguir esta guía.
Opciones de diseño
Obtención y utilización de servicios
Inyecciones de dependencia
Evite utilizar la inyección de dependencias para todas las partes del framework, internamente.
La inyección de dependencias es un mecanismo que consume muchos recursos:
necesita identificar el elemento a instanciar ;
a continuación, proceder a su instanciación ;
para finalmente asignarlo a una variable.
Obtener servicios de un contenedor
Evite también el acceso público a servicios registrados en un contenedor de servicios.
Este tipo de acceso implica manipular objetos cuyo tipo de retorno se desconoce, lo que no es fácil de manejar para el desarrollador.
Por ejemplo, es difícil manipular el retorno no tipado de $this->serviceContainer->get('translator')
, como permiten algunos frameworks, y saber qué métodos llamar en él.
Cuando sea posible, y cuando no reduzca demasiado la flexibilidad, se sugiere el uso de clases estáticas:
Para un desarrollador, la clase TranslatorManager
es accesible desde todo un proyecto sin necesidad de instanciar ningún objeto.
Expone su interfaz pública y permite completar el código:
No es necesario inyectar el traductor para utilizarlo;
No es necesario recuperarlo de un contenedor de servicios.
El uso de clases estáticas crea inevitablemente una fuerte dependencia y afecta a la flexibilidad.
Pero volviendo al ejemplo del Traductor, no hay razón para cambiarlo si es satisfactorio.
No es deseable querer proporcionar flexibilidad a toda costa cuando no es necesario, y que luego el usuario vea que su aplicación es un poco lenta.
Optimización
La ejecución de cada línea de código puede tener importantes repercusiones en el rendimiento.
Compara y compara soluciones de implementación, especialmente si el código se llama repetidamente:
Identifique estas llamadas repetitivas y costosas con herramientas de perfilado de php (Blackfire profiler , Tideways …)
Evalúe sus diferentes soluciones de implementación con phpMyBenchmarks
Calidad de código
Ubiquity utiliza Scrutinizer-CI para la calidad del código.
Para clases y métodos :
Las evaluaciones A o B son buenas
C es aceptable, pero debe evitarse si es posible
Las notas más bajas deben prohibirse
Complejidad del código
Los métodos complejos deben dividirse en varios, para facilitar su mantenimiento y permitir su reutilización;
Para clases complejas, haga una refactorización extract-class o extract-subclass y divídalas usando Traits;
Duplicaciones de código
Evite absolutamente la duplicación de código, excepto si la duplicación es mínima y está justificada por el rendimiento.
Errores
Intenta resolver sobre la marcha todos los errores que se reporten, sin dejar que se acumulen.
Pruebas
Cualquier corrección de errores que no incluya una prueba que demuestre la existencia del error corregido puede ser sospechosa.
Lo mismo ocurre con las nuevas funciones que no pueden demostrar que funcionan.
También es importante mantener una cobertura aceptable, que puede disminuir si no se prueba una nueva función.
Documentación de código
El código actual aún no está completamente documentado, siéntase libre de contribuir para llenar este vacío.
Normas de codificación
Las normas de codificación de Ubiquity se basan principalmente en las normas PSR-1 , PSR-2 y PSR-4 , por lo que es posible que ya conozca la mayoría de ellas.
Las pocas excepciones intencionadas a las normas se informan normalmente en esta guía.
Convenciones de nombrado
Utilice camelCase para variables PHP, miembros, nombres de funciones y métodos, argumentos (por ejemplo, $modelsCacheDirectory, isStarted());
Utilice namespaces para todas las clases PHP y UpperCamelCase para sus nombres (por ejemplo, CacheManager);
Prefija todas las clases abstractas con Abstract excepto PHPUnit BaseTests;
Sufija las interfaces con
Interface
;Sufija los traits con
Trait
;Sufija las excepciones con
Exception
;Sufijo gestor de clases principales con
Manager
(por ejemplo, CacheManager, TranslatorManager);Prefije las clases de utilidad con
U
(por ejemplo, UString, URequest);Utilice UpperCamelCase para nombrar los archivos PHP (por ejemplo, CacheManager.php);
Utilice mayúsculas para las constantes (por ejemplo, const SESSION_NAME=”Ubiquity”).
Sangría, tabulaciones, llaves
Utilizar tabuladores, no espacios; (!PSR-2)
Utilizar llaves siempre en la misma línea; (!PSR-2)
Utilice llaves para indicar el cuerpo de la estructura de control, independientemente del número de sentencias que contenga;
Clases
Defina una clase por archivo;
Declare la herencia de la clase y todas las interfaces implementadas en la misma línea que el nombre de la clase;
Declare las propiedades de la clase antes que los métodos;
Declare primero los métodos privados, luego los protegidos y finalmente los públicos;
Declare todos los argumentos en la misma línea que el nombre del método/función, sin importar el número de argumentos;
Utilice paréntesis al instanciar clases independientemente del número de argumentos que tenga el constructor;
Añade una declaración de uso para cada clase que no forme parte del espacio de nombres global;
Operadores
Utilice comparación idéntica e igual cuando necesite hacer manipulación de tipos;
Ejemplo
<?php
namespace Ubiquity\namespace;
use Ubiquity\othernamespace\Foo;
/**
* Class description.
* Ubiquity\namespace$Example
* This class is part of Ubiquity
*
* @author authorName <authorMail>
* @version 1.0.0
* @since Ubiquity x.x.x
*/
class Example {
/**
* @var int
*
*/
private $theInt = 1;
/**
* Does something from **a** and **b**
*
* @param int $a The a
* @param int $b The b
*/
function foo($a, $b) {
switch ($a) {
case 0 :
$Other->doFoo ();
break;
default :
$Other->doBaz ();
}
}
/**
* Adds some values
*
* @param param V $v The v object
*/
function bar($v) {
for($i = 0; $i < 10; $i ++) {
$v->add ( $i );
}
}
}