Con ispirazione da altre risposte mi si avvicinò con la seguente (ruvida) gerarchia di classe che è simile al modello torta a Scala:
interface UserRepository {
String authenticate(String username, String password);
}
interface UserRepositoryComponent {
UserRepository getUserRepository();
}
interface UserServiceComponent extends UserRepositoryComponent {
default UserService getUserService() {
return new UserService(getUserRepository());
}
}
class UserService {
private final UserRepository repository;
UserService(UserRepository repository) {
this.repository = repository;
}
String authenticate(String username, String password) {
return repository.authenticate(username, password);
}
}
interface LocalUserRepositoryComponent extends UserRepositoryComponent {
default UserRepository getUserRepository() {
return new UserRepository() {
public String authenticate(String username, String password) {
return "LocalAuthed";
}
};
}
}
interface MongoUserRepositoryComponent extends UserRepositoryComponent {
default UserRepository getUserRepository() {
return new UserRepository() {
public String authenticate(String username, String password) {
return "MongoAuthed";
}
};
}
}
class LocalApp implements UserServiceComponent, LocalUserRepositoryComponent {}
class MongoApp implements UserServiceComponent, MongoUserRepositoryComponent {}
Le compilazioni di cui sopra su Java 8 come di Jan.9 2013.
Quindi, può Java 8 fare una torta- come modello? Sì.
È tetro come Scala, o efficace come altri modelli in Java (vale a dire l'iniezione di dipendenza)? Probabilmente no, lo schizzo sopra ha richiesto un sacco di file e non è così lineare come Scala.
In sintesi:
- Self-tipi (come necessario per il modello di torta) può essere emulato estendendo l'interfaccia di base che ci aspettiamo.
- Le interfacce non possono avere classi interne (come notato da @Owen), quindi possiamo usare le classi anonime.
val
e var
possono essere emulati utilizzando una hashmap statica (e l'inizializzazione pigra) o dal client della classe semplicemente memorizzando il valore sul lato (come fa UserService).
- Possiamo scoprire il nostro tipo utilizzando
this.getClass()
in un metodo di interfaccia predefinito.
- Come note @Owen, i tipi dipendenti dal percorso sono impossibili utilizzando le interfacce, quindi un modello di torta completo è intrinsecamente impossibile. Quanto sopra mostra, tuttavia, che si potrebbe usare per l'iniezione di dipendenza.
fonte
2013-01-10 01:03:42
Dovresti poter accedere a 'this' e' this.getClass() 'in un corpo del metodo predefinito ed è possibile aggiungere uno stato extra attraverso una mappa delle identità debole. Tuttavia, nell'esempio di registrazione, non è solo la via java; niente di sbagliato con la semplice/vecchia soluzione di aggiungere un campo di istanza 'Logger logger finale = Logger.of (this);' per ottenere l'effetto mixin. – irreputable
Sei corretto, aggiornato il post per riflettere questo. –
grazie, ottima risposta! –