php - strip_tags - the permalink
¿Cuándo necesitarías usar enlace estático tardío? (6)
Después de leer esta descripción de enlace estático tardío (LSB) veo bastante claramente lo que está sucediendo. Ahora, ¿bajo qué tipo de circunstancias podría ser más útil o necesaria?
Es útil cuando:
Usted tiene una funcionalidad que varía en la jerarquía de clases,
La funcionalidad tiene la misma firma sobre la jerarquía, y
(crucial) No tienes una instancia para suspender la funcionalidad.
Si solo obtuvieran los números 1 y 2, utilizarías un método de instancia ordinario. Entonces el problema de Alex (ver su respuesta a esta pregunta) no requiere LSB.
Un caso típico es la creación de objetos, donde las subclases se crean de diferentes maneras, pero utilizando los mismos parámetros. Obviamente, no tiene ninguna instancia para llamar, por lo que el método de creación (también conocido como método de fábrica) debe ser estático. Sin embargo, desea que su comportamiento varíe según la subclase, por lo que un método estático ordinario no es correcto. Vea la respuesta de Adam Franco para un ejemplo.
Necesitaba LSB esto para la siguiente situación:
- Imagine que está creando un daemon de "procesador de correo" que descarga el mensaje de un servidor de correo electrónico, lo clasifica, lo analiza, lo guarda y luego hace algo, según el tipo de mensaje.
- Jerarquía de clase: tiene una clase de mensaje base, con hijos "BouncedMessage" y "AcceptedMessage".
- Cada uno de los tipos de mensajes tiene su propia manera de mantenerse en el disco. Por ejemplo, todos los mensajes de tipo BouncedMessage intentan guardarse como BouncedMessage-id.xml. Por el contrario, AcceptedMessage necesita guardarse de forma diferente, como AcceptedMessage-timestamp.xml. Lo importante aquí es que la lógica para determinar el patrón de nombre de archivo es diferente para diferentes subclases, pero compartida para todos los elementos dentro de la subclase. Es por eso que tiene sentido que sea en un método estático.
- La clase Base Message tiene un método estático abstracto (sí, abstracto Y estático) "guardar". BouncedMessage implementa este método con un método estático concreto. Luego, dentro de la clase que realmente recupera el mensaje, puede llamar a ":: save ()"
Si quieres saber más sobre el tema:
Si necesita acceder a una propiedad / método estático sobrecargado dentro de un método que no ha sido sobrecargado en una subclase, necesita un enlace estático tardío. Un ejemplo rápido: paste2.org
El ejemplo clásico es la clase ActiveRecord de Rails, si intentas implementar algo similar en PHP, que se vería así: class User extends ActiveRecord
y luego intenta llamar a User::find(1)
el método que se llama es en realidad ActiveRecord::find()
porque no has sobrecargado find()
en User
- pero sin enlace estático tardío el método find()
en ActiveRecord
no tiene forma de saber a qué clase se llama desde ( self
dentro siempre apunta a ActiveRecord
) , y por lo tanto no puede recuperar su objeto de usuario por usted.
Supongamos que tiene clases que representan tablas (instancias de fila) en un mapeador relacional de objetos simplificado. Tendría una clase "Usuario" y una clase "Empresa" cuyas instancias representan filas de las tablas respectivas. El usuario y la empresa heredarían de una clase abstracta base, digamos "BaseObject", que tendrá algunos métodos comunes como save (), delete (), validate () etc ...
Si desea almacenar datos sobre la validación y la definición de la tabla, el mejor lugar sería una variable estática en cada clase derivada, ya que la validación y la definición de la tabla son las mismas para cada instancia de Usuario.
Sin LSB, el método validado () mencionado en BaseObject no tendría referencia a las variables estáticas definidas en Usuario y Empresa, aunque lo esté llamando a través de una instancia de Usuario. Buscará la misma variable estática en la clase BaseObject y generará un error.
Esta es mi experiencia con PHP 5.2.8 - LSB se va a presentar en 5.3
Tengo una clase con un método estático que maneja algunos formatos. Tengo otra clase que necesita toda la funcionalidad del original, excepto cómo maneja el formateo.
Una de las principales necesidades que tengo para el enlace estático tardío es para un conjunto de métodos estáticos de creación de instancias.
Esta clase DateAndTime es parte de una biblioteca de cronología que porté a PHP desde Smalltalk / Squeak. El uso de métodos de creación de instancias estáticos permite la creación de instancias con una variedad de tipos de argumentos, mientras se mantiene la verificación de parámetros en el método estático para que el consumidor de la biblioteca no pueda obtener una instancia que no sea completamente válida.
La vinculación estática tardía es útil en este caso para que las implementaciones de estos métodos de creación de instancias estáticas puedan determinar a qué clase se dirigió originalmente la llamada. Aquí hay un ejemplo de uso:
Con LSB:
class DateAndTime {
public static function now() {
$class = static::myClass();
$obj = new $class;
$obj->setSeconds(time());
return $obj;
}
public static function yesterday() {
$class = static::myClass();
$obj = new $class;
$obj->setSeconds(time() - 86400);
return $obj;
}
protected static function myClass () {
return ''DateAndTime'';
}
}
class Timestamp extends DateAndTime {
protected static function myClass () {
return ''Timestamp'';
}
}
// Usage:
$date = DateAndTime::now();
$timestamp = Timestamp::now();
$date2 = DateAndTime::yesterday();
$timestamp2 = Timestamp::yesterday();
Sin enlace estático tardío, [como en mi implementación actual] cada clase debe implementar cada método de creación de instancias como en este ejemplo:
Sin LSB:
class DateAndTime {
public static function now($class = ''DateAndTime'') {
$obj = new $class;
$obj->setSeconds(time());
return $obj;
}
public static function yesterday($class = ''DateAndTime'') {
$obj = new $class;
$obj->setSeconds(time() - 86400);
return $obj;
}
}
class Timestamp extends DateAndTime {
public static function now($class = ''Timestamp'') {
return self::now($class);
}
public static function yesterday($class = ''Timestamp'') {
return self::yesterday($class);
}
}
A medida que aumenta la cantidad de métodos de creación de instancias y la jerarquía de clases, la duplicación de métodos se convierte en un verdadero dolor en el trasero. LSB reduce esta duplicación y permite implementaciones mucho más claras y sencillas.