2012-06-19 36 views
7

Estaba revisando el código Exchange Web Services Java API y vi una opción de diseño en la forma en que los desarrolladores pasaban los argumentos a sus métodos. Puede ayudar a explicar los beneficios de la técnica:Una forma curiosa de pasar un parámetro a un método

El tipo que se va a procesar con el método está envuelto por una clase de Contenedor genérico antes de pasar al método, por ejemplo, si el método va a funcionar en una String, nuevo Param() se pasa en el método en el que se define de la siguiente Param

class Param<T> { 
    private T param; 
    public T getParam() { return param; } 
    public void setParam(T param) { this.param = param } 
} 

Aquí hay un fragmento de la fuente - el método funciona en un objeto HttpWebRequest.
El llamante crea una instancia del Param, es decir, delimitada por la clase HttpWebRequest. Entonces esa instancia se pasa al método, como se puede ver en la firma del método -

protected HttpWebRequest emit(OutParam<HttpWebRequest> request) 
throws Exception { 
    request.setParam(this.getService().prepareHttpWebRequest()); 
    OutputStream urlOutStream = request.getParam().getOutputStream(); 
    EwsServiceXmlWriter writer = new EwsServiceXmlWriter(this.service,urlOutStream); 
    this.writeToXml(writer); 
    urlOutStream.flush(); 
    urlOutStream.close(); 
    writer.dispose(); 

    request.getParam().executeRequest(); 
    if(request.getParam().getResponseCode() >= 400) 
    { 
     throw new Exception("The remote server returned an error:("+request.getParam().getResponseCode()+")"+request.getParam().getResponseText()); 
    } 
    return request.getParam(); 
} 

Entonces ¿por qué no pasar el objeto HttpWebRequest - Los desarrolladores utilizan este patrón varias veces todo el código base que hace Creo que hay una buena razón para eso. Pero simplemente no puedo ver el beneficio ... por favor, ilumínalo.

+0

Se puede apuntar a uno de esos casos en GitHub, por favor? ¡Gracias! – Miquel

+0

enlace está en la pregunta – bell0

Respuesta

4

En la entrada de método, se espera que la instancia envuelta HttpWebRequest sea nula. Esta es una forma de devolver la instancia por otro medio que no sea la declaración de devolución, incluso si algo sale mal durante la llamada al método (si se produce una excepción, por ejemplo). Este patrón es de alguna manera equivalente a la palabra clave out en C#. Podría ser también utilizado para devolver un objeto un estado de error +:

bool getGreetings(OutParam<Greetings> greetings) { 
    if (aCondition) { 
    greetings.setParam(new Greetings("Hello"); 
    return true; // everything's fine 
    } 
    return false; 
} 

en lugar de la escritura:

Greetings getGreetings() { 
    if (aCondition) { 
    return new Greetings("Hello"); 
    } 
    return null; // caller will have to test a null condition to know it the operation was ok 
} 
+0

Esto tiene sentido, se pasa a un recipiente, que puede ser modificado. – Ixx

+0

Ayuda a definir el tipo que se puede almacenar, como en una colección. – Ixx

+0

Podría hacerlo sin un envoltorio genérico, pero en ese caso tendría que crear un contenedor dedicado para cada objeto en el que desea usar dicho patrón ... A menos que reemplace 'T' por 'Objeto', pero sería mucho menos seguro y legible. – Yanflea

Cuestiones relacionadas