¿Es mejor proteger la llamada al método o el método en sí?

12

Estoy escribiendo una solicitud y llegué a este punto:

private void SomeMethod()
{
    if (Settings.GiveApples)
    {
        GiveApples();
    }

    if (Settings.GiveBananas)
    {
        GiveBananas();
    }
}

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

Esto se ve bastante sencillo. Hay algunas condiciones y si son verdaderas los métodos están siendo llamados. Sin embargo, estaba pensando, ¿es mejor hacerlo así?

private void SomeMethod()
{
    GiveApples();
    GiveBananas();
}

private void GiveApples()
{
    if (!Settings.GiveApples)
    {
        return;
    }

    ...
}

private void GiveBananas()
{
    if (!Settings.GiveBananas)
    {
        return;
    }

    ...
}

En el segundo caso, cada uno de los métodos se guarda, por lo que incluso si se llama a cualquiera de esos métodos GiveApples o GiveBananas desde fuera SomeMethod , se ejecutarán solo si tienen la marca correcta en Configuración.

¿Es esto algo que realmente debería considerar como un problema?

En mi contexto actual, es muy poco probable que estos dos métodos sean llamados desde fuera de este método, pero nadie puede garantizarlo.

    
pregunta Nikola 26.01.2016 - 16:35

3 respuestas

13

Pienso en los guardias como algo que el método debe obedecer. En su ejemplo, el método no debe dar manzanas si Settings.GiveApples es falso.

Si ese es el caso, entonces el guardia definitivamente pertenece al método. Esto evita que lo llame accidentalmente desde otro punto de su aplicación sin consultar primero a los guardias.

Por otra parte, si la configuración solo se aplica al método de llamada, y otro método en otra parte de su código puede proporcionar GiveApples independientemente de la configuración, entonces no es una protección y probablemente debería estar en el código de llamada.

    
respondido por el Jeremy Hutchinson 26.01.2016 - 16:51
5

Coloca la guarda dentro del propio método. El consumidor de GiveApples() o GiveBananas() no debe ser responsable de administrar las guardas de GiveApples() .

Desde un punto de vista de diseño, SomeMethod() solo debe saber que necesita fruta y no debe preocuparse por lo que su aplicación necesita hacer para obtenerla. La abstracción de la recuperación de fruta se vuelve permeable si SomeMethod() es responsable de saber que existe un entorno global que permite la recuperación de cierta fruta. Esto se aplica en cascada si su mecanismo de protección cambia alguna vez, ya que ahora todos los métodos que necesitan GetApples() o GetBananas() deben ser refaccionados por separado para implementar esta nueva protección. También es muy fácil tratar de obtener frutos sin ese cheque mientras escribes el código.

Lo que debe considerar en este escenario es cómo debe reaccionar su aplicación cuando la Configuración no permite que su aplicación dé frutos.

    
respondido por el ravibhagw 26.01.2016 - 17:12
4

En general, a menudo es una buena idea separar las responsabilidades de probar algo como la configuración provista externamente y el "código de negocio principal" como GiveApples . Por otro lado, tener funciones que agrupen lo que pertenece es también una buena idea. Puedes lograr ambos objetivos refactorizando tu código de esta manera:

private void SomeMethod()
{
    GiveApplesIfActivated();
    GiveBananasIfActivated();
}

private void GiveApplesIfActivated()
{
    if (Settings.GiveApples)
    {
        GiveApples();
    }
}

private void GiveBananasIfActivated()
{
    if (Settings.GiveBananas)
    {
        GiveBananas();
    }
}

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

Esto le da una mejor oportunidad de refactorizar el código de GiveApples y / o GiveBananas en un lugar separado sin ninguna dependencia de la clase Settings . Obviamente, esto es beneficioso cuando desea llamar a esos métodos en una prueba unitaria que no cuida a ningún Settings .

Sin embargo, si siempre está mal en su programa, bajo cualquier circunstancia, incluso en un contexto de prueba, llamar a algo como GiveApples fuera de un contexto donde Settings.GiveApples se verifica primero, y está bajo la impresión de que solo está proporcionando un la función como GiveApples sin la verificación Settings es propensa a errores, luego se adhiere a la variante donde se prueba Settings.GiveApples dentro de GiveApples .

    
respondido por el Doc Brown 26.01.2016 - 21:46

Lea otras preguntas en las etiquetas