Domanda

Premessa

Io credo che ci sia un modo per definire oggettivamente "Buoni" e "Cattivi" Object-Oriented " tecniche di progettazione e che, come comunità, siamo in grado di determinare che cosa questi sono.Questo è un esercizio accademico.Se fatto con serietà e risolvere, credo che può essere di grande beneficio per tutta la comunità.La comunità dei vantaggi di avere un posto dove possiamo scegliere di dire "Questa tecnica è 'Buono' o 'Cattivo' e dobbiamo o non dobbiamo usarlo a meno che non sussistano circostanze particolari."

Piano

Per questo sforzo, ci si deve concentrare su principi Orientato agli Oggetti (come invece Funzionale, Set-based, o di altre lingue).

Non intendo accettare una risposta, invece vorrei le risposte a contribuire alla raccolta finale o essere un dibattito razionale dei problemi.

Mi rendo conto che questo può essere controverso, ma credo che possiamo ferro qualcosa.Ci sono eccezioni ad ogni regola, e credo che questo è dove il disaccordo di cadere.Ci deve rendere le dichiarazioni e poi nota rilevanti eccezioni ed obiezioni dei dissidenti.

Base

Mi piacerebbe prendere una pugnalata a definire "Buoni" e "Cattivi":

  • "Bene" - Questa tecnica funzionerà la prima volta e di essere una soluzione duratura.Sarà facile cambiare in seguito a pagare l'investimento di tempo della sua attuazione rapidamente.Può essere applicato in modo coerente e facilmente riconoscibile per la manutenzione programmatori in futuro.In generale, contribuisce al buon funzionamento e di ridurre i costi di manutenzione durante la vita del prodotto.

  • "Cattivo" - Questa tecnica può funzionare nel breve termine, ma ben presto diventa una responsabilità.Immediatamente è difficile cambiare o diventa più difficile nel tempo.L'investimento iniziale può essere piccolo o grande, ma diventa rapidamente un costo in crescita, fino a diventare un costo affondato e deve essere rimosso o si è lavorato costantemente intorno.È soggettivamente applicata e incoerenti, e può essere una sorpresa, o non facilmente riconoscibile per la manutenzione programmatori in futuro.In generale, contribuisce all'ultimo aumento dei costi di mantenimento e/o il funzionamento del prodotto e inibisce o impedisce di apportare modifiche al prodotto.Inibendo o prevenire cambiamenti, diventa non solo un costo diretto, ma un costo-opportunità e una notevole responsabilità.

Motorino di avviamento

Come esempio di ciò che io penso che un buon contributo sarebbe simile, vorrei proporre una "Buona" linea di principio:

La separazione delle Preoccupazioni

[Breve descrizione]

Esempio

[Codice o qualche altro tipo di esempio]

Obiettivi

[Spiegazione di quali sono i problemi che questo principio impedisce]

Applicabilità

[Perché, dove e quando si usa questo principio?]

Eccezioni

[Quando non utilizzare questo principio, o dove potrebbe effettivamente essere dannoso?]

Obiezioni

[Nota di eventuali pareri contrari o obiezioni da parte della comunità qui]

È stato utile?

Soluzione

La separazione delle Preoccupazioni

Preferisco di Aggregazione per Mixin in stile Eredità

Mentre la funzionalità può essere acquisita da ereditare da una classe di utilità che, in molti casi può essere ottenuto utilizzando un membro di tale classe.

Esempio (Boost.Noncopyable):

Boost.Noncopyable è una classe C++ che manca un costruttore di copia o di operatore di assegnazione.Può essere usato come una classe di base per prevenire la sottoclasse da essere copiati o ricevuto (questo è il comportamento comune).Può anche essere utilizzato come un membro diretto

Convertire questo:

class Foo : private boost::noncopyable { ... };

Per questo:

class Foo {
    ...
private:
    boost::noncopyable noncopyable_;
};

Esempio (con Serratura oggetto):

Java ha introdotto il synchronized parola chiave di un linguaggio che permetta a qualunque oggetto per essere utilizzato in un threadsafe modo.Questo può essere riflesso in altre lingue per fornire i mutex di oggetti arbitrari.Un esempio comune è di strutture di dati:

class ThreadsafeVector<T> : public Vector<T>, public Mutex { ... };

Invece, le due classi possono essere aggregati.

struct ThreadsafeVector<T> {
    Vector<T> vector;
    Mutex mutex;
}

Obiettivi

L'ereditarietà è spesso abusato come un codice di riutilizzare il meccanismo.Se l'eredità è utilizzato per oltre un È-Una relazione generale codice chiarezza è ridotto.

Con più catene, mixin classi di base aumentare notevolmente la probabilità di un "Diamante della Morte" scenario in cui una sottoclasse finisce per eredita di più copie di un mixin classe.

Applicabilità

Qualsiasi linguaggio che supporta l'ereditarietà multipla.

Eccezioni

Ogni caso in cui il mixin classe offre o richiede un sovraccarico membri.In questo caso, l'eredità di solito implica un Si-Realizzato-In-Termini-Di relazione e di aggregazione, non sarà sufficiente.

Obiezioni

Il risultato di questa trasformazione può portare a membri pubblici (ad es. MyThreadSafeDataStructure può avere pubblicamente accessibile Mutex come un componente).

Altri suggerimenti

Ci sono alcuni principi ben compresi che potrebbero costituire un buon punto di partenza:

E 'anche una buona idea per studiare gli schemi di progettazione esistenti per trovare i principi dietro di loro, il più importante è quello di (generalmente) preferiscono la composizione per l'eredità.

Credo che la risposta breve è che "buoni", una creazione OO sono robusti sotto il cambiamento, con la rottura del codice almeno per tutte le esigenze cambiano. Se si considerano tutte le solite regole, tutti tendono alla stessa conclusione.

La difficoltà è che non è possibile valutare la "bontà" del progetto senza contesto; è, ritengo, un teorema che per ogni modularizzazione, esiste un cambiamento di requisiti in grado di massimizzare la rottura, causando ogni classe da toccare in ciascun metodo.

Se si vuole essere rigorosi su di esso, è possibile sviluppare una collezione di "casi cambiamento" e loro l'ordine in ordine di probabilità, in modo da ridurre al minimo la rottura per le più alte probabilità modifiche.

Nella maggior parte dei casi, però, un po 'di intuito ben sviluppato aiuta molto: specifica specifico del dispositivo o piattaforma cose tendono a cambiare, regole di business e dei processi di business tendono a cambiare, mentre le implementazioni di, per esempio, l'aritmetica, cambiano molto raramente . (Non, come si potrebbe immaginare, mai. Si consideri, ad esempio, un sistema di business che può o non può essere in grado di fare uso di piattaforme supportate da BCD aritmetica.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top