Domanda

Ho uno scenario comune in cui ho un oggetto (a) che logicamente colpisce un altro oggetto (b), come una fa una nota sulla b, o un Marks b come disabili (di solito a è un oggetto utente del sistema e b è una sorta di oggetto di business come un cliente o un appuntamento).

In passato, il metodo era sull'oggetto interessata come:

customer.Disable(user); // user is marking the customer as disabled

... ma non legge bene (sembra indietro). L'opposto:

user.Disable(customer);

... legge meglio, ma c'è qualcosa che non riesco a mettere il dito su che proprio non mi sembra giusto. L'unica altra opzione è quella di avere un intermediario statica:

ThirdPartyClass.DisableCustomer(customer, user);

... ma gli oggetti di dominio finiscono per diventare più simile DTOs e preferisco l'approccio modello di dominio perché rende più senso.

Quindi la domanda è: che rende più senso? C'è la possibilità che non ho preso in considerazione? Chi possiede in realtà un'operazione come questa?

Modifica

Con la seconda opzione, gli oggetti attuabili nel sistema (gli utenti di solito) finiscono per diventare enorme perché gli utenti del sistema sono quelli che più o meno fanno e colpiscono tutto.

È stato utile?

Soluzione

Come su

customer.SetDisabledBy(user);

o se si utilizza C # 4.0 o una lingua diversa con funzionalità simili:

customer.SetDisabled(by: user);

o se si sta utilizzando C # 3.5 o più recente, è possibile scrivere il seguente:

user.DisableCustomer(customer);

mentre avendo il metodo DisableCustomer essere un metodo di estensione seduta in una chiamata CustomerActions classe che si siede insieme con la classe Customer. In questo modo, quando si è using lo spazio dei nomi Customer, User avrete che metodo di estensione. Quando non stai using esso, non c'è più. User non è più un oggetto Dio ma la classe intermediario è introvabile nel codice. Si potrebbe anche avere una classe OrderActions che fornirà user.CancelOrder(order), ecc.

Buona domanda, mi ha fatto pensare!

Altri suggerimenti

user.Disable(customer) sembra quasi come se fosse dire che user è essere disattivato, in quanto user.Disable() avrebbe letto come se fosse agendo sulla utente, non il cliente.

user.DisableCustomer(customer) legge un po 'meglio, credo, in quanto rende chiaro che il cliente è essere disattivato. Significa anche che non è necessario un classe in più solo per il gusto di farlo.

Se gli oggetti utente stanno assumendo così tante responsabilità che ci si sente come hanno troppi "user.DoFooOnBar (bar)" metodi, allora si può guardare un oggetto Dio. Si potrebbe sentire meglio o utilizzando interfacce per rompere i ruoli di utenti in pezzi dominio-specifici, o utilizzando la composizione a fare lo stesso.

Interfacce

Si avrebbe avuto un ICustomerController interfaccia che implementa l'utente, quindi quando si ha bisogno gli utenti per i clienti disattivare, lanci il cliente in un ICustomerControl e può utilizzare ICC.DisableCustomer (cliente). Che fornisce una lettura naturale mossa perché il cliente viene manipolato, non da un utente, ma da "qualcosa che manipola clienti".

Si lascia inoltre più flessibile per lasciare che le cose che non sono clienti aggiornare gli utenti, se è necessario.

Composizione

solo un'estensione della ultima idea: invece di essere utenti ICustomerControllers (IS-A) che avrebbero possedere un ICustomerController (HAS-A). Così ora la chiamata recita user.CustomerController.Disable (cliente). Ancora una volta, questo lo rende chiaro che gli utenti stanno agendo in una certa capacità (di influenzare i clienti) e solo contro quella del dominio degli oggetti (clienti).

Non aveva detto che problema, ma un metodo come user.Disable () potrebbe sembrare influenzare qualsiasi cosa, anche l'utente stesso. Entrambe le corregge di cui sopra che.

Come fai notare avere un sacco di metodi sulla classe utente sta introducendo il Dio Object anti-modello . Sembra che il problema è quello di incapsulamento, in modo che il flusso di dati

esegue utente un'azione su un'entità

può essere re-interpretata come

Sistema eseguire comandi sul ente con riferimento alla User

Questo significherebbe un design che ha favorito utilizzando un modello di comando con un comando tipico di essere in questo modo:

public class DisableCustomerCommand implements EntityCommand<Customer,User> {

  // This is the single EntityCommand templated method
  public Customer execute(Customer customer, User user) {
    customer.setEnabled(false);

    // TODO Add in audit code for User object

    return customer;
  }
}

Questo segue il principio generale della OOD creare ritrovamento grana oggetti semplici che fanno molto poco, ma farlo bene.

Modifica

Vorrei sottolineare che questa è una semplificazione eccessiva. In genere, la disabilitazione di un cliente richiederebbe parecchi altri campi da modificare. Anche questo fa portare a soggetti anemici (Customer sarebbe solo un mucchio di getter / setter), ma a volte questo può essere un disegno complessivo più semplice.

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