2010-12-30 6 views
5

Ho tre oggetti; Azione, problema e rischio. Questi contengono tutti un numero di variabili/attributi comuni (ad esempio: Descrizione, titolo, Data di scadenza, Generato da ecc.) E alcuni campi specifici (il rischio ha probabilità). La domanda è:Sottoclasse o non sottoclasse

  1. Devo creare 3 separato classi di azione, rischio e rilascia ciascuna contenente i campi di ripetizione.

  2. creare una classe genitore "Abstract_Item" contenente questi campi e operazioni su di essi e poi hanno azione, rischio e Problema sottoclasse Abstract_Item. Ciò si atterrebbe al principio SECCO .

risposta

2

Sì, aderendo a secco è di solito una buona idea tranne se le classi sono molto, molto diversi usi (vale a dire sia le mele e le auto possono essere rosso, ancora non deriverebbe da entrambi una classe base chiamata ProbablyRed). Nel tuo caso, tuttavia, sceglierei una classe base in quanto le implementazioni che descrivi (Action, Issue, Risk) sembrano tutte essere una sorta di regola aziendale con semantica molto simile.

0

Sembra che tu risponda a te stesso. Come dici tu, ASCIUTTO.

0

La classe genitore astratta suona come la strada da percorrere. Inoltre, renderà possibile o più semplice (a seconda della lingua) implementare e utilizzare funzioni che agiscono su uno dei tre elementi. Ad esempio, potresti avere una funzione "Ottieni un elenco di tutti gli articoli generati da {utente}".

0

Un altro aspetto può essere visibile se si osservano i casi d'uso, probabilmente si tratta di diversi sottogruppi delle proprietà.

Se ad esempio "etichetta", "data di scadenza" e "alzato" vengono utilizzati in un'applicazione simile all'applicazione e altre proprietà di "Azione" e "Rischio" saranno prevalenti quando si lavora su tale attività, si potrebbe considerare un aggregazione di Task consente di dire (etichetta, data di scadenza, ...) e soggetto che è un riferimento polimorfico a cose come azione, Problema o qualsiasi altra cosa si presenti un giorno

4

mio punto di vista

diciamo se hai usato l'ereditarietà. Per un periodo si hanno nuovi attributi comuni solo a Azione e Numero ma non Rischio. Come gestirai questo? Se li metti sotto genitore, il rischio eredita roba che è irrilevante (principio di sottotitolazione di Liskov che bussa?). Se metti separatamente in Azione e Rischio allora stai violando DRY, il motivo iniziale per cui hai iniziato l'ereditarietà. Il punto è Inhertence per il riutilizzo è cattivo. Se non c'è "is-a" allora meglio non usarlo e quando si è in dubbio non esiste un vero "is-a".

La mia preferenza

Non ci sono altri modi di raggiungere DRY come mostrato in seguito esempio di codice.Con questa aggiunta di nuove proprietà il mio è un altro Comune2, l'aggiunta di nuovo comportamento è nuovo Comportamento comune se non sono applicabili a tutte e 3 le classi; se sono poi basta cambiare esistente comune e CommonBehavior

public class Common implements CommonBehavior 
{ 
    String Description; 
    String title; 

    public void f() {} 
} 

public interface CommonBehavior 
{ 
    void f(); 
} 

public class Action implements CommonBehavior 
{ 
    private Common delegate; 

    pubic void f() 
    { 
    delegate.f(); 
    } 
} 

Vedi anche la mia risposta a una domanda simile con un altro esempio pratico Design pattern to add a new class

+0

Grazie per il lancio in delegazione e la buona presentazione. Cosa ne pensi del contrario (vedi oltre, Attività -> Argomento). La domanda è: la "data di scadenza" è realmente parte di Action (la tua delega) o un artefatto del flusso di lavoro che svolge un ruolo non all'interno dell'azione, solo nel contesto del flusso di lavoro che incorpora. – mtraut

+0

Grazie per aver mostrato Delegato in modo così chiaro. Quello che ho per azione, problema e rischio è davvero un insieme di comportamenti comuni. L'utilizzo dell'approccio delegato renderà molto più chiaro il funzionamento delle classi durante la lettura dell'inizio del codice. Prendendo esempio di "Attività" sotto, l'Azione può essere un compito ma il Rischio no. L'intenzione delle classi diventa molto chiara quando Action è ora: "Action implements CommonBehaviour, Task, MeetingIem", dove Risk è: "Risk implements CommonBehaviour, MeetingItem". – poulenc

+0

Sono contento che tu l'abbia capito. Suggerisco anche di passare la mia risposta qui a una domanda simile http://stackoverflow.com/questions/4512184/design-pattern-to-add-a-new-class/4512234#4512234 –

0

Non sottoclassi t perché gli oggetti condividono alcuni dati o operazioni. Considera la composizione come il modo predefinito per seguire DRY.

Nel tuo caso particolare, crea una classe genitore solo se i tuoi oggetti sono effettivamente correlati, cioè c'è una relazione semantica "è una" con la classe genitore. Ad esempio, se Azione, Problema e Rischio sono tutti oggetti Ticket.