Quali sono i vantaggi di mantenere rigorosamente dati separati | algoritmo | livelli di interfaccia?

5

Separo sempre l'interfaccia utente da altre funzionalità nei miei programmi - è il modo in cui mi è stato insegnato, e ha evidenti vantaggi dal momento che puoi cambiare l'interfaccia mantenendo la stessa funzionalità.

Tuttavia, ho incontrato alcuni programmatori che separano strettamente i dati, gli algoritmi e l'interfaccia. Quindi gli oggetti dati che contengono i dati nella memoria volatile hanno solo campi / proprietà e i loro getter e setter. Tutti gli algoritmi sono tenuti in una classe separata.

A mio avviso, il principale svantaggio di questo è che le classi dell'algoritmo di solito richiedono un accesso completo ai dati nelle classi di dati. Potresti voler avere una classe più funzionale che crei con molti dati, ma gli oggetti di altre classi possono solo ottenere quei dati in modi specializzati.

    
posta Paul Richards 28.03.2014 - 11:59
fonte

2 risposte

4

Si chiama Plain Old Data Structure (PODS). Sono abbastanza comuni nei luoghi in cui i dati immettono per la prima volta un sistema da una fonte esterna, come un database. In effetti la loro singola responsabilità è quella di astrarre i dati esterni in una forma che è più facile da consumare per i livelli superiori.

In altre parole, consente ai programmatori di livelli superiori di lavorare con oggetti nativi familiari piuttosto che dover cospargere gli accessi alla sorgente esterna attraverso il codice. I dati vengono letti nel sistema in un unico punto e solo quel luogo deve essere modificato se cambia l'interfaccia con l'origine esterna.

Come qualsiasi principio, può essere preso troppo lontano. Se usano comunemente un PODS su dati solo interni, è probabilmente errato in OOP. Nota comunque che passare attorno a un POD è un modello abbastanza comune nella programmazione funzionale, nel bene e nel male.

    
risposta data 28.03.2014 - 14:00
fonte
0

Quando incapsuli i dati, ti stai limitando a essere in grado di eseguire solo un numero limitato di operazioni su di esso. Ma spesso c'è un numero illimitato di cose che vuoi fare con i dati.

Supponiamo di scrivere un semplice gioco di ruolo. Scriviamo una classe Weapon ed esaminiamo cosa succede se nascondiamo tutti i suoi dati.

public class Weapon {
    private int damage;
    private int accuracy;

    public Weapon(int damage, int accuracy) {
        this.damage = damage;
        this.accuracy = accuracy;
    }
}

Naturalmente, vogliamo essere in grado di colpire le persone con l'arma. Quindi abbiamo bisogno di una funzione che calcoli il danno che faremo al nemico. Ma tutte le variabili dell'arma sono private, quindi dovremo trasformare quella funzione in un metodo.

public int hitEnemy(Enemy theEnemy) {
    return theEnemy.getDefense() - this.damage;
}

Avremo anche bisogno di un modo per determinare se siamo riusciti nel nostro attacco. Di nuovo, diventerà un metodo.

public boolean tryToHit(Enemy theEnemy) {
    return random() > (theEnemy.getEvasion() - this.accuracy);
}

In seguito scopriremo che vogliamo confrontare due armi per vedere quale ha più danni. Un altro metodo.

public Order compareDamage(Weapon other) {
    if (this.damage > other.damage) {
        return Order.GREATER;
    } else if (this.damage < other.damage) {
        return Order.LESS;
    } else {
        return Order.EQUAL;
    }
}

Alcuni giorni dopo decidiamo che il prezzo di un'arma dovrebbe essere determinato in base al suo danno e alla sua accuratezza ...

public int getPrice() {
    return 10 * this.damage + 0.5 * this.accuracy;
}

La settimana seguente vogliamo dare le valutazioni delle armi da C a A in base alle loro statistiche ...

public Rating getRating() {
    if (accuracy/10 + damage > 10) {
        return Rating.A;
    } else if (accuracy/10 + damage > 5) {
        return Rating.B;
    } else {
        return Rating.C;
 }

Come puoi vedere, ogni volta che dobbiamo fare qualcosa di nuovo con l'arma, dobbiamo lanciarlo nella classe dell'arma per ottenere le sue variabili. È sbagliato: viola il Principio Aperto / Chiuso , in cui si afferma che il codice deve essere aperto all'estensione e chiuso alla modifica . Se avessimo trasformato Weapon in un semplice vecchio oggetto dati - un semplice record con nient'altro che dati pubblici - saremmo in grado di aggiungere funzioni per utilizzare le armi in modi nuovi senza dover modificare la classe Weapon .

Quando progetti un'astrazione X, devi distinguere tra cose X fa e cose che posso fare con X . Le nostre armi non fanno nulla, quindi non ci sono dettagli di implementazione da nascondere. Nascondere tutti i loro dati dietro variabili private è utile tanto quanto un elenco che non ti consente di accedere ai suoi elementi. Il nostro gioco avrà sicuramente bisogno di incapsulamento e astrazione, ma dovrebbe essere implementato a un livello superiore, nella logica di gioco corretta.

    
risposta data 28.03.2014 - 13:52
fonte

Leggi altre domande sui tag