使用Java8的蛋糕模式可能吗?
2022-09-01 12:02:58
我只是想知道:有了Java 8,以及在接口中添加实现的可能性(有点像Scala特征),是否有可能实现蛋糕模式,就像我们在Scala中所做的那样?
如果是,有人可以提供代码片段吗?
我只是想知道:有了Java 8,以及在接口中添加实现的可能性(有点像Scala特征),是否有可能实现蛋糕模式,就像我们在Scala中所做的那样?
如果是,有人可以提供代码片段吗?
从其他答案中汲取灵感,我想出了以下(粗略的)类层次结构,类似于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 {}
以上内容于 2013 年 1 月 9 日在 Java 8 上编译。
那么,Java 8 能做一个类似蛋糕的模式吗?是的。
它是像Scala一样简洁,还是像Java中的其他模式(即依赖注入)一样有效?可能不是,上面的草图需要大量的文件,并且不像Scala那样简洁。
综上所述:
val
并且可以通过使用静态哈希映射(和延迟初始化)来模拟,或者由类的客户端简单地将值存储在其一侧(如UserService所做的那样)。var
this.getClass()
也许你可以在Java 8中做这样的事情。
interface DataSource
{
String lookup(long id);
}
interface RealDataSource extends DataSource
{
default String lookup(long id){ return "real#"+id; }
}
interface TestDataSource extends DataSource
{
default String lookup(long id){ return "test#"+id; }
}
abstract class App implements DataSource
{
void run(){ print( "data is " + lookup(42) ); }
}
class RealApp extends App implements RealDataSource {}
new RealApp().run(); // prints "data is real#42"
class TestApp extends App implements TestDataSource {}
new TestApp().run(); // prints "data is test#42"
但它绝不比普通/旧方法更好。
interface DataSource
{
String lookup(long id);
}
class RealDataSource implements DataSource
{
String lookup(long id){ return "real#"+id; }
}
class TestDataSource implements DataSource
{
String lookup(long id){ return "test#"+id; }
}
class App
{
final DataSource ds;
App(DataSource ds){ this.ds=ds; }
void run(){ print( "data is " + ds.lookup(42) ); }
}
new App(new RealDataSource()).run(); // prints "data is real#42"
new App(new TestDataSource()).run(); // prints "data is test#42"