Éviter l’implémentation par défaut dans l’interface C#

la programmation


Je cherche un moyen d’intégrer des fonctionnalités supplémentaires dans diverses classes en C#. Se concentrer sur une implémentation par défaut pour les méthodes d’interface était une bonne idée.

Considérez la structure de classe suivante :

La classe A est une base pour les classes B, C et D.
La classe E est une base pour les classes F, G et H.
La classe O est une base pour les classes P, Q et R.

Parmi celles-ci, les classes B, F et P doivent implémenter l’interface IDoablequi comprend une méthode X cela devrait être cohérent dans toutes les classes d’implémentation.

Voici un exemple simplifié :

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 :("; 
    }
}

Cependant, il existe un débat quant à savoir si l’utilisation d’implémentations par défaut pour les méthodes d’interface est recommandée en C#. Existe-t-il des approches alternatives pour obtenir cette fonctionnalité sans s’appuyer sur des implémentations par défaut ? Ou l’utilisation d’implémentations par défaut est-elle acceptable dans ce scénario ?

Remarque : A, E et O n’ont aucune caractéristique commune et ne sont pas liés.

Ce que j’ai essayé :

Premièrement, je me suis abstenu d’implémenter X directement dans les classes B, F et P pour éviter de violer les SEC principe. Étant donné que X est censé être identique dans toutes ces classes, cette approche semble peu pratique, surtout si X est long.

Deuxièmement, j’ai créé une méthode d’extension, qui a bien fonctionné pour fournir la fonctionnalité X :

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

Cependant, cette approche a abouti à un vide IDoable interface, qui viole le “CA1040 : évitez les interfaces vides” règle.

Enfin, j’ai considéré le Modèle de décorateur, mais je ne sais pas comment le mettre en œuvre efficacement tout en respectant le principe DRY. Mais il est possible que cette approche soit la solution clé.

Solution 1

En gardant la question théorique, il est très difficile de donner une réponse concrète sans connaître la situation. Cela donne l’impression que votre professeur, ou un intervieweur pour un emploi, essaie de vous poser une question sans bonne réponse pour voir comment vous réagiriez.

En regardant les options présentées, la solution du modèle de décorateur suggère que les 3 classes de base ont une classe de base ou une interface commune. L’interface vide avec une méthode d’extension serait donc la solution probable. Raison : vous ne pouvez pas hériter de plus d’une classe concrète (de base/abstraite) mais vous pouvez implémenter plusieurs interfaces (implicites/explicites).

コメント

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