web-dev-qa-db-fra.com

Qu'est-ce que la bonne pratique lorsque l'héritage des classes statiques n'est pas possible / autorisée

Je développe un projet en C # et en raison d'une décision de conception, il n'est pas possible d'avoir une classe statique hériter d'une autre classe statique. Mais j'ai, à mon avis, un cas où cela aurait un sens.

J'ai un lecteur de musique qui est capable de jouer de la musique de nombreuses sources de musique différentes: fichiers locaux, YouTube, SoundCloud, Jamendo, etc. J'ai actuellement une classe statique pour chacune de ces sources avec des méthodes statiques telles que la récupération des pistes supérieures, la recherche Pour les pistes, etc.

Naturellement, beaucoup de code est partagé entre toutes ces classes, donc je voulais refroidir et mettre tout le code commun dans une classe de musicsource plus générique. Mais c # ne me permet pas de le faire.

Quelle serait la meilleure pratique ici? Je veux me débarrasser de tout mon code redondant et faciliter la création de nouvelles sources de musique.

4
Christoffer Reijer

Ces classes "Source musicale" sonnent plus comme des classes non statiques que vous n'aurez qu'un exemple de. Ils sont deux choses différentes!

Voici quelques raisons pour lesquelles vous voudrez peut-être les rendre non statiques:

  • S'ils ont (ou pourraient éventuellement avoir) un état interne. par exemple. Cached Connecteurs d'informations de connexion ou listes en cache des 10 meilleurs pistes. Les classes statiques standard sont une mauvaise idée! Ils sont fondamentalement une mauvaise mise en œuvre d'un singleton.
  • Si vous voulez avoir beaucoup de sources de musique, vous voudrez peut-être bien effectuer certaines actions sur chacune d'elles. par exemple. Trouvez une piste particulière à partir de n'importe quelle source. Avec des classes statiques, vous allez avoir besoin d'une ligne pour chaque classe. Si vous avez des cours non statiques, vous pouvez simplement vous en protéger sur une collection.

Il y a une bonne réponse ici qui donne plus de raisons et va dans plusieurs détails.

16
vaughandroid

Il n'est pas possible d'hériter des classes statiques du tout (au moins en C #), quelle que soit la "décision de conception".

Peut-être que votre question a besoin de reformulation, mais ne pouvez-vous pas utiliser de classes non statiques comme dans cet exemple artificiel et trop simple;

abstract class MusicSource 
{  
    abstract MusicData LoadMusic(string source);

    protected string SomeCommonProperty { get; set; }
}

class JamendoSource : MusicSource 
{   
    override MusicData LoadMusic(string source)
    {
        // Jamendo-specific code
    }
}
3
RJ Lohan

L'utilisation de statique dans ce cas est complètement fausse. Les gens ont tendance à utiliser la voie de Statique à souvent! De manière fondamentale, vous avez 1 "MusicPlayer" avec x-quantité de mise en œuvre (YouTube, ...) Donc, la première chose à apparaître dans votre tête est la héritage.

Ils feront tous la même chose, mais abit différent => héritage. Vous voulez que votre demande fonctionne avec plusieurs types de sources, sans qu'il soit nécessaire d'adapter l'application elle-même => Ségrégation d'héritage/interface.

Les classes statiques peuvent être utiles, mais dans ce cas, j'ai un sentiment que les classes de musique sont au cœur de votre application ... Ne construisez pas votre fonctionnalité de base dans des classes statiques, car vous supprimez: Testabilité, maintenabilité, réutilisabilité, extensibilité, ...

Vous dites:

Je veux me débarrasser de tout mon code redondant et faciliter la création de nouvelles sources de musique.

Là encore, l'héritage est central ...

Dans C #, chaque fois que vous utilisez des classes statiques, oubliez l'héritage. L'inverse, chaque fois que vous avez besoin d'héritage, oubliez des classes statiques.

Pourquoi avez-vous initialement fait statique de toute façon?

Si vous souhaitez avoir une seule instance disponible, faites-en un singleton. Sinon, faites-la simplement non statique!

1
Frederik P.

Je ne sais pas si quelqu'un est toujours intéressé par ce sujet, mais Shorty j'ai essayé ce qui suit. C'est probablement une solution pour une solution générique qui impliquait un comportement statique.

  public abstract class StructureItem {
        public int index = 0;
    }

    public abstract class StructureItem<T> : StructureItem where T : StructureItem
    {
        public static List<T> Elements = new List<T>();
    }

    public class TEST1 : StructureItem<TEST1>
    {
        public TEST1()
        {
            StructureItem a = this;
            this.index = 1;
            TEST1.Elements.Add(this);
        }
    }

    public class TEST2 : StructureItem<TEST2>
    {
        public TEST2()
        {
            StructureItem a = this;
            this.index = 2;
            TEST2.Elements.Add(this);
        }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var test1 = new TEST1();
            var test2 = new TEST2();

            List<StructureItem> aList = new List<StructureItem>();

            aList.Add(test1);
            aList.Add(test2);

            Console.WriteLine("all Elements:");
            foreach (var item in aList)
            {
                Console.WriteLine("Element " + item.index);
            }
            Console.WriteLine("TEST1 Elements:");
            foreach (var item in TEST1.Elements)
            {
                Console.WriteLine("Element "+item.index);
            }
            Console.WriteLine("TEST2 Elements:");
            foreach (var item in TEST2.Elements)
            {
                Console.WriteLine("Element " + item.index);
            }

        }
    }

Sortir:

all Elements:
Element 1
Element 2
TEST1 Elements:
Element 1
TEST1 Elements:
Element 2
1
ecn