Después de leer this description 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?¿Cuándo necesitaría utilizar encuadernación estática tardía?
Respuesta
que necesitaba LSB esto para el siguiente escenario:
- Imagínese que usted está construyendo un demonio "procesador de correo" que descarga el mensaje de un servidor de correo electrónico, lo clasifica, lo analiza, lo guarda, y luego hace algo, dependiendo del tipo de mensaje.
- Jerarquía de clases: 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 las diferentes subclases, pero compartió para todos los elementos dentro de la subclase. Es por eso que tiene sentido que sea en un método estático.
- La clase de mensaje base tiene un método estático abstracto (sí, resumen 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 ":: save()"
Si desea obtener más información 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 enlace estático tardío. Un ejemplo rápido: paste2.org
El ejemplo clásico es la clase ActiveRecord de Rails, si se intenta implementar algo similar en PHP, que se vería así: class User extends ActiveRecord
y luego intenta llamar User::find(1)
el método que es llamada es en realidad ActiveRecord::find()
porque no ha sobrecargado find()
en User
- pero sin enlace estático tardío el método find()
en ActiveRecord
no tiene forma de saber de qué clase se llamó desde (self
dentro de él siempre apunta a ActiveRecord
), y por lo tanto no puede recuperar su Usuario-objeto para ti.
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.
Este DateAndTime class 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í está 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 fines de enlace estático, [como en mi aplicación actual] cada clase debe implementar todos los métodos de creación de la instancia 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 el numbe r de los métodos de creación de instancias y la jerarquía de clases aumenta 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.
Es útil cuando:
Usted tiene una funcionalidad que varía a lo largo de la jerarquía de clases,
La funcionalidad tiene la misma firma sobre la jerarquía, y
(crucialmente) Usted no tiene una instancia para suspender la funcionalidad.
Si solo obtuviera el n.º 1 y el n.º 2, utilizaría 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.
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 tabla, el mejor lugar sería en una variable estática en cada clase derivada, ya que la validación y la definición de la tabla es la misma para cada instancia de Usuario.
Sin LSB el método validado() mencionado en BaseObject no tendría ninguna 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 va a ser introducido en el 5,3
tengo una clase con un método estático que se encarga de parte del formato. Tengo otra clase que necesita toda la funcionalidad del original, excepto cómo maneja el formateo.
- 1. Encuadernación temprana y tardía
- 2. encuadernación tardía en C
- 3. PHP 5.2 Equivalente a la unión estática tardía (nueva estática)?
- 4. ¿Cuándo NO utilizar la palabra clave estática en Java?
- 5. Cuándo utilizar IList y cuándo utilizar List
- 6. ¿Cuándo necesitaría usar la palabra clave stackalloc en C#?
- 7. Cuándo utilizar retener y cuándo utilizar la copia
- 8. Cuándo utilizar EntityManager.find() vs EntityManager.getReference()
- 9. Cuándo utilizar WCF/REST
- 10. ¿Cuándo NO utilizar NoSQL?
- 11. Cuándo utilizar Dependency Injection
- 12. Cuándo utilizar un HashTable
- 13. Cuándo utilizar la opción
- 14. Cuándo utilizar el operador "^"
- 15. Cuándo utilizar archivos .xcconfig
- 16. Cuándo utilizar NSNotificationCenter
- 17. Cuándo utilizar importaciones absolutas
- 18. cuándo utilizar hibernate.connection.provider_class
- 19. Cuándo utilizar memcached
- 20. Cuándo utilizar NSEnumerationConcurrent
- 21. Cuándo utilizar Common Table Expression (CTE)
- 22. Cuándo utilizar/proc y cuándo/dev
- 23. Cuándo utilizar Request.UrlReferrer y cuándo Request.ServerVariables ["HTTP_REFERER"]?
- 24. Cuándo utilizar IModelBinder versus DefaultModelBinder
- 25. Cuándo utilizar ServiceTracker vs ServiceReference
- 26. Cuándo utilizar patrones de fábrica?
- 27. Cuándo utilizar "ON UPDATE CASCADE"
- 28. cuándo utilizar OPTIMIZE en mysql
- 29. - Cuándo utilizar DataContractSerializer/Binario/XMLSerialiser
- 30. cuándo utilizar "willChangeValueForKey" y "didChangeValueForKey"?
Sería útil si pudiera agregar * por qué * en este caso usar '' 'static ::' '' sería mejor o más fácil que simplemente usar un método abstracto, * no estático *.Para mí, parece que '' 'save()' '' es algo de lo que no tendrías razón para llamar desde un contexto estático de todos modos, pero tal vez me falta algo. – SeldomNeedy