Per evitare lunghe classi lavorative procedurali come ad es. BookService
con molti, molti metodi che fanno lo stesso, abbiamo deciso di creare una classe di comando invece di ogni metodo - o un insieme di metodi simili. Ad esempio, se BookService
ha il seguente metodo:
Book createBook(String name, String author, String description) {
// business code
db.store(book);
return book;
}
Abbiamo 3 cose qui
- campi obbligatori (
name
,author
) - campo facoltativo (
description
) - utilizzo dell'infrastruttura (
db
)
Dopo la sostituzione, abbiamo il seguente:
Book createBook(String name, String author) {
return new CreateBookCmd(db).withName(name).withAuthor(author);
}
e la classe di comando è:
public class CreateBookCmd() implements Cmd {
public CreateBookCmd(Db db) {this.db=db;}
public CreateBookCmd withName(String name) {this.name=name; return this;}
public CreateBookCmd withAuthor(String author) {this.author=author; return this;}
public CreateBookCmd withDescription(String description) {this.description=description; return this;}
public Book execute() {
// validate inputs
// business code
db.store(book);
return book;
}
}
Cose che mi piacciono:
- metodo factory nella classe originale specifica solo argomenti obbligatori, altri sono chiamati con interfaccia fluente:
bookManager.createBook("A", "B").withDescription("C").execute();
- Il codice aziendale è incapsulato in una classe.
Cose che non mi piacciono:
- senza una fabbrica non c'è modo di capire quale proprietà è obbligatoria in fase di compilazione.
- necessità di inserire l'infrastruttura in business class.
Domanda:
- Non sarebbe meglio se la classe di comando avesse argomenti obbligatori nel costruttore?
- Forse è meglio rimuovere tutti gli argomenti da ctor e iniettare anche l'infrastruttura usando i metodi
with
? - C'è un modo per forzare la verifica in fase di compilazione se tutti gli argomenti richiesti sono impostati prima di chiamare exec ()
In qualche modo mi dà fastidio che qualcosa sia passato in costruttore e qualcosa passi usando setter o con-metodi.