2012-02-08 27 views
5

Digamos que tiene un objeto que es único, y es utilizado por todas las demás clases y funciones ... algo así como $application.Método de clase global vs función vs clase estática

¿Cómo accedería a este objeto en sus funciones?

  1. utilizando una variable global en cada una de las funciones que:

    global $application; 
    $application->doStuff(); 
    
  2. creación de una función, como application() que una instancia del objeto en una variable estática y lo devuelve; a continuación, utilizar esta función en todas partes que necesita para acceder al objeto:

    application()->doStuff(); 
    
  3. crear algo único, como un método estático dentro de la clase de objeto que devuelve el único caso, y utilizar este método para tener acceso al objeto:

    Application::getInstance()->doStuff(); 
    
  4. KingCrunch & skwee: Pasar el objeto de aplicación como argumento para cada función/clase en la que se necesita

    ... 
    public function __construct(Application $app, ...){ 
        .... 
    

Si hay otras opciones, publíquelas. Me pregunto cuál de estas opciones es la "mejor práctica" más eficiente/considerada.

+2

¿Tiene una pregunta específica o simplemente desea hacer una lista? –

Respuesta

4

Lo pasaría a todos los métodos necesarios. decir

function doFoo(Application $app) { 
    $app->doStuff(); 
} 

Tanto global y Singleton considerado malo y corbatas su código demasiado y esto hace que la unidad de pruebas más difíciles. Hay una regla cuando se le permite utilizar Singleton, si su respuesta es "sí" a la siguiente declaración:

¿Es necesario introducir el estado global a mi solicitud y que debe tener una única instancia del objeto dado Y tener más de una instancia causará errores

Si su respuesta es sí a todas las partes 3, puede utilizar Singleton. En cualquier otro caso simplemente pase todas las instancias a todo el método que las necesite. Si usted tiene demasiado de ellos, considere el uso de algo así como Contexto

class Context { 
    public $application; 
    public $logger; 
    .... 
} 
======== 
$context = new Context(); 
$context->application = new Application(); 
$context->logger = new Logger(...); 
doFoo($context); 
======== 
function doFoo(Context $context) { 
    $context->application->doStuff(); 
    $context->logger->logThings(); 
} 

(se puede usar getters/setters si usted necesita para proteger los datos o la manipulación o si desea utilizar la iniciación perezoso, etc).

¡Buena suerte!

+0

2 (Debo tener una única instancia de objeto dado) es cierto :) – Alex

+0

Pero tener más de una instancia causará un error en el programa? Es una declaración lógica de A && B && C, en su caso B es verdadero y A y C falso, por lo que la declaración es falsa :) Realmente no puedo pensar en una situación en la que la respuesta a esta afirmación sea cierta. Tal vez cuando programo algún tipo de microcontrolador cuando tengo una sola CPU o algo así ... –

1

O simplemente déselo a los que estén interesados ​​en él. Todas las sugerencias que hizo son como variables globales, incluso si lo llama no es eso en 2 de 3 variantes.

Antes de eso, si quieres decir "Eso no es posible, porque todo lo necesita", entonces quizás hace demasiado, puede demasiado, y/o sabe demasiado.

+0

Esto es cierto, podría pasar la aplicación como argumento para __construir de cada clase donde lo necesitaba. Pero no sé ... Usar '$ this-> application' dentro de esa clase parece algo extraño – Alex

+0

también tendría que pasar ese argumento a cada método estático de la clase también ... – Alex

+0

Usando' $ this- > property' se ve exactamente cómo debería ser el acceso a una dependencia. En cuanto a tu segundo comentario: Suena que también tienes demasiados métodos estáticos. – KingCrunch

4

Singletons, God Classes, clases monolíticas, etc. son todos patrones anti, así que sugeriría una cuarta opción: inyección de dependencia. Puede crear una instancia de application en su aplicación a través de una fábrica (o incluso new si no tiene dependencias, pero esto puede complicar las cosas más adelante).

Luego, cualquier clase que necesite acceso a application puede obtenerlo como miembro, amablemente a través del constructor. Estoy seguro de que no cada clase necesita acceso a application. Recuerde la Ley de Demeter.

Si necesita alguna funcionalidad genérica como convertir una cadena estática a otra, sugiero usar las funciones globales de php (en lugar de, por ejemplo, una clase estática falsa). Creo que fueron diseñados para ese propósito.