Stile funzionale vs orientato agli oggetti in C #

3

Sto imparando la programmazione funzionale e affronta la seguente confusione quando la applico ai miei progetti C #:

  • Inizio scrivendo pure funzioni statiche e uso la composizione delle funzioni.
  • Dopo che il codice raggiunge una certa dimensione, mi rendo conto che alcune di queste funzioni tendono a "cluster" su alcuni tipi. Ad esempio, esistono > 5 funzioni con lo stesso tipo di parametro.

  • Il prossimo passo, il mio background orientato agli oggetti prende il sopravvento e sposto queste funzioni in questo tipo (classe) come metodi. Di conseguenza, le loro firme semplificano e spesso diventano più coese. Tuttavia, perdo i vantaggi dello stile funzionale.

Mi sono appassionato molto all'approccio funzionale, ma non riesco a convincermi che il mio codice iniziale fosse migliore di sopra. Quale approccio preferiresti in questa situazione (in C # o in un'altra lingua mista)?

Correlati: Design in "misto" lingue: progettazione orientata agli oggetti o programmazione funzionale?

class MyType { }

class Functions
{
    public static void X(MyType t) { }
    public static void Y(MyType t) { }
    public static void Z(MyType t) { }
    public static void T(MyType t) { }
    public static void U(MyType t) { }
}

class Class1
{
    public MyType T { get; private set; }
    public Class1(MyType t) { T = t; }
    public void X() { }
    public void Y() { }
    public void Z() { }
    public void T() { }
    public void U() { }
}
    
posta henginy 11.05.2015 - 13:55
fonte

3 risposte

6

However, I lose the benefits of functional style.

Se sempre perdi i vantaggi del codice di stile funzionale durante la conversione di pacchetti di funzioni in oggetti, stai sbagliando (o hai una normale idea di quali siano i vantaggi dello stile funzionale).

Dopo tutto, le funzioni di istanza sono la stessa cosa come funzioni statiche ma hanno semplicemente un parametro implicito aggiuntivo. Se stai rendendo impure queste funzioni, questo è il tuo problema, non un problema inerente al codice OO. Se rendi le tue classi mutabili, allora sì, perderai i vantaggi dello stile funzionale.

Ma se si mantengono immutabili le classi (tranne che per le raccolte / DTO), trovo che è possibile mantenere molti dei vantaggi della codifica in stile funzionale e ottenere allo stesso tempo una certa bontà OO.

    
risposta data 11.05.2015 - 15:14
fonte
2

Non penso che il semplice utilizzo di metodi statici lo renda funzionale

Non penso che spostare semplicemente i metodi precedentemente statici in una classe lo renda OO

Se stai facendo OO, le tue classi dovrebbero avere proprietà e i metodi dovrebbero cambiare quelle proprietà. Questo rende la programmazione mutabile e funzionale degli oggetti dati fuori dalla finestra

Mentre Static non ti consente di utilizzare proprietà della stessa classe, puoi comunque fare riferimento ad altri dati statici o database ecc. La programmazione funzionale si basa sui metodi che restituiscono sempre lo stesso risultato per gli stessi parametri.

Dal tuo codice di esempio:

ive ha seguito il tuo pattern ma ha aggiunto un metodo reale

public class MyType
{
    public int ANumber { get; set; }
}

public class StaticFunctions
{
    public static int AddOne(MyType x)
    {
        return x.ANumber + 1;
    }
}

quindi converti il tuo metodo statico in OO tramite questo tipo di pattern:

public class MyOOClass
{
    public MyType data { get; private set; }
    public MyOOClass(MyType data)
    { this.data = data; }

    public int AddOne()
    {
        return this.data.ANumber + 1;
    }
}

Ma in realtà questo non è altro che uno spazio dei nomi per le tue funzioni statiche. probabilmente li rende più difficili da utilizzare in quanto devi avviare un MyOoclass aggiuntivo per ogni MyType.

Se volessi renderlo OO, lo cambierei in qualcosa del genere:

public class OOClass
{
    public int ANumber { get; private set; }
    public OOClass(int n)
    {
        this.ANumber = n;
    }

    public void AddOne()
    {
        this.ANumber= this.ANumber+1;
    }
}

se vuoi renderlo funzionale lo cambierei in qualcosa del genere:

public Func<int, int> AddOne = (x) => x + 1;

Il mio preferito personale sarebbe ADM

public class AdditionService()
{
    public MyType AddOne(MyType a)
    {
        return new MyType() {ANumber=a.ANumber+1};
    }
}
    
risposta data 11.05.2015 - 15:42
fonte
1

Puoi scrivere funzioni anche quando usi le classi.

Hai detto che hai creato delle funzioni statiche, quindi non esiste uno "stato". Quando sposti questi metodi nelle rispettive classi, ovviamente non possono continuare a essere statici, devono essere metodi di istanza regolari.

Ma se non modifichi nessuno dei parametri, anche il ricevente del messaggio (che è lo stesso del contenitore del metodo), continua ad essere uno stile funzionale. Basta non modificare nessuno dei parametri.

Il vero vantaggio dello stile funzionale è che lo stile funzionale può essere eseguito funzionalmente in un modo molto semplice: sostituire il codice chiamato con il corpo dell'ode richiamato. Puoi ripetere questo molte volte. E quindi puoi essere sicuro che produce l'output desiderato.

    
risposta data 11.05.2015 - 15:47
fonte

Leggi altre domande sui tag