Z inspiracji od innych odpowiedzi wymyśliłem następujący (szorstki) klasowej hierarchii, który jest podobny do wzoru ciasto 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 {}
Powyższe kompiluje się na Javie 8 od Jan.9 2013.
Tak, można zrobić Java 8 cake- jak wzór? Tak.
Czy jest tak zwięzły jak Scala, czy tak samo skuteczny, jak inne wzorce w Javie (to jest zastrzyk zależności)? Prawdopodobnie nie, powyższy szkic wymagał dużej ilości plików i nie jest tak zwięzły jak Scala.
Podsumowując:
- samoczynnej rodzaje (ile potrzeba do wzorca ciasto) może być naśladowane przez rozszerzenie interfejsu bazową spodziewać.
- Interfejsy nie mogą mieć klas wewnętrznych (jak zauważył @Owen), więc zamiast tego możemy używać klas anonimowych.
val
i var
mogą być emulowane za pomocą statycznej hashmap (i leniwej inicjalizacji) lub przez klienta klasy po prostu przechowującej wartość po swojej stronie (jak robi UserService).
- Możemy odkryć nasz typ za pomocą
this.getClass()
w domyślnej metodzie interfejsu.
- Jak zauważa @Owen, typy zależne od ścieżki są niemożliwe przy użyciu interfejsów, więc pełny wzór ciasta jest z natury niemożliwy. Powyższe pokazuje jednak, że można go użyć do zastrzyku zależności.
Powinieneś mieć dostęp do 'this' i' this.getClass() 'w domyślnej treści metody i możesz dodać dodatkowy stan przez słabą mapę tożsamości. Jednak w przykładzie rejestrowania nie jest to po prostu sposób java; nic złego w prostym/starym rozwiązaniu dodawania pola instancji 'końcowy Logger Logger = Logger.of (this);' w celu uzyskania efektu mixin. – irreputable
Masz rację, zaktualizowałeś wpis, aby to odzwierciedlić. –
dzięki, świetna odpowiedź! –