Evitar la implementación predeterminada en la interfaz C#

programación


Estoy buscando una manera de integrar funciones adicionales en varias clases en C#. Centrarse en una implementación predeterminada para los métodos de interfaz fue una buena idea.

Considere la siguiente estructura de clases:

La clase A es una base para las clases B, C y D.
La clase E es una base para las clases F, G y H.
La clase O es una base para las clases P, Q y R.

Entre estas, las clases B, F y P deben implementar la interfaz IDoableque incluye un método X eso debería ser consistente en todas las clases de implementación.

Aquí hay un ejemplo simplificado:

C#
public class A
{ }

public class B : A, IDoable
{ }

public class C : A
{ }

public class D : A
{ }

public class E
{ }

public class F : E, IDoable
{ }

public class G : E
{ }

public class H : E
{ }

public class O
{ }

public class P : O, IDoable
{ }

public class Q : O
{ }

public class R : O
{ }

public interface IDoable
{
    // Yuck, that smells. Default implementation.
    string X() => "I want to implement method X only once";
}

public class Test
{
    public void Run()
    {
        string bx = new B().X();
        string fx = new F().X();
        string px = new P().X();
        
        string result = bx == fx && bx == px ? "Same :)" : "Various :("; 
    }
}

Sin embargo, existe un debate sobre si es aconsejable usar implementaciones predeterminadas para métodos de interfaz en C#. ¿Existen enfoques alternativos para lograr esta funcionalidad sin depender de implementaciones predeterminadas? O ¿Es aceptable el uso de implementaciones predeterminadas en este escenario?

Nota: A, E y O no comparten características y no están relacionados.

Lo que he probado:

En primer lugar, me abstuve de implementar X directamente en las clases B, F y P para evitar violar el SECO principio. Dado que X debe ser idéntico en todas estas clases, este enfoque parecía poco práctico, especialmente si X es largo.

En segundo lugar, creé un método de extensión que funcionó bien para proporcionar la funcionalidad X:

C#
public static class DoableExtensions
{
    public static string X(this IDoable doable)
    {
        return "I want to implement method X only once";
    }
}

Sin embargo, este enfoque resultó en un vacío IDoable interfaz, que viola la “CA1040: Evite interfaces vacías” regla.

Por último, consideré la Patrón decorador, pero no estoy seguro de cómo implementarlo de manera eficiente manteniendo el cumplimiento del principio DRY. Pero es posible que este enfoque sea la solución clave.

Solución 1

Mantener la pregunta teórica hace que sea muy difícil dar una respuesta concreta sin conocer la situación. Esto suena como si tu maestro, o un entrevistador para un trabajo, estuviera tratando de hacerte una pregunta sin una respuesta correcta para ver cómo responderías.

Al observar las opciones presentadas, la solución del patrón decorador sugiere que las 3 clases base tienen una clase base o interfaz común. Entonces, la interfaz vacía con un método de extensión sería la solución probable. Motivo: no puede heredar más de una clase concreta (base/abstracta), pero puede implementar múltiples interfaces (implícitas/explícitas).

コメント

タイトルとURLをコピーしました