Che cosa è buona pratica quando si ereditano le classi statiche non è possibile / permesso

3

Sto sviluppando un progetto in C # ea causa di una decisione di progettazione non è possibile che una classe statica erediti un'altra classe statica. Ma ho, a mio parere, un caso in cui ciò avrebbe senso.

Ho un lettore musicale che è in grado di riprodurre musica da diverse fonti musicali: file locali, YouTube, SoundCloud, Jamendo, ecc. Attualmente ho una classe statica per ognuna di queste fonti con metodi statici come il recupero della parte superiore tracce, ricerca di tracce, ecc.

Naturalmente, un sacco di codice è condiviso tra tutte queste classi, quindi ho voluto refactoring e mettere tutto il codice comune in una classe MusicSource più generica. Ma C # non mi consente di farlo.

Quale sarebbe la migliore pratica qui? Voglio sbarazzarmi di tutto il mio codice ridondante e rendere più facile la creazione di nuove fonti musicali.

    
posta Christoffer Reijer 12.07.2013 - 10:20
fonte

4 risposte

15

Quelle classi "sorgente musicale" suonano più come classi non statiche alle quali ti capita di volere una sola istanza. Sono due cose diverse!

Ecco alcuni motivi per cui potresti voler renderli non statici:

  • Se hanno (o potrebbero eventualmente avere) uno stato interno. per esempio. Credenziali di accesso memorizzate nella cache o elenchi memorizzati nella cache delle prime 10 tracce. Le classi statiche statiche sono una cattiva idea! Sono fondamentalmente una cattiva implementazione di un singleton.
  • Se hai molte fonti musicali, potresti voler eseguire alcune azioni su tutte. per esempio. Trova una traccia particolare da qualsiasi fonte. Con le classi statiche avrai bisogno di una linea per ogni classe. Se hai classi non statiche puoi semplicemente eseguire il loop su una raccolta di esse.

Esiste un'ottima risposta qui che fornisce ulteriori motivi e fornisce maggiori dettagli.

    
risposta data 12.07.2013 - 11:01
fonte
3

Non è possibile ereditare affatto le classi statiche (almeno in C #), indipendentemente da qualsiasi "decisione di progettazione".

Forse la tua domanda necessita di riformulazione, ma non puoi usare classi non statiche come in questo esempio forzato e troppo semplice,

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

    protected string SomeCommonProperty { get; set; }
}

class JamendoSource : MusicSource 
{   
    override MusicData LoadMusic(string source)
    {
        // Jamendo-specific code
    }
}
    
risposta data 12.07.2013 - 10:36
fonte
1

L'uso statico in questo caso è completamente sbagliato. Le persone tendono a usare spesso la statica! In pratica hai 1 "MusicPlayer" con X-quantità di implementazione (youtube, ...) Quindi la prima cosa che dovrebbe apparire nella tua testa è l'ereditarietà.

Faranno tutti lo stesso, ma abit different = > Eredità. Vuoi che la tua applicazione funzioni con diversi tipi di fonti, senza alcuna necessità di adattare l'applicazione stessa = > Segregazione di ereditarietà / interfaccia.

Le classi statiche possono essere utili, ma in questo caso ho la sensazione che le lezioni di musica siano il fulcro della tua applicazione ... Non costruisci le tue funzionalità di base in classi statiche, dato che rimuovi: testabilità, manutenibilità, riusabilità , estensibilità, ...

Dici:

I want to get rid of all my redundant code and make it easier to create new music sources.

Anche qui, l'ereditarietà è centrale ...

In C #, ogni volta che usi classi statiche dimentichi l'ereditarietà. Al contrario, ogni volta che hai bisogno di ereditarietà, dimentica le classi statiche.

Perché inizialmente li hai resi statici comunque?

Se vuoi avere una sola istanza disponibile, rendila un singleton. In caso contrario, basta renderlo non statico!

    
risposta data 17.07.2013 - 13:44
fonte
1

Non sono sicuro che qualcuno sia ancora interessato a questo argomento ma ho provato quanto segue. Probabilmente è un modo per una soluzione generica che implica un comportamento statico.

  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);
            }

        }
    }

Output:

all Elements:
Element 1
Element 2
TEST1 Elements:
Element 1
TEST1 Elements:
Element 2
    
risposta data 10.01.2019 - 15:50
fonte

Leggi altre domande sui tag